Wargame/dreamhack.io

[Lenas Reversing for Newbies] 19

maple19out 2021. 4. 1. 22:09

이번 실습에서는 아래와 같은 6가지 파일을 패치해봄으로써 Anti-Anti에 대한 개념을 정리한다.

 

- ReverseMe.A.exe

- ReverseMe.B.exe

- ReverseMe.C.exe

- Reverse.Me.D.exe

- Debugger Detected.exe

- antisniff.exe  (무슨 원인인지 모르겠으나, OllyDbg에서 Anti-Debugging 기법을 감지하지 못하는 문제가 발생한다.)

 

1. ReverseMe 시리즈

ReverseMe 시리즈는 기본적으로 Lenas Reversing 02번에서 다뤘던 파일과 거의 동일한 구조다.

maple19out.tistory.com/53?category=913479

 

[Lenas Reversing for Newbies] 02

1. 프로그램 실행 01편 강좌와 동일한 reverseMe.exe 파일을 이번에는 패치를 이용하지 않고 크랙을 이용해 문제를 해결한다. 2. Debugging(with OllyDbg) 위의 동그라미 친 부분에서 CreateFileA() API가 호출되..

maple19out.tistory.com

이미 Keyfile.dat 파일까지 친절하게 첨부되어 있으며, 각 파일을 실행하면 다음과 같이 별 문제가 없어 보이는 메시지 박스가 나타난다.

 

실행 화면

 

하지만 OllyDbg로 파일을 열어 실행하면 다음과 같이 에러 화면이 나타난다.

 

ReverseMe.A.exe 디버깅 중 실행

 

ReverseMe.B.exe 디버깅 중 exception 발생

 

ReverseMe.C.exe 실행 후 바로 종료

 

ReverseMe.D.exe 실행 중 exception 발생

 

따로 파일을 패치하지 않았지만, 디버깅 환경에서 파일을 실행했을 때 위와 같은 문제가 발생한다. 각 파일을 명령어 한 줄씩 실행하면서 왜 이런 현상이 나타나는지 분석해보자.

 

- ReverseMe.A.exe

ReverseMe.A.exe를 실행하다보면 아래와 같은 API를 호출하는 것을 확인할 수 있다.

IsDebuggerPresent() API

위 API를 MSDN에서 검색해보면 해당 API는 user-mode debugger에 의해 process가 디버깅 중일 경우, nonzero 값을 반환하고, 그렇지 않은 경우 zero를 반환한다. 현재 OllyDbg로 디버깅 중이므로 F8을 눌러 API를 실행하면 EAX 레지스터에 다음과 같이 1이 담겨 있는 것을 확인할 수 있다.

 

EAX 레지스터

이어지는 JE 명령어에 의해 결국 "Keyfile is not valid." 문구를 출력하는 메시지 박스 호출 루틴으로 이동하게 된다. 단순히 JE 명령어를 NOP 처리 하면 안티 디버깅 기법을 우회할 수 있다.

 

- ReverseMe.B.exe

마찬가지로 F8을 이용해 한줄씩 실행시키다 보면 ReverseMe.A.exe 같이 IsDebuggerPresent() API를 호출한다.

ReverseMe.B.exe 디버깅

이번에는 JE에 의해 00401106 라인으로 점프하게 되는데, 해당 메모리에서 MOV 연산을 통해 401121위치에 쓰기 연산을 수행하고 있다. Memory map을 통해 해당 주소 영역을 확인해보자.

 

ReverseMe.B.exe Memory map

위와 같이 data 영역은 현재 읽기권한(R)만 부여된 상황으로, 명령어를 수행하면 다음과 같이 Access Violation이 일어난다.

 

Access Violation

마찬가지로 JE 명령어를 NOP 처리하여서 우회할 수 있다.

 

- ReverseMe.C.exe

똑같은 구조이지만 아래와 같이 IsDebuggerPresent가 호출된 후, ExitProcess(0)이 호출된다. (우회 방법 동일)

 

ReverseMe.C.exe 디버깅

- ReverseMe.D.exe

마찬가지이다. 이번에는 JE 명령어가 가리키는 곳으로 가보면 JMP EAX 명령어가 나타난다. IsDebuggerPresent API가 호출된 이후 EAX 레지스터에는 1이 저장되어 있어 JMP 1이 실행되고 결과적으로는 Access Violation이 발생하게 된다. (우회 방법 동일)

 

ReverseMe.D.exe

 

2. DebuggerDetected

먼저 파일을 일반 환경에서 실행해보자.

실행 화면

 

위와 같이 윈도우가 나타난다. Verify 버튼을 클릭해보자.

실행 화면

"Debugger NOT detected !!"라는 문구의 메시지 박스가 나타난다. 이번에는 OllyDbg로 파일을 실행해보자.

 

디버깅 중 실행 화면

위와 같이 "Your debugger is detected !!!" 라는 문구가 나타난다. 호출된 시점의 Call Stack을 통해 어느 부분에서 메시지 박스가 나타난 건지 추적해보자.

 

DebuggerDetected 콜 스택

Debugger 모듈에서 메시지 박스 API 직전에 호출된 부분인 동그라미 친 부분으로 이동해보자.

 

디버깅

아래 쪽 동그라미가 콜 스택을 통해 이동된 부분이다. 위쪽 동그라미 부분에서 함수가 시작하면서 스택 프레임을 생성하는 것을 확인할 수 있으므로, 해당 지점에 BP를 설정하고 다시 실행해보자.

 

BP 적중

위와 같이 BP에 적중한다. 아마도 0040109E (콜 스택에 찍힌 부분)에서 안티 디버깅 관련 루틴이 있을 가능성이 높으므로, 해당 부분으로 step in 해보자.

 

안티 디버깅 루틴

무언가 복잡해 보이지만 천천히 코드를 살펴보면 다음과 같은 역할을 하는 루틴이라는 것을 파악할 수 있다.

 

(1) CreateToolhelp32Snaphot API()를 호출하여 process 들의 스냅샷을 생성한다. CreateToolhelp32Snapshot() API의 원형은 다음과 같다.

HANDLE CreateToolhelp32Snapshot(
  DWORD dwFlags,
  DWORD th32ProcessID
);

Argument로 TH32CS_SNAPALL과 0을 넘겨주므로 모든 프로세스에 대한 스냅샷을 생성한다.

 

(2) 루프를 돌며 스냅샷에 찍힌 프로세스들을 순회한다. 이때, lstrcmpiA 함수를 통해 프로세스의 이름이 "OLLYDBG.EXE"인지 체크한다. 만약에 "OLLYDBG.EXE"가 존재할 경우, "Your debugger is detected !!!" 문구의 메시지 박스 호출 루틴으로 이동하게 된다.

 

위 안티 디버깅 루틴을 우회하는 방법은 간단하다. 마찬가지로 함수 시작 부분에 스택 프레임을 생성하는 부분에 바로 ret 명령어로 패치를 하는 방법, 호출하는 코드를 NOP 처리하는 방법 등이 있다. 아니면 OLLYDBG가 아닌 다른 x32dbg와 같은 디버거를 이용해도 디버거 탐지가 안될 것이다.

 

3. Comment

기본적인 안티 디버깅과 안티-안티 디버깅에 대한 내용을 실습할 수 있는 예제다. 리버싱 핵심원리 서적에서도 다루는 내용으로, 보다 손쉽게 문제를 해결할 수 있었다.

반응형