乾貨 | 惡意代碼最新混淆技術分析
惡意軟體代碼使用各種各樣的混淆技術來保護自己,這樣可以躲避一些基於靜態的特徵值檢測的殺軟,同時還可以阻止安全研究人員的逆向分析。到目前為止很多常見的混淆技術已經存在解決方案了,即便混淆後的代碼非常混亂,但是還有會有很多相應的技術幫助我們快速反混淆腳本文件。在這篇文章中,主要介紹對惡意腳本混淆技術的一些新研究以及如何反混淆。
代碼混淆
攻擊者利用代碼混淆技術可以保護自己的真實源碼,這樣做的目的主要有兩個:躲避殺軟、IDS以及遏制安全研究人員的逆向工程。
通常情況下,代碼混淆是通過自動混淆器自動完成的。目前已經有許多免費的自動混淆器:
- Stunnix (Multiple Languages)
- Crunchcode (VBA)
- ScriptCryptor (VBA, JavaScript)
- CodeProtection (VBA)
- Vbad (VBA)
- ISESteroids(PowerShell)
- Scripts Encryptor(Multiple Languages)
由於混淆後的代碼不會改變腳本的功能,因此是不是可以使用動態惡意軟體分析方法來確定腳本的功能以及提取出IOC,然而對於安全研究人員來說,這是一件相當難的事情。事實上,動態分析方法可以作為其中的一部分環節,而反混淆以及靜態分析方法可以知道腳本所有的內容以及還原整個過程。
一些準備工作
在反混淆之前,我們頭腦中需要理清一些思路:
- 可讀性:反混淆的目的就是讓代碼具有可讀性。
- 簡化代碼:代碼越簡化,可讀性越強,也就越能理解腳本的控制流程和數據流。
- 理清控制流和數據流:理清這兩點可以幫助我們靜態分析腳本的可能執行流程。
- 獲取上下文:通過腳本的上下文相關性可以幫助我們更好的理清前面的3點。
需要使用的工具:
1. 虛擬機
2. 源碼編輯工具,一般最基本的要求是具備語法高亮等功能。
3. 調試器
當然如果我們對腳本語言熟悉,也能幫助我們進行反混淆,一些腳本語言的說明如下:
- JScriptVBScript
- WindowsPowerShell Reference
- OfficeVBA Language Reference
- MozillaJavaScript Reference
在推薦一些在線的腳本調試框架,這些框架都提供單步調試功能:
- JSFiddle
- .NET Fiddle
- CodingGround
混淆技術分析
1. 垃圾代碼
一些混淆器會將多餘的代碼片段植入腳本中,例如一些變數以及函數再被定以後從來沒有被引用或者調用。這些代碼是可能會執行的,但是不會影響腳本的整體執行結果。如果發現這些拉架代碼可以將其從代碼中移除。
在下面的例子中可以看出,在子程序中的幾個變數被定義,並設置為一個整數的值,加上一個整數的字元串表示。這些變數在代碼中其他地方沒有被引用,所以可以將他們安全地從子程序中刪除,而不會影響結果。
2. 命名複雜化
最常見的混淆技術是將變數或者函數的命名過於複雜化。例如字元串由大寫,小寫字母,數字組成,這樣子乍一看很難區分這些符號。因此這些命名可以被替換為更加具體的命名。
這裡我們可以使用文本編輯器的查找/替換功能,但是當涉及到全局變數時需要小心點。
在上面的例子中,將子程序的變數重命名為一個更簡單的標籤。同時將程序的形參也替換成更容易理解的輸入變數。
3. 間接調用和混淆控制流程
在程序的執行流程中,往往會間接調用函數,攻擊者可以在調用某個函數時,不是直接調用,而是經常幾次其他無功能函數的調用最終調用該函數,因此可以混淆控制流程。
在上面的例子中,有五個子程序。在這些子程序中有一個sub5。如果你通過跟蹤子程序的調用可以發現子程序最終執行的是sun2。因此,調用任何一個函數都將調用sub2。因此,可以移除sub1,sub3,sun4,和sub5而不是影響程序的執行結果。
4. 序列求和
混淆器可以採用簡單的算術方法來阻止逆向。除了實際的數學方法外,腳本語言還經常使用數學函數進行轉化。
在上面的例子中可以看到,8個數字進行算術運算後得到的值再使用CHA函數進行轉化。
在這裡我們可以看到更加複雜的算術方法,接連使用了數組求值,sgn以及Abs方法對變數的值進行操作,而最終運算的結果就是escouecm=2000.
5. 混淆字元串的值
至於對字元串的混淆可以看一下下面這個例子:
其實上述代碼主要是通過StrReverse VBA函數,對字元串進行倒轉。空字元串可以被刪除,因為他們沒有任何表示。一旦字元串被倒轉之後,再添加到初始的「C」字元串,可以很明顯的看到,它調用一個cmd命令。
一種通用的惡意VBA宏的常用方法是使用其他腳本語言釋放和調用腳本。在這種情況下,宏建立一個Windows批處理文件,稍後將被執行。雖然構建一個批處理文件比較明顯,但是文件的確切目的剛開始仍然還是不清楚的。
6. 高級的方法
有一種情況是當我們嘗試了各種方法後還是無法還原混淆的代碼,下面介紹一種更加通用的方法。
我們可以使用調試器對混淆的腳本進行單步調試,在一些需要解碼的字元串的地方插入eval方法,將其直接列印出來。這種方法可以在最短的時間內得到我們想要的數據。
在上面的代碼中,綠色部分的函數被多次調用。可以看到函數的參數分別是十六進位數字和一些字母組成的字元串,函數存在一個返回值。從該函數的上下文可以看出,函數的返回值應該是一個字元串。因此我們可以藉助調試器,在函數返回後下斷點,這樣就可以看到這個函數的返回值了。一旦得到這個返回值就可以採用前面的一些方法進行替換了,是不是很簡單。
總結
腳本反混淆技術其實也不需要藉助任何過於複雜的工具。因此我們需要的是得到可讀性較強的代碼即可,邏輯上是相當於原來的混淆腳本。在這個過程中,可以從比較小的代碼片段開始著手反混淆,先解決部分代碼,再通過上下文判斷整個過程他們是如何使用,刪除不必要的代碼和簡化代碼,可以使得腳本更具可讀性和更容易理解。最後,需要的時候查閱官方的腳本語言文檔。
註:本文屬於原創獎勵計劃文章,未經許可禁止轉載
推薦閱讀: