- QEMU로 해당 펌웨어를 실행시키는 환경 구축해보기
- Firmware 를 변경하여 공유기에 올려보기
- NAND FLASH의 내용을 추출해보기
ARM Firmware Hacking
AVR reverse engineering(1) - 환경구축
Reversing.Kr 에 CustomShell 이라고 AVR revese engineering 문제가 있어서 풀어보려고 한다.
우선 Atmel AVR 8 bit 이기 때문에 이에 맞는 실행 환경을 구축해야한다.
다양한 방법이 있지만,
Atmel Studio 4.19와 HAPSIM을 사용하여 구축하려고 한다.
사실 Linux의 simavr, simulavr 을 사용하려고 했는데, 동작이 내가 예상했던대로 안되는데..
ATmega128L에서 USART를 사용하여 입,출력을 하는데 내가 simavr,simulavr의 USART 입출력을 제대로 다루지 못해 안되는 것이라고 생각되지만
정확하게 원인을 잘 모르겠다. ㅠㅠ
ATmel Studio 4.19 - https://www.microchip.com/avr-support/avr-and-sam-downloads-archive (스크롤을 내려서 하단에 보면 Atmel studio 4를 다운받을 수 있다.)
HAPSIM - http://www.helmix.at/hapsim/#hapsimdownload
아무래도 윈도우 10 이전에 나온거다 보니 구동환경은 윈도우 7 32bit 가 적절하다고 생각한다.
이하 환경 구축은
https://blukat29.github.io/2015/09/debugging-avr/ 이 분의 글을 보면서 구축하였다.
(1)초기화면에서 Open을 누르고 기존에 있는 ELF 파일을 누르고 나면 해당화면과 같이 Device를 고를 수 있다. 나는 ATmega128을 선택하였다.
(2)hapsim을 실행시키고 File -> New -> Terminal을 선택하고, Options -> Terminal Settings 에 들어간 후 아래의 화면처럼 Local Echo에 체크하고 USART0을 선택한 후 OK를 눌렀다.
(3) AVR studio 에서 Run 을 누르면 아래와 같이 출력된다. 근데 처음 Run을 눌렀을 때 화면도 안나오고 했었는데,
AVR studio 에서 start debugging 을 누른 상태에서 hapsim을 실행하고 그 후 (2)을 거친 후 Run 눌러야 잘 동작했다.
끗
'reversing.kr' 카테고리의 다른 글
AVR reverse engineering (5) CustomShell (0) | 2018.08.06 |
---|---|
reversing.kr CRC1 (0) | 2018.02.07 |
AVR reverse engineering (4) CustomShell (0) | 2018.02.05 |
AVR reverse engineering (3) CustomShell (0) | 2018.02.05 |
AVR reverse engineering (2) AVR ATmega128 (0) | 2018.01.30 |
SIMPLE BIT
IDA로 해당파일을 열면 아래와 같은 그래프가 우리를 맞이해준다.
오우야
어셈블리어로 보면 위와 같은 사진으로 1이 쭉 들어가고 있다.
이 부분을 대충보고 넘어갔는데, 뻘짓하다가 다시 돌아와서 보니 4byte 배열로 1이 들어간게 아 니라 듬성듬성 띄워져 있었다.
끝없는 1의 나열 끝에 다음과 같이 분기문과 루프문이 보인다. 입력한 문자열로 무언가 하고 있 었는데 이 부분에서 멀쩡한 Hex Ray 기능을 안쓰고 이것만 보고있다가 시간을 까먹었다.
Hex Ray 기능을 쓰면 아래와 같이 간결하게 나온다.
278~285 라인에서 받은 문자열을 4byte 배열에 0과 1로 바꿔서 넣는다.
그리고 286~296라인에서 0과 1로 표현 4byte 배열을 가지고 이리저리 비트를 뒤집는다.
나머지 297~304라인에서 무언가와 비교를 해서 모두다 일치하면 1 아니면 0을 리턴 한다.
그 무언가는 앞서 말했던 1이 쭈욱 들어가던 녀석들이다. 즉, 초기에 들어가던 1값을 역산하면 무 언가가 나온다고 생각하였다.
Sub_104C에서는 무엇을 하는가 살펴보았는데 아래와 같았다.
파라미터 a2 는 문자열길이*8 이었고, a1은 입력한 문자열을 0과 1로 바꾼 배열의 포인터이다. 따라서 해당 함수는 a2배열의 v4번째 원소와 i번째 원소에 대해 if 문 내의 과정을 거치는데 저것을 계산해보면 아래와 같다.
A1[i] 의 값을 x a1[v4]의 값을 y라고 한다면
14번째라인 a1[i] = x^y
15번째라인 a1[v4] = y^(x^y)
16번째라인 result 은 a1[i]를 가리키게 한다.
17번째라인 result = (x^y)^(y^x^y) = a1[i]
XOR 연산에서는 교환법칙 결합법칙이 모두 성립하므로 A1[v4] = y^y^x, y^y = 0 이므로 A[v4] = x
Result = (x^y)^(y^x^y) = x^(y^y)^x^y = x^x^y = y = a[i] 이다
즉 결과적으로 해당 함수의 행동은
0~(a2-1) 사이의 인덱스를 rand()%a2 로 구한 후
a1[i] 와 a1[v4]를 교환하는 것이다.
다시 sub_104c를 호출하는 함수로 돌아가면
이 곳을 거꾸로 하면 플래그가 출력되겠다는 생각이 들었다.
따라서 아래와 같은 과정으로 역산 하는 코드를 작성하였다.
1. gdb에서 비교대상이 되는 배열에서 값을 가져온다.
2. Rand() 함수가 srand()를 사용하여 시드를 바꾸지 않으므로 항상 일정한 패턴의 난수가 출력 출력된다. 따라서 미리 rand()함수를 여러 번 호출하여 rand()값이 들어있는 16*비교대상 배 열 길이의 배열을 생성한다.
3. 이 후 295 -> 287순으로 16번 반복하는 코드를 작성한다
이렇게 진행하였으나 3에서 문제가 생겨서 안되었다. 저것을 거꾸로 해도 원래의 값이 안 나왔 기 때문 ㅠㅠ
뭔가 그레이코드 처럼 보이기도 해서 그레이코드인가 유심히 살펴봤으나 그레이코드도 아니라는 생각이 들었고 어떻게 저 부분을 역연산 할까 고민하다가 생각난 것이
v3 값을 처음에 주기 때문에 v3 값을 알고 있고 결과값을 안다면 연산하기 전 값이 출력되지 않을까? 라는 가정을 세우고 다시 역연산을 해보았다.
예를들어 v3=1 이고 결과값이 1 일 때, 연산 전 값이 0 라면 결과값이 1이 나오므로 맞다.
하지만 v3=1 이고 결과값이 1 일 때, 연산 전 값이 1 이라면 v3 은 0이 되므로 결과값이 0이 나와야 하므로 모순이다.
이런 식으로 v3와 결과값에 대한 테이블을 작성하니 아래와 같이 나왔다.
v3 가 0 일 때 |
v3 가 1 일 때 |
|
연산결과 가 0 일 때 |
0 |
1 |
연산결과 가 1 일 때 |
1 |
0 |
따라서 위와 같은 테이블을 참조하여 역연산 하도록 하였다.
결과가 아래와 같이 출력되었다.