Thursday, August 1, 2013

Anti-reversing - PEB.BeingDebugged


 Anti Reversing 즉, Reverser 들이 Debugging 을 하지 못하게 막아 놓은 기법들을
잠깐 소개할까 합니다.

아주 많은 방법들이 있다고 알려져 있지만, 아는 한도 내에서 간단히 소개합니다.

여기서 사용한 Debugging tool은 OllyDBG v1.1입니다.

프로그램이 실행이 되어 메모리상에 적재가 되면 하나의 프로세스가 생성이됩니다.
이때 프로세스의 상태를 알려주는 정보도 포함이 되게 되는데
이 프로세스가 현재 Debugging이 되고 있는지에 대한 정보도 포함이 됩니다.
그 정보가 PEB(Process Environment Block) 라는 구조체에 실리는데
사용하기가 쉽기 때문에 많이 쓰입니다.

PEB.BeingDebugged

PEB 구조체에 대한 내용은 생략합니다. 검색하시면 얼마든지 공부하실 수 있음.
PEB 구조체의 시작주소로 부터 0x2 만큼 떨어진 지점에 BeingDebugged 라는 1바이트
크기의 멤버가 있는데 Debugging 중일때 이 값은 1로 변합니다.(Default 0)

따라서 이 값을 0으로 변경하면 끝입니다. 아주 쉽습니다.

<PEB 시작주소 구하기>
OllyDBG 에서는 고민할 필요 없이 처음 OllyDBG로 해당 Debugee를 불러왔을때
EBX Register가 PEB 시작 주소를 기억하고 있기 때문에 한눈에 보고 찾아 갈수가 있습니다.
아래에서는  7FFD9000 이 PEB 의 시작주소이기 때문에 0x2 만큼 떨어진 지점이
PEB.BeingDebugged 멤버입니다.



















또 다른 방법으로 TEB(Thread Environment Block) 구조체를 확인하여 알 수도 있습니다.
TEB 구조체 역시 직접 학습하기 바랍니다.
TEB 구조체에서 0x30만큼 떨어진 지점에 PEB 구조체의 의 주소가 있습니다.
TEB 구조체 시작지점으로 접근 하려면 FS:[18] (Olly에서 Ctrl+G 로 이동) 로
이동하면 됩니다. 그러면 TEB 구조체가 시작되고, 거기에서 0x30만큼 떨어진지점이
PEB 구조체의 시작지점 거기에서 0x2 만큼 떨어진 지점이 우리가 찾는 PEB.BeingDebugged 멤버입니다.

이것 저것 다 귀찮다 그러면 가장 간단한 방법으로 Olly에서 Ctrl + G 한 뒤에 FS:[30]+2 
로 PEB.BeingDebugged 멤버로 바로 날라가는 방법도 있습니다.

<예제>













위 예제는 Anti Reversing 기법중에 PEB.BeingDebugged 멤버를 찾아 현재
프로세스가 Debugging 당하는지 확인하는 코드입니다.
FS:[18] 로 TIB 시작주소를 찾습니다. TEB 시작주소로부터 0x30 만큼 떨어진 지점에
PEB 의 시작주소가 있으므로 [EAX+30] 를 다시 EAX로 담습니다.
그후 0x2 만큼 떨어진 지점 [EAX+2] 의 위치를 반환 받습니다.
이 위치의 data 가 0인지 1인지를 확인하는 cmp 명령이 RETN 다음에 있을것으로
예상됩니다.

cmp 가 아닌 TEST 로 확인을 하고 있습니다.
TEST 는 내부적으로 AND 연산을 통해 0인지 아닌지만을 판단합니다.

0이라면 즉, Debugging 이 되고 있지 않고 있으므로 정상적으로 실행이 됩니다.
0이 아니라면 즉, Debugging이 되고 있다고 판단하고 바로 종료 시킬것입니다.
TEST 의 결과를 가지고 아래 JE 에서 분기 되는것입니다.
그 아래로는 두개의 메시지 박스가 보입니다. 디버깅이 되고 있다는 메시지와
정상 실행되었다는 메시지로 보입니다.











<관련 API>
windows API 중에서 PEB.BeingDebugged 멤버를 바로 찾아주는 함수가 있습니다.
바로 isDebuggerPresent() 라는 함수입니다.

Olly 에서 함수찾기 기능으로(search for All intermodular calls) 해당 함수가 존재하는지
확인 할 수 있습니다.

사실 위에서 예제로 사용한 코드가 바로 isDebuggerPresent() 함수가 BeingDebugged
값을 찾아가는 과정입니다. 아주 단순합니다.

<WinDBG>
WinDBG를 이용하는 분들을 위해 WinDBG에서 PEB시작주소를 찾아가는법을
알려 드리겠습니다.

open executable file로 해당 file을 로딩합니다.
아래와 같이 dg 3b 로 peb 구조체의 시작을 알 수 있다.(base 값이 시작주소)
PEB의 구조체에서 각 옵셋에 해당하는 멤버을 알고 있으므로, 시작 주소만 알려주면
해당 멤버들의 주소를 알려주게 된다.









아래의 dt 는 구조체를 보겠다는 명령어. nt_tib 는 구조체 이름이며, 구조체 앞에는
항상 _를 붙여주어야 한다. 아래와 같이 구조체의 각 멤버를 확인 할 수 있다.











위에서 알아낸 구조체의 시작주소 정보를 가지고

dt _peb 주소 라고 입력하게 되면, 입력된 주소를 시작주소로 하여 각 옵셋을 계산후 peb 구조체의 각 멤버의 주소를 자동으로 계산해 보여준다.









No comments:

Post a Comment