본문 바로가기

RVS

Reversing.kr 4번 문제(Music Player)

요즘 시간이 한가해서 CTF 문제나 풀어야겠다는 생각에 Reversing.kr 문제를 풀고 있다.

풀면서 무한 디버깅을 하게 되면 짜증이 나기도 하지만.....

어쨌든 참고로 여기서 사용한 디버거는 x32dbg 이다. 특별히 이 도구를 쓰는 이유는 없고 그냥 내가 편해서..

 

자, 본론으로 돌아가 4번 문제(Music Player) 문제 풀이를 해보자!

 

Ready


Music Player 압축파일 내에는 아래 그림에서와 같이 세 개의 파일이 존재한다.

 

 

아래의 ReadMe.txt 파일을 통해 MP3 Player은 1분미리 듣기로 제한된 프로그램으로 1분 이상 실행시켜야 하는 것이 문제라는 것을 알게되었다.

* msvbvm60.dll(Microsoft Visual Basic Virtual Machine 6.0)파일은 VB 전용엔진으로 Music_Player.exe 실행에 필요

 

그렇다면.. 먼저 Music_Player.exe를 실행해보자!

 

프로그램 GUI만 보더라도 아주 간단한! 프로그램인 걸 알 수 있다.

내가 원하는 mp3 파일을 가져와 실행시킬 수 있다.

다만, 1분이 넘게 되면 저렇게 "1분 미리 듣기만 가능합니다."라는 팝업창이 뜬다.

 

1분 이상으로 오디오 파일을 재생시키기 위해서 해당 팝업창이 뜨지 않도록 해야겠다.

즉, 디버거를 통해서 해당 팝업창이 실행되는 위치(함수)를 찾아야한다. 

 

 

Problem 1


 

프로그램을 디버깅 시작해보자!

디버거를 통해 프로그램을 실행하게되면 [open] 버튼을 이용해 mp3 파일을 선택하여야 한다.

 

그러나 [Open] 버튼을 누르게 되면 프로그램이 계속해서 멈추는 문제가 발생해서 mp3 파일의 경로를 직접 입력해 주었다. -> [F9]로 무한 클릭하면서 파일을 열어도 되지만 매우 귀찮다..

 

디버거를 통해 해당 프로그램을 실행하게 되면 1분 미리듣기가 완료된 후에 마찬가지로 "1분 미리 듣기만 가능합니다." 팝업창이 뜨게 되고 아래의 그림에서와 같이 디버거가 72A1D132 주소에 도달한다.

 

해당 주소는 오른쪽에 쓰여진 문자와 같이 rtcMsgBox 함수 내 주소인 듯하다.

 

즉, 팝업창은 rtcMsgBox 함수로부터 호출되는 것을 확인했으니 해당 함수를 호출하는 곳을 찾아야겠다.

 

해당 프로그램의 모듈간의 호출을 찾아 rtcMsgBox 함수를 필터링하니 아래 그림에서와 같이 rtcMsgBox가 네번 호출된 것을 확인하였다.

 

여기서 "1분 미리 듣기만 가능합니다."를 호출하는 위치을 찾아야 하므로 [F2] 단축키로 네 개의 호출에 모두 Breakpoint를 걸어두자.

 

[ctrl]+[F2] 단축키를 통해 프로그램을 다시 디버깅해보면  "1분 미리 듣기만 가능합니다." 팝업창이 뜨기 이전에 아래 그림에서처럼 004045D8 주소에서 Breakpoint가 걸렸다.

 

그렇다면 즉! 우리는 004045D8주소에 도달하지 않게 함으로써 rtcMsgBox 함수가 실행되지 않도록하여야 한다.

 

 

 

Problem 1: Explanation


004045D8 주소에 도달하기 않게 하기 위해서는 004045D8 이전 주소에서 004045D8에 도달하지 않을 수 있는 코드를 찾아야겠다. 즉, JUMP을 찾는 것이다.

 

아래의 그림에서와 같이 004045D8 주소 조금 위를 살펴보면 0040456B 주소와 0040457C 주소에서 JUMP 문이 존재한다.

 

먼저 0040456B 위치의 점프문에서 점프하게되면 004045FE 주소로 점프하게 되기 때문에 팝업창을 호출하는 함수 주소인 004045D8로 도달하지 않을 것이다. 즉, 0040456B에서 무조건 점프 되도록 해야한다!!!

 

0040457C 주소는 점프 유무에 상관없이 팝업창을 호출하는 함수 주소인 004045D8로 도달하기 때문에 무시해도 좋다.

 

그렇다면 아래에서 0040456B 점프문을 자세히 살펴보자.

 

 

아래 그림의 0040456B 주소에서의 JUMP문은 Jl 어셈블리 명령어이다.

Jl은 Jump if less의 줄임말로 비교 대상이 더 값이 작다면 점프하고, 그렇지 않다면 점프하지 않는다.

우리는 무조건 점프를 시켜야 하므로 비교 대상의 값이 더 작아야한다!

비교문은 00404563 주소의 cmp eax, EA60이 존재한다.

그렇다면 eax가 EA60 보다 더 작아야 한다! 이전에는 eax가 EA60보다 값이 크기 때문에 점프하지 않았을 것이다.

 

eax가 어느정도로 작아야하는지 확인하는 것보다 EA60 값을 가장 크게 FFFF로 바꿔주는게 편할 것 같다.

 

편리를 위하여 00404563 주소에 Breakpoint를 걸어두고 디버깅을 다시 수행하여 EA60을 FFFF로 수정한 후 실행해보자!

오..! 점프를 성공하고 아래 그림과 같이 이번에는 Run-time error '380' 문제가 발생한다.

 

 

 

Problem 2


두 번째 문제는 Run-time error를 해결하는 것이다.

먼저, 다시 디버깅을 하면서 Run-time error 팝업 창이 발생하는 위치를 찾아보자.

 

 

다시 한번, [ctrl]+[F2] 단축키를 통해 프로그램을 다시 디버깅하여 위의 Problem 1을 해결하고 음악 재생을 계속 수행하게 되면 59초에 프로그램이 멈춘다. 

멈추는 구간은 아래 그림과 같이 76404592 주소이다.

 

 

그리고 계속 Run-time error 팝업 창을 발생시키기 위해 디버깅을 수행 계속해서하게 되면 아래 그림에서와 같이 771DCD67 주소에서 Run-time error 팝업 창이 발생한다. 

 

해당 함수로 오기까지의 콜스택을 살펴서 어디서 이런 에러를 발생시키는 지를 확인해보았다.

[Alt] + [K] 단축키를 통해 오류가 발생한 곳에서 호출 스택을 확인해보았다.

아래 그림에서와 같이 004046BF에서 호출된 것으로 보인다. 해당 주소로 가보자.

 

[Ctrl] + [G] 단축키를 통해 아래 그림에서처럼 004046BF 주소로 이동하자.

 

아래 그림에서 004046BF 주소를 살펴보면 해당 주소 바로 위에서 __vbaHresultCheckObj 함수가 선언된 것을 확인할 수 있다.

위의 콜스택에서 004046BF가 호출된 이후에 해당 에러가 발생하는 것을 보니 __vbaHresultCheckObj 함수에서 문제가 있는 것으로 보이므로 004046AB 주소의 Jump 문을 활용해서 __vbaHresultCheckObj 함수를 뛰어 넘어 실행시키지 않도록 하자.

 

 

Problem 2: Explanation


우리는 이제 004046AB의 Jump 문을 활용해서 __vbaHresultCheckObj 함수를 뛰어 넘겨야한다.

가장 쉬운 방법은 004046AB 주소의 명령 jge를 jmp로 수정해서 무조건 점프를 수행하는 방법이다.

 

편의를 위해 004046AB 주소에 Breakpoint를 걸어놓고, 다시 프로그램을 디버깅을 시작한다.

디버깅 시작 시 첫 번째 문제를 해결하고,  breakpoint를 걸어둔 004046AB 주소로 가 아래 그림과 같이 jge를 jmp로 수정한다.

 

 

그리고 계속 프로그램 음악을 실행하게 되면 아래 그림과 같이 mp3 파일이 1분 이상으로 실행되면서 키를 획득할 수 있다!

 

헷 하나 풀었당! 두 번째 Problem 때문에 애를 좀 먹었지만..

풀고나면 또 이렇게 기분이 좋을 수가 없다..ㅎ 이래서 리버싱을 하는건가

 

'RVS' 카테고리의 다른 글

Reversing.kr 11번 문제(Easy ELF)  (0) 2020.03.19
Reversing.kr 7번 문제 (Position)  (0) 2020.03.19
Reversing.kr 9번 문제(Ransomware)  (0) 2020.03.16
UPX Manual Unpacking  (0) 2020.03.12
Reversing.kr 2번 문제(Easy Keygen)  (0) 2020.03.11