CodeEngn Write Up/Basic

CodeEngn Basic RCE L01 Write Up

서원근양학계정 2021. 9. 15. 16:42

문제:HDD를 CD-Rom으로 인식시키기 위해서는 GetDriveTypeA의 리턴값이 무엇이 되어야 하는가

https://ch.codeengn.com/

 

CodeEngn.com [코드엔진]

코드엔진은 국내 리버스엔지니어링 정보공유를 위해 2007년 부터 리버스엔지니어링 컨퍼런스 및 세미나, 워크숍을 현업 실무자들과 함께 운영하고 있는 비영리 커뮤니티입니다.

ch.codeengn.com

 

문제를 다운로드하고 압축을 풀어주었습니다. 파일의 압축을 풀 때 암호는 codeengn입니다.

이제 실행시키면 이런 창이 뜹니다.

 

확인을 눌러주면 이런 창이 뜹니다.

 

이제 어느정도 이 문제에 대한 정보를 얻었으니 Ollydbg로 이 문제를 열어보겠습니다.

 

첫 번째로 MessageBoxA함수를 호출하는데 함수의 이름을 통해서 어떤 역할을 하는 함수인지 추정할 수 있습니다.

이 함수는 메시지 박스를 띄워주는 함수로, 문제를 실행시켰을 때 나왔던 문자열을 확인할 수 있습니다.

 

다음으로 GetDriveTypeA함수를 호출합니다.

GetDriveTypeA함수가 어떤 역할을 하는지 알기 위해서 GetDriveTypeA함수 다음 줄에 F2로 브레이크포인트를 걸고 실행해보았습니다.

브레이크포인트를 걸게 되면 F9를 이용해서 프로그램을 실행시킬 때 브레이크포인트가 걸린 곳에서 멈추게 됩니다.

 

GetDriveTypeA함수는 디스크의 종류를 파악해서 그에 따른 값을 리턴하는 함수입니다.

https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getdrivetypea

 

GetDriveTypeA function (fileapi.h) - Win32 apps

Determines whether a disk drive is a removable, fixed, CD-ROM, RAM disk, or network drive.

docs.microsoft.com

이 함수는 디스크가 하드디스크인 경우에 3을 리턴하게 됩니다.

함수의 리턴값을 받는 EAX에 3이 들어간 것을 확인할 수 있습니다.

 

이다음 부분의 코드를 확인해보겠습니다.

INC와 DEC가 보이는데 INC는 1을 더하는 명령어이고 DEC는 1을 빼는 명령어입니다.

INC ESI가 세 번 있고 DEC EAX가 두 번 있으므로 ESI의 값은 3만큼 증가하고 EAX의 값은 2만큼 감소합니다.

 

CMP를 통해서 EAX와 ESI를 비교합니다.

CMP는 두 값을 비교하는 명령어로, 값을 빼는 방식으로 작동합니다.

따라서 두 값이 같으면 계산 결과는 0이 되고 ZeroFlag가 1로 바뀌게 됩니다.

JE는 ZF가 1이면 그 주소로 이동하는 명령어입니다.

정리하자면 두 값이 같으면 JE명령어가 작동하면서 성공메시지를 출력하고 아니면 실패메시지를 출력하는 구조입니다.

 

이제 성공메시지를 출력하게 하는 GetDriveTypeA함수의 리턴값을 구해보겠습니다.

GetDriveTypeA함수의 리턴값은 EAX에 저장되는데 EAX의 값을 2만큼 감소시키고 ESI의 값을 3만큼 증가시키므로

EAX의 값이 ESI의 값보다 5만큼 크면 두 값이 같아지게 됩니다.

ESI가 0일 때 GetDriveTypeA함수의 리턴값이 5가 되면 성공메시지가 출력됩니다.

 

이제 성공메시지가 출력되게 해보겠습니다.

먼저 GetDriveTypeA함수에 BP(BreakPoint)를 걸어줍니다.

 

그다음 F9를 이용해서 BP가 걸린 곳까지 실행시킨 다음 F8을 이용해서 GetDriveTypeA함수를 실행시킵니다.

그리고 레지스터의 값을 확인해보면 EAX에 3이 있고 ESI에 00401000이라는 값이 있습니다.

 

EAX에서 3을 빼고 ESI에 2를 더했을 때 값이 같아야 하므로 EAX의 값을 ESI보다 5만큼 큰 00401005로 바꿔주도록 하겠습니다.

EAX의 값인 00000003을 더블클릭하면 값을 수정할 수 있습니다.

그런 다음 F9로 실행시키면 성공메시지가 출력됩니다.

 

이 방법 말고도 한 가지 방법이 더 있습니다.

 

00401026주소에서 JE가 실행되면 성공메시지가 출력되는 곳으로 점프하게 됩니다.따라서 조건에 상관없이 항상 점프가 실행되게 하면 항상 성공메시지가 출력되게 할 수 있습니다.무조건 점프를 하는 명령어는 JMP이므로 JE를 JMP로 바꿔줍시다.코드가 있는 줄을 더블클릭하면 코드를 수정할 수 있습니다.

 

성공적으로 코드를 수정했습니다.

이제 다른 조건과 상관없이 00401026에서는 성공메시지를 출력하는 주소인 0040103D로 무조건 점프하게 됩니다.

F9를 이용해서 실행시키면 역시 성공메시지가 출력됩니다.

 

Flag: 5

'CodeEngn Write Up > Basic' 카테고리의 다른 글

CodeEngn Basic RCE L06 Write Up  (0) 2021.09.29
CodeEngn Basic RCE L05 Write Up  (0) 2021.09.23
CodeEngn Basic RCE L04 Write Up  (0) 2021.09.16
CodeEngn Basic RCE L03 Write Up  (0) 2021.09.16
CodeEngn Basic RCE L02 Write Up  (0) 2021.09.16