Basic RCE L19번과 거의 동일한 문제였다.
해당 프로그램이 몇 밀리세컨드 후에 종료되는지 알아야 하므로 일단 실행시켜보았다.
위와 같은 창이 뜨고 약 12~13초 정도 후에 종료되는 것을 확인하였다.
당연히 답이 12나 13은 아닐 것이므로 exeinfo로 확인해주었다.
역시나 19번과 동일하게 패킹이 되어있어서 언패킹을 한 파일을 새로 만들어 주었다.
언패킹 한 파일을 다시 실행시켜보니 기존 파일과 동일하게 작동이 되었다.
X32 디버거로 분석해주었다.
그런데 열어서 실행을 눌러보니 아래와 같은 창이 뜨는 것을 알 수 있었고,
안티디버깅 함수가 있는 것을 알 수 있었다.
안티디버깅을 피하기 위해 다시 실행하지 않고 모듈 분석으로 안티 디버깅 함수를 찾아보았다.
“IsDebuggerPresent” 함수가 있었고 제일 윗부분으로 이동해보았다.
그래프 모드로 확인해보니 맨 윗 노드에서 eax와 eax를 비교해서 같지 않으면 에러문을 출력하는 부분으로 점프하는 것을 알 수 있었다.
따라서 안티디버깅을 피하기 위해서 jne 부분을 je로 바꾸고 패치파일을 생성해주었다.
이제 패치된 파일을 가지고 나머지 분석을 이어서 해주었다.
일정 시간 후 종료되는 것과 연관된 함수들이 여러 가지 있겠지만 나는 19번과 같게 timegettime 함수를 찾아보았다.
역시 해당 함수가 존재하였고, 444C3E 부분이 중요해 보이긴 하지만 일단 모두 BP를 걸고 확인해주었다.
BP를 걸고 실행해보니 아래의 그림과 같이 444C3E 위치에서 멈추었다.
한 줄씩 확인을 해 보았다.
(후에 다시 한번 확인해보니 esi, eax 값이 계속 바뀐다! 찾아보니 실행시간, 전 실행시간 등의 영향을 받아서 값이 달라진다고 한다.)
(timegettime : 윈도우 시작 후 경과된 시간을 밀리 초 단위로 반환)
< 444C3E >
1. EDI에 timegettime 함수의 4바이트를 저장
2. EDI 호출 ( timegettime 함수 호출 )
3. mov ESI, EAX (edi의 리턴값은 첫 번째 경과시간을 ESI에 저장)
4. je [444D54] (esi와 eax가 같으면 444D54로 점프 / 여기서는 다르므로 점프하지 않음)
5. mov ebx, [esp+14]
6. mov ebp = [&Sleep]
7. EDI 호출 ( timegettime 함수 호출 )
8. cmp eax, esi (ESI : 첫 번째 경과시간 / EAX : 두 번째 경과시간)
9. jae [444D38] ( 두 번째 경과시간 >= 첫 번째 경과시간 : 444D38로 점프)
< 444D38 >
1. sub eax, esi (두 번째 경과시간 – 첫 번째 경과시간)
2. cmp eax, [ebx+4] (eax = 두 번째 경과시간 – 첫 번째 경과시간, ebx+4 = 337B)
3. jae [444C71] (eax가 ebx+4 보다 크거나 같으면 444C71로 점프(종료))
그리고 444C71에서 EAX가 [EBX+4]보다 작으면 다시 444C5F로 돌아가서 TIMEGETTIME을 호출하고 CMP 하는 부분을 반복한다.
결국 [EBX+4] 값과 비교하는 것이므로 [EBX+4] 값을 확인해보니 아래와 같이 “7B 33”이 들어있는 것을 볼 수 있다.
리틀 엔디언으로 담겨있으므로 337B 순서이고, 계산기로 돌려보면 13179라는 값임을 알 수 있다.
문제에서 주어진 대로 13179를 MD5 해시로 변환해주면 아래와 같은 값이 나온다.
db59260cce0b871c7b2bb780eee305db
'Reversing > CodeEngn' 카테고리의 다른 글
[CodeEngn] Advance RCE L03풀이 (0) | 2021.10.05 |
---|---|
[CodeEngn] Advance RCE L02풀이 (0) | 2021.10.05 |
[CodeEngn] Basic RCE L20풀이 (0) | 2021.09.13 |
[CodeEngn] Basic RCE L19풀이 (0) | 2021.09.13 |
[CodeEngn] Basic RCE L18풀이 (0) | 2021.09.13 |