kj0on

[RCE] Basic L04 본문

Reversing/CodeEngn

[RCE] Basic L04

kj0on 2025. 6. 29. 17:02
목차 접기

0. 실행환경

 

0-1. 운영체제 (1)

Window 11 Home


0-2. 툴 (2)

x32dbg
Detect it easy


1. 파일

https://codeengn.com/challenge/rce_basic
04.7z
0.04MB

 

password : codeengn


2. 프로그램 동작

[이미지1] Basic 04

프로그램 실행 시 "정상" 문자열을 반복해서 출력한다.

 

[이미지2] Basic 04

x32dbg에서 실행 시 "디버깅 당함" 문자열을 반복해서 출력한다.


3. Detect It Easy

[이미지3] DIE 실행 결과

32비트 실행파일, Microsoft Visual C/C++로 작성된 콘솔 프로그램 인 것을 확인할 수 있다.


4. 분석

[이미지4] EntryPoint

EntryPoint로 이동해서 우선 문자열이 출력되는 부분을 먼저 찾기로 했다.

 

[이미지5] 문자열 참조

 EntryPoint에서 문자열을 참조하면 프로그램 동작에서 출력된 문자열을 확인할 수 있다. 해당 문자열의 구분하는 분기지점을 파악해야한다.

 

[이미지6] 문자열 참조

더블클릭해서 해당지점으로 이동해 보면 코드를 확인할 수 있다.

 

[이미지7] _chkesp

Sleep 함수 호출 이후 _chkesp 함수로 esp값을 체크한다.

 

[이미지8] Error

_chkesp는 컴파일 시 Debug 모드로 세팅하면 자동적으로 넣어준다고 한다(GPT). 값을 수정해 보면 위와 같은 에러가 출력된다. 문제풀이에 크게 중요하지는 않기 때문에 넘어갔다.

 

[이미지9] 조건부 분기

밑을 살펴보면 조건부 분기가 나타나는데 저 코드로 "정상", "디버깅 당함"을 구분한다. 해당 분기는 eax값이 0인지에 따라 결정된다.

 

[이미지10] IsDebuggerPresent

해당 분기는 IsDebuggerPresent 함수의 반환값으로 결정된다.

 

[이미지11] IsDebuggerPresent (https://learn.microsoft.com/ko-kr/windows/win32/api/debugapi/nf-debugapi-isdebuggerpresent)

MSDN에서 반환값을 살펴보면 디버거에서 실행 시 0이 아닌 값이 반환되고, 아니라면 0을 반환한다고 한다. 실제 디버거에서 반환값을 확인해 보면 0x1이 반환된다. 해당 함수에 대한 더 자세한 내용은 나중에 다루기로 하고, 분석을 계속 진행한다.

 

[이미지12] printf

이후 printf 함수가 호출된다. je를 통해 분기하기 때문에 디버거에서 실행하면 분기하지않는다(반환값이 0x1이기 때문). 따라서 "디버깅 당함" 문자열이 출력되는 것이다. 반대로 디버깅 중이지 않을 때는 반환값이 0x0이 되면서 조건부 분기가 이루어진다. 그래서 정상 실행중일 때는 "정상"이 출력되는것이다.

 

[이미지13] 조건부 분기 수정

ZF를 설정해서 분기가 발생하게 하면 위와 같이 디버깅 중에도 "정상"을 출력할 수 있다.


5. 풀이

[이미지14] IsDebuggerPresent

je의 조건부 분기는 IsDebuggerPresent의 반환값(EAX)에 의해 결정된다. test를 통해 해당 반환값이 0인지를 확인한 뒤 조건부 분기한다. 따라서 디버거를 탐지하는 함수는 IsDebuggerPresent이다.

 

[이미지15] _chkesp

해당 함수는 앞서 설명했듯이 프로그램 실행에 영향을 주지 않는다. ESP값의 오류를 체크하는 부분이다.


 

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

[RCE] Basic L06  (0) 2025.06.29
[RCE] Basic L05  (0) 2025.06.29
[RCE] Basic L03  (0) 2025.06.28
[RCE] Basic L02  (0) 2025.06.28
[RCE] Basic L01  (0) 2025.06.28