最新 抖音 x-gorgon 算法定位查找過程筆記 2020-06-03

介紹:

本次分析抖音版本: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的分析筆記過程,但願可以有所幫助,也可以對自身的產品安全方面進行一個參考借鑑。

免責聲明

  1. 請勿使用本服務於商用
  2. 請勿使用本服務大量抓取
  3. 若因使用本服務與抖音官方形成沒必要要的糾紛,本人蓋不負責
  4. 本人純粹技術愛好,若侵犯抖音貴公司的權益,請告知
相關文章
相關標籤/搜索