본문 바로가기

Reversing/CodeEngn

[CodeEngn] Basic RCE L19풀이

https://ch.codeengn.com/

 

CodeEngn.com [코드엔진]

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

ch.codeengn.com


그림 1

문제에서 해당 프로그램이 몇 밀리세컨드 후에 종료되는지를 구해야 한다고 한다.

문제를 실행시켜보았더니 아래의 그림과 같은 창이 출력된 후 약 11초정도 후에 자동으로 종료된다.

 

그림 2 

Exeinfo로 확인해보았다.

 

그림 3

일단 upx 패킹이 되어있는 상태이고 autoit script라고 한다.

 

Autoit script를 처음 들어봐서 검색해보니 마이크로소프트 윈도우를 위한 프리웨어 자동화 언어라고 한다. 특수 제작된 파일인가보다.

 

일단 upx 언패킹을 진행해주었다.

 

그림 4

언패킹 한 19_unpacked.exe 파일을 따로 생성해주었다.

 

그리고 x32 디버거로 열어서 실행을 시켰는데 아래와 같은 에러가 뜨면서 실행이 종료되는 것을 확인할 수 있다. 우리는 필요한 부분을 보기 위해서는 아래의 에러가 출력되지 않아야 하기 때문에 어셈블리어를 변경해서 패치파일을 생성해주려고 한다.

 

그림 5


<여기에서 잠깐 한 헛짓,,,>

1.    autoit이라는 단어에서 auto가 익숙해서 문자열 찾기로 보던 중, autoit script가 있는 게 아닌가,,, reversing.kr에서 auto hot key에 인상이 깊었는지, 이 부분이다! 하고 쭉 봤는데 전혀 아니었다,,, 넓은 시야를 가진 사람이 되어야겠다,,,


다시 문제로 돌아가서,

그런데 이렇게 디버거를 탐지하는 프로세스를 전에 어떤 문제에서 풀었던 것 같아서 모듈 분석을 보았다.

 

확인해보니 역시 IsDebuggerPresent라는 함수가 있었다.

 

그림 6

 

맨 위의 부분으로 들어가서 그래프 형식으로 확인해보았다.

 

그림 7

위의 그림을 보면 중간의 왼쪽 노드에서 우리가 아까 본 에러문의 내용을 담고 있는 것을 알 수 있다.

그렇다면 맨 위의 노드에서 왼쪽으로 진행하면 안 되므로,를 je로 수정하여 패치파일을 생성해주었다.

 

다시 생성한 파일을 가지고 실행시켜보면 아주 잘 실행이 된다.

 

이다음부터 어떻게 해야 할지 모르겠어서 검색을 해보니 timegetTime이라는 함수가 윈도우가 시작된 후 지난 시간을 리턴하는 함수라고 한다.

그래서 똑같이 모듈 검색을 통해 확인하고, 많길래 BP를 다 걸었다.

 

그림 8

사실 중간에 형식이 다른 한 부분이 있길래 조금 의심이 되었는데, 정확하지 않아서 에라이 다 걸어버렸다.

 

걸고 실행을 해보니 신기하게 MOV 부분에서 멈췄다!

 

그림 9

위의 그림에서 맨

윗줄부터 F8을 이용하여 한 줄씩 확인해보았다.

edi에 4바이트 timeGetTime을 저장하고 edi를 호출한다.

그리고 edi 호출을 통해 나온 리턴 값을 esi에 저장하고 있다.

 

다음 je를 따라 가면 점프하지 않고 그대로 아래로 진행한다.

이제 444c55에서 ebx에 [esp+14] 값을 저장하고 Sleep 함수를 실행한다.

 

그리고 444c5f에서 다시 edi를 호출하면서 timegettime함수를 다시 가져오고 있다.

 

그 후 eax와 esi를 비교하는데, 이때 timegettime의 리턴값이 eax에 저장된다.

그리고 jae를 통해 eax값이 esi보다 크거나 같으면 점프를 취하고 있다.

 

위의 그림에서 eax와 esi에 저장된 값을 확인해보면 각각 ef4edf와 ef069c가 저장되어 있고, eax가 더 큰 값이므로 44d38로 점프를 취하게 된다.

 

이어서 진행을 하면 아래의 그림과 같은 위치로 이동하게 되고, 해당 위치에서 eax에 eax-esi를 저장하고 eax와 [ebx+4]를 비교하고 있다.

 

그림 10

비교한 결과, eax 값이 더 크면 444c71로 이동하고, 그렇지 않으면 444c5f의 위치로 이동한다.

 

444c5f는 위에서 본 것과 같이 sleep 다음에 timegettime 함수를 재호출하는 위치임으로, [ebx+4]에 우리가 구해야 하는 밀리세컨드가 저장되어 있을 것이라고 추측할 수 있다.

 

그림 11

해당 위치를 덤프 해서 따라가 보면 70 2B가 저장되어 있고, 리틀 엔디언 방식으로 저장되어 있기 때문에 2B70 값을 10진수로 바꾸면 11,120이라는 값이 나오게 된다.

 

그림 12

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

[CodeEngn] Advance RCE L01풀이  (0) 2021.10.05
[CodeEngn] Basic RCE L20풀이  (0) 2021.09.13
[CodeEngn] Basic RCE L18풀이  (0) 2021.09.13
[CodeEngn] Basic RCE L17풀이  (0) 2021.09.13
[CodeEngn] Basic RCE L16풀이  (0) 2021.09.13