본문 바로가기

WARGAME/codeengn

Advance 8

Korean : 

Key 값이 5D88-53B4-52A87D27-1D0D-5B09 일때 Name은 무엇인가 

힌트 : Name은 두자리인데.. 알파벳일수도 있고 숫자일수도 있고.. 

정답인증은 Name의 MD5 해쉬값(대문자) 


먼저 "Please Enter More Chars..." 문자열을 찾아서 해당 주소 근처의 Key를 비교하는 루틴을 찾았습니다.



먼저 아래 루틴에서 Name의 길이를 검사하고 (3글자 이상 , 30글자 이하)


Address      Hex dump          Command                                     Comments

0045BB07  |.  8B83 68030000 MOV EAX,DWORD PTR DS:[EBX+368]           ; <= CHECK LENGTH >3

0045BB0D  |.  E8 62E5FDFF   CALL 0043A074

0045BB12  |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]

0045BB15  |.  8945 F8       MOV DWORD PTR SS:[EBP-8],EAX

0045BB18  |.  8B45 F8       MOV EAX,DWORD PTR SS:[EBP-8]

0045BB1B  |.  85C0          TEST EAX,EAX

0045BB1D  |.  74 05         JZ SHORT 0045BB24

0045BB1F  |.  83E8 04       SUB EAX,4

0045BB22  |.  8B00          MOV EAX,DWORD PTR DS:[EAX]

0045BB24  |>  83F8 03       CMP EAX,3

0045BB27  |.  7D 15         JGE SHORT 0045BB3E

0045BB29  |.  BA 18BC4500   MOV EDX,0045BC18                         ; ASCII "Please Enter More Chars..."

0045BB2E  |.  8B83 74030000 MOV EAX,DWORD PTR DS:[EBX+374]          

0045BB34  |.  E8 6BE5FDFF   CALL 0043A0A4

0045BB39  |.  E9 91000000   JMP 0045BBCF

0045BB41  |.  8B83 68030000 MOV EAX,DWORD PTR DS:[EBX+368]           ; <= CHECK LENGTH <=30
0045BB47  |.  E8 28E5FDFF   CALL 0043A074
0045BB4C  |.  8B45 F4       MOV EAX,DWORD PTR SS:[EBP-0C]
0045BB4F  |.  8945 F8       MOV DWORD PTR SS:[EBP-8],EAX
0045BB52  |.  8B45 F8       MOV EAX,DWORD PTR SS:[EBP-8]
0045BB55  |.  85C0          TEST EAX,EAX
0045BB57  |.  74 05         JZ SHORT 0045BB5E
0045BB59  |.  83E8 04       SUB EAX,4
0045BB5C  |.  8B00          MOV EAX,DWORD PTR DS:[EAX]
0045BB5E  |>  83F8 1E       CMP EAX,1E
0045BB61  |.  7E 12         JLE SHORT 0045BB75
0045BB63  |.  BA 3CBC4500   MOV EDX,0045BC3C                         ; ASCII "Please Enter Not More Then 30 Chars..."
0045BB68  |.  8B83 74030000 MOV EAX,DWORD PTR DS:[EBX+374]
0045BB6E  |.  E8 31E5FDFF   CALL 0043A0A4
0045BB73  |.  EB 5A         JMP SHORT 0045BBCF


그리고 좀 더 내려가다 보면 아래 Name 값을 이용해서 Key를 생성하는 함수(빨간색)를 찾을 수 있습니다.

해당 키를 0045bba9 주소(파란색)에서 비교해 올바른 경우 실패 루틴으로 점프하지 않고 그대로 성공 루틴으로 이어집니다. 


CPU Disasm

Address   Hex dump          Command                                  Comments

0045BB9B  |.  E8 B0FCFFFF   CALL 0045B850                            ; <= CREATE KEY

0045BBA0  |.  8B55 EC       MOV EDX,DWORD PTR SS:[EBP-14]

0045BBA3  |.  58            POP EAX

0045BBA4  |.  E8 9390FAFF   CALL 00404C3C                            ; [08.00404C3C

0045BBA9  |.  75 1A         JNE SHORT 0045BBC5


0045BBAB  |.  6A 40         PUSH 40                                  ; /Arg1 = 40

0045BBAD  |.  B9 64BC4500   MOV ECX,0045BC64                         ; |ASCII "Good Boy!!!"

0045BBB2  |.  BA 70BC4500   MOV EDX,0045BC70                         ; |ASCII "Well done!"

0045BBB7  |.  A1 C0E94500   MOV EAX,DWORD PTR DS:[45E9C0]            ; |

0045BBBC  |.  8B00          MOV EAX,DWORD PTR DS:[EAX]               ; |

0045BBBE  |.  E8 B5D0FFFF   CALL 00458C78                            ; \08.00458C78



이제 Key 생성 함수(위 루틴에서 빨간색)에 들어가보면 '-'를 기준으로 각 부분마다 생성하는 루틴이 존재합니다.
대충 분석했더니 '-'를 기준으로 각 부분의 키 값이 전부 독립적인것 같아서 (다른 부분 키 생성에 영향을 안줌) 
첫번째 부분 키를 만드는 루틴만 분석하였습니다. 

아래는 Key의 첫 번째 부분 생성 루틴
Address   Hex dump          Command                                  Comments
0045B898  |.  B9 01000000   MOV ECX,1                                ; <= 1th value, 0xOOOO XXXXX, ESI

0045B89D  |>  8B5D FC       /MOV EBX,DWORD PTR SS:[EBP-4]
0045B8A0  |.  0FB6740B FF   |MOVZX ESI,BYTE PTR DS:[ECX+EBX-1]
0045B8A5  |.  03F2          |ADD ESI,EDX
0045B8A7  |.  69F6 72070000 |IMUL ESI,ESI,772
0045B8AD  |.  8BD6          |MOV EDX,ESI
0045B8AF  |.  0FAFD6        |IMUL EDX,ESI
0045B8B2  |.  03F2          |ADD ESI,EDX
0045B8B4  |.  0BF6          |OR ESI,ESI
0045B8B6  |.  69F6 74040000 |IMUL ESI,ESI,474
0045B8BC  |.  03F6          |ADD ESI,ESI
0045B8BE  |.  8BD6          |MOV EDX,ESI
0045B8C0  |.  41            |INC ECX
0045B8C1  |.  48            |DEC EAX
0045B8C2  |.^ 75 D9         \JNZ SHORT 0045B89D

루틴은 단순히 Name에서 한 글자씩 가져와 사칙연산+비트연산을 하게되고 마지막으로 나온 결과값에서 상위 2바이트(더블워드 기준)를 첫 번째 부분의 키로 사용합니다. 

그러므로 문제를 다시 보면 키의 첫 번째 부분은 5D88 이고 + Name은 두 글자 + 알파벳or숫자로 이루어져 있다는 정보를 알 수 있습니다. 

따라서, 경우의 수가 적으므로 brute force로 결과값이 0x5d88이 나올때 까지 연산하면 바로 답을 얻을 수 있습니다.




'WARGAME > codeengn' 카테고리의 다른 글

Advance 10  (0) 2015.04.06
Advance 9  (0) 2015.04.06
Advance 7  (0) 2015.03.19
Advance 6  (0) 2015.03.19
Advance 5  (0) 2015.03.19