쉬는시간/xcz.kr

[xcz.kr] PROB9 문제풀이

happy-nut 2015. 10. 31. 12:51

9번 문제의 Title은 「Easy Reversing」입니다.

xcz.kr의 리버싱 문제 중 가장 쉬운 문제로 보입니다.

Download Here을 클릭하여 파일을 다운로드 받아보면 약 8KB짜리 "REV.exe"라는 실행파일이 보입니다.

리버싱을 하려면 Olly Debugger같은 리버싱 툴이 필요한데, 개인적으로 Immunity Debugger의 알록달록함을 선호하는 편이라 이 풀이에선 Immunity Debugger를 사용했습니다.

 그러나 사실 Olly Debugger와 Immunity Debugger는 동일 인물이 만들었기 때문에 인터페이스 상으로 큰 차이가 없을 뿐더러 리버싱을 하는 데 필요한 여러 단축키등이 거의 동일합니다. 차이점은 Immunity Debugger는 Olly Debugger와는 다르게 Python 모듈을 지원한다는 겁니다. Olly나 Immunity말고도 IDA라는 Debugger가 있는데, 아쉽게도 유료입니다. IDA는 Olly나 Immunity보다 프로그램의 구조를 파악하는 데 유리합니다만, 이런 간단한 프로그램을 분석할 땐 Olly나 Immunity가 더 적절합니다. IDA가 숲을 들여다보는 느낌이라면, Olly나 Immunity는 나무를 자세히 들여다 보는 느낌이기 때문입니다.

이뮤니티에 프로그램을 올려보면 위와 같은 모습이 보입니다.

리버싱을 하는 데 가장 중요한 능력 중 하나는 더미(Dummy, 쓰레기) 코드를 잘 건너뛰는 능력입니다. 그런 의미에서 <Alt + E> 단축키는 매우 중요합니다. <Alt + E> 키를 누르면 Immunity는 프로그램이 실행되면서 로드할 모듈들을 나열하고 각 모듈 별 EP(Entry Point)를 왼쪽 Base카테고리에 적어줍니다. 해당 파일과 같이 패킹이 되지 않은 파일은 자연스레 디버거가 찾아준 EP가 OEP(Original Entry Point)가 되는 것이고, 패킹된 파일일 경우 PEP(Packing Entry Point)라고 합니다. PEP는 디버거가 패킹된 파일에 속아 잘못 찾아주는 Entry Point를 말합니다.

가장 위에 "C:\Users\Administrator\Downloads\REV.exe" 가 보이는데 이는 프로그램이 실질적으로 실행되는 Main부분입니다. 

저 부분을 더블클릭하여 들어가면 REV 모듈의 Base Address지점으로 가게 되고,이 부분은 C언어로 따지자면 int Main()인 셈입니다.

브레이크 포인트(단축키 F2)를 걸고 이부분까지 실행(단축키 F9)하게되면, REV.exe를 로드하는 데 필요한 dll 코드 등 이 프로그램을 리버싱하는 데 불필요한 Dummy Code 는 손쉽게 건너뛰게 됩니다.

한가지 더, ImmunityDebugger의 강력한 기능이 또 있다면 어셈블리 창을 우클릭했을 때 나타나는 메뉴 중 "Search for" ▶ "All Referenced Text Strings"입니다. 이 기능은 프로그램이 실행되면서 사용된 문자열과 이 문자열이 쓰인 주소번지를 나타내는 창을 보여줍니다.

이렇게 되면 문제처럼 간단한 프로그램은 직접 돌려보지 않더라도, 대강 어떤 식으로 흘러갈 지 짐작할 수 있게 됩니다. 

REV.exe의 경우엔 ID와 PW를 입력받고, 프로그램에서 원하는 값이 아니면 "Who are you???"라는 문자열을 띄우고, 원하는 값을 내놓았을 경우엔 "long time no see! sir, ..."이라는 문자열을 보여줄 것이라 짐작 가능합니다. 이런 key 문자열들이 보이면 브레이크 포인트를 걸어두는 것도 좋습니다.

"long time no see!"의 주소는 0x9D112C이고, "Who are you???"의 주소는 0x9D1181입니다. 이제 프로그램이 대강 어떻게 돌아갈지 파악을 했으니, 조심스럽게 F8을 눌러 실행시켜볼 차례입니다.

아니나 다를까 scanf를 사용하여 ID와 PW를 입력을 받습니다. 필자는 ID에 "Doubleng"을, PW에는 a를 10개 입력한 "aaaaaaaaaa"를 넣었습니다.

입력받는 부분 바로 밑에서 CMP로 비교하는 부분이 보이는데, 오른쪽 레지스터창을 잘 살펴보면 필자가 입력한 "Doubleng"과 "XCZ"라는 문자열을 비교하는 부분인 걸 알 수 있습니다. 

이 부분에서 ID에는 왠지 "XCZ"라는 문자열이 들어가야 할 것 같다는 걸 눈치로라도 알아챘을 겁니다. 하지만 좀 더 근거를 대보자면, 주황색으로 박스친 부분에서 JNZ로 문자열을 비교한 결과가 같지 않다면 0x9D10F0으로 보내고, 이 주소에서 조금 더 내려오면 0x9D1181로 보내는데, 0x9D1181은 아까 "All Referenced Text Strings"로 열어본 창에서 확인한 "Who are you???"라는 문자열을 Stack에 Push하는 부분의 주소값 입니다. 

다시말해 ID가 "XCZ"가 아니라면 "Who are you???"라고 프로그램이 물어볼 것이라는 소리다. 

따라서 브레이크 포인트가 망가지지 않게 바로 재시작을 하여 ID에 "XCZ"를, PW에 "aaaaaaaaaa"를 넣어보면 아이디를 검증하는 부분은 가볍게 통과하게 됩니다.

또, 아래 이미지에서 레지스터 창을 보면 알 수 있듯이 ID를 비교했을 때와 아주 비슷하게 필자가 입력한 "aaaaaaaaaa"와 "UNL1M1T"이라는 문자열을 비교한다는 사실을 알 수 있습니다. 

즉, "XCZ"의 PW는 "UNL1M1T" 입니다.

알아낸 값들을 넣고 프로그램을 돌려보면 다음과 같이 Key값을 보여줍니다.



답 : RevERsingisfun!!

'쉬는시간 > xcz.kr' 카테고리의 다른 글

[xcz.kr] PROB12 문제풀이  (0) 2015.11.01
[xcz.kr] PROB17 문제풀이  (0) 2015.11.01
[xcz.kr] PROB32 문제풀이  (0) 2015.10.30
[xcz.kr] PROB8 문제풀이  (0) 2015.10.30
[xcz.kr] PROB1 문제풀이  (0) 2015.10.29