PADOCON 2010 hand-ray 리버싱 풀이 3rd

PADOCON 2010 핸드레이 세 번째 문제는 두 번째 문제보다 더 많은 삽질을 요구했습니다. 예선전 문제였던 ddanjin과 유형이 같은데요, 차이라 하면은 핸드레이로 풀어야 한다는 것 뿐이네요…

문제

다음 코드에서 입력코드가 k1n0TheBest 일 때 출력될 값은 무엇인가?

00401000  /$  83EC 70                 SUB ESP,70
00401003  |.  A1 34604000             MOV EAX,DWORD PTR DS:[406034]
00401008  |.  8B0D 38604000           MOV ECX,DWORD PTR DS:[406038]
0040100E  |.  8B15 3C604000           MOV EDX,DWORD PTR DS:[40603C]
00401014  |.  894424 0C               MOV DWORD PTR SS:[ESP+C],EAX
00401018  |.  894C24 10               MOV DWORD PTR SS:[ESP+10],ECX
0040101C  |.  33C0                    XOR EAX,EAX
0040101E  |.  33C9                    XOR ECX,ECX
00401020  |.  895424 14               MOV DWORD PTR SS:[ESP+14],EDX
00401024  |.  894C24 01               MOV DWORD PTR SS:[ESP+1],ECX
00401028  |.  BA 0C000000             MOV EDX,0C
0040102D  |.  894C24 05               MOV DWORD PTR SS:[ESP+5],ECX
00401031  |.  895424 30               MOV DWORD PTR SS:[ESP+30],EDX
00401035  |.  66:894C24 09            MOV WORD PTR SS:[ESP+9],CX
0040103A  |.  895424 3C               MOV DWORD PTR SS:[ESP+3C],EDX
0040103E  |.  B9 09000000             MOV ECX,9
00401043  |.  BA 01000000             MOV EDX,1
00401048  |.  884424 00               MOV BYTE PTR SS:[ESP],AL
0040104C  |.  C74424 18 02000000      MOV DWORD PTR SS:[ESP+18],2
00401054  |.  C74424 1C 0A000000      MOV DWORD PTR SS:[ESP+1C],0A
0040105C  |.  C74424 20 04000000      MOV DWORD PTR SS:[ESP+20],4
00401064  |.  C74424 24 08000000      MOV DWORD PTR SS:[ESP+24],8
0040106C  |.  C74424 28 0B000000      MOV DWORD PTR SS:[ESP+28],0B
00401074  |.  C74424 2C 05000000      MOV DWORD PTR SS:[ESP+2C],5
0040107C  |.  894C24 34               MOV DWORD PTR SS:[ESP+34],ECX
00401080  |.  C74424 38 0F000000      MOV DWORD PTR SS:[ESP+38],0F
00401088  |.  894424 40               MOV DWORD PTR SS:[ESP+40],EAX
0040108C  |.  C74424 44 04000000      MOV DWORD PTR SS:[ESP+44],4
00401094  |.  C74424 48 02000000      MOV DWORD PTR SS:[ESP+48],2
0040109C  |.  C74424 4C 03000000      MOV DWORD PTR SS:[ESP+4C],3
004010A4  |.  895424 50               MOV DWORD PTR SS:[ESP+50],EDX
004010A8  |.  894C24 54               MOV DWORD PTR SS:[ESP+54],ECX
004010AC  |.  C74424 58 06000000      MOV DWORD PTR SS:[ESP+58],6
004010B4  |.  C74424 5C 08000000      MOV DWORD PTR SS:[ESP+5C],8
004010BC  |.  894C24 60               MOV DWORD PTR SS:[ESP+60],ECX
004010C0  |.  C74424 64 05000000      MOV DWORD PTR SS:[ESP+64],5
004010C8  |.  894C24 68               MOV DWORD PTR SS:[ESP+68],ECX
004010CC  |.  895424 6C               MOV DWORD PTR SS:[ESP+6C],EDX
004010D0  |>  8B5484 44               /MOV EDX,DWORD PTR SS:[ESP+EAX*4+44]
004010D4  |.  8B4C84 18               |MOV ECX,DWORD PTR SS:[ESP+EAX*4+18]
004010D8  |.  33CA                    |XOR ECX,EDX
004010DA  |.  894C84 18               |MOV DWORD PTR SS:[ESP+EAX*4+18],ECX
004010DE  |.  40                      |INC EAX
004010DF  |.  8A4C0C 0C               |MOV CL,BYTE PTR SS:[ESP+ECX+C]
004010E3  |.  83F8 0B                 |CMP EAX,0B
004010E6  |.  884C04 FF               |MOV BYTE PTR SS:[ESP+EAX-1],CL
004010EA  |.^ 7C E4                   \JL SHORT Q3.004010D0
004010EC  |.  8D5424 00               LEA EDX,DWORD PTR SS:[ESP]
004010F0  |.  52                      PUSH EDX
004010F1  |.  68 30604000             PUSH Q3.00406030               ; ASCII "%s"
004010F6  |.  E8 15000000             CALL Q3.00401110               ; printf
004010FB  |.  33C0                    XOR EAX,EAX
004010FD  |.  83C4 78                 ADD ESP,78
00401100  \.  C3                      RETN


방금 전 얘기했듯이 예선전의 ddanjin과 같은 유형입니다. PADOCON 2010 CTF 예선 문제를 보신 분이라면 대충 눈치 채시겠죠? 문제를 푸는 요령은 핸드레이 두 번째 문제와 같습니다.

  • Encoding Routine이 어디인가?
  • Encoding Routine 직전의 스택은 어떤 모습인가?
  • Encoding Routine 직전의 레지스터의 값은 무엇인가?
  • ASCII 테이블

풀이

여기서부터 풀이입니다. [열기]간단한 안티 리버싱 기법이 적용되어 있는 문제입니다. ddanjin 처럼요. 키 테이블의 값들을 일일이 하나씩 입력해놓아서 분석하는 것을 힘들게 하지요. 하지만, 삽질의 핸드레이 리버싱 앞에서는 이런 것은 작은 기교에 불과합니다.

요령은 두 번째 문제와 같습니다. 먼저 Encoding Routine을 찾습니다. 이번에는 친절하게 주석이 달려 있어서 금방 찾을 수 있네요. 0x004010D0~0x004010EA 가 for/while 문으로 이루어진 Encoding Routine입니다. Encoding Routine을 찾았으니 이전까지의 스택과 레지스터를 그립니다.

사용자 삽입 이미지
[그림1]이 제가 그린 스택입니다. 이번 문제에서 스택을 그릴 때 주의할 게 두 가지 있습니다. 하나는 DWORD, WORD, BYTE를 혼동하지 않는 것입니다. DWORD는 4바이트, WORD는 2바이트, BYTE는 1바이트의 메모리를 참조하거나 쓸 때 사용하는 지시어입니다. 또 하나는 중간중간 레지스터 값을 놓치지 않아야 하는 것입니다. 키 테이블을 만들 때 상수 대신 레지스터 값을 집어넣을 수도 있거든요. 그리고 Little Endian 고려하는 것은 기본이겠죠?

스택을 그렸으니 Encoding Routine을 분석할 차례인데요. 아래에 그 과정만 살짝 빼놓았습니다.

004010D0  |>  8B5484 44               /MOV EDX,DWORD PTR SS:[ESP+EAX*4+44]
004010D4  |.  8B4C84 18               |MOV ECX,DWORD PTR SS:[ESP+EAX*4+18]
004010D8  |.  33CA                    |XOR ECX,EDX
004010DA  |.  894C84 18               |MOV DWORD PTR SS:[ESP+EAX*4+18],ECX
004010DE  |.  40                      |INC EAX
004010DF  |.  8A4C0C 0C               |MOV CL,BYTE PTR SS:[ESP+ECX+C]
004010E3  |.  83F8 0B                 |CMP EAX,0B
004010E6  |.  884C04 FF               |MOV BYTE PTR SS:[ESP+EAX-1],CL
004010EA  |.^ 7C E4                   \JL SHORT Q3.004010D0


자세히 보시면 참조하는 키 테이블이 2개라는 것을 알 수 있는데요. esp+18 ~ esp+40가 하나이고, esp+44 ~ esp+68이 또 하나입니다. EAX 값을 인덱스로 사용하죠. 그리고 각각의 인덱스에 위치한 값끼리 순서대로 XOR 연산을 합니다.

XOR 연산을 해서 얻은 값은 또 다시 인덱스로 쓰입니다. esp+c부터 위치한 입력된 문자열의 인덱스로 참조되어서 그 위치의 문자를 esp에 초기화 해놓은 메모리로 순서대로 복사하지요. 즉, 입력된 문자열의 순서를 섞는 애너그램 코드입니다.

애너그램 코드인 게 파악되니까 그 다음부터는 일사천리였습니다. 두 키 테이블의 값들을 XOR 연산해서 애너그램 순서를 구하기만 하면 되니까요. 그리하여 답은 “eeBsn0Tkth1” 입니다.


참고 문헌

Intel Instruction Set pages :: http://www3.itu.edu.tr/~kesgin/mul06/intel/index.html
ASCII printable characters :: http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters

Similar Posts

0 Comments

  1. 안녕하세요 SecurityFirst의 대표입니다^^
    재미로 만들어봤던 핸드리버싱이었는데
    멋지게풀이를해주셔서 감사드려요^^
    다음에한번만나뵐 기회가있겟지요?ㅋㅋ

  2. 제가 버스를 타서 핸드레이 디컴파일 작업을 할수 없었던 것이었군요……
    갑자기 제 고향에 기차가 없다는게 슬퍼집니다..

  3. 아뇨 오히려 핸드레이 리버싱이 더 쉽고 재미나요. 특히, 기차 타고 가면서 핸드레이 리버싱하는 낭만이 있죠.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다