Propagate – yet another follow-up (hypothetical clipboard execution version)

I’ve been thinking of tricking the Windows Clipboard to execute code inside other processes for a while now. It perhaps sounds crazy, but I thought there may be _some_ way to do it. The below is just a pure speculation based on some cursory analysis of 2 popular Windows APIs.

So dunno if it works. Still, I will just jot it down here, and if anyone has time and mood to test it in practice — feel free to do so, and share the results.

(Update: modexp created and described a POC here. nice work!)

Accessing clipboard via Windows API is very straightforward – refer to the MSDN for details. The only thing that matters is that data using typical data formats can be placed in a clipboard via SetClipboardData API. We could potentially use it to inject data to any process that deals with the clipboard, and somehow make it execute before the user changes the clipboard content? Possibly, who knows… Since I couldn’t come up with any trick to make it happen I looked at other clipboard functions. My attention was drawn to the concept of sharing non-standard clipboard data formats between processes. How does the clipboard works with these? The SetClipboardData is not enough – we need to use the OleSetClipboard API.

As far as I can tell, the implementation details of this API are not covered anywhere. At least I couldn’t find it. A very good high-level description of the OLE Clipboard can be found in the excerpts from the ‘Programming Windows with MFC’ book by Jeff Prosise that was published in 1999 (I don’t include links as the sites look dodgy). The Windows documentation simply says that the function ‘places a pointer to a specific data object onto the clipboard. This makes the data object accessible to the OleGetClipboard function.’.

This is a very curious statement. How can you place a pointer onto the clipboard?

I immediately started looking at these two APIs. It turns out that lots of applications use OleGetClipboard API to access the clipboard. If we use the OleSetClipboard and make it point to our IDataObject interface, some application will sooner or later retrieve the pointer in their own process space. It will then start calling the IDataObject methods to access the OLE Clipboard. Due to internal working of COM the interface pointer returned inside the remote process is not something we can directly control (as far as I can tell) and we can’t get a code execution this way.

Are there any other options?

I mentioned the internal working of OleSetClipboard and OleGetClipboard that are a bit of a mystery. And they are actually far more complex that I imagined. The simple bit is that Ole32 library that implements these functions registers a window class named ‘CLIPBRDWNDCLASS’. And surprise, surprise, when we run OleSetClipboard API the IDataObject data pointer we pass to this API… will be stored as a window property of this OLE clipboard window!

Sounds familiar?

Yup. You may recall the Propagate technique I described last year – it relies on a fact that certain windows properties can be modified by external programs. That is, if we can find the CLIPBRDWNDCLASS window, we can probably modify some of its clipboard-related properties?

After checking the code of the OleSetClipboard API we can quickly discover a number of interesting windows properties:

  • OLEClipPackgeOwner
  • OleClipProcessOwner
  • ClipboardDataObjectInterface
  • ClipboardRootDataObjectInterface
  • ClipboardDataObjectInterfaceMTA

If it has an ‘interface’ in the name, it is obviously _very_ interesting.

The ‘ClipboardDataObjectInterface’ property is where the IDataObject pointer is stored. What about the other two ‘interface’ properties? The ‘MTA’ in the name of one of them suggests ‘Multi Thread Apartment’, the ‘root’ one stores the source IDataObject – both seem to be used internally by CClipboardBroker::SetClipboard method only.

After browsing through the references to these properties I noticed that in some cases the pointer retrieved from the window is not being marshalled. As far as I can tell, such are the cases when:

  • the pointer retrieved via the GetProp API is used inside the same process that owns the CLIPBRDWNDCLASS window
  • when OleFlushClipboard is called
  • same thing happens when the OLE clipboard is destroyed. e.g. in reaction to CLIPBRDWNDCLASS window receiving a WM_DESTROYCLIPBOARD message.

I guess this part of code was written with an assumption that the message will never be received from an external application(?). The important bit is that during this clipboard destruction process, and before the RemoveProp API is called for all these ‘interface’ clipboard properties, the Release method of the IDataObject retrieved from the ClipboardDataObjectInterface (and other interfaces) will be called as well.

If the hypothesis is right,

  • changing the CLIPBRDWNDCLASS window property ‘ClipboardDataObjectInterface’ to point to a controlled memory region storing pointer to a dummy IDataObject object pointing in return to a malicious code (with the callback registered under Release method); other ‘interface’ properties can be used too
  • then sending a WM_DESTROYCLIPBOARD message to the CLIPBRDWNDCLASS window

should end up with a code execution…

Analyzing Word Documents via VBA/VBS

Analyzing malicious Word documents usually focuses on using 2 different types of tools. Some can analyze a file structure with the intention of extracting macros for further analysis. Others support dynamic analysis with the aim of extracting the run-time IOCs. Some sandboxes and reversers try to deobfuscate the VBA code as well, but it’s quite a tedious job if done manually. Luckily, this area of research is now so advanced that reversing tools supporting this mundane task exist, and sandboxes (e.g. Joe Sandbox) use this approach to trace the VBA code execution in a manner similar to a classic API Monitor for a while now.

There is one more approach, or should I say, one more additional avenue we can pursue – and it is by using the VBA code itself. I used it many times in the past and found it pretty useful.

Once you load a malicious document into Word and access the malicious VBA code (and provided there is no trickery that prevents or makes it harder), you can inject your own snippet of code into the analyzed document. You can then run it in a context of the active document structure. It’s super trivial – just add a new module, or paste the code in the same module where the malware code is present. While such injected code cannot answer all the reversing questions, sometimes it can help to extract, and also attribute certain values to specific objects (e.g. strings or blobs seen in the file can be hidden in some less-obvious property) – it’s an important association that otherwise may be much harder to establish.

For instance, the below snippet walks through all shapes in the document and prints out all URLs associated with them:

Dim S As Shape
Dim ish As InlineShape

For i = 1 To ActiveDocument.Shapes.Count
Set S = ActiveDocument.Shapes.Item(i)
Debug.Print i & " " & S.LinkFormat.Type
On Error Resume Next
Debug.Print S.LinkFormat.SourceFullName
Next i

For i = 1 To ActiveDocument.InlineShapes.Count
Set ish = ActiveDocument.InlineShapes.Item(i)
Debug.Print i & " " & ish.LinkFormat.Type
On Error Resume Next
Debug.Print ish.LinkFormat.SourceFullName
Next i

One can easily expand this snippet to add all the possible objects that include URL-related properties. And of course, we can go a step further and add enumeration of all major document objects and their properties in general (e.g. normal and custom or advanced properties, their names, values, including blobs of data that may be well hidden in some objects’ properties, etc.). As such, bypassing the UI limitations (plus, it is much faster to do it this way).

Apart from the specifically malicious items, such script can help with a possible actor attribution as well. Some of the file properties may be stored in different languages, or refer to a different language (names of the properties, text encodings, hidden texts, historical entries, etc.) – they are normally not that easy to discover using the UI, yet with the direct access to the document structure they become immediately available, once enumerated.

And we don’t need to use VBA all the time. Using VBS to open Office documents is a trick as old as Office itself. We can open malicious documents via the word application object and apply the data extraction code immediately. (note that it will obviously trigger the execution of malware in most cases).

Some examples of useful VBS code that can be re-purposed for this task are here, and here. Lots of old code doing this sort of stuff can be easily found via Google.

Of course, the technique can be used for all Office documents supporting automation / VBA.

Last, but not least – I mentioned in my older post that sometimes opening macro-malware  in Office 2003 version will help accessing data more than we can get through the eye-candy interface of the latest Office versions (newer versions remove access to some properties that you could still see in the Office 2003 via GUI). Using VBS we can run a quick scripted conversion to other formats so a malware could be opened and saved as .rtf, .doc, .docx, .txt in one a simple batch job. The resulting files can be made available to other tools for further processing.