Beyond good ol’ Run key, Part 6

The subject of today’s post is an obscure autorun mechanism that targets specifically users of applications written in Visual Basic. The trick forces VB applications to load a specific DLL into the context of the application. Let me repeat it – this particular autorun mechanism will trigger anytime someone runs an application written in Visual Basic so it’s sort of a random autorun which I believe is still very reliable – after all, VB applications are very popular and many people use them on daily basis.

If you ever ‘procmonned’ any VB application you might have noticed that at some stage it is checking the content of the following registry key:

  • HKLM\SOFTWARE\Microsoft\VBA\Monitors

vbappenummonitorskey

The VB app (or, more precisely MSVBVM60 DLL) enumerates this registry node (if it exists) looking for subkeys which in turn are later queried for a few specific values.

The mechanism appears to be designed for debugging/monitoring purposes because one of the values the VB apps query for is called EnableEventMonitor. The registry keys  used by this mechanism point to Event Monitoring DLLs that can be loaded into the process space of the VB application. The loading happens via CoCreateInstance API utilizing  some unknown interface referenced via GUID DE32EFB0-4A56-11D1-AA89-00008612DCF1.

Knowing what expected values are allows us to craft a registry file that will help us to add our own VB monitor:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VBA\Monitors\TestMonitor]
"EnableEventMonitor"=dword:00000001
"CLSID"="foobar"

[HKEY_CLASSES_ROOT\foobar]

[HKEY_CLASSES_ROOT\foobar\Clsid]
@="{00000000-0000-0000-0000-FFFFFFFFFFFF}"

[HKEY_CLASSES_ROOT\CLSID\{00000000-0000-0000-0000-FFFFFFFFFFFF}\InprocServer32]
"ThreadingModel"="Apartment"
@="<your path>\\test.dll"

Just to quickly walk through it, we are adding the TestMonitor entry under:

  • HKLM\SOFTWARE\Microsoft\VBA\Monitors

We then enable it by setting the value of EnableEventMonitor to 1.

After that we are linking it to the HKCR entry that in turn links it to the actual DLL via the CLSID value (it’s actually a bit misleading name for the value since this particular CLSID doesn’t need to look like a regular GUID).

As a result CLSID entry under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VBA\Monitors\TestMonitor (foobar in our case) points to the entry under HKCR (HKCR\foobar in our case), and that entry points to the typical COM server entry via its Default value (pointing in our case to 00000000-0000-0000-0000-FFFFFFFFFFFF). And of course, the HKEY_CLASSES_ROOT\CLSID\{00000000-0000-0000-0000-FFFFFFFFFFFF}\InprocServer32 points to our DLL.

I hope you are confused 🙂

After we add the registry entries all we need to do now is dropping our test dll file in the <your path>\\test.dll location.

Running a simple ‘Hello World’ application written in VB loads the specified dll – in my case the test DLL sends notifications to the debugger and these can be intercepted with a Debug View:

vbamonitorsThe procmon log is much richer this time:

eventmonitoradded

Notably, the DLL doesn’t need to implement any COM functionality. CoCreateInstance will load it as a DLL library, and then query for the interface; it is not implemented, but the code execution is achieved. One could obviously add DLL exports to handle the COM requests and maybe even implement the mystery interface.

Last, but not least. Instead of EnableEventMonitor value set to 1 (which is a global setting), one can use Environment variable  called VBAEV_<name of the monitor> and set it prior to running VB program in the environment of that targeted VB application.

In our case it would be:

set VBAEV_TestMonitor=1
helloworld.exe

launched from a command line. This would make the VB app launch with the inherited environment from the command line processor in which we set the VBAEV_TestMonitor to 1. This will ensure we load a DLL only to the helloworld.exe, but not other VB applications.

Update 2016

It turns our that I have not explored all the possibilities here – the very same mechanism is used by the Visual Basic Engine libraries (VBE6.dll, VBE7.dll) that are responsible for running Visual Basic for Applications code (yes, the Office macros). Not a big surprise, but worth documenting and only shows how close the source code of these VB products must be…

So, as long as the system’s user is working with the macrodocuments, or using VBA in Outlook, the malware could leverage this key as a persistence mechanism.

Some forensic artifacts are just like this: sometimes Visual, often Basic, and… on occasion – Iconic

Visual Basic is quite popular amongst malware writers. It’s simple, it allows to hide the ‘juicy’ code under the layer of p-code, and is often used as a relatively cheap wrapper as many routines for loading PE files inline (RunPE) are easily available online for copy&paste. It is also not that well-documented despite many years of research on its internals. In today’s post I will describe one ‘feature’ of VB that makes it for a minor, yet still interesting (and potentially helpful in some cases) forensic artifact.

Let’s begin from the end. Have you ever seen any %TEMP%\~DF*.tmp files on the investigated system? The chances are – you did. These temporary files are created by OLEAUT32 library; this and other OLE2 components are essential to run many Windows applications and Visual Basic happens to rely on them a lot. When executed, the Visual Basic app loads the form that has an icon associated with it. It turns out, at some stage Visual basic calls an OleLoadPictureEx API function function that is responsible for manipulating the application’s icon… and, indirectly, is also creating these temporary OLE2 files in a form of:

  • %TEMP%\~DF4BA7.tmp
  • %TEMP%\~DFBBA3.tmp
  • %TEMP%\~DFCBD8.tmp
  • etc.

If you want to confirm it on your own, you can try the following:

  • Clean the %TEMP% directory
  • Load a sample Visual Basic Application into OllyDBg
  • Make a breaakpoint on OleLoadPictureEx (Ctrl+G, then paste ‘OleLoadPictureEx’ there and hit Enter)
  • Run until the breakpoint hits (F9)
  • Check the %TEMP% directory – still nothing there
  • Now Execute till return (CTRL+F9)
  • Check %TEMP% directory again
  • There you have it… see below, before (breakpoint on OleLoadPictureEx hits) and after (after the function completes the execution).

vb_temp_files

The temporary files are deleted after the program terminates, but sometimes they can be forensically recovered, or simply still present in the folder if e.g. malware or system crashed.

The structure of the file is OLE2 compound and storage file and can be previewed with OffVis – The Microsoft Office Visualisation Tool (Link is a direct download):

vb_ole2_internals

The actual content usually starts at offset 0x600 if it is a non-icon (i.e. a file in an .ico format), and 0x800 if it is an icon; I don’t know the reason why the difference – I assume that for .ico files the area between 0x600-0x7FF contains some internal data used for handling .ico files (if you know what’s there, please let me know).

The screenshot above highlights the beginning of the icon (00 00 01 00); One can easily extract it and view it using any image viewer, even Windows Explorer itself. In our case, it’s:

~DF55EB.tmp

Not surprisingly, the very same icon can be found inside the resources of the executable:

resources

The conclusion?

If you come across %TEMP%\~DF*.tmp file(s), you can attempt to:

  • View their content
  • If it contains an .ico resource, it could be a trace of Visual Basic application running on the system
  • In such case you can extract the icon and recognize if it’s sth dodgy e.g. one of the infamous fake Acrobat Reader, Microsoft Word, etc. icons used by malware all over the place and if you are lucky and it stands out, use the file timestamps in your analysis, especially if main executable is no longer on the system; in a way, it’s a weak way of confirming some VB app was possibly executed on the system

Word of caution:

  • It’s OleLoadPictureEx that creates the file, not Visual Basic alone – the function is used widely by non Visual Basic applications as well and it’s common to find the content of the ~DF*.tmp files to contain e.g. PNG files; ~DT files should be seen as containers storing the stream of data related to some graphics. If these are .ico files, then high chances of it begin associated with some Visual Basic application, if not, it may still be useful as it may contain traces of pictures processed on a computer using an application that happens to rely on OleLoadPictureEx to manipulate the graphics.