在做APP抓取時,會發現有的APP Response回來的資料有“加密”。不知道返回的內容是什麼。
本文偏長,理論基礎偏多。
如下:
如上,內容不是明文的,沒辦法解析資料。
APP常見的對資料加密有三種情況:
第一種是,用諸如AES這類加密演算法對資料加密,然後在APP裡用key進行解密,這類的資料解密的難度不是很大,弄清楚是用的什麼加密演算法就能反解。
第二種是,用“私有”協議把資料序列化,只有瞭解該協議的細節才有可能把資料反序列化出來。這個的難度較大,沒有功底,頭髮擼白都不一定擼出來。遊戲和大廠APP盛行搞一個自己的私有協議來交換資料。
第三種是,用第三方廠商的協議來資料序列化,自己搞不出來私有協議的就選用第三方廠商的。比如用 Google 的 Protobuf ,來做資料序列化,也就是資料“加密”。
今天聊的就是第三種,Protobuf 的資料反解析。
先來看一個 Protobuf ,做資料序列化的直觀例子。
比如一個 APP 的 Response 原先是以 json 格式返回的:
這樣很容易被解析,用Protobuf把上面資料序列化再傳輸就變成類似這樣:
這張圖片只是樣例這樣就沒法直接解析資料,如果瞭解 Protobuf 協議的話就能加快反解速度。
所以還得從頭來聊 Protobuf 。
一、什麼是 Protobuf ?
Protobuf 是 Google 開發的一套資料儲存傳輸協議,跟 xml 和 json 一樣的,都是用來儲存和傳輸資料的。 因為 Protobuf 能夠把資料壓縮得很小,所以傳輸資料就比 xml 和 json 快幾倍,Protobuf 解析資料的速度也比它兩快,所以在資料網路傳輸上,用 Protobuf 而不用 json 就有點受歡迎了。
不過 Protobuf 儲存、壓縮、傳輸效率比 json 好,付出的代價就是用法麻煩,不像 json.loads() json.dumps() 一下就搞定了這麼簡單。Protobuf 有一套自己的語法。不瞭解 Protobuf 協議語法和用法的話也無法反解資料。
先了解下 Protobuf 序列化和反序列化的整個流程:
1.1.先定義一個 Protobuf 語法檔案( .proto 檔案)
該語法檔案用來說明要傳輸哪些欄位、欄位的資料型別、資料間的巢狀關係這些。比如一個APP要返回的資料有電話號碼,姓名,年齡這三個欄位,你就需要把這三個欄位定義在 .proto 檔案裡,並且指明他們的資料型別,比如姓名和電話是字串, 年齡是整型。
1.2.使用 Protobuf 提供的工具編譯該語法檔案。
用工具編譯 .proto 檔案的目的是,把 .proto 檔案編譯成程式碼,工具會根據該 .proto 檔案自動生產程式碼。 這個程式碼就是用來做資料序列化和反序列化的。
1.3.服務端用第2步中的程式碼,把“明文”資料序列化,變成“密文”後,返回給APP。
1.4. APP 客戶端用第2步中的程式碼,把“密文”資料反序列化,就“解密”成明文拉。
理論說多了很迷糊,再整個完整的直觀例子:
二、Protobuf 正向開發流程
2.1.先配置 Protobuf 環境https://github.com/protocolbuffers/protobuf/releases/
在 Google 官方 github 地址下載 Protobuf 。
下載一個 Protobuf 編譯器和一個呼叫編譯器的介面程式,我們這裡用Python版的。如上圖,箭頭所示,解壓 protoc.win64.zip 裡有個 protoc 命令就是編譯器。PS:注意要給 protoc 配置上環境變數,不然沒法全域性呼叫該命令。
解壓 protobuf-python-3.11.4.zip 這是Python模組,cd到python目錄裡執行 Python setup.py build 和 Python setup.py install 安裝Python模組。Python編輯器裡執行 import google.protobuf 可以檢測是否安裝成功。
example目錄裡有官方寫好的Python示例程式 和 示例 .proto檔案。
2.2.寫一個 .proto 語法檔案語法檔案怎麼寫,要根據具體的傳輸資料來定製,
比如按照 example 裡的示例,如果要傳輸的資料是如下格式:
那麼定義的 .proto 語法檔案就如下:
這樣就定義好了一個 .proto 語法檔案,語法檔案如何定義要根據傳輸資料的不同而變。更全的 protobuf 語法 可以看這個,有網友翻譯成了中文版的。https://colobu.com/2017/03/16/Protobuf3-language-guide/
2.3.使用第一步中下載的 protoc 編譯器來編譯 .proto 檔案
protoc –python_out=. addressbook.proto
上述表示把 addressbook.proto 檔案編譯成Python版的。如果檔案語法錯誤,在編譯的時候會有提示。編譯完後,會多出一個.py檔案
我們就可以呼叫這個 .py 來序列化上面的資料。2.4.開始序列化資料
print裡輸出的就是序列化(“加密”)後的資料。2.5.對序列化後的資料進行反序列化(“解密”)
反序列化就把資料又還原啦。
上述過程就是一個完整的正向資料 protobuf 序列化過程。我們可以看出來,主要是定義一個 .proto 檔案,然後把它編譯生成程式碼。 後面就主要用這個程式碼來做序列化和反序列化工作。
三、逆向解析 Protobuf
正向過程比較輕鬆,因為對方即有 .proto 檔案,也有序列化程式碼,也知道要傳輸的資料樣式。但是逆向這個過程,APP裡是沒有 .proto檔案的,APP裡是有反序列化的程式碼,但是看得也頭暈。那該怎麼辦呢?
藉助工具,我們使用上面下載的protoc編譯工具,這個工具提供反解析引數
protoc –decode_raw < people.bin
如上,使用 –decode_raw 引數就能把序列化後的資料,反序列化(解密)出來。上面只是把資料還原了,那如果我們要完全把 .proto 檔案也還原出來該怎麼辦呢?
如果 APP 傳送 request 的資料要先序列化後再傳送給服務端的話,那爬蟲要做的事情就不只反序列化,還要能序列化。做序列化是一個正向的過程,按照上面流程,必須先要有 .proto 檔案才行。
所以繼續還原 .proto 檔案,還原 .proto 是個體力活和細緻活。就是參照反解析出來的資料,還原出 .proto 檔案。
上面這張圖是關鍵,看懂了就能還原出來。上圖左邊是反解析出來的資料,中中間是參照左邊寫出來的 .proto 檔案,右邊是人家原本的 .proto 檔案。左邊和中間圖對比可以看出,就是根據左邊的欄位,挨個把欄位重新定義出來就OK啦。
遇到 “{” 就定義一個message。中間和右邊圖對比可以看出,變數的名字是無關緊要的,資料型別還原正確就行。變數賦值的那些1,2,3是標識號,message裡同一層級的標識號不能重複,一般是按照變數順序從1開始遞增。標識號的數字是個關鍵,數字寫錯了反解析出來的資料會不對。這樣就把 .proto 檔案還原出來了,然後按照正向流程又去編譯,就可以使用它去序列化(“加密”)和反序列化(“解密”)APP資料了。
APP逆向抓取相關閱讀
PS: 再廣而告之一聲
我有在系統性的教爬蟲技術APP逆向抓取技術JS高階逆向技術群控抓取技術
利用爬蟲技術年掙10萬被動收入的思維和實踐方法如果你想爬蟲技術進階,或找一份不錯的爬蟲工作,我想是能夠有幫助的。感興趣可以加我私人微信,備註:學習。PS,費用不便宜,非誠勿擾。
我的公眾號:猿人學 Python 上會分享更多心得體會,敬請關注。
***版權申明:若沒有特殊說明,文章皆是猿人學 yuanrenxue.com 原創,沒有猿人學授權,請勿以任何形式轉載。***