01.7z 파일을 풀면, 01.exe 파일이 주어진다.
더블 클릭해서 실행시키면 위와 같은 창이 뜨고 몇 초 있다가 알아서 꺼진다.
이 창이 꺼지는데 걸리는 시간을 구하는 것 같다.
일단 PEiD로 패킹 여부를 살펴보니 UPX로 패킹
upx -d 01.exe: 언패킹을 완료하고 올리디버거에서 열었다.
언패킹 후 디버거에서 실행시켜보니 위와 같은 메시지가 출렸되었다.
구글링해보니 별 내용 아니고(AutoIt을 통해 컴파일된 스크립트라는..)
우린 이 메시지를 없애면(안티디버깅) 된다.
IsDebuggerPresent()는 해당 프로세스가 디버깅을 당하고 있는지 여부를
PEB구조체의 디버깅 상태값으로 확인한다.
일단 IsDebuggerPresent 함수가 쓰인 곳을 찾아봤다. 0040E961
Search for-All intermodular calls에서 사용된 함수를 볼 수 있다. 여기서 찾으면 된다.
0040E961에서 IsDebuggerPresent 함수가 실행되고 그 밑 TEST EAX, EAX가 있다.
IsDebuggerPresent는 앞서 디버깅 당하는지 여부를 확인한다고 했다.
디버깅 당하면 리턴값으로 1이, 아니면 0이 되는데 이를 TEST와 연결지어서 생각해보자.
결과부터 말하자면, TEST를 CMP로 수정해야 한다.
TEST EAX, EAX -> CMP EAX, EAX
TEST와 CMP의 차이는 아래와 같다.
TEST: EAX AND EAX. 연산 결과(1)는 ZF(0)에만 영향을 미치고 인자에는 영향을 미치지 않고 버려진다.
따라서 연산 결과가 1이 되어 디버깅 당하고 있구나를 알게 되고 ZF는 0이 된다.
CMP: EAX - EAX. 연산 결과(0)는 ZF(1)에만 영향을 미치고 인자에는 영향을 미치지 않고 버려진다.
CMP의 연산 결과는 0으로 IsDebuggerPresent의 리턴값이 0이 된다. 따라서 ZF는 1이다.
이제 수정해보자.
ZF는 1이다.
ZF가 1이되면 그 다음 라인인 JNZ의 조건을 만족하지 못하게 된다.
JNZ == JNE: Jump if Not Zero = 0이 아니면 점프 = ZF가 1이 아니면 점프 = ZF가 1이면 점프 X
ZF가 1이므로 점프하지 않는다.
CMP로 수정하기 전 TEST였다면, 여기서 004338DE로 점프했을 것이다.
004338DE에는 아까 봤던 메시지를 출력하는 MessageBoxA 함수가 있다.
아무튼 TEST를 수정했으니 메시지 없이 아래 창이 뜬다.
여기까지를 패치하여 이제 02.exe 파일로 진행할 것이다.
이제 다시 문제 풀기로 돌아가서, 관련 함수를 찾아보자.
Search for -> All intermodular calls
Destination 정렬 후 시간 관련 함수인 timeGetTime()을 찾았다.
DWORD __stdcall timeGetTime(VOID);
timGetTime()은 윈도우가 시작된 후 지난 시간을 DWORD(unsinged long)형 데이터로 리턴한다.
문제와 매우 관련있어 보이니 BP를 걸자.
이제 다시 실행해보자. BP를 걸었으니 적당한 곳에서 멈추면 다시 분석할 것이다.
444C444에서 걸렸다. timeGetTime이 호출되는 곳이다.
그 아래 코드를 보자.
1. 444C44에서 timeGetTime 함수를 호출하고 리턴된 eax값을, 444C4D에서 ESI에 넣어준다.
2. 444C5F에서 다시 timeGetTime 함수를 호출한다.
3. 444C61에서 이전에 호출한 값인 ESI와 두 번째로 호출한 리턴값인 EAX를 비교한다: CMP EAX, ESI
4. 444C63에서 (EAX - ESI)의 결과값이 JNB 처리된다. 즉 EAX(두 번째 호출)가 ESI(첫 번째 호출)보다 크거나 같을 때 444D38로 점프한다.
JNB: Jump Not Below - 작지 않을 때 점프
00444D38로 가보면, EAX와 ESI의 차를 구한 뒤, [EBX+4]의 값과 비교한다.
[EBX+4]는 0000337B
[EBX+4]의 값은 두 번째 timGetTime 함수가 호출되었을 때에서
첫 번째 timGetTime 함수가 호출되었을 때 사이의 시간과 비교된다.
물론 이 두 시점의 차이가 실행 시간이라고는 할 수 없다. 하지만 비교하는 값인 EBX+4는?
시점 차이의 시간와 비교하는 유의미한 값이므로 EBX+4의 값인 0x337B가 답이 될 거라고 추측할 수 있다.
0x337B = 13179
db59260cce0b871c7b2bb780eee305db를 대문자화하여 검증해보자.
'Wargame > CodeEngn.com' 카테고리의 다른 글
Basic RCE L02, L03 (0) | 2020.06.07 |
---|---|
Basic RCE L09 (0) | 2020.06.04 |
Basic RCE L19 (1) | 2020.05.10 |