VBA & Powershell Malware

Here, I am going to walk through something I made. This is an attack that carries characteristics that malware authors normally include. This particular one has a characteristic used by Red October. There are 3 parts to this attack, the Office document you send to the target, the persistence file and Invoke-Shellcode. Invoke-Shellcode and the persistence file need to be hosted.

Setting up the attack:

1. The macro code goes as an auto_open macro in a word or excel document.

2. Make sure you have Invoke-Shellcode and the persistence file hosted and accessible. I implemented a little trick to get around appliances that block downloads of specific files, such as exe’s and vbscripts. As you can see below, I have 2 hosted files in /var/www/, one is invoke-shellcode and the other is the persistence file.


If you open the persistence file, you get this:


Obviously, this isn’t a word document. This is a VBScript that will get us our shell. What I have done is put this in a file called “Payment.docx”. If you try to copy and paste the persist code into a new file using nano or vi, it won’t work as it throws formatting off. To get this to execute correctly, you MUST create the persist script in notepad, save it as SomeFileName.vbs and then move the script to your linux machine. Once on your linux machine, you can move the file into /var/www and rename it using “mv persist.vbs Payment.docx”. Doing this will keep the formatting.


When the macro downloads it, it comes into the network and onto the target machine as a Word document instead of an obvious VBScript, exe or something.


The macro downloads Payment.docx and drops it in the hidden “Default” user folder. Once on the machine, it renames Payment.docx to “cookie.vbs” and sets the file attribute to “hidden”:



(After setting “Show hidden files and folders”):


Now that we have a VBScript in a hidden folder with hidden attributes, the macro then creates a registry key to call the script on startup. What is different about this, is it doesn’t use the run registry keys (that’s too obvious, right?). Instead, it creates a key called “Load” in HKCU\Software\Microsoft\Windows NT\CurrentVersion


Now, when the user logs in, it executes cookie.vbs and shovels out another shell. Some may wonder why I am using VBScript when Powershell exists. After some testing, Powershell pops a black DOS prompt when executing the script on startup. To get around this, I wrapped the Powershell script in VBScript to get rid of the obvious DOS prompt.

-Matt Nelson (@enigma0x3)

6 thoughts on “VBA & Powershell Malware

  1. Hey –
    I’ve been reading through your psh posts, and they’re really interesting and crazy inventive. Since I know zero things about VB or PowerShell, some of it is hard to follow. (I have another macro I’ve been working with that gets caught by AV right away. When I obfuscate it, the macro fails to run. So I figure I might as well learn enough to rewrite the commands instead — which is what led me here.)

    I have a few questions on this one — it looks like you download Payment.docx and then immediately reference it in C:\Users\Default\AppData\Roaming\Microsoft\Windows\Cookies — but how did it get there? Would’t it be in their temp folder by default? Or is this where Windows puts files when they’re download via macro? (I suppose I could not be lazy and just test that one out myself.)

    And second, is there an easy way to make that location relative? For example, when I executed this on my own Windows 7 system, it failed — I’m assuming because that folder is located in D:\. I looked around and it seems people are pretty passionate about how to create relative paths in a macro and it gets complicated. But in another one of your macro examples, you seem to handle it fairly easily (almost too easily….) using Environ. Is there any reason why I couldn’t reuse that here? e.g.

    (reusing code from the WordPersistance macro):

    FileNum = FreeFile
    Path = Environ(“ALLUSERSPROFILE”) + “\AppData\Roaming\Microsoft\Windows\Cookies\”
    Open Path + “Payment.docx” For Binary Access Write As #FileNum
    Put #FileNum, 1, FileData
    Close #FileNum
    OldFileName = “Payment.docx”
    NewFileName = “cookie.vbs”
    Name Path & OldFileName As Path & NewFileName
    SetAttr Path + “cookie.vbs”, vbHidden

    Third: In general, would it be worth it to encode the PS command in base64, e.g.

    Set objProcess = GetObject(“winmgmts:\\” & strComputer & “\root\cimv2:Win32_Process”)
    objProcess.Create “powershell.exe -EncodedCommand blahblahblahbase64blahblahblah=”, Null, objConfig, intProcessID
    End Function

    OR would it cause a conflict?
    (Also the same thing in the persist file.)
    (And I’m not sure if I got the boundaries right on that one.)
    (And I included -ExecutionPolicy Bypass in the base64 — which I assume is redundant, but shouldn’t break it(?))

    Since I’m not familiar with PS or VBS, I don’t know if this would cause a massive hiccup in execution. It’s not necessarily for obfuscation, but it seems like it would be safer to minimize how often “meterpreter” appears in files. I know our IT dept. at work does periodic scans of file content to check for keywords.

    • Hey Caitlin,
      First off, thanks for taking interest in my posts! To answer your first question, I am going to refer to the macro associated with this particular attack, which can be located here: https://github.com/enigma0x3/VBAPowershellMalware/blob/master/OfficeMacro

      If you take a look at the Function “Download”, it used WHTTP.Open and WHTTP.Send to grab the file from a server you control and it then drops it in the specified location. This happens right under the “FileNum = FreeFile” line.

      For your second question, you can definitely use “Environ” to make the download path dynamic. I made it static in my example for the sake of simplicity (so I could delete the file over and over again when testing on different machines during the creation of this). This would definitely work for you.

      For your third question, I would recommend encoding the PS command if you are going to use this in a live pentest. The only benefit to encoding is to mask your C2 address, which is only useful during a pentest. If that is the case, you can definitely encode it.


  2. (I honestly figured I should say something because if you have any kind of analytics installed, having me click all kinds of links at odd hours all over your blog was probably creeping you out.)

    And ah – ok, I was totally grouping the commands incorrectly as I read through it. That makes sense, then.

    I’ll definitely be testing a few of these out. I’m largely curious about the social engineering tactics to get someone to click ‘allow.’ The strategies I’ve seen out there so far seem fairly easy to screen.

    I’m also interested in the AV aspect. I’m wondering if yours get past so easily because they use more common commands that, if flagged by AV, would cause too many false positives? That’s what initially attracted me to this example.

    I mean, the other one I was working with is maybe more “sophisticated” but 1) I can’t take it anywhere near an AV-enabled system without it getting quarantined, which is annoying when I forget to disable Auto-Save, and 2) the code seems pretty inflexible. Or at least it is to me – I’m sure someone with better VBA comprehension could get further along with it. (It’s auto-generated as part of a pentesting software suite.)

    BASICALLY – I’m totally into all these posts, they’re by far some of the most ingenuitive exploits I’ve seen, and please don’t get creeped out by my obsessive clicking between posts.

    • It gets past AV easily because its using an exe that is already known and trusted. The payload is downloaded and executed in memory, so AV doesn’t see it.

      Feel free to click away! You can also hit me up on twitter (@enigma0x3) if you have additional questions or input if that is easier for you.


  3. Right! What I mean is that I couldn’t even get it to the point of saving the macro in an Office document, let alone executing it. Even after I deleted the entire byte array, removed all references to the shellcode, etc. — AV flagged the files. It had nothing to do with the payload, so I assume it was flagging the actual VBA commands, which surprised me somewhat. Like, maybe 10 years ago they’d be that strict, but not anymore.

    Oh, you kids and your tweets. But thanks!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s