Protobuf是由Google开发的一种序列化格式,用于越来越多的Android,Web,桌面和更多应用程序。它由一种用于声明数据结构的语言组成,然后根据目标实现将其编译为代码或其他类型的结构。
PBTK( Protobuf Toolkit )是一组成熟的脚本,可通过统一的GUI访问,提供了两个主要功能:
从程序中提取Protobuf结构,将它们转换回可读的.proto s,并支持各种实现:
通过方便的图形界面,您可以为Protobuf消息编辑实时字段并查看结果,并通过方便的图形接口进行编辑,重播和模糊数据发送到Protobuf网络端点。
PBTK需要Python≥3.5,Pyqt 5,Python-protobuf 3,以及少数可执行程序(Chromium,Jad,dex2jar ...),以进行运行的提取器脚本。
Archlinux用户可以通过包装直接安装:
$ yay -S pbtk-git
$ pbtk
在大多数其他发行版中,您都需要直接运行它:
# For Ubuntu/Debian testing derivates:
$ sudo apt install python3-pip git openjdk-9-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
$ ./gui.py还支持Windows(需要相同的模块)。运行GUI后,它应该警告您您缺少的东西,具体取决于您尝试做的事情。
GUI可以通过主要脚本来进行。
./gui.py
以下脚本也可以独立使用,没有GUI:
./extractors/jar_extract.py [-h] input_file [output_dir]
./extractors/from_binary.py [-h] input_file [output_dir]
./extractors/web_extract.py [-h] input_url [output_dir]
假设您正在逆向Android应用程序。您使用自己喜欢的分解器探索了该应用程序,并认为它以典型的方式将Protobuf作为邮政数据传输为Post Data。
您打开PBTK并以有意义的方式受到欢迎:
第一步是使您的.protos成为文本格式。如果您要针对一个Android应用程序,请放入APK并等待魔术工作! (除非这是一个非常异国情调的实施)
这样做,您可以跳到~/.pbtk/protos/<your APK name> (通过命令行或欢迎屏幕底部的按钮以打开文件浏览器,按照您喜欢的方式)。所有应用程序的.protos确实在这里。
回到分解器中,您偶然发现了构建发送给您感兴趣的HTTPS端点的数据的类。它通过调用由生成的代码制成的类来序列序列化。
后一类应该在您的.protos目录内具有完美的匹配(即com.foo.bar.ab将匹配com/foo/bar/a/b.proto )。无论哪种方式,格格普的名称都应该使您可以参考它。
太好了:接下来是第2步,选择所需的输入.proto,并填写有关端点的一些信息。
您还可以提供一些通过Mitmproxy或Wireshark捕获的示例原始Protobuf数据,这些数据已发送到此端点,并且您将以十六进制编码的形式粘贴。
第3步是点击按钮的有趣部分,看看会发生什么!您有一个树视图代表Protobuf结构中的每个字段(重复的字段由“+”后缀,所需字段没有复选框)。
只是悬停一个领域以获得重点。如果该字段是整数类型,请使用鼠标车轮递增/减少它。枚举信息也出现在悬停。
这里是!您可以通过此确定每个字段的含义。如果您从缩小的代码中提取.protos,则可以根据您注意到的意思来重命名字段,通过单击其名称。
快乐的倒车! ? ?
PBTK商店提取的.proto信息中~/.pbtk/protos/ (或Windows上的%APPDATA%pbtkprotos )。
您可以直接通过常规文件浏览器和文本编辑器直接从该目录中移入,搬出,重命名,编辑或删除数据,这是执行此操作的预期方法,不会干扰PBTK。
基于HTTP的端点存储在~/.pbtk/endpoints/作为JSON对象中。这些对象是成对的请求/响应信息,看起来像这样:
[ {
"request" : {
"transport" : "pburl" ,
"proto" : "www.google.com/VectorTown.proto" ,
"url" : "https://www.google.com/VectorTown" ,
"pb_param" : "pb" ,
"samples" : [ {
"pb" : "!...." ,
"hl" : "fr"
} ]
} ,
"response" : {
"format" : "other"
}
} ] PBTK在内部使用两种可插入的模块:提取器和运输。
提取器在extractors/*.py中定义。它们被定义为装饰器之前的方法,例如:
@ register_extractor ( name = 'my_extractor' ,
desc = 'Extract Protobuf structures from Foobar code (*.foo, *.bar)' ,
depends = { 'binaries' : [ 'foobar-decompiler' ]})
def my_extractor ( path ):
# Load contents of the `path` input file and do your stuff...
# Then, yield extracted .protos using a generator:
for i in do_your_extraction_work ():
yield proto_name + '.proto' , proto_contents
# Other kinds of information can be yield, such as endpoint information or progress to display.运输是在utils/transports.py中定义的。它们被定义为以装饰器之前的班级定义:这样:
@ register_transport (
name = 'my_transport' ,
desc = 'Protobuf as raw POST data' ,
ui_data_form = 'hex strings'
)
class MyTransport ():
def __init__ ( self , pb_param , url ):
self . url = url
def serialize_sample ( self , sample ):
# We got a sample of input data from the user.
# Verify that it is valid in the form described through "ui_data_form" parameter, fail with an exception or return False otherwise.
# Optionally modify this data prior to returning it.
bytes . fromhex ( sample )
return sample
def load_sample ( self , sample , pb_msg ):
# Parse input data into the provided Protobuf object.
pb_msg . ParseFromString ( bytes . fromhex ( sample ))
def perform_request ( self , pb_data , tab_data ):
# Perform a request using the provided URL and Protobuf object, and optionally other transport-specific side data.
return post ( url , pb_data . SerializeToString (), headers = USER_AGENT )以下可能是进一步发行的:
我试图为大多数模块提供最大的努力,以制作彻底可读和评论的代码(除了大多数自我描述的零件,例如连接GUI信号),因此您可以做出贡献。
由于PBTK使用PYQT,它是根据GNU GPL许可证(i,特此等)发布的,我可能会选择类似公共领域的东西。
项目名称的字母案例没有形式规则,该规则正遵循您的心❤