Spartacus勒索軟體分析
Spartacus是一個比較直接的勒索軟體樣本,使用了ShiOne,Blackheart等過去的一些勒索軟體的技術和代碼。但是該惡意軟體與這些勒索軟體和攻擊單元沒有直接的關係。
Satyr和Blackheart中的代碼基本上相同,而Spartacus的代碼流雖然相似,但是做了一定的修改。研究人員作出假設,這可能來源於同一攻擊單元或者不同的攻擊單元使用相同的代碼。但是,還沒有證據能夠證明。
總的來說,所有的.NET勒索軟體彈出的字元串或多或少是相似的。這只是犯罪分子創建的一種簡單形式的勒索軟體,因為花費的時間相對很少。
Spartacus的分析可以作為分析其他.net勒索軟體樣本的一個參考和基準。本文的兩個主要目的是詳細理解代碼和如何將一個混淆後的.NET勒索軟體樣本進行反混淆變成可讀的狀態。
Spartacus
Spartacus開始就使用Rijndael演算法(AES加密的一種)生成一個唯一的加密密鑰。該密鑰用於加密每個單獨的文件,意味著兩個系統的文件會有相同的密文。AES密鑰是用文件中嵌入的RSA密鑰進行加密的。密文會被編碼並在勒索信息中展示給用戶。
RSA密鑰靜態嵌入勒索軟體的事實說明私鑰存在於勒索軟體作者的系統服務端。所以,如果私鑰泄漏,那麼所有受害者的AES密鑰就可以用該私鑰解密。
如果勒索軟體極其複雜,就需要對其進行深度技術分析和代碼走查。
解包
首先,用ILSpy軟體打開Spartacus樣本:
因為所有的代碼都是混淆過的,所以函數的代碼是不可見的。
然後使用de4dot工具,該工具可以處理文件並輸出可讀的代碼。-r標記是設定目錄用的,含有混淆後的.NET樣本。
分析
首先看一下main函數。
首先它確保系統只有一個該惡意軟體的實例運行,這是通過CheckRunProgram函數創建mutex來確保唯一性的。
檢查完成後,會在線程中執行smethod_3。
在smethod_3開始前,該類的構建者會自動化地調用並設置所有的私有成員(變數),其中包含所有要搜索和加密的特殊文件夾。還有使用KeyGenerator.GetUniqueKey(133)函數來創建AES密鑰,該密鑰對受害者來說是唯一的。這些特殊的文件夾可以在下面看到,可以通過勒索軟體進行參考來開始文件夾轉化。
上面提到的密鑰生成函數是GetUniqueKey(),該函數會用RNGCryptoServiceProvider.GetNonZeroBytes API函數創建一系列的加密的強隨機數。然後使用一系列隨機數作為字符集的索引array = 「abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890」來建立唯一的字元串。這就是AES密鑰,可以用來加密所有的文件。
這樣就初始化了類的構造器,下面我們看一下調用的smethod_3函數。
該函數重複了特殊文件夾列表,這是構造器中生成的,並且用smethod_6函數中文件夾中開始遞歸遍歷加密文件。這裡的加密循環中並不區別文件的類型或特殊文件,會加密所有遍歷到的文件。
下面是調用的smethod_1,這是程序設計者的一個錯誤,因為其輸出並沒有在程序的其他部分使用,只有在向用戶顯示加密密鑰時被調用了。
smethod_6函數是執行所有加密的函數,smethod_5函數是進行遞歸的函數,不管從什麼位置開始遞歸,都調用smethod_6函數加密子文件夾中的文件。
該函數還會調用自己來最終覆蓋所有的子文件夾。然後調用smethod_6來進行實際的加密,在文件夾中對每個文件完成一個迴環。
該方法會重複當前文件夾的所有文件,唯一的說明就是該文件沒有被加密。這是通過擴展名是不是.spartacus來確認的。
if (Path.GetExtension(text) == ".Spartacus")
{
return;
}
如果檢查通過,就會調用smethod_7,該函數會用加密的內容對文件內容進行重寫。
該函數調用smethod_0函數,加密原始的文件數據,接下來的兩行將加密的數據寫入文件,並將文件擴展名修改為.Spartacus。另一個所有的文件都有相同密鑰進行加密的標記是勒索軟體並沒有將加密的AES密鑰寫入文件中。
如果使用Rijndael方法的ECB模式,構造器就會用MD5進行哈希,事實上密鑰本事也是這麼使用的。
整個文件系統的文件加密過程是通過smethod_3的子函數完成的。
下面看一下主函數的下一行,調用了smethod_4()函數:
smethod_4執行的是smethod_3中的遞歸函數調用。除了在特殊文件夾中loop外,還會對文件系統中掛載的所有邏輯驅動進行重複。所以所有的外部和映射驅動也會被加密。
需要注意的是smethod_6被調用了2次,可能是運行了兩個線程來加速加密的過程。
回到主函數,下一個也是最後一個重要的函數調用時:
Application.Run(new Form1());
該函數會向用戶展示勒索信息,並在勒索信息中顯示加密的AES密鑰。
這是通過調用smethod_1()開始的,這裡簡單的使用了簽名生成的AES密鑰,並用硬編碼的公開的RSA密鑰進行加密。
public static string smethod_1()
{
return Convert.ToBase64String(Class1.smethod_2("xA4fTMirLDPi4rnQUX1GNvHC41PZUR/fDIbHnNBtpY0w2Qc4H2HPaBsKepU33RPXN5EnwGqQ5lhFaNnLGnwYjo7w6OCkU+q0dRev14ndx44k1QACTEz4JmP9VGSia6SwHPbD2TdGJsqSulPkK7YHPGlvLKk4IYF59fUfhSPiWleURYiD50Ll2YxkGxwqEYVSrkrr7DMnNRId502NbxrLWlAVk/XE2KLvi0g9B1q2Uu/PVrUgcxX+4wu9815Ia8dSgYBmftxky427OUoeCC4jFQWjEJlUNE8rvQZO5kllCvPDREvHd42nXIBlULvZ8aiv4b7NabWH1zcd2buYHHyGLQ==AQAB", Encoding.UTF8.GetBytes(Class2.smethod_0())));
}
RSA密鑰是硬編碼的,並且嵌入在勒索軟體中,這意味著勒索軟體的作者提前在服務端生成了私鑰。
然後在所有的驅動之間重複,並寫入勒索信息。
最後,打開勒索信息展示消息和RSA加密的AES密鑰,受害者可以用來解密。
完成了這些之後,還需要調用smethod_0,該函數會刪除所有的Shadow Volume來防止用戶用它來進行Windows恢復。
該勒索軟體是完全離線的,因為沒有與C2或其他伺服器進行通信。直到受感染者向其發送個人ID(AES密鑰),勒索軟體作者才知道誰被感染了。這也就意味著作者發送的解密工具可能是嵌入在AES密鑰中的,而每個受害者也是不一樣的。
雖然該樣本沒有什麼特殊性,也沒有太多的創新性,但是不意味著它就不危險。截止目前針對該勒索軟體還沒有解密器。如果用戶感覺可能感染了該惡意軟體,那麼最好的辦法就是執行進程內存dump,從中可能會提取到密鑰。
※利用Raspberry PI 3打造AWS VPN用戶網關
※史上最全攻擊模擬工具盤點
TAG:嘶吼RoarTalk |