go-pwn中的protobuf
字数 1468 2025-08-20 18:17:53
Go Pwn中的Protobuf分析与利用
1. Protobuf基础
1.1 Protobuf在Go Pwn中的作用
在Go Pwn的堆题中,结构体通常通过Protobuf来传递。Protobuf是一种轻量级的数据交换格式,常用于网络通信和数据存储。
1.2 Protobuf类型定义
Protobuf定义了多种数据类型,每种类型对应一个枚举值:
typedef enum {
PROTOBUF_C_TYPE_INT32, // 0 - int32
PROTOBUF_C_TYPE_SINT32, // 1 - signed int32
PROTOBUF_C_TYPE_SFIXED32, // 2 - signed int32 (4 bytes)
PROTOBUF_C_TYPE_INT64, // 3 - int64
PROTOBUF_C_TYPE_SINT64, // 4 - signed int64
PROTOBUF_C_TYPE_SFIXED64, // 5 - signed int64 (8 bytes)
PROTOBUF_C_TYPE_UINT32, // 6 - unsigned int32
PROTOBUF_C_TYPE_FIXED32, // 7 - unsigned int32 (4 bytes)
PROTOBUF_C_TYPE_UINT64, // 8 - unsigned int64
PROTOBUF_C_TYPE_FIXED64, // 9 - unsigned int64 (8 bytes)
PROTOBUF_C_TYPE_FLOAT, // 10 - float
PROTOBUF_C_TYPE_DOUBLE, // 11 - double
PROTOBUF_C_TYPE_BOOL, // 12 - boolean
PROTOBUF_C_TYPE_ENUM, // 13 - enumerated type
PROTOBUF_C_TYPE_STRING, // 14 - UTF-8 or ASCII string
PROTOBUF_C_TYPE_BYTES, // 15 - arbitrary byte sequence
PROTOBUF_C_TYPE_MESSAGE // 16 - nested message
} ProtobufCType;
1.3 关键偏移量
在分析Protobuf结构时,有几个关键偏移量需要注意:
- 第一个字节是变量的初值
- +8偏移处决定Protobuf中的变量类型(参考上表)
- 0x10偏移处对应着这个偏移
2. 工具准备
2.1 安装pbtk工具
pbtk是一个用于分析Protobuf的工具:
sudo apt install python3-pip git openjdk-11-jre libqt5x11extras5 python3-pyqt5.qtwebengine python3-pyqt5
sudo pip3 install protobuf pyqt5 pyqtwebengine requests websocket-client
git clone https://github.com/marin-m/pbtk
cd pbtk
2.2 使用pbtk提取Protobuf定义
有两种使用方式:
- GUI模式:
./gui.py - 命令行模式:
./extractors/from_binary.py [-h] input_file [output_dir]
提取后生成.proto文件,然后可以生成对应的Python文件:
protoc --python_out=./ ./devicemsg.proto
3. 案例分析
3.1 CISCN2024初赛 ezbuf
3.1.1 题目分析
- 需要手动分析提取Protobuf定义
- 关键结构:
syntax = "proto2"; message devicemsg { required bytes whatcon = 1; required sint64 whattodo = 2; required sint64 whatidx = 3; required sint64 whatsize= 4; required uint32 whatsthis= 5; }
3.1.2 功能分析
- add: 数据(msg)在堆上,根据大小申请相应堆块
- delete: 存在UAF,可以double free,但有次数限制
- show: 可以泄露信息,但show三次会关闭标准输出
- clean: 看似无操作,实际会处理输入的msg并申请堆块
3.1.3 利用思路
- 泄露heapbase和libcbase
- 通过有限的delete次数实现多次任意地址申请
- 利用tcache_perthread结构进行攻击
- 通过打stdout泄露stack,最后实现ORW
3.2 CISCN2024初赛 SuperHeap
3.2.1 题目特点
- 可以直接用pbtk提取Protobuf定义
- 使用一个堆块存储其他堆块信息
3.2.2 逆向分析
- add函数:对输入数据进行base32解密,再对解密后的date,title,author,isbn进行protobuf获取数据,再进行base64解密
- delete函数:检查有无UAF
- edit函数:没有长度限制,可以任意写
- show函数:常规打印功能
3.2.3 利用思路
- 利用edit函数的无长度限制特性实现任意写
- 构造IO链进行攻击
- 布置ROP链实现最终利用
4. 利用技巧
4.1 堆布局技巧
- 通过多次add和delete创造理想的堆布局
- 利用smallbin和unsorted bin泄露libc地址
- 通过tcache poisoning实现任意地址写
4.2 泄露技巧
- 通过show函数泄露heap和libc地址
- 当标准输出被关闭时,可以通过IO结构体泄露信息
- 利用environ变量泄露栈地址
4.3 最终利用
- 构造ROP链实现ORW (Open-Read-Write)
- 利用setcontext进行栈迁移
- 通过文件描述符操作读取flag
5. 防御与绕过
5.1 常见防御
- Protobuf标志抹除
- 堆操作次数限制
- 标准输出关闭
5.2 绕过方法
- 手动分析Protobuf结构
- 精心设计堆布局以最大化利用有限的操作次数
- 通过其他方式(如IO结构体)实现信息泄露
6. 总结
Go Pwn中的Protobuf分析需要结合逆向工程和堆利用技巧。关键点包括:
- 正确识别和提取Protobuf结构
- 理解题目中的堆管理机制
- 在有限的操作次数内实现信息泄露和任意写
- 最终构造有效的利用链
通过案例分析和工具使用,可以系统性地掌握这类题目的解题方法。