介紹:
本次分析抖音版本:11.1.0 x-gorgon版本:0404
抖音做爲目前流量最大、日活躍最高的平臺,目前也有不少不一樣行業的人對它進行逆向分析研究,在抓包分析過程當中,抖音的通信會涉及到一個叫x-gorgon的簽名,該簽名是發送數據請求必不可少的基礎參數,本次我就帶你們分析下這個參數。python
小編自戀一下,逆向大神 屬於逆向愛好者,如須要交流技術或者算法請在評論區留下郵箱,或者聯繫我郵箱1610199291@qq.comandroid
抓包
假設咱們的業務須要爬蟲獲取抖音的熱門視頻列表,那麼咱們先經過抓包來定位到具體的接口,這裏我選擇使用charles工具進行抓包,具體配置https方法能夠百度的方法。安卓手機抓包最好使用6.0如下的!git
經過抓包發現接口是來自: https://aweme.snssdk.com/aweme/v2/feed/ 後面跟了很長的參數,具體字面意思分析估計是手機的型號以及抖音本身生成的一些信息,咱們發現其返回的是protobuf格式,charles已經幫咱們解析好了,那麼咱們編寫python3腳本構造一個跟他同樣的請求進行嘗試。算法
咱們發現可以正常的返回數據,可是咱們看到他的header除了 x-gorgon和x-tt-trace-id之外,其餘的都很好理解,咱們會發現,若是咱們改變了URL的參數,可是header內容得不到對應的修改,就會返回不到數據,以下所示:api
{安全
- status_code: 2154,
- aweme_list: [ ],
- has_more: 1,
- min_cursor: 0,
- max_cursor: 0
}cookie
分析
那麼咱們就可以更加確信header裏的x-gorgon對它進行了一次簽名,因此咱們直接jadx上手閱讀一波反編譯後的代碼,這裏我直接搜索了x-gorgon關鍵字,列出瞭如下結果:session
這裏我選擇了hashMap.put("X-Gorgon", a3);這一行,跳轉進去咱們來分析一下它的代碼app
這裏咱們看到有一個它的值是來自a3,a3則是經過String a3 = a.a(com.ss.sys.ces.a.leviathan(i, currentTimeMillis, a.a(a2 + str4 + str5 + str6)));這行代碼進行獲取到的結果,咱們看到它傳了4個參數,咱們來仔細看一下這4個參數具體都是什麼內容:工具
a2來源:
String b2 = tt.d(str);
d.a(b2);
str它就是該方法傳進來的參數,咱們後面能夠經過hook方式來獲取它的具體內容,而它會執行tt.d()、d.a() 進行2次操做,咱們對其tt.d()跟進去
咱們看到它對這個字符串進行了取 ? 和 # 中間值,懷疑是url,若是是url證實它只是取了url後面的參數,那麼繼續看它的下一個方法:d.a()
咱們看到這裏就是進行了MD5簽名取值,那麼a2分析到此結束,咱們繼續分析第2個參數
str4來源:
這裏很是簡單,它就是枚舉傳進來的第二個參數map,判斷若是有X-SS-STUB這個值的話就獲取,反之則填充32個0,那麼咱們抓包發現並無X-SS-STUB這個參數,實際上若是咱們的包是POST的話它就會有,實際上它就是POST數據的一個MD5簽名值。
str5來源:
str5也很是簡單,也是枚舉map裏面有沒有COOKIE,若是有就把COOKIE進行MD5,那麼該參數也到此結束了
str6來源:
1
2
3
4
5
String c2 = tt.e(str3);
if
(c2 !=
null
&& c2.length() >
0
`) {`
str6 = d.a(c2);
StcSDKFactory.getInstance().setSession(c2);
}
這裏咱們記得str3是cookie,它執行了tt.e(str3) 方法獲取一個返回值,若是它不是空一樣給這個返回值md5,那麼咱們跟進去看一下它是作了什麼處理:
這裏咱們看到它是枚舉了cookie裏面有沒有sessionid這個值,若是有就取出來,那麼str6到此結束
參數整理:
a2 = md5(url) 疑似對網址的參數進行md5
str4 = x-ss-stub,只有post時纔有效,不然是32個0
str5 = md5(cookie) 對cookie進行md5
str6 = md5(cookie['sessionid']) 對cookie裏面對sessionid進行md5,不然也是32個0
咱們整理完了這4條參數後,繼續分析,它將這4個參數進行了字符串合併,接着執行 a.a(a2+str4+str5+str6),咱們跟進去看看裏面作了什麼操做
咱們看到它這裏循環了總長度/2次,每次都是把 str[i] 轉換成十進制左移4,而後加上 str[i+1] 都一個簡單運算,並返回結果,也就是原本是4個32位(128位)而後通過加密後縮短成了64位長度。最後它執行了com.ss.sys.ces.a.leviathan(i, currentTimeMillis, a.a(a2 + str4 + str5 + str6))進行計算,咱們看到它還傳了2個參數,i和currentTimeMillis,咱們往前能夠看到 i是-1,而currentTimeMillis是當前都十位時間戳。
最後把計算好都byteArray通過位移轉換成了string類型,並put到map裏面,那麼咱們也清楚到看到,k-khronos也就是剛剛到currentTimeMillis時間戳了。咱們發現因爲om.ss.sys.ces.a.leviathan是在so層到libcms.so文件,而且裏面有大量到混淆就沒有再度分析。咱們能夠經過xposed或者unidbg到方法進行調用。
0x02:參數確認
這裏咱們分析完了它算法到具體參數構造完成後,咱們還須要確認它傳到參數是不是咱們所聯想到,那麼這裏咱們發現因爲它這個方法是一個callback,咱們往前跟一下,尋找一個合適到hook點,使用frida進行hook
這裏我對它進行了調用查找,看到只有1個地方,咱們跟進去看看,跟進去以後它就是如下內容,就只是一個簡單對賦值給sAddSecurityFactorProcessCallback,咱們在對它進行調用查找,看看是什麼地方對它進行對調用。
public static void setAddSecurityFactorProcessCallback(a aVar) {sAddSecurityFactorProcessCallback = aVar;
}
這裏咱們看到它從這裏取的回調指針變量,而後判斷若是不爲null則執行,那麼咱們就能夠直接hook這個方法:tryAddSecurityFactor$___twin___,這裏個人hook代碼也就比較簡單,直接輸出它傳進去的map和str的值以及返回的map進行確認。
//frida -U com.ss.android.ugc.aweme -l test.js Java.perform(function() { var NetworkParams = Java.use("com.bytedance.frameworks.baselib.network.http.NetworkParams"); NetworkParams['tryAddSecurityFactor$___twin___'].implementation = function(str,map){ var keyset = map.keySet(); var it = keyset.iterator(); console.log("str:\t"+str) while(it.hasNext()){ var keystr = it.next().toString(); var valuestr = map.get(keystr).toString() console.log("map:\t"+keystr+"\t"+valuestr) } var ret ret = this.tryAddSecurityFactor$___twin___(str,map); var keyset = ret.keySet(); var it = keyset.iterator(); while(it.hasNext()){ var keystr = it.next().toString(); var valuestr = ret.get(keystr).toString() console.log("ret map:\t"+keystr+"\t"+valuestr) } return ret; } });
綠色部分就是str參數1的值,黃色則是map,藍色則是返回的map,咱們看下charles的這個包的header裏的xgorgon是否是返回的值。
總結
以上就是對抖音對一個簡單的x-gorgon的分析筆記過程,但願可以有所幫助,也可以對自身的產品安全方面進行一個參考借鑑。
免責聲明
- 請勿使用本服務於商用
- 請勿使用本服務大量抓取
- 若因使用本服務與抖音官方形成沒必要要的糾紛,本人蓋不負責
- 本人純粹技術愛好,若侵犯抖音貴公司的權益,請告知