Skip to main content

Alternative Execution: A Macro Saga (part 7)

Thanks for returning to Alternative Execution: A Macro Saga! This will be the last post in this series (here are the links to part 1, part 2, part 3, part 4, part 5, and part 6), and as such we’ve left the best for last. Although we took a break for a few months, I double-checked that Microsoft hasn’t recently deployed new ActiveX Kill Bits for the COM class we’re going to look at. What’s interesting about this COM class is that not only is it silly that it’s available for embedding in MS Office, but its counterpart COM class is actually disabled.

Digging for Xmas Presents

In the last blog we used an automated approach to generate Word document test cases from a list of CLSIDs, detonate them and screenshot the results. We then followed this up with reviewing the screenshots in File Explorer to spot potential candidates for further analysis. Unfortunately, with the CLSID we’re going to look at this time around this approach was not very helpful as the test case’s screenshot looked just like test cases that weren’t interesting:

But how did we get to choosing the 978th test case? Well, after reviewing all of the test cases and not identifying many that both looked interesting and were likely to be weaponized, I decided to generate a list of the CLSIDs and their corresponding name with the following PowerShell:

$ctr = 1;
Get-Content '.\clsids.txt' |split-path -leaf | % {
    $clsid = "{$_}";

    $name = (Get-ItemProperty -Path $CLSID_KEY\$clsid -ErrorAction Ignore ).'(default)'
    echo "$ctr`t$clsid $name";
} | Out-File -FilePath '.\clsid_names.txt' 

I then performed a manual review to look for interesting-looking CLSIDs, and this is what stood out:

The reason why this stood out was because of this ActiveX Control, which cannot be embedded due to policy configuration:

The Microsoft Web Browser control corresponds to the CLSID 8856F961-340A-11D0-A96B-00C04FD705A2, which is banned from loading/rendering via Office Kill Bits:

Microsoft Web Browser Class:

This COM class has been around for quite a while. In effect it allows developers to easily embed Internet Explorer frames in applications, which is pretty obvious from its name. Let’s take a look at OleView to get some more context on this class:

Based on what OleView tells us, we can instantiate this Microsoft Web Browser via either Shell.Explorer or Shell.Explorer.2 ProgIDs, and that it’s categorized as an ActiveX Control.

But what about that CLSID we found in our output? Let’s take a look at Microsoft Web Browser Version 1 aka CLSID EAB22AC3-30C1-11CF-A7EB-0000C05BAE0B:

There are several properties that differ from the Microsoft Web Browser class, but it’s pretty obvious that they’re both implemented by C:\Windows\System32\ieframe.dll. It’s worth noting that the “Categories” section, in practice, doesn’t really mean very much as we’re about to see below.

Ever Need a Web Browser in Your Word Docs?

Due to the Microsoft Web Browser ActiveX Control being abused in the past, it’s been added to the Office Kill Bit list. We won’t go over historical abuses, but it’s worth noting that in 2016 the Grey Hat Hacker blog had exposed some of the event handlers that could be used to execute macros: For some reason, I hadn’t come across these details when originally doing this research, but it’s worth giving credit where credit is due. However, since this control is now blacklisted, we can’t use it.

But what about Microsoft Web Browser Version 1? Short version: Yes, we can totally use this to embed a browser in Office applications. To do so effectively, we’ll need to make use of what we’ve learned from previous blogs in this series. We’ll need to manually modify a DOCM file to load this class, identify any properties/parameters to include to ensure that the class loads correctly, and then identify event handlers to abuse via OleView.

Let’s do this from scratch. Starting with Microsoft Word, let’s embed an ActiveX Control in a document. In our case we’ll choose the RDPViewer Control because based on previous experience it produces a fairly clean activex1.xml file for editing:

After embedding the Control, let’s make our lives a little easier and change the Name property to something a little more appropriate. You’ll need to Right-Click the Control and select Properties:

We’ll change that from RDPViewer1 to IFrame:

Then we’ll save this as a DOCM file before jumping to a Linux terminal. I just used the default of Doc1.docm.

Once we’ve got it saved, we’ll hop into a Linux terminal to unpack, edit and repack the Word doc. First thing we’ll do is make a directory and unzip the DOCM file:

Then we’ll open the file word/activeX/activeX1.xml. Note that there’s a CLSID associated with the RDPViewer ActiveX Control. We’ll be modifying that:

We’ll remove that CLSID and replace it with the CLSID of EAB22AC3-30C1-11CF-A7EB-0000C05BAE0B for Microsoft Web Browser Version 1:

Now let’s zip it back up and try opening it:

Back in Windows, once you’ve got the document fully loaded (clicking: Enable Content / ActiveX / etc.) you’ll want to get the document into Design mode through the Developer tab. I’ll skip this step here, since we’ve done this in previous posts. Once in Design mode, you can right-click over your ActiveX Control to see that you’ve loaded the Microsoft Web Browser Version 1 Control!

Excellent! Now the next thing we’ll want to do is to Save this document. It doesn’t matter if you save over Doc1_modified.docm or create a new file. Saving causes Word to embed parameters for the control in the activeX1.xml file that will allow us to configure a webpage to load when the document is opened. In my case, I saved my file as Doc2.docm and returned to my console to extract the content:

Then we’ll open the word/activeX1/activeX1.xml file to see the new content. I’ve went ahead and highlighted the parameter that we’ll want to modify:

Let’s make this easy, and set its value to Google:

Now, let’s zip this up again:

And finally, let’s open it in Word to see if it worked:

So far so good. Let’s jump into Design Mode and resize that Control to make it fill the document a bit more. After we exit from Design Mode we should see:

Outstanding! You can use the embedded browser just like a normal browser to search and browse arbitrary sites. If you’ve recently needed to resize the control, you might want to save and reopen the doc file, as this control doesn’t play well immediately after being in design mode. Otherwise you may need to double-click elements within the control. Let’s try it out and search for something:

weaponizing the Browser Control:

Just like our other ActiveX Controls, we’ll want to open up this class in OleView to see what event handlers are available. We’ll look at DWebBrowserEvents first, and then DWebBrowserEvents2:



There are actually a LOT of event handlers that could be used with this browser control class. We’ll sample just a few from DWebBrowserEvents, since they look like the easiest to work with based on function prototypes:

WebBrowser.BeforeNavigate(string URL, int Flags, string TargetFrameName, Object& PostData, string Headers, [Out,In] Boolean& Cancel)
  • Event fires once a button/link has been clicked, but before the browser loads the subsequent page
WebBrowser.NavigateComplete(string URL)
  • Event fires once navigation to another page is fully complete
WebBrowser.StatusTextChange(string Text)
  • Event fires when the browser’s status text value changes (this fires fairly frequently, as modern web content trigger things such as XMLHTTPRequests, which will alter the browser’s status text)
WebBrowser.ProgressChange(int Progress, int ProgressMax)
  • Event fires during page load, while navigating to another web page
WebBrowser.TitleChange(string Text)
  • Event fires when a page’s title changes

At this point it’s relatively straight-forward for how to define the functions in VBA. The following is pretty basic code for triggering these event handlers:

It’s worth noting that it appears that in practice, you’d only want to make use of one event handler to trigger a malicious payload. However, if we try to test the above set of event handlers, what will happen is that only some of the event handlers will be triggered. This is likely due to making use of MsgBox as an interstitial for validating the triggering of our handlers, other events queuing and subsequently being discarded. That means that if you want to test the above handlers, you’ll probably want to comment out MsgBox for all of the handlers you’re not interested in testing.

If you tinker around on your end, you can stage your document to get any of these handlers to fire reliably at document detonation time, and they will definitely fire if you start navigating within the browser control. The most reliable handler to detonate at document open is the WebBrowser.StatusTextChange handler. It also happens to be the noisiest handler, and similar to some of the event handlers in the InkPicture and Sysmon controls, we’ll want to control the number of times a payload is run with a global variable. Here’s an example of the stripped-out VBA code, and the usage of a global variable to permit triggering of a payload only once:

Now we’ll save and reopen the document:



What should be pretty obvious at this point is that organizations who have not yet used Group Policy to disable Office Macros and ActiveX Controls are in a tough spot for preventing malicious macro execution. This series only scraped the surface for abusing ActiveX for macro execution, but nonetheless this is still a pretty serious issue.

In practice, we still see many organizations that are susceptible to attacks using these techniques. During our Red or Purple Team testing, we’ll frequently utilize these ActiveX controls, and if an advanced EDR is not installed or tuned to prevent ActiveX control loading it is absolutely possible to use these controls to launch payloads.

In the event that you’re hard-pressed to disable either Macros or ActiveX Controls in your environment, you should at least set Office Kill Bits for the ActiveX Controls we’ve analyzed throughout this series. The following is a running list of Controls and their GUIDs that you’ll want to disable:

InkPicture Control: 04A1E553-FE36-4FDE-865E-344194E69424

Windows Media Player Control: 6BF52A52-394A-11d3-B153-00C04F79FAA6

System Monitor Control: C4D2D8E0-D1DD-11CE-940F-008029004347

ActiveMovie Control: 05589FA1-C356-11CE-BF01-00AA0055595A

Windows Media Player Control (alternate): 22D6F312-B0F6-11D0-94AB-0080C74C7E95

WebBrowser Control: EAB22AC3-30C1-11CF-A7EB-0000C05BAE0B

Thanks again for following the series, and hopefully you’ve enjoyed following it as much as we have writing it!