#About
Author : CodeEngn
KO : 이 프로그램은 몇 밀리세컨드 후에 종료 되는가
EN : How many miliseconds does it take for this program to terminate
#Contents
해당 문제는 안티디버깅 함수인 IsDebuggerPresent와 timeGetTime 함수의 이해를 목표로 한다
#Solution
[그림 1] - 실행화면
19.exe의 실행화면이며 약 10초 후 해당 프로그램이 종료된다. 메시지 박스만 띄우고 종료되기에 딱히 프로그램이라 할 것은 없지만 분석을 진행해보자
[그림 2] - UPX 패킹
패킹 여부 확인 결과 UPX로 패킹되어 있었으며 upx.exe를 이용해 아래와 같이 언패킹을 진행했다
[그림 3] - UPX 언패킹
다른 문제 들과 같이 언패킹 진행 후 아스키 값과 함수 목록을 보았지만, 데이터가 많은 탓에 파악하기 힘들었다
그래서 많은 양의 데이터 중 필요한 데이터만 찾아내기 위해 문제에서 주어진 "밀리세컨드"라는 단어를 이용해
시간 관련 API를 검색결과 timeGetTime()라는 함수의 리턴 값의 단위가 "밀리 초"임을 통해 문제와 관련 있음을 유추할 수 있었다
[그림 4] - BreakPoint > timeGetTime()
유추한 것을 토대로 함수 목록에서 timeGetTime()을 찾아 보았더니 여러개를 확인할 수 있었고, 모든 해당 함수에
bp를 걸어준 뒤 실행 시켜보았더니 아래와 같은 메시지가 출력된 후 프로그램이 종료 되었다
[그림 5] - Information MessageBox
무엇 때문에 자꾸 종료되는지 해 있던 찰나, 코드엔진 Basic 4번(http://croas.tistory.com/21)에서 확인할 수 있었던 안티 디버깅 함수
IsDebuggerPresent()이 떠올랐고, 해당 함수의 존재 여부를 확인후 bp를 걸고 아래와 같이 조금의 코드 수정을 해주었다
[그림 6] - 코드 수정
위와 같이 코드 수정을 진행해준 뒤 실행시키다보면 아래와 같이 00444C44에서 멈추는 것을 확인할 수 있다
[그림 7] - 주석(1)
[그림 8] - 주석(2)
[그림 7]과 [그림 8]의 과정은 해당 문제의 핵심이되는 부분이기에 주석을 달아 놓았으며 세부 설명으로는 00444C5F에서
timeGetTime 함수를 재 호출하여, 00444C44에서 받아 왔던 처음 시간 값과 비교하여 크거나 같으면 00444D38 지점으로
분기하여 2번째 timeGetTime 함수의 반환 값에서 1번째 timeGetTime 함수의 반환 값을 뺀다 timeGetTime 함수 반환의 차이값인
EAX와 EBX+4 주소가 가리키는 값을 비교하여 분기
- 차이값이 작으면 시간을 구하는 부분으로 돌아가 이 과정을 반복
- 차이값이 크면 다른 곳으로 분기 후 프로그램을 종료시킨다
( 인용 : http://l3m0n-tr33.tistory.com/entry/CodeEngn-Basic-RCE-L19 )
따라서 EAX와 비교하는 EBX+4의 주소가 가르키는 값을 확인하면 해당 문제를 해결할 수 있으며 값 확인 결과는 아래와 같다
[그림 9] - EBX+4의 4바이트 값 확인
0x2B70 = 11120ms = 11.12초
'Wargame' 카테고리의 다른 글
[Lord of SQL Injection] Gremlin (0) | 2017.10.25 |
---|---|
CodeEngn Basic 20 (0) | 2017.10.23 |
CodeEngn Basic 18 (0) | 2017.10.17 |
CodeEngn Basic 17 (0) | 2017.10.17 |
CodeEngn Basic 16 (0) | 2017.10.13 |