Thursday, May 18, 2017

Subvert CLR Process Listing With .NET Profilers

I recently stumbled onto an interesting capability of the CLR.

"A profiler is a tool that monitors the execution of another application. A common language runtime (CLR) profiler is a dynamic link library (DLL) that consists of functions that receive messages from, and send messages to, the CLR by using the profiling API. The profiler DLL is loaded by the CLR at run time."

https://msdn.microsoft.com/en-us/library/bb384493(v=vs.110).aspx

So. whats the big deal, really?

Turns out in .NET 4 allows for Registry-Free Profiler Startup and Attach.  This can lead to some unintended consequences.

https://msdn.microsoft.com/en-us/library/ee471451(v=vs.100).aspx

In order for this work, you need to set 3 environment variables.

Again from MSDN:

Startup-Load Profilers


A startup-load profiler is loaded when the application to be profiled starts. The profiler is registered through the value of the following environment variable:
  • COR_ENABLE_PROFILING=1
Starting with the .NET Framework 4, you use either the COR_PROFILER or the COR_PROFILER_PATH environment variable to specify the location of the profiler. (Only COR_PROFILER is available in earlier versions of the .NET Framework.)
  • COR_PROFILER={CLSID of profiler}
  • COR_PROFILER_PATH=full path of the profiler DLL
If COR_PROFILER_PATH is not present, the common language runtime (CLR) uses the CLSID from COR_PROFILER to locate the profiler in the HKEY_CLASSES_ROOT of the registry. If COR_PROFILER_PATH is present, the CLR uses its value to locate the profiler and skips registry lookup. (However, you still have to set COR_PROFILER, as discussed in the following list of rules.)
So, if our objective is to hijack a .NET process, like say PowerShell, we don't really want a Profiler to load, we just want to be able to manipulate the process.  It turns out you can get a dll to load into the .NET process that is not even a Profiler.  This was interesting to me.  The CLSID is just random for this purpose.

So, I had this idea, I could write quick POC DLL that hides a process from PowerShell.  Well, short story is this.  If you load a Profiler, and don't properly setup the Profiler structures, then the .NET CLR will promptly eject your dll.

For details of how we hook and hide see this article.

Thats ok.  ;-)  So what I did was create a DLL that loads another DLL from memory, and then when my profiler gets evicted, my hooking dll will stay resident.  So the Profiler just becomes a bootstrap.

The result seen in this clip below.  We enumerate processes with Get-Process in a "non-profiled" PowerShell process.  We get the details just fine.  Then we set our environment variables, load our PowerShell process, and now, the processes are not seen.

Video:



Why does this matter.  As PowerShell become the window through which many sysadmins poll and interrogate the operating system.  By using attaching a malicious profiler, we can mold the output so to speak to be what we want.

This was just a very basic example.  I leave it up to you to explore further capabilities of tampering with the CLR/.NET applications through profilers.

Hope that was helpful.

Thats all for today.




Casey
@subTee





Wednesday, May 3, 2017

Using Application Compatibility Shims

Overview:

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.


Shim Installation:
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:


HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Custom
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\InstalledSDB


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.


Shim Detection:
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.


Cheers,


Casey
@subTee


References: