protobuf初探
protobuf简介
Protocol Buffers(通常简称为protobuf)是由Google开发的一种语言中立、平台中立的序列化结构数据的方法。它用于高效地存储和交换数据,特别适合用于网络通信和数据存储。protobuf的主要特点包括:
- 高效性:protobuf使用紧凑的二进制格式,比其他文本格式(如JSON或XML)更小、更快。
- 语言中立:支持多种编程语言,包括C++、Java、Python、Go等,使得跨平台的数据交换变得简单。
- 易于扩展:可以在不破坏现有数据结构的情况下,轻松地添加新字段。
- 定义文件:使用
.proto
文件来定义数据结构和服务,可以通过工具自动生成相应的代码。
通过protobuf,开发者可以定义消息类型,使用这些类型进行数据序列化和反序列化,从而在不同的系统或服务之间传输数据。
Proto2: 支持 required
和
optional
修饰符。
Proto3: 默认所有字段为 optional
,不支持
required
工具集安装
- pbtk:(自动化分析)
1 | sudo apt install python3-pip git openjdk-11-jre libqt5x11extras5 python3-pyqt5.qtwebengine python3-pyqt5 |
- Protobuf 库:(本地搓proto文件并编译成python)
1 | sudo apt-get update |
目标
protobuf这类题一般都会将输入转化成特殊的结构体,这就要求我们首先要逆向出proto结构体。
一些结构体定义
ProtobufCFieldDescriptor

1 | struct ProtobufCFieldDescriptor { |
label和type
label和type都是枚举类型:
1 | typedef enum { |
定位结构体方式
1.手动定位
因为我们输入的内容会通过protobuf_c_message_unpack
这个函数进行解析。所以我们可以对比链接库中的函数具体定义以及我们pwn的主程序中调用的传参。然后就能跳转到主程序中的具体descriptor中进行下一步分析。



首先要在主程序里找一个message_descriptor
,一般在.data.rel.ro段,其开头的魔数(magic)是0x28AAEEF9,一般而言下面会直接解析出Protobuf结构体的名字,但也有IDA识别不出来的情况,我们可以手动将db类型转为dq类型,然后就会清晰很多。


我们的消息结构体名字就为MyMessage
。接着我们可以往my_message__field_descriptors
里看,里面就是具体的字段,也就是ProtobufCFieldDescriptor
这个结构体。但是也都被IDA当作了db解析,我们可以按照下表结构体的字段分布进行修改,手动将其解析一下,主要看name,id,label,type,其他怎么改影响不大。一下子就清晰了不少,然后我们就可以对照着枚举表还原出protobuf了。



1 | //message.proto |
然后在命令行将其转化成python文件即可
1 | protoc --python_out=. message.proto |
2.自动分析
首先进入之前安装好的pbtk目录,python3 gui.py
就可以启动一个gui窗口,然后选择Extract .proto structures from apps
,就可以选择pwn程序自动提取其中的proto文件了。但有时会不灵,还是手动分析有趣。
脚本编写
分析完proto的结构,就可以进行exp脚本的编写了,之前我们通过proto生成的python文件名为proto结构体名_pb2
,可以先导入exp。
1 | import message_pb2 |
判别proto版本方式
一般proto分为proto2和proto3两个版本,在写proto文件时要在开头指明syntax=proto2/3
。
在proto3中移除了require这个修饰符,如果有的label位为0(required),就说明用的是proto2语法。
其实也可以都带进去试试,总共就两个版本,别的地方没分析错的话总有一个会通过的。
常见问题解决
1.库找不到

可以手动在/usr/lib下添加一个链接
1 | sudo ln -s /mnt/e/ctf/2024shctf/pwn/shctf——challage_pwn_protobuf/libprotobuf-c.so.1 /usr/lib/libprotobuf-c.so.1 |
2.运行exp时因为引入了proto转成的python文件报错

提高python库中protobuf的版本
1 | pip3 uninstall protobuf |
3.逆出结构体后prpto一直无法正常解析
可以尝试把sendline
换成send
,有时候多一个换行符就解析不出来了。
- 标题: protobuf初探
- 作者: collectcrop
- 创建于 : 2024-11-21 23:47:01
- 更新于 : 2024-11-23 23:26:34
- 链接: https://collectcrop.github.io/2024/11/21/protobuf初探/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。