protobuf協議逆向解析
前言
在app抓包的過程中,我們會發現有些app的數據也是存在加密的,抓到的數據是一堆亂碼。無法來解析數據。

常見的對于數據的加密方式有三種:
1 第一種是利用常見加密算法,諸如AES等算法,對響應數據進行加密。
2 第二種是利用第三方廠商的協議進行數據序列化,常見的有xml、json、Fastjson、protobuf等。
3 第三種是自己的“私有協議”,自己編寫的不開源的協議,進行數據序列化。
這三種方式逆向難度是逐級遞增的,特別是私有協議,那完全是搞不清楚的話,頭發都掉沒了也解不開。
所以為了保護頭發,本次給大家分享的是第二種,利用第三方廠商的數據序列化方案,protobuf的數據泛解析。
protobuf流程
對于protobuf的數據序列化,開發師傅們更懂一些,簡單介紹一下protobuf,protobuf 是 Google 開發的一套數據存儲傳輸協議。通過將結構化的數據進行序列化,進而來實現數據存儲或者是RPC數據交換的功能。
序列化:將數據結構或對象轉換成二進制串的過程
反序列化:將在序列化過程中產生的二進制串再轉換成數據結構或者對象的過程
首先,protobuf會定義一個.proto文件,其中包括了要傳輸的字段,字段的數據類型、數據的嵌套關系。
然后定義完成后,protobuf官方工具會編譯這個語法文件,使其變成代碼,然后根據這個代碼來做數據序列化與反序列化。
這個過程在app中的體現就是,服務器端用生成的代碼,將明文序列化,然后變成密文,返回到app端。
app客戶端就會利用生成的代碼,將密文反序列化后,在服務器端解密成明文。
for example:
傳輸如下類似的數據,
{ 'name':"火線安全", //名稱 'id':303, //編號 'mail':"@huoxian.cn" //郵箱 { 'tel':"13111111111" 'type':2 //私人 or 公司 }
}
定義的.proto文件則如下所示
syntax = "proto3" //固定
message Person {
string name=1; int32 id =2; string mail=3; enum PhoneType{ MOBILE = 0; HOME = 1; WORK = 2; }
message PhoneNumber{ //嵌套一個message string number = 1; PhoneType type = 2; } repeated PhoneNumber phones = 4; }
message AddressBook{ repeated Person people = 1;}
然后利用這個.proto文件來進行后續的序列化和反序列化操作。
逆向分析
對于正向過程來說,有了.proto文件,也有了序列化代碼。很輕松,但是對于逆向過程來說,如何分析得到這個.proto文件則是最重要。
這類信息一般是在java層中,普遍的逆向過程是,根據url進行關鍵詞搜索也可以直接利用hook的方式進行尋找。hook的話定位快。
展示一下之前某app的proto文件,因為封裝做的很好,所以可以直接重寫就可以了。(重申一下,這是網圖,網圖,不是我分析的)

類似上面那樣就可以直接重寫了。
當然如果想要根據protobuf提供的官方工具直接解密的話,可以根據解密后的信息來一步一步填充.proto文件。
拿上面那個例子來說,最后肯定是這樣一個
1:"火線安全", //名稱 2:303, //編號 3:"@huoxian.cn" //郵箱 4{ 1:"13111111111" 2:2 //家庭 or 公司 }
}
那還原一下就是這樣
message Ts1 {
string field1=1; int32 field2 =2; string field3=3;
message Ts2{ //嵌套一個message string field1 = 1; int32 field2 = 2; } repeated Ts2 ts2 = 4; }
message TT{ repeated Ts1 ts1 = 1;}
可以對比一下。手動還原就是這么個思路。當然了,也可以利用腳本來進行這個操作。
https://github.com/SeeFlowerX/frida-protobuf
總結
該方法可以應對可能響應包中會有一些敏感信息泄露,或者是爬蟲來進行數據爬取時,對于亂碼數據的解密。