-榮-

[CodeEngn] Basic RCE L19 (+α AutoIt 전용 디컴파일러) 본문

CodeEngn/Basic

[CodeEngn] Basic RCE L19 (+α AutoIt 전용 디컴파일러)

xii.xxv 2021. 3. 27. 22:29

 

● CodeEngn Basic RCE L19 문제

 

CodeEngn Basic RCE L19

 

 

 

◎ 파일 실행 화면

 

[그림 1] 파일 실행 화면

 

 

패킹 및 난독화 여부 확인

 

[그림 2] Exeinfo PE - UPX 패킹 확인

 


 

● CodeEngn Basic RCE L19 풀이

 

 

[그림 3] 디버거 - OllyDbg / 디버기 - 19.exe (Basic RCE L19 실행파일)

 

[※참고]

UPX 패킹에서 OEP를 찾는 법은 CodeEngn Basic RCE L05의 "+α UPX 패킹 상태에서 OEP 찾는 법"

 

 

[그림 4] 19.exe의 OEP 위치

 

 

[Search for > All intermodular calls]에서 MessageBox 관련 함수를 찾아 BP를 걸고 실행[F9]하여 "CodeEngn.com by Lee Kang-Seok"를 띄우는 MessageBox 함수를 찾아봅시다.

 

[※참고]

Found intermodular calls에 BP 관련은 CodeEngn Basic RCE L03의 "+α 함수를 알고 있다면..."

 

[그림 5] MessageBoxA / MessageBoxW BP

 

실행을 돌리면 AutoIt script로 컴파일되었다는 메시지 창을 띄웁니다.

 

[그림 1]과 나오는 메시지가 다른 것을 보아 디버거를 탐지하는 함수가 있을 것입니다.

 

MessageBoxA의 마지막 파라미터(004338DE)의 위에 JMP 명령어가 있는 것을 보았을 때, JMP 명령어를 통하여 해당 위치로 왔을 것입니다. 004338DE로 JMP하는 명령어의 위치를 찾기 위해 언패킹을 하고 똑같이 진행합니다.

 

[그림 6] compiled AutoIt script

 

[그림 7] UPX Unpacked

 

언패킹 후 해당 위치로 가면 0040E969에 JMP 명령어가 있다는 것을 찾을 수 있습니다.

 

[그림 8] Jump from 0040E969

 

0040E969로 이동하면 IsDebuggerPresent 함수가 디버거를 탐지하는 것을 볼 수 있습니다.

디버거 탐지를 우회하기 위해 0040E969의 JNZ 명령어를 JZ로 패치합시다.

 

[그림 9] 디버거 탐지 함수

 

[그림 10] 0040E969 패치

 

[※참고]

패치파일 관련은 CodeEngn Basic RCE L01의 "+α 패치파일 만드는 법"

 

 

 

[그림 11] 디버거 - OllyDbg / 디버기 - 19_patched.exe


[Search for > All intermodular calls]에서 MessageBox 관련 함수를 찾아 BP를 걸고 실행[F9]하여 "CodeEngn.com by Lee Kang-Seok"를 띄우는 MessageBox 함수를 찾습니다.

 

[그림 12] CodeEngn.com by Lee Kang-Seok MessageBoxW

 

00444DB8을 Step Over[F8]하면 실행 파일이 종료되어 시간 관련 함수는 CALL MessageBoxW 내부에 있는 것을 알 수 있습니다. CALL MessageBoxW 내부에서 CALL MessageBoxTimeoutW 내부로 이동해 봅시다.

 

[그림 13] CALL MessageBoxW 내부
[그림 14] CALL MessageBoxW 내부의 CALL MessageBoxTimeoutW

 

MessageBoxTimeoutW 내부에서 시간과 관련된 함수들을 찾을 수 없었습니다. 관련 함수를 찾으려면 내부로 더 들어가야 될 것 같아서 [Search for > All intermodular calls]에서 시간과 관련된 함수들을 찾아보았습니다.

 

[그림 15] MessageBoxTimeoutW 내부

 

 

[Search for > All intermodular calls]에서 timeGetTime 함수와 Sleep 함수를 발견하였습니다.

두 함수에 BP를 걸고 실행[F9]하여 사용되는 시간 관련 함수를 찾아봅시다.

 

[그림 16] timeGetTime / Sleep

 

timeGetTime 함수는 밀리 초 단위로 시스템 시간을 검색하며, 검색한 시간을 반환합니다. (출처:MSDN)

 

[그림 17] timeGetTime 함수 정의 및 반환 값

 

Sleep 함수는 제한 시간 간격이 경과 할 때까지 현재 스레드의 실행을 일시 중단합니다. (출처:MSDN)

 

[그림 18] Sleep 함수의 함수 정의

 

 

실행을 하면 00444C44에서 BP에 걸립니다. 이 주소가 CodeEngn Basic RCE L19의 답을 찾기 위한 핵심코드입니다.

 

◎ 코드의 흐름을 보자.

 

 1. 00444C44에서 시스템 시간을 가져와서 ESI에 넣습니다.

 

[그림 19] timeGetTime 함수

 2. 00444C5F(timeGetTime)에서 시스템 시간을 가져와서 이전의 시스템 시간과 비교합니다.

    비교 결과가 EAX가 ESI 보가 크면 00444D38로 JMP합니다.

    (00444C44에서 00444C5F까지 실행되는 동안 시간이 흐르기 때문에 EAX가 ESI보다 큽니다.)

 

[그림 20] 두 번째 timeGetTime 함수

 

 3. 00444D38으로 JMP 후 EAX에서 ESI를 뺍니다.

    (두 번째 timeGetTime 결과 - 첫 번째 timeGetTime = 프로그램 실행 시간)

    프로그램 실행 시간이 2B70보다 큰지 비교하여 크면 00444C71로 JMP합니다.

 

[그림 21] 00444D38로 점프 및 CMP

 

프로그램이 특정 시간 이후 자동으로 종료된는 것을 생각했을 때, "2B70"이 지나면 종료되는 것으로 보입니다.

 

 


 

● CodeEngn Basic RCE L19 확인

 

timeGetTime 함수가 시스템 시간을 밀리 초 단위로 반환하는 것을 생각하면 "2B70"을 10진수로 변환하면 CodeEngn Basic RCE L19의 답이 나올 것입니다.

 

[그림 22] CodeEngn Basic RCE L19의 답

 

 


 

+α AutoIt 전용 디컴파일러

 

AutoIt는 "Exe2Aut"라는 전용 디컴파일러가 있습니다.

 

사용방법은 AutoIt로 만들어진 파일을 다운받은 Exe2Aut에 드래그해서 올리면 됩니다.

 

 

CodeEngn Basic RCE L19의 파일을 Exe2Aut에 올리면 MsgBox를 확인할 수 있습니다.

 

[그림 23] Exe2Aut

 

AutoIt의 MsgBox의 Parameters (출처:autoitscript.com)를 확인해 보면 해당 timeout Parameter는 초 단위로 밀리초로 변환하면 11,120이다.

 

[그림 24] MsgBox의 Parameters

 

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

[CodeEngn] Basic RCE L02  (0) 2021.03.30
[CodeEngn] Basic RCE L20  (0) 2021.03.29
[CodeEngn] Basic RCE L18  (0) 2021.03.27
[CodeEngn] Basic RCE L17  (0) 2021.03.26
[CodeEngn] Basic RCE L16  (0) 2021.03.26