Basic RCE L01 해설 - 코드 엔진

2020. 3. 13. 13:16문제연습/CodeEngn (REC)

반응형

 

본 티스토리 블로그는 PC에 최적화되어 있습니다.

모바일 유저분들은 아래 네이버 블로그를 이용해 주세요.

 

Basic RCE L01 해설 - 코드 엔진

본 네이버 블로그는 모바일에 최적화되어 있습니다.PC 유저분들은 아래 티스토리 블로그를 이용해 주세요...

blog.naver.com

 

안녕하세요, ICMP입니다.

이번 시간에는 코드 엔진 챌린지인 Basic RCE L01를 풀어 보도록 하겠습니다.

 

1. 문제 내용

HDD를 CD-Rom으로 인식시키기 위해서는 GetDriveTypeA의 리턴 값이 무엇이 되어야 하는가

Author: abex

File Password: codeengn

 

 

2. 문제 해설

일단 문제를 다운로드하고 압축 해제하도록 합시다.

비밀번호는 codeengn입니다.

 

일단 디버깅을 시작하기 전에 먼저 파일을 실행해 보도록 하겠습니다.

프로그램이 CD-Rom으로 인식하도록 해달라고 합니다. 계속해서 실행 시켜보도록 하겠습니다.

 

CD-Rom으로 인식이 안되는군요. 흠...

 

 

이 프로그램은 실행시 어떠한 과정을 통해 CD-Rom 판별 후 그 결과를 화면에 출력 시키는 듯합니다.

또한 윈도우즈 프로그래밍을 하신 분들이라면 화면 창을 띄우기 위해 메시지 박스 함수를 사용했다는 것도 눈치채셨을 것입니다.

 

대략적인 프로그램의 구조를 추측해 보았으니 본격적으로 올리 디버거를 관리자 권한으로 실행한 후Basic RCE L01을 압축 해제한 폴더로 가서 디버깅을 시작하겠습니다.

 

(ollydbg 실행 파일을 우클릭하여 관리자 권한으로 실행하기 하면 됩니다.)

 

디버깅을 시작하면 다음과 같은 창이 뜹니다.

뭔가 복잡해 보이지만 화면에 나오는 어셈블리 코드가 전부입니다.

(아마도 이 문제를 제작한 abex라는 분은 어셈블리어를 이용하여 코딩한 듯합니다.)

 

 

여기서부터는 우리가 추측을 해내야 합니다.

코드를 처음부터 해석하는 방법도 좋지만 그러기에는 분석하는데 시간이 너무 많이 걸립니다.

 

아까화면 창에서 Nah... This is not a CD-ROM Drive! 와 같은 문자열이 출력되었고 메시지 박스 함수를 사용했을 것이라는 추측을 했습니다.

 

그러면 문제 접근 방식을 생각해야 합니다.

 

1. 메시지 박스를 호출하여 화면을 띄우는 시점 부근을 조사하여 CD-Rom 탐색하는 과정을 찾아낸다.

2. 화면에 출력 되는 문자열의 위치를 찾아서 CD-Rom 탐색하는 과정을 찾아낸다.

 

일단 1번 방식으로 진행해 보도록 하겠습니다. (2번은 여러분들의 숙제입니다 ㅎㅎ)

어셈블리 코드가 있는 창에 우클릭을 하여 Seach for -> All intermodular calls을 눌러 줍니다.

(All intermodular calls 옵션은 코드에서 호출되는 모든 API 함수를 확인하는 옵션입니다.)

 

All intermodular calls을 누르면 다음과 같은 화면이 나옵니다.

그러나 현재 어떤 함수가 Nah... This is not a CD-ROM Drive! 와 같은 문자를 띄우는지는 모릅니다.

지금은 호출되는 함수가 적어서 그냥 하나하나 다 볼 수 있지만 규모가 있는 프로그램은 엄청난 시간이 걸립니다.

 

여기서 우리들의 잔머리를 굴리도록 하겠습니다.

 

일단 팝업창을 띄우기 위해서는 메시지 함수가 필요하다.

-> 그러나 어떤 메시지 박스 함수가 우리가 원하는 문자열이 들어가 있는지는 모른다.

-> 메시지 박스를 호출하는 모든 지점에 중단점을 설정하여 실행 과정을 관찰한다.

-> 원하는 실행 결과가 나오는 부분이 있으면 그 부분을 집중적으로 분석한다!!!!

 

 

그럼 위에서 말한 방법대로 가보도록 하겠습니다.

(디버거 단축키는 아래 링크를 참고해 주세요.)

 

OllyDbg 단축키

ctrl + F2 : 다시 처음부터 디버깅 F7 : 하나의 OP code 실행(call 명령을 따라 함수코드 내부로 들어감) F8 : 하나의 OP code 실행(call 명령을 따라 함수코드 내부로 들어가지 않음) ctrl + F9 : 함수코드 내에..

mooreunself.tistory.com

 

MessageBoxA를 호출하는 주소에 한 번만 클릭 후 F2를 눌러서 중단점을 설정합니다.

그럼 이제 실행해야겠지요?

F9을 눌러서 중단점 이전까지 실행하도록 하겠습니다.

 

0040100E 주소에서 중단점을 만났습니다.

옆에 보니 처음 우리가 실행했을 때 만난 팝업창과 같은 것 같습니다.

(함수의 어셈블리 코드를 분석하고 싶으시면 F7 또는 주소 지정 후 Enter를 누르면 call 한 주소로 이동합니다.)

 

다시 F9을 누르니 다음과 같은 화면을 출력시키고 00401036으로 주소를 이동합니다.

 

계속해서 F9을 이용해 실행하니 다음과 같은 화면이 출력됩니다.

 

그럼 생각해 봅시다.

 

처음 0040100E 주소에서 메시지 함수를 호출시킨 후 00401036로 이동하여 CD-Rom 인식이 되지 않았다는 문구가 발생되었습니다.

 

즉, 0040100E ~ 00401036주소 사이에 CD-Rom 탐색하는 과정이 있다는 것입니다.

아까 All intermodular calls 옵션 창에서 한 가지 의심스러운 함수가 있었습니다.

바로 GetDriveTypeA입니다.

 

이 함수의 위치도 메시지 박스 호출 후 바로 call 되는 함수입니다.

즉, GetDriveTypeA의 리턴 값에 따라 CD-Rom 인식 여부가 판별되는 구조가 아닐까 추측했습니다.

우리에게는 검색이라는 아주 강력한 무기가 있습니다.

바로 확인해 보도록 하겠습니다.

(GetDriveTypeA에 대한 내용은 아래 링크를 참고해 주세요.)

 

GetDriveTypeA function (fileapi.h) - Win32 apps

Determines whether a disk drive is a removable, fixed, CD-ROM, RAM disk, or network drive.

docs.microsoft.com

 

리턴 값을 확인해 보니 아래 사진과 같습니다.

 

문제를 풀기 위해서는 GetDriveTypeA가 5를 리턴해야 CD-Rom으로 인식하는군요.

 

여기서 두 가지 방식이 있습니다.

1. 함수 리턴 값을 받는 레지스터의 값을 조작한다.

2. 그냥 어셈블리 코드를 조작하여 인식된 결과를 출력하도록 한다.

 

1번 방식을 이해하기 위해서 아주 중요한 내용인 함수 호출 규약을 알아야 합니다.

그 이유는 어셈블리 코드를 이용해서 어떻게 함수의 인자와 리턴 값을 전달하는지 패턴을 이해해야만 정확하게 레지스터의 값을 조작할 수 있기 때문입니다.

 

아래에 함수 호출 규약 링크를 참고해 주세요.

 

함수호출규약

1. 함수 호출 규약 개요 함수 호출 규약(Calling Convention)이란, 함수를 호출하는 방식에 대한 약속이다. 함수 호출 규약은 인자 전달 방법, 인자 전달 순서, Stack Frame을 정리하는 방법에 따라 그 종류를 구..

blog.kimtae.xyz

 

2번 방식은 아주 간단합니다.

CMP EAX, ESI

JE SHORT 0040103D

에서 EAX, ESI의 값이 같아야(JE) 0040103D 주소로 이동합니다.

 

레지스터의 값 상관없이 무조건 0040103D로 이동하게 하면 되겠지요??

JE를 JMP로 변경하면 됩니다.

어셈블리어 분기문에 대한 설명은 아래 링크를 참고해 주세요.

 

[SYSTEM HACKING] 어셈블리 분기문( compare, jump )

어셈블리 분기문( compare, jump )에 대해서 정리한다. 분기문: if, switch 1. cmp: compare - 레지스터나 메모리의 값을 변경하지 않는다. - 플래그 레지스터에만 영향을 준다. - SF,CF, ZF - cmp left..

btyy.tistory.com

 

아래와 같이 수정하면 다음과 같은 화면이 출력되고 종료됩니다.

 

Basic RCE L01 문제를 푸느라 고생 많았습니다.

이 문제는 단순히 GetDriveTypeA 리턴 값을 물어보는 문제였지만

기본기를 다지기에는 정말 좋은 문제입니다.

 

다음 시간에는 Basic RCE L04 문제 해설을 진행하도록 하겠습니다.

이상 ICMP였습니다!!!

 

 

반응형

'문제연습 > CodeEngn (REC)' 카테고리의 다른 글

Basic RCE L07 - 코드 엔진  (0) 2020.11.17
Basic RCE L06 - 코드 엔진  (0) 2020.03.19
Basic RCE L05 - 코드 엔진  (0) 2020.03.18
Basic RCE L04 해설 - 코드 엔진  (0) 2020.03.17
codeengn.com 준비  (0) 2020.03.13