成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

兩種姿勢批量解密惡意驅動中的上百條字串

安全 應用安全
文中介紹兩種基本方法,在 IDA 中批量解密 雙槍 木馬傳播中間環節的惡意驅動 kemon.sys 中的大量自定義加密字串:Python 實現解密函數和指令模擬解密函數。

[[263481]]

作者:JiaYu 轉自公眾號:信口雜談

 1. 概述

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

這在 雙槍 木馬的傳播鏈條中只是一個很小的技術點,所以文中也沒說具體是什么樣的加密算法以及怎樣解密,供分析員更方便地做樣本分析工作。但這個技術點還算有點意思,尤其是對逆向入門階段的朋友來說,可以參考一下解法。最近又碰到了這個驅動程序的變種,跟團隊的老司機討教了一番,索性寫篇短文記錄一下。

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

2. 樣本概況

MD5: b001c32571dd72dc28fd4dba20027a88

2.1 字符串加密情況

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


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


2.2 加密算法

前面說了,算法不復雜。以 DecryptAsciiStr 函數為例: 

反編譯看看: 

DecryptUnicodeStr 算法其實相同,只是因為字節構成不同,所以是兩個解密函數分開寫: 


簡單總結起來,這套解密過程其實就是:把當前字節后面特定偏移處的字節與 0xC 異或,然后替換掉當前字節,把解密后的字節寫入到當前位置,即完成解密。本人對密碼學不熟,不知道這是不是已有名號的加密算法,看起來像是 凱撒密碼 的變形加強版?對此有了解的朋友歡迎指教。

3. 解密

了解了上面的情況之后,就該著手解密這百十多條字符串了。既然是用 IDA 來分析這個樣本,理想的狀況應該是把這些字串批量解出來,直接在 IDA 中呈現,然后就可以進行后續分析了。既然是要自動化批量解密,寫 IDAPython 應該算是最便捷的做法了。最終效果如圖:


3.1 姿勢 1——自行實現解密算法

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


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

  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 界面中,可以選擇生成的字符串的類型(如下圖),快捷鍵只有一個 A,對應的 idc 函數是 idc.MakeStr(0。然而 ida.MakeStr() 函數默認是生成 Ascii 字串的,要想生成 Unicode 字串,就需要調用 idc.SetLongPrm() 函數設置一下字符串的類型。


IDA 中支持的字符串類型如上圖,相應地,在 idc 庫中的定義如下:

  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() 函數設置一下字符串類型。其中 idc.INF_STRTYPE 即代表字符串類型的常量,在 idc 庫中的定義如下: 


用 Python 實現了解密函數之后,如何模擬這一波解密過程把這 100+ 條字串依次解密呢?這里可以結合 IDA 中的 xrefs 和 idc.PrevHead() 函數來實現:

  1. 先通過 xrefs 找到調用兩個解密函數的位置;
  2. 再通過 idc.PrevHead() 定位到兩個解密函數的參數地址,并解析出參數的值;
  3. 執行解密函數,將解密后的明文字串寫回 IDB 并 MakeStr。

3.2 姿勢 2——指令模擬

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

這時不妨考慮一下指令模擬器。

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

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

不過,這個姿勢需要注意兩點問題:

  1. 指令模擬器無法模擬系統 API ,如果解密函數中有調用系統 API 的操作,那指令模擬這個姿勢就要費老勁了。
  2. 所謂模擬指令執行,真的只是模擬,而不會修改 IDA 中的任何數據。這樣一來,需要自己把指令模擬器執行結束后的明文字串 Patch 到 IDB 文件中,這樣才能在 IDA 中看到明文字串。

3.2.1 hook api

第 1 點問題,IdaEmu 中需要自己實現相關 API 的功能,并對指令片段中相應的 API 進行 Hook,才能順利模擬。比如下圖示例中,指令片段里調用了 _printf 函數,那么就需要我們手動實現 _printf 的功能并 Hook 掉指令片段中的 _printf 才行: 


而 Flare-Emu 就做的更方便了,他們直接在框架中實現了一些基礎的系統 API,而不用自己手動實現并進行 Hook 操作: 


之所以提這么個問題,是因為這個 kemon.sys 樣本中的批量解密字串的過程中,涉及了對 memcpy 函數的調用: 


這樣一來,直接用 Flare-Emu 來模擬執行應該是個更便捷的選項。

3.2.2 Patch IDB

第 2 點問題,將模擬結果寫回 IDB 文件,在 IDA 中顯示。

首要問題是如何獲模擬執行成功后的結果——明文字符串。前面描述字串解密算法時說過,解密后的字節(Byte)會直接替換密文中的特定字節,把密文的前 dataLen 個字節解密出來,就是明文字串。這個字節替換的操作,其實對應 Unicorn 指令模擬器中定義的 MEM_WRITE 操作,即寫內存,而且,字串解密過程中也只有這個字串替換操作會寫內存 。恰好,Flare-Emu 中提供了一個 memAccessHook() 接口(如下圖),可以 Hook 多種內存操作:

  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 的的內存操作有以下幾個:


于是,我們 Hook 掉指令模擬過程中的 UC_MEM_WRITE 操作,即可獲取解密后的字節,并將這些字節手動 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 的基本操作當然是像前文中 IDAPython 腳本那樣,調用 idc.PatchXXX 函數寫入 IDB 文件。前面一個姿勢中,Patch IDB 文件,只調用了一個 idc.PatchByte() 函數。其實,idc 庫中共有 4 個函數可以 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; 

指令模擬器中執行 Patch 的操作,并不只有 PatchByte 這一項。根據我 print 出來的指令模擬過程中寫內存操作的細節,可以看到共涉及 3 種 Patch 操作(如下圖):1 byte、2 Bytes 和 4 Bytes,所有才有了上面 mem_hook() 函數中的 3 種 memAccessSize。


明確并解決了「系統 API Hook」和「捕獲指令模擬結果并 Patch IDB」這兩點問題,就可以寫出準確無誤的 IDAPython 腳本了。

3.2.3 Radare2 ESIL 模擬

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


在 r2 上用這個東西來模擬指令解密這一批字符串,就不用像 IDA 中那樣還要自己動手寫 IDAPython 腳本了,只需要通過 r2 指令配置好幾個相關參數即可。下面兩張圖是在 r2 中通過指令模擬批量解密這些字符串的前后對比:


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

4. 總結

文中介紹兩種基本方法,在 IDA 中批量解密 雙槍 木馬傳播中間環節的惡意驅動 kemon.sys 中的大量自定義加密字串:Python 實現解密函數和指令模擬解密函數。

原理都很簡單,介紹的有點啰嗦,希望把每個關鍵細節都描述清楚了。

兩種方法對應的 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

 

責任編輯:武曉燕 來源: 信口雜談
相關推薦

2020-06-18 08:18:35

密碼加密安全

2014-03-06 17:52:25

2010-09-02 16:46:18

SQL刪除

2021-11-16 06:55:36

Linux字符設備

2010-03-16 15:23:32

java動態載入

2011-03-03 17:00:37

pure-ftpdchroot

2009-06-29 18:11:40

JSP設計模式

2010-10-11 10:31:51

MySQL分區

2013-05-27 14:31:34

Hadoop 2.0

2010-07-13 10:10:28

WPF

2009-08-31 12:46:22

雪豹蘋果操作系統

2009-09-14 19:25:09

Ruby form

2019-09-15 17:35:28

Wireshark解密HTTPS

2021-05-27 10:57:01

TCP定時器網絡協議

2009-12-07 13:42:24

WCF框架

2011-06-22 14:14:27

pageEncodincontentType

2012-12-24 13:30:34

iOS

2010-09-06 17:26:54

SQL函數

2010-10-09 10:04:45

FunctionJS

2011-03-03 10:26:04

Pureftpd
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产一级视频免费播放 | 国产毛片毛片 | 一本色道精品久久一区二区三区 | 福利视频一区 | 国产精品无码久久久久 | 亚洲综合无码一区二区 | 免费国产黄网站在线观看视频 | 欧美一区二区免费电影 | 久久亚洲天堂 | 日韩精品一区二区三区视频播放 | 91精品国产自产精品男人的天堂 | 羞羞视频网 | 成人免费网站视频 | 国产中文在线 | 亚洲黄色在线免费观看 | 亚洲免费片 | 久久精品久久久 | 99reav| 午夜精品网站 | 欧美中文字幕一区二区三区 | 国产精品一区在线观看 | 亚洲精品视频免费看 | 欧美精品乱码99久久影院 | 成人福利网 | 欧美亚洲激情 | 日韩一二三区视频 | 欧美5区| 精品一区二区三区电影 | 91精品国产91综合久久蜜臀 | 另类专区亚洲 | 九九热免费观看 | 免费一区| 国产一区二区三区四区五区加勒比 | 日韩av在线中文字幕 | 成人免费淫片aa视频免费 | 日本免费视频在线观看 | 亚洲一区二区在线 | 日韩在线中文 | 久久99精品久久久久久 | 欧美成人黄色小说 | 欧美在线一区二区三区 |