武漢大學信息安全協會 · 2015/12/19 15:25php
持續更新的惡意軟件
原文:blog.talosintel.com/2015/12/cry…css
在過去的一年裏,Talos花費了大量的時間去研究ransomware的運做原理,它與其餘惡意軟件的管理,還有它的經濟影響。這項研究對開發檢測方法和破壞攻擊者的攻擊有很大的價值。CrytoWall是一款惡意軟件,在過去的一年裏,先是升級成了CryptoWall2,隨後升級爲CryptoWall3。儘管你們都在努力檢測和破壞它的攻擊行爲,可是這款惡意軟件開發者仍是很厲害的,改進了一些技巧,而後如今放出了CryptoWall4這個版本。html
爲了保證咱們能最有效地檢測出來,Talos對CryptoWall4進行了逆向,去理解它的行爲,還有升級以後的差別,並放在這裏分享咱們的研究成果。git
讀者可能不熟悉,ransomware是一款惡意軟件,它鎖定用戶的文件(好比照片,文檔,音頻文件等等),而後對其進行加密。用戶要給贖金才能解密這些文件,查看裏面的內容。一般,用戶會經過釣魚郵件感染ransomware。CryptoWall4的核心功能仍然沒變,加密用戶文件而後要贖金解密。然而,Talos發現了一些新的特性。好比加密算法變了,並且CryptoWall4加入了一項新的技術來禁用並刪除了Windows全部的自動備份機制,沒有外部的備份想自行恢復文件基本不可能了。算法
咱們還發現CryptoWall4用了一些沒有公開的API來得到入侵主機的本地語言設置。在後面的文章裏,會更詳細地闡述Talos發現的CryptoWall的新特性。數據庫
對於有經驗的讀者,咱們建議您繼續讀下午。咱們強烈建議用戶和企業遵循安全規範,並且採用多層次的檢測手段來規避風險。咱們對新版本CryptoWall的深刻分析,給了咱們保護用戶和肯定更好的檢測方案的技術支持。最後,針對FBI聲明說的:用戶沒辦法了仍是支付贖金吧。Talos強烈建議用戶們不要支付贖金,由於這樣會直接讓這項惡意行動受益。windows
CryptoWall的經營者用網絡釣魚和drive-by-download來將他們的惡意程序傳播給用戶。一旦CryptoWall4被成功運行,就會從C2服務去下載一個RSA公鑰。而後全部的文件都被暫時地先被AES祕鑰加密,以後就會被下載下來的RSA公鑰加密。而後會用三種不一樣的方式告訴用戶,你被加密了。第一種是一個文本文件,第二種是一張.png的圖,第三種是一個HTML文檔。全部的都會自動地從受害者的桌面打開。以下面所示。安全
FigureA.1bash
FigureA.2服務器
FigureA.3
FigureA.4
FigureA.5
一個有趣的發現是,一旦CryptoWall4不能從C2 server檢索到RSA公鑰,它就會不停地循環來下載公鑰。只要公鑰得不到,CryptoWall就不會破壞受害者的電腦。Talos一樣觀察到,這個樣本也有一些另外的安全檢查,好比若是受害者機器上的語言不受支持,就會自動終止感染進程。下面幾種語言設置不會被感染:
Russian, Kazakh, Ukrainian, Uzbek, Belarusian, Azeri, Armenian, Kyrgyz, Georgian.
很明顯,攻擊者想要排除一些地區,使之免受感染。
感染進程就以下圖描述的同樣:
Figure B
從上圖所示的 」Delete all shadow copies「開始,CrytoWall4已經注入到了svchost進程。注入到這個進程是爲了在受害者機器上得到更高的權限,以此來繞過UAC。有權限了才能靜默地刪除全部的系統備份,否則會有UAC提示用戶來處理。
下圖C描述的是其網絡通信,用的是HTTP協議,可是對payload進行了加密。如圖D和圖E
Figure C
Figure D
Figure E
CryptoWall4用了一個新的文件名生成算法來給加密後的文件命名:
CryptoWall4用的CRC32校驗算法來排除一些目錄,文件名和擴展名。下面是一些白名單:
Extensions:
exe, dll, pif, scr, sys, msi, msp, com, hta, cpl, msc, bat, cmd, scf
Directories:
windows, temp, cache, sample ,pictures, default pictures, Sample Music, program files, program files (x86), games, sample videos, user account pictures, packages
Files:
help_your_files.txt, help_your_files.html, help_your_files.png, thumbs.db
完整的白名單在文章末尾Appendix A.
這些在白名單裏的目錄,文件名以及擴展名都是爲了保證操做系統的穩定性。這意味着受害者能夠繼續用他們的電腦來支付贖金。任何被感染的用戶都應該記住,下次開機,加密又會自動運行,而後把新建立的任何文件都加密一次。
生成新文件的文件名後,它的加密算法如圖F所示:這也清楚地告訴咱們,在CryptoWall4將文件加密以後,若是沒有RSA私鑰來還原AES祕鑰,要還原文件,基本不可能。然而私鑰只存在於攻擊者的電腦上,並且不會傳給用戶的電腦。換句話說,用戶不支付贖金得到私鑰,就沒辦法還原文件。用戶應該備份好本身的重要文件,才能保證遭受這種攻擊後,不用支付贖金就能將其恢復。
Figure F
病毒程序主體被壓縮,且被不一樣的殼保護了,殼裏面有不少垃圾代碼,無用的API調用,還有代碼混淆技巧,好比用調用隨機的API,參數還很奇怪。
Figure G
第二層保護用的一種交錯跳轉形式的代碼:
INSTRUCTION 1
INSTRUCTION 2
JNO nextSteo
複製代碼
主要的代碼和以前版本的CryptoWall是很是類似的:首先構造本身的IAT,得到須要的系統調用而且建立本身的主事件對象來管理進程同步(名字是workstation的MD5)。這個事件有兩個目標:在執行期間,阻止其他的CryptoWall4進程運行並且爲感染有關的不一樣的進程實現同步。這寫代碼注入到一個新命名爲「explorer.exe」進程裏。注入到目標進程裏的實際代碼,用了這兩種技術中的一種:
最後,代碼被從新安置。用了兩種不一樣的技術來進行注入:
最終注入到新的 宿主「explorer.exr」進程裏的代碼,會被執行而後用CryptoWall4感染系統而且實現持續感染。程序主體被複制進%APPDATA%目錄,而後在用戶根目錄的"Run"鍵值後添加進去,實現開機自啓。
病毒程序會用一種如今還沒被發現方法來禁止全部的系統還原點,和windows備份。首先調用SRRemoveRestorePoint,而後參數是0-1000,直到方法返回ERROR_INVALID_DATA
。它將註冊表HKLM\Software\Microsoft\Windows Nt\SystemRestore
路徑下的「DisableSR」鍵值設置爲1,這樣就徹底禁止了系統還原。最後它開始執行刪除存儲備份的標準命令:
#!bash
vssadmin.exe Delete Shadows /All /Quiet
複製代碼
接下來的流程在 「svchost.exe」進程裏面。代碼會重建IAT表,建立另外一個事件(只在「svchost.ext」裏使用),而後去造成而且打開本身的配置文件。這一步常常會失敗,由於配置文件這時候尚未存在。dropper打開並解壓位於本身內部的C&C URL列表(用的LZ壓縮算法)。最後它嘗試發廣播去鏈接其中的某個 C&C server。
能夠在IOC段找到惡意程序使用的C&C server的列表。
CryptoWall4的網絡包比較特別,是下面這樣的:
| request Id | crypt7 | workstation MD5 [|subRequest Id 1|subRequest 1 Data| … ]
在寫這篇文章的時候,咱們成功地了分出了五種不一樣的類型的包(request ID不一樣)。
1,3 --- Announcement packet --用來告訴C&C server有新的機器被感染了
7 --- Multi purpose packets。第一個sub-request ID用來區分不一樣類型的包:
1 - Public key request -用來向 C&C server請求一個新的公鑰,爲以後的加密作準備
2 - End announcement packet 用來告訴服務器感染結束了。另外一個sub-request ID表明感染如何結束的詳細信息:
1 - Success
2, 3 - Unsupported OS language packet - Exit
複製代碼
這些包用標準的HTTPS協議送到網絡上,可是在這以前就被加密了。加密算法很普通,用一個隨機的字符串做爲key,而後造成這樣格式的數據流:
| Letter |=| encryption Key in Hex | encrypted stream |
例如:
s=6975376e7a9b0fd24886fbd0c0de32d3ab4dd97174462ca3b06af16a1c840ae893eddacafbd93e56847c23a41352d4f45fc75468e4408
在廣播進程成功鏈接到 C&C server後,就會請求得到公鑰。這裏有一個CryptoWall4的作的不足的地方:若是防火牆或者IPS足夠好,可以攔截CryptoWall4的包,感染就進行不下去了。RSA-2048公鑰請求包的request ID是7。C&C server返回的包這樣子構成:
Figure H.1
Figure H.2
Figure H.3
公鑰用CryptStringToBinary API來解密。解密後的數據被存在一個全局變量中。HTML和text文件(用LZ 壓縮算法壓縮)由dropper釋放出來,最終建立好配置文件並被加密,存儲在 C:\Users\[Username]\AppData\Roaming\[Random 8 digits]
中。
CryptoWall4會確認配置文件的完整性,包含執行惡意代碼所須要的所有信息。還會保證就算被中斷了,惡意程序仍是能繼續加密文件。這個文件有不少連續的區段,開頭是一個DWORD的值,來指定該區段的大小。
CryptoWall4在配置文件裏,存儲以下的信息:
文件加密進程完成後,最後三個文件會被寫到感染者機器的全部目錄下。
配置文件最終被壓縮(LZ壓縮算法,RtlCompressBuffer API,參數是2 COMPRESSION_FORMAT_LZNT1),而後爲寫入磁盤中。
一切順利的話,主線程會被建立,以前的線程被終止(RtlExitUserThread)
主線程從導入公鑰開始,這會把加密的公鑰的二進制的數據解析成能被Windows Crypto APIs識別的數據結構。CryptoWall4用的CryptDecodeObjectEx API來解析加密的公鑰。這以後,二進制數據被轉化爲一個CERT_PUBLIC_KEY_INFO
結構體。最後,新的數據結構被導入到Crypto APIs中,用的函數是CryptImportPublicKeyInfo,會返回一個xx句柄。而後會計算公鑰的MD5,這一步很是重要,由於它會被用來檢查受害者的文件是否已經被加密。
這以後,真正的加密進程啓動。對每一個邏輯分區,會有下面的檢查:
#!cpp
LPWSTR pngFilePath = new TCHAR[MAX_PATH];
// This produces something like "C:\HELP_YOUR_FILES.PNG"
ComposePngPath(driveName, "HELP_YOUR_FILES.PNG", pngFilePath, MAX_PATH);
if (!FileExists(pngFilePath) == TRUE) {
// Proceed with the encryption
// … … …
}
複製代碼
通常來講,若是磁盤的根目錄下含有HELP_YOUR_FILES.PNG
文件,這塊磁盤會被跳過。咱們不知道這是一個bug仍是它故意這麼作的。對每一個過濾掉的磁盤,一個新的加密線程會被啓動(線程主函數的參數是一個小的結構體,一部分是公鑰,一部分是磁盤名字符串的指針)
主線程會等待全部的加密進程完成。而後把那三個含有解密指示的文件放在兩個位置:一是開始菜單的啓動目錄,而是桌面。
最後,一個end announcement包會被建立併發給C&C server。配置文件被刪除,進程被終止(用的ZwTerminateProc)
Figure I
加密線程有兩個主要任務:首先它調用「DoFilesEncryption」將全部白名單以外的文件加密,最後它將HELP_YOUR_FILES.PNG
寫到根目錄裏。
DoFileEncryption會遍歷目標磁盤目錄下全部的文件夾和文件。
遇到子目錄,會檢查目錄名字,進行CRC32檢驗,看是否在白名單裏(這樣,「windows」,「system32」,「temp」這樣的文件夾被過濾掉)。並且檢查HELP_YOUR_FILES.PNG
是否存在,若是不存在,就繼續調用DoFileEncryption,參數是當前的目錄。
對文件的檢查作了兩次:擴展名和文件名。沒有在白名單裏面的,會調用EncryptFile來進行加密。
「EncryptFile」函數,是用來將目標文件加密的。「IsFileAlreadyEncrypted"函數會檢查目標文件是否已經被加密:讀取最開始的16字節,而後和公鑰的MD5值做比較。
這個時候,惡意程序會生成隨機的文件名和擴展名。下面是算法:(用的RtlRandomEx API得到每個可打印字符)
#!cpp
// Generate a random value
DWORD GenerateRandValue(int min, int max) {
if (min == max) return max;
// Get the random value
DWORD dwRandValue = RtlRandomEx(&g_qwStartTime.LowPart);
DWORD dwDelta = max - min + 1;
dwRandValue = (dwRandValue % dwDelta) + min;
return dwRandValue;
}
// Generate a Random unicode string
LPWSTR GenerateRandomUString(int minSize, int maxSize) {
DWORD dwStringSize = 0; // Generated string size
DWORD dwNumOfDigits = 0; // Number of number letters inside the string
LPWSTR lpRandString = NULL; // Random unicode string
// Generate the string size, and alloc buffer
dwStringSize = GenerateRandValue(minSize, maxSize);
lpRandString = new TCHAR[dwStringSize+1];
for (int i = 0; i < (int)dwStringSize; i++) {
DWORD dwLetter = 0; // Generated letter
dwLetter = GenerateRandValue(0, 1000);
dwLetter = (dwLetter % 26) + (DWORD)'a';
lpRandString[i] = (TCHAR)dwLetter;
}
// NULL-terminate the string
lpRandString[dwStringSize] = 0;
// Now insert the digits inside the string
DWORD dwUpperHalf = GenerateRandValue(dwStringSize / 2, dwStringSize);
dwNumOfDigits = GenerateRandValue(1, dwUpperHalf);
for (int i = 0; i < (int)dwNumOfDigits; i++) {
DWORD dwValue = 0, dwPos = 0; // Generated value and position
dwValue = GenerateRandValue(0, 9) + (DWORD)'0';
dwPos = GenerateRandValue(0, dwStringSize-1);
lpRandString[dwPos] = (TCHAR)dwValue;
}
return lpRandString;
}
// Generate a random file name starting from a file full path
BOOLEAN GenerateRandomFileName(LPWSTR lpFileFullPath, LPWSTR * lppNewFileFullPath,
LPWSTR * lppOrgFileName) {
LPWSTR lpRandFileName = NULL; // New random file name (without extension)
LPWSTR lpRandExt = NULL; // New random file extension
LPWSTR lpNewFileName = NULL; // The new file full name
DWORD dwSize = 0; // size of the new filename
// Check the arguments
if (!lpFileFullPath || !lppNewFileFullPath || !lppOrgFileName)
return FALSE;
// Generate the new file name (without extension)
lpRandFileName = GenerateRandomUString(5, 10);
// Generate the random file extension
lpRandExt = GenerateRandomUString(2,5);
// Combine the new file name and extension and generate the final new file path
// ....
dwSize = wcslen(lpRandFileName) + wcslen(lpRandExt) + 1;
lpNewFileName = new TCHAR[dwSize+1];
swprintf_s(lpNewFileName, dwSize+1, L"%s.%s", lpRandFileName, lpRandExt);
// ....
}
複製代碼
新的文件被建立,一個新的AES-CBC 256 key也經過調用CryptGenKey和CryptExportKey生成。這個32位的key會用來加密整個文件。
這時CryptoWall4採起了一個技巧:講生成的AES key用從C&C server獲得的RSA-2048公鑰加密,這樣就生成了一個256位的key,並且只能被攻擊者解密。
RSA公鑰的MD5值會寫到被加密的文件頭部16字節。而後CryptoWall4寫入256位的加密字串。原始文件的屬性和大小被寫入接下來的8字節。原始文件名被獲得的AES密鑰加密,而後和文件大小一塊兒,被寫入到新的加密文件中。
這以後,開始真正的文件內容加密。原始文件每次被讀512kb,存到一個大的數據塊裏。每一個數據庫會被加密密鑰進行AES-CBC 256加密。而後直接寫入到新文件裏(開頭四字節是塊的大小)
完成後,CryptoWall4佔用的全部資源被釋放。原始文件被刪除,這個過程比較有趣,見下面代碼:
#!cpp
// Move the new encrypted file name in the old original position, replacing the old one
bRetVal = MoveFileEx(newEncFileName, lpOrgFileName,
MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING);
if (!bRetVal)
// Delete the old file in the standard manner:
DeleteFile(lpOrgFileName);
else {
// Rename the original replaced file in the new random file name
bRetVal = MoveFileEx(lpOrgFileName, newEncFileName, MOVEFILE_REPLACE_EXISTING);
}
複製代碼
從僞代碼看得出來,存儲原始文件的磁盤區被特殊地重寫了,這樣能保證數據恢復起來很是困難。這是惡意程序的做者來保證高付款率的新奇有趣的方法。減小數據恢復的可能,這樣他們更好賺錢。下圖是加密後的文件的結構:
Figure J
這篇分析裏,咱們細緻分析了CryptoWall4。惡意程序沒有任何創新性的技術,可是仍是有幾個技術亮點。缺陷是感染進程須要和C2 server進行交互。若是防火牆或者IPS能捕獲它用來交互的數據包,感染進程就進行不下去了,由於它須要獲得公鑰才能加密受害者的文件。然而,一旦CryptoWall4加密了受害者的文件,不給攻擊者支付贖金,就沒有辦法恢復私鑰或者是解密文件。由於受害者的機器上得不到RSA私鑰。私鑰只存在於攻擊者手裏。
正如咱們的分析展現的,CryptoWall的開發者不斷在更新這款惡意軟件,保證它對用戶仍然是有效的。在威脅之上,企業須要認識到,攻擊者會不斷地改進這款惡意軟件。用多層次的自我保護方法,能幫助企業監測到CryptoWall,阻止其威脅。Talos也會繼續跟進CryptoWall的研究,找到更好的監測方法,而後爲用戶創建更好的防禦體系。沃恩強烈建議用戶和企業遵循安全規範,好比及時安裝系統補丁,收到未知的三方信息的時候要謹慎,還要保證有一個給力的備份。這些措施能減小這些惡意程序的威脅,並且被攻擊了也能有應急措施。
IOC DETAILS
這裏能夠下載IOCs blogs.cisco.com/wp-content/…
樣本:
3a73bb154506d8a9a3f4f658bac9a8b38d7590d296496e843503323d5f9b7801
複製代碼
類似樣本:
2d04d2a43e1d5a6920a806d8086da9c47f90e1cd25aa99b95af182ee9e1960b3
bf352825a70685039401abde5daf1712fd968d6eee233ea72393cbc6faffe5a2
299b298b433d1cc130f699e2b5c2d1cb3c7e5eb6dd8a5c494a8c5022eafa9223
複製代碼
威脅報告:
panacea.threatgrid.com/samples/d25…
C2 URL 列表
abelindia.com/1LaXd8.php
purposenowacademy.com/5_YQDI.php
mycampusjuice.com/z9r0qh.php
theGinGod.com/HS0ILJ.php
yahoosupportaustralia.com/8gX7hN.php
successafter60.com/iCqjno.php
alltimefacts.com/EiFSId.php
csscott.com/YuF59b.php
smfinternational.com/eRs70a.php
lexscheep.com/OIsSCj.php
successafter60.com/r_kfhH.php
posrednik-china.com/etdhIk.php
ks0407.com/VoZQ_j.php
stwholesaleinc.com/yL54uH.php
ainahanaudoula.com/GH09Dp.php
httthanglong.com/yzoLR7.php
myshop.lk/6872VF.php
parsimaj.com/60wEBT.php
kingalter.com/uVRfPv.php
shrisaisales.in/ZUQce4.php
cjforudesigns.com/E8B2gt.php
mabawamathare.org/WEAbCT.php
manisidhu.in/zJE0fD.php
adcconsulting.net/XEGeuI.php
frc-pr.com/dA91lI.php
localburialinsuranceinfo.com/zDJRc8.phpsmfinternational.com/AYNILr.php
複製代碼
附錄A
Excluded files CRC32 Checksums
8E87F076h = help_your_files.txt
0A73B295Ch = help_your_files.html
11A8ACA3h = help_your_files.png
88068F93h
775DBED4h
60479578h
7BD40679h = iconcache.db
48F43013h = thumbs.db
95ED794Ah
884F3F52h
7DAC63A1h
4208466h
0BA069E4Ch
0EC619E8Dh
9B0FD8B3h
Excluded extensions CRC32 Checksums
6B63B6F0h = exe
3DD3B336h = dll
0BB5EA5C1h = pif
592D276Fh = scr
9E07ED22h = sys
8F3272A8h = msi
0A45BDDC1h = no three letter ext
0B65F578Ah = no three letter ext
0EB59DA68h = msp
64B6C6E6h = com
0C863AEB6h = hta
0DEEBF8EEh = cpl
6FE79BB6h = msc
9F9C299Fh = bat
2F5C1CC0h = cmd
43F7F312h = scf
Excluded directories CRC32 Checksums
0E3E7859Bh = windows
0B5385CAh = temp
0ED4E242h
9608161Ch
41476BE7h = cache
0F5832EB4h
0D8601609h
1DF021B7h
0B91A5F78h = sample pictures
0A622138Ah = default pictures
3FF79651h = sample Music
62288CBBh = program files
224CD3A8h = program files (x86)
72D480B3h
0FF232B31h = games
0A33D086Ah = sample videos
78B7E09h = user account pictures
9BB5C0A7h = packages
24FA8EBDh
複製代碼