본문으로 바로가기

[keygen] Lena tutorial 01, 02 writeup, 풀이

category Reversing/Keygen 2018. 7. 10. 11:51

Lena tutorial 01, 02



reverseMe.exe가 어떤 기능, 행위를 하는지 알아보기 위해 실행시켜 보자.

아래와 같이 실행될 것이다.




"Evaluation period out of date. Purchase new license" !!!

평가 기간이 끝났으니 새로운 라이센스를 구입하라는 메세지 박스가 뜬 후 프로그램이 종료된다.


단지 메세지만 전달하는 것은 매우 어색하다. reverseMe.exe의 의도는 "현재 나오는 메세지 박스를 우회해봐"라고 외치는것 같다.


이제 위를 바탕으로 분석을 시작해보자.



가장 처음 진행할 것은 패킹 여부와 어떤 언어로 작성되었는지 확인해야 한다.

PEiD를 사용하면 위 두 정보를 모두 뽑을 수 있다.




패킹은 되어있지 않고, MASM32와 TASM32로 작성되었다.

MASM32는 microsoft assembler이고, TASM turbo assembler이다.



더 정확히 패킹을 확인하고 어떤 API 함수들을 사용했는지 보기 위해 IAT(Import Address Table)를 확인할 것이다.

IAT는 PE Header 정보로 저장되어 있다. PEview를 통해 PE Header 정보를 확인할 수 있다.




IAT 에 함수들이 충분히 많고, 함수들이 깨져 있지 않으므로 정확히 패킹이 되지 않은 프로그램라고 간주할 수 있다.

이제 본격적인 ollydbg를 이용한 디버깅 번지를 찾기 위해 PE Header를 다시 찾아보자.


IMAGE_OPTIONAL_HEADER 구조체의 Image base, Base Of Code를 유심히 보자.




우리가 분석할 주소의 시작 번지는 Image Base + Base of Code의 번지이다.

0x00400000 + 0x00001000  = 0x004001000 번지이다.



이제 우리가 지금까지 얻은 정보를 바탕으로 분석을 진행해보자.

디버거는 ollydbg를 사용하였다.


0x004001000번지부터 분석을 시작해보자.





살펴보면 0x0040108B번지에 우리가 프로그램을 실행하면서 본 "Evaluation period out of date. Purchase new license" 부분이다.

즉, 0x0040108B번지 위에 어떠한 조건 때문에 이러한 메서지 박스가 실행되었다고 생각할 수 있다.


0x00401078 번지를 보면 cmp를 통해 플래그를 설정한 뒤 jnz로 인하여 분기한다.

그렇다면 바로 위에 있는 CreateFileA 함수를 주요하게 봐야한다.


CreateFileA 함수를 CALL 한뒤 cmp eax, -1을 한다. CreateFileA의 return 값을 비교하는 것이다.

CreateFileA 함수가 성공하면 반환값은 파일의 핸들값을 전달한다.

CreateFileA 함수가 실패하면 INVALID_HANDLE_VALUE를 반환한다. 일반적으로 INVALID_HANDLE_VALUE는 -1값이다.


우리가 현재 나오는 메세지 박스를 우회하기 위해서, CreateFileA 함수를 성공시켜야한다.

CreateFileA의 modeOPEN_EXISTING이다. OPEN_EXISTING 모드는 파일이 존재하면 열고, 존재하지 않으면, 함수가 실패한다.


CreateFileA를 성공시키기 위해 파일이 반드시 현재 경로에 존재해야한다. 파일의 이름은 "keyfile.dat"임을 알 수 있다.

"keyfile.dat" 파일을 현재 폴더에 추가한 후 다시 reverseMe.exe를 실행시켜보자.





똑같은 파일을 실행했는데, 메세지 박스가 다른 내용을 포함하고 있다.

"keyfile.dat"을 읽어들이는것은 맞지만, 내용이 다르기 때문에 "Keyfile Is not vaild. Sorry"라는 메세지 박스가 나온것 같다.





처음의 메세지 박스를 우회하면 ReadFile 함수를 만난다. ReadFile을 호출 한 뒤 test eax, eax를 한다.

ReadFile의 return 값을 비교한뒤 분기하는 것이다. 

만일 ReadFile이 성공하면, return 값은 True이다. ReadFile이 실패하면, return 값은 False이다.


Buffer는 읽어들인 data를 저장할 포인터이다.

BytesToRead최대로 읽어들일 길이이다.

pBytesRead는 실제로 읽은 바이트 수가 저장되는 주소이다.





위 화면에서 많은 분기들이 존재한다. 이러한 분기들을 지나면 "Keyfile Is not vaild. Sorry"라는 메세지 박스가 나온다.

즉, 이 부분이 keyfile.dat의 내용을 확인하는 루틴이라는것을 추측해 볼 수 있다.


cmp dword ptr ds:[402173], 10을 한다. 0x0402173번지에는 Readfile 함수로 인해 keyfile.dat의 길이가 들어있다.

jl short reverseM.004010F7을 통해 "Keyfile Is not vaild. Sorry"라는 메세지 박스를 출력하는 곳으로 이동한다.

"keyfile.dat"의 길이는 0x10보다 커야한다.

 mov

 al 

 byte ptr ds:[ebx+40211A] 

 cmp

 al 

 0 

 je

 short reverseM.004010D3

 


위 코드는 "keyfile.dat"의 내용을 한문자씩 al에 옮기고, 끝(NULL)까지 읽고난 후 short reverseM.004010D3 점프 한다.


 cmp

 al 

 47 

 jnz

 short reverseM.004010D0

 

 inc

 esi   

 inc

 ebx  

 jmp

 short reverseM.004010C1  


만일 "keyfile.dat"의 내용이 0x47(G)를 포함하면 esi를 1 증가시키고 , ebx도 1 증가시킨다.


 cmp

 esi 

 jl 

 short reverseM.004010F7 

 

 jmp

 reverseM.00401205 

 


만일 0x47(G)의 개수가 8 이상이면 0x00401205로 점프해라. 0x00401205에는 성공 메세지 박스가 있다.

만일 0x47(G)의 개수가 7 이하이면 0x004010F7로 점프해라. 0x004010F7에는 실패 메세지 박스가 있다.



즉, Lena tutorial 01의 문제 풀이는 같은 경로에 "keyfile.dat"파일이 있어야하고,

"keyfile.dat"내용으로는 16글자 이상이면서 G가 8개 이상 존재하면 우회가능한 프로그램이다.






'Reversing > Keygen' 카테고리의 다른 글

[keygen] abexcm1 writeup, 풀이  (0) 2018.09.11
[keygen] Lena tutorial 03-1 writeup, 풀이  (0) 2018.07.17
[keygen] FSC_Level1 writeup, 풀이  (0) 2018.07.08