Skip to main content

Alternative Execution: A Macro Saga (part 6)

Over the past five blogs (part 1, part 2, part 3, part 4, part 5) we’ve covered utilizing event handlers for ActiveX controls to obtain code execution in Office documents, policy-based options for disabling three ActiveX controls supported for insertion by Office UIs, and started the process to discover arbitrary COM classes that can be inserted into Office documents that are not available through the Office UI.

In the last post we discussed targeting 1059 COM classes (by CLSID) for insertion into Office documents. Most Windows desktop operating systems will have 5000+ CLSIDs intended for defining COM classes. When you spend the time to dig through these CLSIDs you’ll find that there are far fewer than 5000 that can actually be instantiated, and to be completely fair 1059 classes is a fairly small survey. However, in my testing I identified two new COM classes that can be used as ActiveX controls in Office documents that also have usable event handlers for code execution!

Searching for Easter Eggs

In the last blog I talked about generating screenshots from sample execution so that I could visually inspect ActiveX control loading in Word. While skimming through these samples back in January my eyes almost deceived me in what I saw.

One of these things is not like the others! Notice the difference?

I almost missed that one too. So that Doc83.docm file corresponds to the GUID 05589FA1-C356-11CE-BF01-00AA0055595A. Looking this fellow up in OleView tells us this:

What is an activemovie control?

Good luck finding information on it. I more or less gave up trying to find documentation on Microsoft’s main site, and ultimately found some details on some unnamed website out of Bulgaria (http://193.68.19.127/install/VS%206%20%20%20%200/cd2/SAMPLES/VC98/SDK/GRAPHICS/DIRECTANIMATION/help/ds/dssd0012.htm):

This article describes how Microsoft® Visual Basic® applications can use the ActiveMovie Control. The ActiveMovie Control is a high-level interface that meets the needs of most multimedia application developers. Additional lower-level interfaces are also available to Visual Basic programmers.

Interestingly enough, it appears that there are some details on Wikipedia (https://en.wikipedia.org/wiki/ActiveMovie):

ActiveMovie was the immediate ancestor of Windows Media Player 6.x, and was a streaming media technology now known as DirectShow, developed by Microsoft to replace Video for Windows. ActiveMovie allows users to view media streams, whether distributed via the Internet, an intranet or CD-ROMs.

Originally announced in March 1996,[1] the first version was released in May 1996 bundled with the beta version of Internet Explorer 3.0.[2]

We can check OleView to determine which DLL is responsible for this COM class:

And checking the DLL properties we find that it’s called Windows Media Player Extension:

So, it looks like this may be some piece of Microsoft technology that’s been around for 26 years, and still supported in Windows 10. What’s also a bit funny is searching on this control yields this (https://www.exploit-db.com/exploits/19928):

source: https://www.securityfocus.com/bid/1221/info
The Microsoft Active Movie Control (a multimedia ActiveX control) will download files of any type specified in the control parameters in an HTML document, regardless of whether or not they are a valid media type. A hostile website, HTML email or HTML newsgroup post could therefore write executables and other potentially harmful content to target machines, which will be stored with their known filenames in the default Windows Temp directory. 
This vulnerability could be used in conjunction with other exploits to run arbitrary code on the target machine(s).
The following script assumes a default Windows Temp folder of c:\windows\temp
<OBJECT classid=clsid:05589FA1-C356-11CE-BF01-00AA0055595A height=1 style="DISPLAY: none" width=1>
<PARAM NAME="Filename" VALUE="C:\WINDOWS\TEMP\MALWARE.exe">

The CVE for this issue is 2000-0400, which is a 20 year old bug with this component. As much as we could hope a bug similar to this issue is still present, it appears that either the bug has been patched (likely), or the strange behavior I noticed with this control gets in the way of making use of it.

Examining Our Sample

After opening this sample, the first thing I did was switch to Design Mode and right click the control to verify that it was loading the ActiveMovieControl, and was immediately confused.

As you can see above, it appears to be loading a Windows Media Player control, which seems odd. If we save this file elsewhere and unpack it, what does it contain?

Interesting, that GUID corresponds to WMPlayer.OCX.7, the COM class for Windows Media Player. It appears that once the Word document has been opened that our ActiveMovie control was converted to a Windows Media Player control.

ActiveMovie Control Exploitation

As it turns out, despite that ActiveMovieControl loads Windows Media Player, we can still take advantage of the ActiveMovieControl event handlers to trigger code execution! Take a look at the following event handlers associated with this class:

The ones that I’ve validated can be used for automatic execution are:

ActiveMovie.StateChange()
  • Event fires when the control’s state changes. Appears not to fire when a video plays, but will fire at pause and completion.
ActiveMovie.OpenComplete()
  • Event fires when a video has been loaded and starts playing.
ActiveMovie.Error()
  • Event fires when an error condition occurs, such as an invalid video URL.

Instead of just jumping in and modifying the Doc83.docm file to make use of these event handlers, I’ll save us some time troubleshooting. As it turns out, when you open that Doc83.docm file Word will convert the ActiveX object to a Windows Media Player (WMP) object, and this persists after a save. Furthermore, when Word decides to convert your ActiveMovie control to a WMP control, whatever you had originally named the ActiveMovie control is no longer valid. Specifically, if you have no other WMP controls in your document, then this new one will be named WindowsMediaPlayer1. So we have 2 options: either start over with a new document, or just use Doc83.docm. For the sake of clarity, we’ll just create a new document!

So what we’ll do is create the new Word doc, insert a WMP control, and rename it (for the full steps on how to do this, feel free to refer to my blog on Windows Media Player usage):

You can see above we’ve entered some very basic event handler test cases that just open a MessageBox for each event handler. As it turns out, the ActiveMovie.OpenComplete() handler will only fire if there is a valid video file referenced. If you make use of an invalid video file both ActiveMovie.Error() and ActiveMovie.StateChange() will fire. For our first test we’ll trigger both ActiveMovie.Error() and ActiveMovie.StateChange() in one case, then we’ll go back and trigger ActiveMovie.OpenComplete().

I’ll save this file to my VM’s shared drive as ActiveMovie_test.docm, and then unpack the file:

Then we’ll open the word/activeX/activeX1.xml file.

We’ll replace the CLSID 6BF52A52-394A-11D3-B153-00C04F79FAA6 corresponding to Windows Media Player with the CLSID for ActiveMovie. Also, we didn’t really look too closely at all this XML in the last blog, but if you look at instances of ax:name=”<NAME>” you’ll notice these appear to initialization parameters. As it turns out, many ActiveX controls don’t need the full list of initialization parameters, and also these specific parameters in question are applicable to Windows Media Player, but may not be for ActiveMovie. Taking a look at the definition for one of the ActiveMovie classes, we see the following parameters:

The interesting one, FileName, has been highlighted above. As it turns out, this is the only parameter needed to load a video file with the ActiveMovie control.

Back to our word/activeX/activeX1.xml file. What we’ll do next is remove ALL of the parameters and replacing them with one single parameter to trigger our ActiveMovie.Error()and ActiveMovie.StateChange()event handlers. Then afterward we’ll modify the parameter we’ve added to trigger only the ActiveMovie.OpenComplete()handler.

We can see in the above screenshot that we’ve updated the classid parameter with the ActiveMovie Control CLSID, and we’ve remove all ActiveX parameters, replacing with just one: FileName. And in this case we’ve set the FileName parameter to point at Google, which will result in an error because there’s no video at that URL.

Now we’ll zip up the file contents, naming it ActiveMovie_test1.docm:

And we’ll detonate it in our testing VM (Windows 10, Office 2016:

We’re first prompted to click “Enable Content”, and once we do, we receive a popup:

The ActiveMovie.Error()event handler was triggered first as the control attempts to load a video from a URL that doesn’t contain one. After we click “OK” we see the following:

We see that the ActiveMovie.StateChange()event handler fires, because the media control has entered a stopped/completed state. Obviously, if we were an attacker, we wouldn’t need to make use of both of these event handlers. But this combined demo has been helpful to demonstrate how to trigger either event handler by creating an error condition. The ActiveMovie.StateChange()event handler will fire when a video has completed playing as well, so you could alternatively supply a short video and trigger once it’s complete.

Now let’s modify the FileName parameter to induce the ActiveMovie.OpenComplete() event handler to fire! To do this, we’ll return to the word/activeX/activeX1.xml file and modify it to the following:

We’ve chosen a simple MP4 video that can be discovered by a Google search. Realistically, as long as it’s a raw video file, just about anything should work. Now we’ll zip up and detonate. I’ll skip the zip screenshot and jump directly to detonation. Again, we’re prompted to “Enable Content”:

Once we click the button the video begins to play and we see the following message box demonstrating our event handler has fired:

Excellent!

BONUS TIME!

I’d like to give away a freebie with this blog that’s up to the reader to experiment with. It turns out that the DLL responsible for the ActiveMovie control (e.g. wmpdxm.dll)  also hosts another variation of the Windows Media Player control, accessible via a different CLSID. When loading this specific CLSID you can reuse the event handlers for the typical Windows Media Player control to obtain code execution! I’ll include that CLSID in the list after the Wrap-Up for remediation items, but here’s a quick screenshot:

Wrap-Up

Well, this has been fun! In this post we demonstrated how to take advantage of a specific COM class to obtain execution via an ActiveX control that can’t be embedded via the Office UI. Specifically, we’ve demonstrated how to utilize the ActiveMovie control to achieve this goal. Although we had to take extra steps to modify unpacked DOCM content, all of the manual steps we’ve taken can be automated quite easily with PowerShell or Python.

Since we want to make sure that we’re updating our Office ActiveX Kill Bits, make sure that you apply them for the following 2 controls:

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

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

And for the next blog in this series (quite possibly the last, but I reserve the right to have some follow-up episodes) we’ll take a look at loading yet another ActiveX control unavailable through the Office UI. This one will be a funny one, and a cautionary tale about how Microsoft tried to stop a COM class from loading.