There have been number of blog posts and presentations on Application Compatibility Shims in the past [See References at End]. Application Compatibility is a framework to resolve issues with older applications; however, it has additional use cases that are interesting. For example, EMET is implemented using shims[1,2]. Please see the Reference section below for additional reading and resources. In short, this document will focus on the following tactics: injecting shellcode via In-Memory patches and injecting a DLL into a 32bit process, and lastly, detection and shim artifacts will be discussed. An In-Memory patch has this advantage over backdooring an executable: it this preserves the signature and integrity checks. This technique can also bypass some Application Whitelisting deployments. AppLocker, for example, would allow the startup of a trusted application, and then an In-Memory patch could be applied to alter the application.
The shim infrastructure is built into Windows PE loader. Shims can be applied to a process during startup. There is a two-step process that I will refer to as “Match and Patch”. The Match process checks the registry on process create and looks for a relevant entry. If an entry is found, the Match process further checks the associated .sdb file for additional attributes, version number for example. Based on my understanding, the sdb does need to be present on disk. I have not encountered any tactics to load an sdb file from memory or remotely. When the Shim Databases are installed they are registered in the registry at the following two locations:
These entries can be created manually, using sdb-explorer.exe, or using the built-in tool sdbinst.exe. If you use sdbinst.exe there will also be an entry created in the Add/Remove Programs section. In order to install a shim, you need local administrator privileges.
An example of a shim entry would look like this:
Once the shim has been installed, it will be triggered upon each execution of that application. Remember, there is further validation of the executable inside of the sdb file. For example, matching a specific version or binary pattern. I have not found a way to apply a shim when a DLL is loaded, or apply a shim to an already running process. These registry keys plus the actual sdb file are the indicators for the Blue Team that a shim is present.
Shim Creation and Detonation:
There are two tools we can use to create shims. First, the Microsoft provided Application Compatibility Toolkit (ACT). Second, the tool created by Jon Erickson, sdb-explorer.exe. ACT will allow us to inject a DLL into a 32-bit process, while sdb-explorer allows us to create an In-Memory binary patch to inject shellcode. The ACT has no ability to parse or create an In-Memory patch. This can only be done via sdb-explorer.
There is an excellent walk-through here on creating an InjectDLL Demo.
For the remainder of this document, we will focus on using sdb-explorer to create and install an In-Memory patch.
My testing seems to indicate this will not work on Windows 10. This tactic will only work on Windows versions <= 8.1. I could be wrong about this, so please share any insight if you have it.
There are two approaches you can take with sdb-explorer. First, you can simply Replace or write arbitrary bytes to a region in memory. Second, you can match a block of bytes and overwrite. There are advantages and disadvantages to both approaches. It is worth noting that this method of persistence will be highly specialized to the environment you are operating in. For example, you will need to know specific offsets in the binary
For this to work, we need an offset to write out shellcode to. I like to use CFF Explorer.
Here we are going to target the AddressOfEntryPoint. There are other approaches as well. The drawback to this approach is the application doesn’t actually execute. In order to do that you would need to execute your patch and then return control to the application. I leave that as an exercise for the reader.
Once we have the offset, we can use the syntax provided by sdb-explorer to write our shellcode into the process at load time.
If we break down the syntax, it is pretty easy to understand.
Line 7. 0x39741 matches the PE Checksum. This is in the PE Header.
Line 8. 0x3689 is the offset of our AddressOfEntryPoint. What follows is just stock shellcode to execute calc.
Once our configuration file is created, we “compile” or create the sdb.
sdb-explorer.exe –C notepad.conf –o notepad.sdb.
Then install it:
sdb-explorer.exe –r notepad.sdb –a notepad.exe
You can also use:
sdbinst –p notepad.sdb.
In either case it requires local administrative rights to install a shim.
Notepad.exe is nice. But more likely shim targets would be explorer.exe, lsass.exe, dllhost.exe, svchost.exe. Things that give you long term persistence. Of course your shellcode would need to return control to the application, instead of just hijacking AddressOfEntryPoint.
There are two primary indicators that a shim is being used. First, the registry keys mentioned above. Second, the presence of the .sdb file. The presence of the .sdb file is not necessarily bad, it would be wise to build a baseline to understand which shims your organization uses and which would be an indicator. There was a good example of detecting shim databases given here: Hunting Memory, on slide 27. Also, some shim registration activity can be recorded in the Microsoft-Windows-Application-Experience-Program-Telemetry.evtx.