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,特此等)發布的,我可能會選擇類似公共領域的東西。
項目名稱的字母案例沒有形式規則,該規則正遵循您的心❤