<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    對1x06app網絡請求時Sign簡單的分析

    VSole2023-02-13 10:42:32

    目標:找出請求中sign值的來源。

    準備

    1.修改后的專用分析機。

    2.準備抓包環境。

    3.準備Frida、ida、jadx等分析環境。

    簡單說一下分析過程中遇到的問題:

    1.首先是定位native在so中的位置,這個很簡單,方法也很多。

    2.使用frida配置主動調用環境,讓測試變的更簡單一些。

    3.對算法核心代碼進行定位,定位核心算法的方法很多,各有各的優劣,多嘗試,合適的地方使用合適的方法。

    (1)Ida的trace功能,這種方法本身是非常好的一種方法,因為大部分的情況下這種方法更有效也更簡單,但目前這種方式已知存在一些問題導致這種方式的使用受限。

    ①慢,ida trace的方式會很慢,所以一般都是在縮小范圍后再使用這種trace的方式來操作。

    ②容易跑偏,跑到系統庫里面,這種問題一般配合ida的腳本的DBG_Hooks進行主動對指令范圍進行控制,通過ida_dbg.enable_insn_trace(True)來控制是否開啟指令跟蹤,不過這種方式沒有具體用過所以這里不作評價,我常用的還是縮小范圍后再開啟trace,或通過trace來找一些異常代碼,比如退出指令等,因為這樣操作比較簡單,可以繞開大部分問題,讓日志也更簡潔一些。

    ③ida的trace功能貌似開啟后就無法關閉,所謂的關閉只是不再打印日志,實際上trace的功能代碼還是在跑,手動操作的時候貌似存在這個問題,沒有用腳本試過,所以不清楚腳本的接口關閉會不存在同樣的問題。

    ④碰到特殊指令會導致功能異常,比如這里碰到的問題就是在trace功能開啟的狀態下STXR/STXRH指令會操作失敗,包括在這行指令上F8也會失敗,原因在于單步會導致讀和寫同時存在時寫就會失敗,目前這個算法里面沒有看到被用在反調試功能上,只是在系統庫里面大量看到了這種指令。從反調試的角度來說,這個指令其實存在好幾個反調試點,對熟悉它的人來說影響不大,但對不熟悉它的人來說可以讓人給整懵逼了,比如,算法中穿插著用這個指令進行賦值,根據指令執行結果改變算法流程(這個指令的第一個操作寄存器會被寫入執行成功與否的狀態),系統庫中就是用這個指令配合CBNZ一起使用的,將指令執行結果帶入算法中進行計算等等,都是騷操作。

    ⑤算法中穿插反調試手段的情況,這種比較普遍,這個Sign算法里面就有,這種方式也好解決,碰到了改掉就行,無非就是麻煩一點罷了。

    (2)Unidbg,這種方法很強大,它的強大主要體現在無感知hook這塊,但這種也不夠完善,存在很多問題,主要是在環境這一塊,畢竟是一個脫機的環境,補環境這塊讓人很頭疼,不過在指令級追蹤這塊非常強大,可以對任意指令地址進行日志打印以分析流程,雖然這個也支持調試,但是那種調試還是不太習慣,所以整體來說這個我用的比較少,一般用它大致看看JNI_OnLoad還不錯。

    (3)Frida,frida一般配合ida一起使用,這也是我最常用的手段,這種方式也基本上算是一種萬能的方法,復雜環境使用這種方式可以讓分析變得更輕松一些,基本流程就是ida靜態分析一下可疑的關鍵代碼,然后通過Frida進行確認定位以縮小關鍵代碼的范圍,之后再對關鍵代碼進行trace日志分析,或進行單步調試分析均可以,同樣的,這種方法通用是通用,但是同時也要面對frida和ida存在的共同的問題。

    問題:說說過程中碰到的問題。

    1.STXR/STXRH指令的問題以及ida的指令跟蹤總是跑到庫函數里面等,這些問題直接導致了我trace整個函數的計劃失敗,后面縮小范圍的時候還是會碰到,這時候我使用的方法就是在碰到這種指令時在保證單線程的情況下將這種指令替換為了等價的STR之類的指令進行繞過了,trace也就自然而然的可以了。

    2.frida對指令hook的問題,在Hook函數時沒有碰到問題,只有在一個函數頻繁打印時frida才會異常掛掉,但是在對指令進行hook時,基本上90%的情況下都會異常,比如hook bl x8這樣的指令,拿取x8的值時,基本上一hook就掛掉了慶幸的是第一次到來時基本可以拿到地址,不過也有例外情況,有一些就碰到了x8==0x20的情況,跳轉到0x20的地址進行執行,汗,然后大致看了下frida對函數頭部hook和指令間Hook的差異:

    frida在hook函數頭部的時候會將頭部改寫為:

    ADRP            X16, #0x7F75F8E000BR              X16
    

    而在對中間指令進行hook時,確替換了4條指令,比如在hook blr x8指令時將就bl及接下來的三條指令一起替換成了下面的這種指令:

    LDR             X16, =0x7F75F8AD00BR              X16qword_7F4DA12FE0 DCQ 0x7F75F8AD00
    

    對于函數頭部的代碼來說還好,沒什么問題,但是對于指令間Hook的代碼來說就存在兩種情況:

    (1)指令占用空間過大,如果其占用了跳轉指令的目標地址的指令導致在執行前有指令跳轉到了這4條指令上,那基本上也就異常無疑了。

    (2)X16雖然做為保留寄存器存在,正常編譯器一般不盡量不用它,但如果刻意使用呢,就會導致環境異常,比如將blr x8這種指令用x16替代

    3.混淆,主要碰到了3種混淆,強度都不算太大,解決起來也很簡單,這三種混淆主要還是對靜態分析造成干擾,對動態分析沒感覺到有太大的阻礙,無非就是注意不要跑偏就好

    (1)第一種混淆,在函數頭部,解決方法也很簡單,分析一下函數特征,腳本里面根據特征直接替換就行了,比如上面的混淆整個nop掉,然后直接b sub_68314即可。

    LOAD:00000000000682EC                 STP             X0, X30, [SP,#var_10]!LOAD:00000000000682F0                 BL            LOAD:00000000000682F4                 ADR             X0, sub_68314LOAD:00000000000682F8                 MOV             X30, X0LOAD:00000000000682FC                 RET
    

    (2)第二種混淆,存在偏移表的這種,觀察代碼邏輯,直接以w0的值代入表達式算出表中的偏移量,然后取出偏移表中的值算出跳轉的最終地址直接跳轉過去即可。

    LOAD:0000000000068394                 STP             X0, X30, [SP,#-0x10]!LOAD:0000000000068398                 LDR             W0, =5LOAD:000000000006839C                 BL              loc_68320LOAD:0000000000068320                 BL              sub_5D6B0LOAD:000000000005D6B0                 STP             X0, X1, [SP,#var_10]!LOAD:000000000005D6B4                 ADD             W0, W0, #1LOAD:000000000005D6B8                 LDR             W0, [X30,W0,UXTW#2]LOAD:000000000005D6BC                 ADD             X30, X30, W0,UXTWLOAD:000000000005D6C0                 LDP             X0, X1, [SP+0x10+var_10],#0x10LOAD:000000000005D6C4                 RET
    

    (3)第三種,也有規律可尋,這種我沒有處理,直接單步調的,看起來str ldr一大片一大片的,實際上都是一些保存環境和恢復環境的代碼,調試的時候基本可以忽略,碰到邏輯上不符合預期的再回頭看看就好。而要pass掉這種代碼其實也不難,比如下面的這段代碼。

    LOAD:0000000000068438                 MOV             W2, #0x18LOAD:000000000006843C                 STR             X2, [X19,#0x100]LOAD:0000000000068440                 MOV             X4, #0x100LOAD:0000000000068444                 MOV             X21, #0x18LOAD:0000000000068448                 MOV             X25, #0LOAD:000000000006844C                 MOV             X20, #4LOAD:0000000000068450                 MOV             X23, #0x18LOAD:0000000000068454                 B               loc_68614LOAD:0000000000068614                 LDR             X4, [X19,X4]LOAD:0000000000068618                 LDR             X21, [X19,X21]LOAD:000000000006861C                 B               loc_68678LOAD:0000000000068678                 ADR             X0, qword_68688LOAD:000000000006867C                 LDRSW           X20, [X0,X20,LSL#2]LOAD:0000000000068680                 ADD             X20, X20, X0LOAD:0000000000068684                 BR              X20
    

    分為三個部分,一是賦值部分一大片的mov常量,然后一個B跳轉,第二部分可以算是干擾部分,將前面的賦值部分代入后實際上也是一個賦值代碼,可以替換第一部分的相關賦值指令,不過需要注意位置會不會有影響,第三部分就是一個跳轉表,大致意思就是jmp table + (table + index 4)

    最終結果就是:

    MOV W2,#0x18STR X2, [X19,#0x100]MOV X25,#0MOV X23,#0x18LDR X4,[X19,#0x100]MOV X21,[X19,#0x18]jmp qword_68688 + *(qword_68688 + #4 * 4)
    

    如果只是追求邏輯修復能F5的話這樣就可以了。

    最后附上字符串解密還原的代碼,代碼量比較少,比較簡單,示例代碼還原后與代碼中的一致,調試的時候忘截圖了,只記錄了參數和結果,所以這里沒有ida里面的截圖,結果為字符串“sec.umeng.com”:

    void decode(){    printf("start decode data.\r");     const char key[] = "DcO/lcK+h?m3c*q@";    unsigned char buf[] = {0xE9, 0xAD, 0x2F, 0x3C, 0x8D, 0x32, 0xF4, 0x7B, 0x1E, 0x01, 0x97, 0x32, 0xA9};     unsigned char S[0x100] = {0};    unsigned char T[0x100] = {0};     for(int i = 0; i < 0x100; i++){        S[i] = (unsigned char)i;        T[i] = key[i % 0x10];    }     //打亂數組    int w12 = 0;    for(int i = 0; i < 0x100; i++){        unsigned int w13 = S[i];        w12 = w13 + w12 + T[i];        unsigned int w14 = w12 + 0xFF;        if(w12 >= 0){            w14 = w12;        }        w12 = w12 - (w14 & 0xFFFFFF00);    //還原的時候在這里踩了個坑,"-"與"&"同級,不加括號會先算減號        int w15 = S[w12];        S[i] = w15;        S[w12] = w13;    }     int i = 0;    int k = 0;    char outbuf[0x100] = {0};    char* pOut = (char*)outbuf;    char* pIn = (char*)buf;     int nLen = sizeof(buf);    while(nLen--){        i = (i + 1) & 0xFF;        char tmp = S[i];        k = (tmp + k) & 0xFF;        S[i] = S[k];        S[k] = tmp;        *(char*)pOut++ = S[(S[i] + S[k]) & 0xFF] ^ *pIn++;    }    printf("%s\r", outbuf);}
    
    signida
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    Ida的trace功能,這種方法本身是非常好的一種方法,因為大部分的情況下這種方法更有效也更簡單,但目前這種方式已知存在一些問題導致這種方式的使用受限。①慢,ida trace的方式會很慢,所以一般都是在縮小范圍后再使用這種trace的方式來操作。
    準備◆iOS 12.5.5◆frida 14.0.0◆ipa 5rG96L2m5LmL5a62 11.33.5抓包1.抓包使用 charles,請自行安裝并配置證書。使用假賬密測試抓包 123456 / 123456,能夠抓包成功。分析1、登錄頁面需要輸入3個信息,分別是賬號 / 密碼 / 驗證碼,對應字段 logincode / userpwd / validcode。
    首先使用jadx對apk進行逆向。?搜索關鍵字 QDSign,可以直接找到對應的類,可以看到參數經過加密得到。??進一步跟蹤,發現了c類中有如下三個so方法,還有3個loadlibrary,分別進行了hook,發現c-lib動態注冊了sign,sos動態注冊了s,沒有發現crypto有動態注冊。
    意料之中一大堆參數,反復幾次總結需分析的參數應該為以下幾個:X-Sign、wToken、X-Ca-Signature、X-Access-Token、X-Ca-Timestamp. 跟進得:public static Map z { String str; String a2 = wo3.a; HashMap hashMap = new HashMap(); hashMap.put; hashMap.put; hashMap.put; if (!TextUtils.isEmpty) { hashMap.put; no3.a; } hashMap.put("Authorization", StringUtils.isEmpty(it3.g()) ?= '\t') || charAt >= 127) { str2.replace; } } hashMap.put; hashMap.put("X-ConnectionType", y
    把他扔到ida中,等待ida分析完成就好。定位到這個方法,對比抓包結果判斷這個方法就是用于添加請求頭的位置,分析代碼找到X-PA-SIGN應該是由下面這個函數返回。
    逆向某平臺分析過程指導
    初衷是刷抖音太多,發現不能在點贊過的視頻列表中直接搜索,就想自己實現下,把這個過程做了下記錄,當學習筆記了,純技術交流用。
    MRCTF2022 stuuuuub 題解
    2023-02-07 10:15:04
    Overview學了這么一段時間的Android,難得見到的一道比較對口的逆向題。e.c()通過執行which su命令后讀取輸出來檢查是否有su文件。讀取res.dat文件后調用了decodeSo函數進行解密存放在應用的數據目錄下的libnative.so,而decodeSo是libstub.so里的native函數。但是在libstub.so里卻沒有直接找到decodeSo函數,因此應該是JNI_OnLoad里動態注冊的。decode String另外libstub.so使用了Ollvm的字符串加密和控制流平坦化。這里參考官方給的WP中使用了AndroidNativeEmu框架。
    大廠基本為了程序的安全,會使用大量內聯SVC去調用系統函數,以此來保護程序的安全。如何實現SVC指令的IO重定向,成為最大的問題。內核態是當Linux需要處理文件,或者進行中斷IO等操作的時候就會進入內核態。當arm系列cpu發現svc指令的時候,就會陷入中斷,簡稱0x80中斷。
    它通過解壓縮 APK 并應用一系列規則來檢測這些漏洞來做到這一點https://github.com/SUPERAndroidAnalyzer/super9、AndroBugs 框架是一種高效的 Android 漏洞掃描程序,可幫助開發人員或黑客發現 Android 應用程序中的潛在安全漏洞。它可以修改任何主進程的代碼,不管是用Java還是C/C++編寫的。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类