Reversing

[코드엔진] basic 01

BIGFROG 2020. 1. 7. 16:43

CodeEngn.com의 challenge basic RCE level 01 문제풀이입니다.

 


Location : http://codeengn.com/

Author : abex

Debugger : Immunity Debugger

 

 


1번 문제입니다.

HDD를 CD-ROM으로 인식시키기 위해,

GetDriveTypeA라는 함수의 리턴값을 바꿔줘야합니다.

일단 Download를 통해 첨부파일을 받습니다.





실행파일이 하나 나옵니다.

이걸 그대로 실행시켜보면 다음과 같은 메시지박스가 나옵니다.





"Make me think your HD is a CD-ROM."

문제 내용과 같은 문구가 나옵니다.

이 메시지박스에 확인을 누르고 나면 다른 메시지박스가 나옵니다.





"This is not a CD-ROM Drive!"


이렇게 파일만 실행시켰을 경우에는 CD-ROM으로 인식시킬 다른 방법이 없습니다.

디버깅을 통해 CD-ROM으로 인식시킬 방법을 찾아야 합니다.

 















Imunnity Debugger를 통해 위 실행파일을 열었습니다.

F9를 통해 Entry Point로 이동했습니다.

운이 좋게도 첫 화면부터 이 파일의 main 함수를 찾을 수 있었습니다.

왼쪽 상단의 디스어셈블리 코드를 보여주는 부분에서

주석으로 Comment가 있는 부분에서 MessageBox를 찾을 수 있었습니다.



Text = "Make me think your HD is a CD-ROM."

Text = "This is not a CD-ROM Drive!"

Text = "Okay, i really think that your HD is a CD-ROM! :p"


위와 같은 MessageBox와 아까의 파일 실행 결과를 통해서,

특정 부분을 조작하면 세 번째 MessageBox로 넘어갈 수 있을거라는 예측을 할 수 있습니다.

 











디버깅을 하는 도중 가장 처음에 나타나는 MessageBox는

파일 실행시 맨 처음 나타난 문구입니다.

그 이후에는 문제에서 언급했던 GetDriveTypeA라는 함수가 등장합니다.

문제대로 이 함수의 리턴값을 조정해서 세 번째 MessageBox가 출력되게 하면 됩니다.


디버깅을 할 때는 F8(Step Over)를 이용해서 함수 내부로는 진입하지 않았습니다.

GetDrvieTypeA를 CALL 함수로 호출한 뒤부터 보도록 하겠습니다.

위에 보이는 디스어셈블리 코드 창에서 한 줄을 실행할 때마다

오른쪽에 보이는 Register 값이 변화됩니다.

그 값의 변화에 주의하면서 보도록 하겠습니다.


표시한 부분에서 CMP 구문이 나오기 전까지는

INC(Increase) 와 DEC(Decrease)를 통해 EAX 레지스터 값과 ESI 레지스터 값을 변화시킵니다.

그리고 CMP 구문에서는 EAX 레지스터 값과 ESI 레지스터 값을 서로 비교합니다.

 


비교하기 전 각각 레지스터 값을 확인해보니

EAX Register : 00000001

ESI Register : 00401003

으로 서로 값이 다르다는 것을 알 수 있습니다.

 


그리고 CMP 구문 바로 아래에 나오는 JE라는 함수가 나옵니다.

JE는 Jump if Equal의 약자로 앞서 CMP를 통해 비교한 값이 같으면 뒤에 나오는 주소로 Jump하겠다는 의미입니다.

따라서 CMP 구문 이후에는 Jump 구문이 반사적으로 나오게 됩니다.

다시 해석해보면,

CMP로 비교한 값이 같을 경우(if equal) 0040103D로 Jump하게 됩니다.

오른쪽에 Comment를 보면 알 수 있듯이, 우리가 원하던 곳으로 이동하게 됩니다.

그렇다면 "서로 다른 EAX Register 값과 ESI Register 값을 어떻게 같게 하느냐?" 가 새로운 문제가 됩니다.

 


디버거에서 일부 레지스터 값은 수정이 가능합니다.

문제에서는 GetDriveTypeA의 리턴값을 물었으니까,

리턴값을 저장하는 EAX Register의 값을 수정해야 합니다.

 


위처럼 EAX의 값을 ESI의 값과 똑같이 입력해주면 됩니다.

그리고나서 다시 CMP 구문부터 함수를 실행하면,

 


원하는 곳으로 Jump한 모습을 볼 수 있습니다.

MessageBox가 뜰 때까지 Step Over 하고 나면 다음과 같은 MessageBox가 나타납니다.

 



따라서 문제에서 물었던 GetDriveTypeA의 리턴값에 대한 답은

ESI Register의 값이 됩니다.


+ 당연히 ESI 레지스터 값을 EAX 레지스터 값으로 조정해도 결과는 똑같습니다. 다만 문제에서는 '함수의 리턴값'을 물었기 때문에 함수의 반환값을 저장하는 EAX 레지스터 값을 조정해 준 것입니다.