Beyond good ol’ Run key, Part 124

Most of persistence tricks rely on a modification of Registry, adding files, dropping phantom DLLs, lolbins, etc. Today (for a change), I will describe a trick that is a) a close relative of Office macros & b) introduces yet another file format that security product may need to learn to scan.

The target is Ultraedit – pretty much my favorite editor.

It supports a lot of different mechanisms that could be used for persistence and trickery, but I will describe only one which meets the criteria I specified above.

The editor supports a mechanism of macros. Macros can be easily edited using a dedicated Macro panel. While the commands are primarily editing-related, there is one command that is interesting to us – RunTool:

The macro on the screenshot is called ‘foo’ and runs a tool called ‘notepad’. What is the ‘notepad’ tool you may ask? It is actually not the Windows Notepad, but a reference to a task one can set up in UE Tool Configuration panel:

Not surprisingly, I set it up to actually execute c:\windows\system32\notepad.exe.

Okay, now we have a macro that runs our task called ‘notepad’ and that task in turn runs the actual Windows Notepad.

We can save our macro to a .mac file which is using a proprietary format:

And now we are ready for a final piece of a puzzle…

UE allows us to automatically set macros to run during startup (via command line):

as well as during load and save file events (works in GUI):

With all that in place… Notepad will be running a lot… perhaps as a celebration of these events.

Feels like Office macros – tick. Proprietary file format – tock.

Run DLL – Walk this way

The role of Rundll32 is to load DLLs.

On a 32-bit OS it is a very straightforward task, but when you mix architectures interesting things happen. One of a side-effects of having more than one architecture on the same box is that Windows On Windows (WOW) layer gets involved so that we can run 32- and 64- bit code at the same time.

This makes life of rundll32 developer harder. There are two version of rundll32 on a 64-bit Windows system: one inside system32 directory, and another one – in SysWOW64. But rundll32 users don’t want to known about these versions, couldn’t care less about multiple architectures, and when they run a command they simply expect their library to be loaded, and its function called.

When 32-bit rundll32.exe is called to load a 64-bit DLL, 32-bit rundll32.exe will spawn 64-bit version of rundll32.exe and that 64-bit DLL will be loaded there.

The very same happens when a 64-bit rundll32.exe is used to load a 32-bit library.

It’s like that… and that’s the way it is.

This is a well-known stuff and you are probably wondering where I am going with it.

Today most of applications are 64-bit, so one could exploit the rundll32.exe behavior I described in various ways:

Scenario 1

Set up a persistence Run key (or use any other common startup method) to point to rundll32.exe <name of a 32-bit library>

This will keep the persistence entry clean (points to a signed 64-bit rundl32.exe, even if full path is not explicitly set in a startup entry to point to c:\windows\system32\rundll32.exe), and will ensure cascading execution of a 32-bit rundll32.exe that will load the given 32-bit DLL (possibly malicious).

Scenario 2

Same as before, set up a persistence in any way you like, just pointing it to a rundll32.exe and using a file name of an existing, clean 32-bit DLL, and then place a malicious rundll32.exe under c:\windows\SysWOW64.

This will launch the malicious 32-bit rundll32.exe.