日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
兩種姿勢(shì)批量解密惡意驅(qū)動(dòng)中的上百條字串

作者:JiaYu 轉(zhuǎn)自公眾號(hào):信口雜談

創(chuàng)新互聯(lián)建站2013年開(kāi)創(chuàng)至今,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站、成都外貿(mào)網(wǎng)站建設(shè)公司網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元定安做網(wǎng)站,已為上家服務(wù),為定安各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:13518219792

 1. 概述

在 360Netlab 的舊文 《“雙槍”木馬的基礎(chǔ)設(shè)施更新及相應(yīng)傳播方式的分析》 中,提到了 雙槍 木馬傳播過(guò)程中的一個(gè)惡意驅(qū)動(dòng)程序 kemon.sys ,其中有經(jīng)過(guò)自定義加密的 Ascii 字符串和 Unicode 字符串 100+ 條:

這在 雙槍 木馬的傳播鏈條中只是一個(gè)很小的技術(shù)點(diǎn),所以文中也沒(méi)說(shuō)具體是什么樣的加密算法以及怎樣解密,供分析員更方便地做樣本分析工作。但這個(gè)技術(shù)點(diǎn)還算有點(diǎn)意思,尤其是對(duì)逆向入門(mén)階段的朋友來(lái)說(shuō),可以參考一下解法。最近又碰到了這個(gè)驅(qū)動(dòng)程序的變種,跟團(tuán)隊(duì)的老司機(jī)討教了一番,索性寫(xiě)篇短文記錄一下。

感謝老司機(jī)們解惑。也歡迎各路師傅不吝賜教,提一些更快準(zhǔn)狠的解法。

2. 樣本概況

MD5: b001c32571dd72dc28fd4dba20027a88

2.1 字符串加密情況

驅(qū)動(dòng)程序中用到的 100+ 條字符串都做了自定義加密處理,在設(shè)置完各 IRP 派遣函數(shù)和卸載例程之后,依次解密這些字符串。IDA 中打開(kāi)樣本,部分解密過(guò)程如下:

整個(gè)解密過(guò)程的函數(shù)是 sub_100038 ,里面會(huì)多次調(diào)用兩個(gè)具體的解密函數(shù):sub10003871 和 sub_10003898。前者解密 Ascii 字串,后者解密 Unicode 字串,都有兩個(gè)參數(shù):arg1—>要解密的字符串地址;arg2—>字符串長(zhǎng)度。后面會(huì)把這兩個(gè)函數(shù)分別命名為 DecryptAsciiStr 和 DecryptUnicodeStr 。這兩個(gè)函數(shù)在 IDA 中看到的 xrefs 狀況如下:

2.2 加密算法

前面說(shuō)了,算法不復(fù)雜。以 DecryptAsciiStr 函數(shù)為例:

反編譯看看:

DecryptUnicodeStr 算法其實(shí)相同,只是因?yàn)樽止?jié)構(gòu)成不同,所以是兩個(gè)解密函數(shù)分開(kāi)寫(xiě):

簡(jiǎn)單總結(jié)起來(lái),這套解密過(guò)程其實(shí)就是:把當(dāng)前字節(jié)后面特定偏移處的字節(jié)與 0xC 異或,然后替換掉當(dāng)前字節(jié),把解密后的字節(jié)寫(xiě)入到當(dāng)前位置,即完成解密。本人對(duì)密碼學(xué)不熟,不知道這是不是已有名號(hào)的加密算法,看起來(lái)像是 凱撒密碼 的變形加強(qiáng)版?對(duì)此有了解的朋友歡迎指教。

3. 解密

了解了上面的情況之后,就該著手解密這百十多條字符串了。既然是用 IDA 來(lái)分析這個(gè)樣本,理想的狀況應(yīng)該是把這些字串批量解出來(lái),直接在 IDA 中呈現(xiàn),然后就可以進(jìn)行后續(xù)分析了。既然是要自動(dòng)化批量解密,寫(xiě) IDAPython 應(yīng)該算是最便捷的做法了。最終效果如圖:

3.1 姿勢(shì) 1——自行實(shí)現(xiàn)解密算法

首先想到的思路是:就兩個(gè)解密算法,而且不復(fù)雜,不妨直接寫(xiě)個(gè) IDAPython 腳本,實(shí)現(xiàn)這兩個(gè)解密算法。解密之后把明文字串直接寫(xiě)到 IDB 文件中,在 IDA 中呈現(xiàn)。兩個(gè)解密算法的 Python 版本分別如下(附帶對(duì) IDB 的 Patch 操作):

這里稍微解釋一下 make unicode str 時(shí)的操作:

 
 
 
 
  1. old_type = idc.GetLongPrm(INF_STRTYPE)
  2. idc.SetLongPrm(idc.INF_STRTYPE, idc.ASCSTR_UNICODE)
  3. idc.MakeStr(argv[0], argv[0]+(argv[1]*2))
  4. idc.SetLongPrm(idc.INF_STRTYPE, old_type)

在 IDA 的 UI 界面中,可以選擇生成的字符串的類型(如下圖),快捷鍵只有一個(gè) A,對(duì)應(yīng)的 idc 函數(shù)是 idc.MakeStr(0。然而 ida.MakeStr() 函數(shù)默認(rèn)是生成 Ascii 字串的,要想生成 Unicode 字串,就需要調(diào)用 idc.SetLongPrm() 函數(shù)設(shè)置一下字符串的類型。

IDA 中支持的字符串類型如上圖,相應(yīng)地,在 idc 庫(kù)中的定義如下:

 
 
 
 
  1. ASCSTR_C       = idaapi.ASCSTR_TERMCHR # C-style ASCII string
  2. ASCSTR_PASCAL  = idaapi.ASCSTR_PASCAL  # Pascal-style ASCII string (length byte)
  3. ASCSTR_LEN2    = idaapi.ASCSTR_LEN2    # Pascal-style, length is 2 bytes
  4. ASCSTR_UNICODE = idaapi.ASCSTR_UNICODE # Unicode string
  5. ASCSTR_LEN4    = idaapi.ASCSTR_LEN4    # Pascal-style, length is 4 bytes
  6. ASCSTR_ULEN2   = idaapi.ASCSTR_ULEN2   # Pascal-style Unicode, length is 2 bytes
  7. ASCSTR_ULEN4   = idaapi.ASCSTR_ULEN4   # Pascal-style Unicode, length is 4 bytes
  8. ASCSTR_LAST    = idaapi.ASCSTR_LAST    # Last string type

所以,要生成 Unicode 格式的字串,需要先用 idc.SetLongPrm() 函數(shù)設(shè)置一下字符串類型。其中 idc.INF_STRTYPE 即代表字符串類型的常量,在 idc 庫(kù)中的定義如下:

用 Python 實(shí)現(xiàn)了解密函數(shù)之后,如何模擬這一波解密過(guò)程把這 100+ 條字串依次解密呢?這里可以結(jié)合 IDA 中的 xrefs 和 idc.PrevHead() 函數(shù)來(lái)實(shí)現(xiàn):

  1. 先通過(guò) xrefs 找到調(diào)用兩個(gè)解密函數(shù)的位置;
  2. 再通過(guò) idc.PrevHead() 定位到兩個(gè)解密函數(shù)的參數(shù)地址,并解析出參數(shù)的值;
  3. 執(zhí)行解密函數(shù),將解密后的明文字串寫(xiě)回 IDB 并 MakeStr。

3.2 姿勢(shì) 2——指令模擬

這個(gè)樣本中的字串解密算法并不復(fù)雜,所以可以輕松寫(xiě)出 Python 版本,并直接用 IDAPython 腳本在 IDA 中將其批量解密。那如果字串解密算法比較復(fù)雜,用 Python 實(shí)現(xiàn)一版顯得吃力呢?

這時(shí)不妨考慮一下指令模擬器。

近幾年,Unicorn 作為新一代指令模擬器在業(yè)界大火。基于 Unicorn 的 IDA 指令模擬插件也不斷被開(kāi)發(fā)出來(lái),比如簡(jiǎn)捷的 IdaEmu 和 FireEye 開(kāi)發(fā)的功能強(qiáng)大的 Flare-Emu。指令模擬器可以模擬執(zhí)行一段匯編指令,而 IDA 中的指令模擬插件可以在 IDA 中模擬執(zhí)行指定的指令片段(需要手動(dòng)指定起始指令地址和結(jié)束指令地址,并設(shè)置相關(guān)寄存器的初始狀態(tài))。這樣一來(lái),我們就可以在 IDA 中,利用指令模擬插件來(lái)模擬執(zhí)行上面的批量解密指令,解密字串的匯編指令模擬執(zhí)行結(jié)束,字串也就自然都給解密了。

本文 Case 的指令模擬姿勢(shì)基于 Flare-Emu。

不過(guò),這個(gè)姿勢(shì)需要注意兩點(diǎn)問(wèn)題:

  1. 指令模擬器無(wú)法模擬系統(tǒng) API ,如果解密函數(shù)中有調(diào)用系統(tǒng) API 的操作,那指令模擬這個(gè)姿勢(shì)就要費(fèi)老勁了。
  2. 所謂模擬指令執(zhí)行,真的只是模擬,而不會(huì)修改 IDA 中的任何數(shù)據(jù)。這樣一來(lái),需要自己把指令模擬器執(zhí)行結(jié)束后的明文字串 Patch 到 IDB 文件中,這樣才能在 IDA 中看到明文字串。

3.2.1 hook api

第 1 點(diǎn)問(wèn)題,IdaEmu 中需要自己實(shí)現(xiàn)相關(guān) API 的功能,并對(duì)指令片段中相應(yīng)的 API 進(jìn)行 Hook,才能順利模擬。比如下圖示例中,指令片段里調(diào)用了 _printf 函數(shù),那么就需要我們手動(dòng)實(shí)現(xiàn) _printf 的功能并 Hook 掉指令片段中的 _printf 才行:

而 Flare-Emu 就做的更方便了,他們直接在框架中實(shí)現(xiàn)了一些基礎(chǔ)的系統(tǒng) API,而不用自己手動(dòng)實(shí)現(xiàn)并進(jìn)行 Hook 操作:

之所以提這么個(gè)問(wèn)題,是因?yàn)檫@個(gè) kemon.sys 樣本中的批量解密字串的過(guò)程中,涉及了對(duì) memcpy 函數(shù)的調(diào)用:

這樣一來(lái),直接用 Flare-Emu 來(lái)模擬執(zhí)行應(yīng)該是個(gè)更便捷的選項(xiàng)。

3.2.2 Patch IDB

第 2 點(diǎn)問(wèn)題,將模擬結(jié)果寫(xiě)回 IDB 文件,在 IDA 中顯示。

首要問(wèn)題是如何獲模擬執(zhí)行成功后的結(jié)果——明文字符串。前面描述字串解密算法時(shí)說(shuō)過(guò),解密后的字節(jié)(Byte)會(huì)直接替換密文中的特定字節(jié),把密文的前 dataLen 個(gè)字節(jié)解密出來(lái),就是明文字串。這個(gè)字節(jié)替換的操作,其實(shí)對(duì)應(yīng) Unicorn 指令模擬器中定義的 MEM_WRITE 操作,即寫(xiě)內(nèi)存,而且,字串解密過(guò)程中也只有這個(gè)字串替換操作會(huì)寫(xiě)內(nèi)存 。恰好,F(xiàn)lare-Emu 中提供了一個(gè) memAccessHook() 接口(如下圖),可以 Hook 多種內(nèi)存操作:

 
 
 
 
  1. memAccessHook can be a function you define to be called whenever memory is accessed for reading or writing. It has the following prototype: memAccessHook(unicornObject, accessType, memAccessAddress, memAccessSize, memValue, userData).

Unicorn 支持 Hook 的的內(nèi)存操作有以下幾個(gè):

于是,我們 Hook 掉指令模擬過(guò)程中的 UC_MEM_WRITE 操作,即可獲取解密后的字節(jié),并將這些字節(jié)手動(dòng) Patch 到 IDB 中:

 
 
 
 
  1. def mem_hook(unicornObject, accessType, memAccessAddress, memAccessSize, memValue, userData):
  2.     #if accessType == UC.UC_MEM_READ:
  3.     #    print("Read: ", hex(memAccessAddress), memAccessSize, hex(memValue))
  4.     if accessType == UC.UC_MEM_WRITE:
  5.         #print("Write: ", hex(memAccessAddress), memAccessSize, hex(memValue))
  6.         if memAccessSize == 1:
  7.             idc.PatchByte(memAccessAddress, memValue)
  8.         elif memAccessSize == 2:
  9.             idc.PatchWord(memAccessAddress, memValue)
  10.         elif memAccessSize == 4:
  11.             idc.PatchDword(memAccessAddress, memValue)

Patch IDB 的基本操作當(dāng)然是像前文中 IDAPython 腳本那樣,調(diào)用 idc.PatchXXX 函數(shù)寫(xiě)入 IDB 文件。前面一個(gè)姿勢(shì)中,Patch IDB 文件,只調(diào)用了一個(gè) idc.PatchByte() 函數(shù)。其實(shí),idc 庫(kù)中共有 4 個(gè)函數(shù)可以 Patch IDB:

 
 
 
 
  1. idc.PatchByte(): Patch 1 Byte;
  2. idc.PatchWord(): Patch 2 Bytes;
  3. idc.PatchDword(): Patch 4 Bytes;
  4. idc.PatchQword(): Patch 8 Bytes;

指令模擬器中執(zhí)行 Patch 的操作,并不只有 PatchByte 這一項(xiàng)。根據(jù)我 print 出來(lái)的指令模擬過(guò)程中寫(xiě)內(nèi)存操作的細(xì)節(jié),可以看到共涉及 3 種 Patch 操作(如下圖):1 byte、2 Bytes 和 4 Bytes,所有才有了上面 mem_hook() 函數(shù)中的 3 種 memAccessSize。

明確并解決了「系統(tǒng) API Hook」和「捕獲指令模擬結(jié)果并 Patch IDB」這兩點(diǎn)問(wèn)題,就可以寫(xiě)出準(zhǔn)確無(wú)誤的 IDAPython 腳本了。

3.2.3 Radare2 ESIL 模擬

r2 上也有強(qiáng)大的指令模擬模塊,名為 ESIL( Evaluable Strings Intermediate Language):

在 r2 上用這個(gè)東西來(lái)模擬指令解密這一批字符串,就不用像 IDA 中那樣還要自己動(dòng)手寫(xiě) IDAPython 腳本了,只需要通過(guò) r2 指令配置好幾個(gè)相關(guān)參數(shù)即可。下面兩張圖是在 r2 中通過(guò)指令模擬批量解密這些字符串的前后對(duì)比:

具體操作方法就不細(xì)說(shuō)了,有興趣的朋友可以自行探索。

4. 總結(jié)

文中介紹兩種基本方法,在 IDA 中批量解密 雙槍 木馬傳播中間環(huán)節(jié)的惡意驅(qū)動(dòng) kemon.sys 中的大量自定義加密字串:Python 實(shí)現(xiàn)解密函數(shù)和指令模擬解密函數(shù)。

原理都很簡(jiǎn)單,介紹的有點(diǎn)啰嗦,希望把每個(gè)關(guān)鍵細(xì)節(jié)都描述清楚了。

兩種方法對(duì)應(yīng)的 IDAPython 腳本,已上傳到 Github,以供參考:https://github.com/0xjiayu/decrypt_CypherStr_kemonsys

5. 參考資料

https://en.wikipedia.org/wiki/Caesar_cipher

https://github.com/tmr232/idapython/blob/master/python/idc.py

https://unicorn-engine.org

https://github.com/36hours/idaemu

https://github.com/fireeye/flare-emu

https://github.com/unicorn-engine/unicorn/blob/master/bindings/python/unicorn/unicorn_const.py#L64


當(dāng)前名稱:兩種姿勢(shì)批量解密惡意驅(qū)動(dòng)中的上百條字串
網(wǎng)頁(yè)路徑:http://www.5511xx.com/article/djgsphh.html