Rundll32.exe bomb

Update

Turns out @sixtyvividtails has already discovered the very same issue via a minimalist PE file back in June. Touche!

Old Post

This is a silly example of a basic mistake leading to a funny discovery…

When I was experimenting with the imported phantom DLLs I accidentally placed a dummy 64-bit DLL in a place of a 32-bit phantom DLL called WDSUTIL.dll that was imported by the 32-bit uxlib.dll. I then attempted to enforce loading of uxlib.dll with a 32-bit version of rundll32.exe by referencing its full path c:\WINDOWS\SysWOW64\rundll32.exe:

c:\windows\syswow64\rundll32 uxlib.dll bar

Turns out that loading of the 32-bit library with an import that points to DLL that is actually 64-bit creates a chain of never-ending executions of the very same command line!

What happens is that when the 32-bit DLL (uxlib.dll) is loaded, the importing fails on the 64-bit phantomDLL (WDSUTIL.dll) which leads rundll32.exe to receive the ERROR_BAD_EXE_FORMAT error from the loading attempt, which in turn leads it to follow the internal _TryWow64Scenario path in its code, which… literally means creating a new SysWow64’s rundll32.exe process with the very same command line passed to it – aka repeating the cycle that we have started this test with!

This leads to a cascade of new rundll32.exe processes being spawn, and it’s similar in nature to regsvr32.exe bomb:

Yes, it is a dolbin!

1 little known secret of regsvr32.exe, take three

In the past I wrote a few times about the side-effect of having 2 binaries named the same way and residing in respective System32 and SysWOW64 directories.

Regsvr32.exe is not different. If you run a 32-bit Regsvr32.exe with a command line argument being a path to a 64-bit DLL or OCX, it will spawn its 64-bit twin Regsvr32.exe to handle the request:

I am happy to report that regsvr32.exe is using GetSystemDirectoryW and GetSystemWow64Directory2W APIs instead of relying on environmental variables to build the paths for respective binaries, so there is definitely less chances for lolbinish abuse.

Now, this is not the little known secret yet.

The secret is this:

When you force the regsvr32.exe for one architecture to spawn the other regsvr32.exe with the other architecture, the command line argument that you started with will be passed to children regsvr32.exe process, in full.

Do you see where it is going?

Based on the idea from the post number one in this series, we now know we can pass a list of library names (limit is 256) to regsvr32.exe and it will load them all one by one. What if we passed a command line argument that interleaves 32-bit and 64-bit libraries?

The result will be a never-ending, chain reaction-like tree of interleaving regsvr32.exe processes executed one bye one!

Do you want to test it at home?

Warning: do not try this at home!

regsvr32.exe c:\WINDOWS\system32\hhctrl.ocx c:\WINDOWS\syswow64\hhctrl.ocx c:\WINDOWS\sysnative\hhctrl.ocx

As far as I can tell this is the first documented case where c:\WINDOWS\system32\, c:\WINDOWS\syswow64\, and c:\WINDOWS\sysnative\ have ever been used together in a command line of any program.

And yes, you can add /s parameter to it too, that is – if you don’t want any control over it (/s stands for silent and is disabling any GUI feedback from regsvr32.exe)!

regsvr32.exe /s c:\WINDOWS\system32\hhctrl.ocx c:\WINDOWS\syswow64\hhctrl.ocx c:\WINDOWS\sysnative\hhctrl.ocx

Be warned tough! This is a regsvr32.exe bomb! And it’s a possible DOLBIN!