基於DNS通信的Powershell惡意軟體DNSMessenger分析
在這篇文章中,我將介紹通過分析DNSMessenger惡意軟體提取的一些有趣見解,通過分析結果,討論我使用的方法,並思考每個步驟的過程。
提取源代碼
此惡意軟體被發現在一個攜帶SHA-256 hash: 340795d1f2c2bdab1f2382188a7b5c838e0a79d3f059d2db9eb274b0205f6981的惡意Word文檔中。為了從宏中提取VBA源代碼,我使用了OLETools,安裝OLETools之後,只需運行命令olevba 就可以顯示出宏。
第1層 - VB和嵌入式PowerShell
這裡,你會發現馬上就遇到了難題,攻擊者做的一些事情讓腳本難以解開——作者嵌入了大量換行間距,廣泛分散內容,使重要代碼難以被發現。在使用OLETools顯示宏之後,你還需要進行大量滾動才能讀取整個腳本。更糟糕的是,如果你的終端具有有限的回滾緩衝區,則會隱藏部分腳本。
你還會注意到作者使用了無償字元串連接來破壞簡單的字元串簽名——這有助於攻擊者逃避靜態分析工具,尋找像"winmgmts:\.
ootcimv2"這樣的字元串,並可能會被以下內容拋出:
"w" & "" & "in" & "" & "mgm" & "" & "ts" & "" & ":" & "" & "" & "." & "
" & "" & "ootc" & "" & "imv" & "" & "2"
名為lStr的變數中還包含一個大型Base64字元串,該變數由PowerShell命令包裝,該命令對字元串進行解碼。
lStr = "powershell -ep bypass -C ""$data = [System.Convert]::FromBase64String("H4sIAAAAAAAEAO1da3PayNL+7l+hol ... many many more lines ...
這是lStr的部分快照:
讓我們解碼它並進一步進行研究。
解開Base64
下面是一個簡單的Python3腳本,用於解碼前面提到的Base64 blob。
解碼後,你會注意到生成的內容仍然無法讀取。我們可以通過幾種方式知曉其內容是GZIP格式的:最顯而易見的是,存儲在lStr中的VB字元串具有使用System.IO.Compression.GZipStream對象解壓縮解碼內容的命令;另一種識別方式是通過其魔數(magic number),即開始文件簽名(1F8B);我們還可以在Unix機器上使用file 命令來確定文件類型。
現在,我們將使用gunzip 解壓縮內容,這會創建一個具有相同名稱的解壓縮文件,打開解壓縮的文件將顯示模糊的PowerShell代碼(第2層),經過一些清理和重構後,腳本行為的一些有趣細節會變得更加明顯。
第2層 - Base64解碼和解壓縮的PowerShell
滾動解壓縮的腳本你會找到另一個Base64 blob,它充當下一階段的有效負載,我將其命名為第3層有效負載。
存儲有效負載
如果受害者具有PowerShell 3.0或更高版本,則該腳本將編碼的第3層有效負載存儲在名為kernel32.dll的備用數據流中,位於%PROGRAMDATA%Windows。惡意軟體作者通常濫用ADS來編寫隱藏數據,只需導航到目錄並列出其文件,你就無法找到有效負載。如果受害者具有較舊版本的PowerShell,則該腳本會在註冊表中為密鑰添加名為Path的新屬性,以存儲有效內容。如果用戶具有管理員許可權,有效內容將存儲在HKLM:SoftwareMicrosoftWindowsCurrentVersion中,否則,它將存儲在HKCU:SoftwareMicrosoftWindows中。
註冊表鍵
這些腳本在%PROGRAMDATA%Windows中創建了一個名為kernel32.vbs的備用數據流,並向其寫入代碼,該代碼可以從上一步中存儲的任何位置檢索並執行有效負載。
每次用戶登錄等待30分鐘後,攻擊者會修改運行註冊表項以執行kernel32.vbs。如果用戶具有管理員許可權,則目標密鑰為HKLM:SoftwareMicrosoftWindowsCurrentVersionRun, 否則,目標密鑰為HKCU:SoftwareMicrosoftWindowsCurrentVersionRun。
創建新的WMI對象
如果用戶具有管理員許可權,則腳本將創建永久WMI事件訂閱,該訂閱會監視用戶登錄,30分鐘之後執行編碼的有效負載。此時,該程序已展示出足夠的惡意,它會被SentinelOne檢測到並被定義為惡意行為。
以下是代碼。
首先,它會刪除現有的訂閱:
gwmi __eventFilter -namespace rootsubscription | Remove-WmiObject
gwmi CommandLineEventConsumer -Namespace rootsubscription | Remove-WmiObject
gwmi __filtertoconsumerbinding -Namespace rootsubscription | Remove-WmiObject
然後它會創建自己的訂閱。如果你有PowerShell 3.0或更高版本,邏輯會是這樣的:
$event_filter = Set-WmiInstance -Computername $env:COMPUTERNAME -Namespace 「rootsubscription」 -Class __EventFilter -Arguments @
$event_consumer = Set-WmiInstance -Computername $env:COMPUTERNAME -Namespace 「rootsubscription」 -Class CommandLineEventConsumer -Arguments @
Set-WmiInstance -Computername $env:COMPUTERNAME -Namespace 「rootsubscription」 -Class __FilterToConsumerBinding -Arguments @
定時任務
該腳本還會創建一個定時任務,以便在用戶登錄30分鐘後運行惡意軟體。用於啟動惡意軟體的方法僅略有不同,具體取決於用戶是否具有管理員許可權,如果用戶是非管理員,則使用wscript執行kernel32.vbs的內容,。否則,使用Invoke-Expression cmdlet。
第3層 - DNS查詢
現在我們已經討論了攻擊者實現惡意軟體持久性的各種方法,讓我們來看看下一個編碼的有效負載是由什麼造成的。
在Base64解碼和一些手動反混淆之後,你會注意到函數邏輯開頭的這段代碼,它包含了if之後的許多其他代碼。
[bool]$flag = $false;
$mutex = New-Object System.Threading.Mutex($true, "SourceFireSux", [ref] $flag);
if (!$flag) { exit; }
乍一看,似乎這個if之後的惡意代碼應該永遠不會執行,但由於構造System.Threading.Mutex的語義,靜態分析工具或弱動態分析系統可能無法實現將$flag神奇地變為true。從Source Fire的厚顏無恥來看,可能是加入了這種特定的逃避技術,以阻止Source Fire分析。
很明顯,代碼使用nslookup命令重複查詢DNS文本記錄,這些查詢的響應決定了程序的行為:
?"idle"會導致進程在3500到5400秒之間休眠,然後繼續
?"stop"會提示進程退出
?繼續
?使用Invoke-Expression執行查詢響應
由於這些領域不再具有活性,我們將不得不依賴先前Edmund Brumaghin和Colin Grady at Talos的數據,因為它們進行了原始分析。
第4層 - 命令與控制通信
為了響應DNS文本查詢,你必須發送另一個有效載荷,它包括一個gzip壓縮和Base64編碼的字元串,以及對第3層中dec函數的調用,用以解開它,所得的結果將傳遞給要執行的Invoke-Expression命令行。根據Talos的分析,這個有效負載重定向STDIN,STDOUT和STDERR,以便攻擊者可以讀取和寫入命令行處理器,有效負載執行更多DNS查詢命令,並與命令和控制伺服器建立通信通道。從這裡開始,攻擊者可以通過DNS文本查詢、響應發送要在受害者計算機的命令行,來解釋器上執行的命令,並接收這些命令的結果。
小結
這是一段較舊但有趣的惡意軟體分析,我將其分解為4個不同的層並描述了每個層的屬性,具體來說,是回顧了此惡意軟體所採用的混淆方式,以及它用於實現持久性的不同方法。
希望你能學到一些東西,謝謝閱讀!
※Facebook因劍橋分析數據泄露而受罰50萬英鎊
※2018 WCTF 圓滿落幕 日本 TokyoWesterns 戰隊摘得桂冠
TAG:嘶吼RoarTalk |