Blog

.NET Core Evasion Detection

Environments that have installed the .NET Core (version 3.11) are affected by a directory traversal vulnerability since the environment variable doesn’t sanitize user input and therefore custom Garbage Collector DLL files could be called from arbitrary locations. This could assist a threat actor to use this technique for evasion since malicious code could be executed from a trusted .NET assembly or directly by invoking the “dotnet.exe” binary. The vulnerability has been discovered by Paul Laine and the technical details have been described in great detail in the official blog of Context.

Pentest Laboratories to assist blue teams and threat hunters have also analysed the technique from the offensive and defensive perspective. The offensive analysis can be found the the article Abusing .NET Core – Evasion. The purpose of this article is to highlight various indicators that could assist towards detection. Analyzing the technique it is understood that the focus for threat hunters should be in three areas:

  1. Logs
  2. Processes
  3. Memory of Processes

Logs

During the execution of the assembly the custom garbage collector DLL is called. The DLL contains the shellcode and perform some actions on the system. Initially a new process is created as the function “CreateProcess” is used.

The process creation event (Event ID 1) on Sysmon logs the event. Examining this specific log would raise some initiation suspicious since Internet Explorer process (iexplore.exe) has been created from a random executable (ConsoleApp.exe) which acts as a parent.

The “CustomGC.dll” allocates a virtual memory space (VirtualAllocEx) and writes the shellcode into the memory regions (WriteProcessMemory) of the target process.

This kind of behavior is performed from the initial process (ConsoleApp.exe) which attempts to access another process (iexplore.exe) in order to perform these tasks. Process access events are also logged by Sysmon (Event ID 10).

The DLL uses the function “CreateRemoteThread” to create a a Thread within the target process that the arbitrary code will be injected.

Sysmon (Event ID 8) detects when a process creates a thread in another process. The initial process is the .NET binary (ConsoleApp.exe) which will take the instruction to create a thread on the target process from the garbage collector DLL file. From the perspective of threat hunting this looks abnormal behavior as there are no legitimate reason why a random process could create a thread into “iexplore.exe” or in any other trusted process of the system.

it is not uncommon some of the processes to establish a network connection with remote hosts. However a connection to a random high level port is in indication that an implant lives inside the process. EDR’s have the ability to detect and prevent connections to random ports and the same is applicable for Sysmon (Event ID 3). Sophisticated attackers will attempt to evade products and encrypt traffic with a certificate. Therefore logs that contain connections to hosts on the network in random ports should be examined further to ensure the connection is legitimate.

During the execution of the technique there is also a registry modification since the .NET assembly “ConsoleApp.exe” attempts to create a new process on the system. Registry value modifications are also captured by Sysmon (Event ID 13).

Processes

The technique creates a new process on the system. The process is arbitrary therefore monitoring for the creation of a specific process couldn’t assist towards detection. However, the “CreateRemoteThread” function is used in order to execute the code within the process. Jared Atkinson developed a PowerShell script (Get-InjectedThread) that could discover threads of processes which are potentially injected by arbitrary code.

The script initially retrieves all threads of the system by using a Windows API and checks their base address. Then performs a query on the memory page for that base address and checks the memory state and whether is allocated or not (MEM_COMMIT) and the memory type and whether it is memory image (MEM_IMAGE). If it is not a memory image (meaning that is not backed by a file) then this is an indication that the thread of the process is injected.

Import-Module .\Get-InjectedThread.ps1
Get-InjectedThread

The script has identified that the process iexplore.exe has a Thread ID (2792) which has a memory region allocated that is not a memory image but it’s type is set to “MEM_PRIVATE“.

The technique relies on setting the environment variable for the Garbage Collector (COMPlus_GCName) to point on the path of a custom DLL. The “COMPlus_GCName” entry and it’s value will appear in the Environment tab of “Process Hacker” in contrary with a legitimate process which by default doesn’t have that entry.

Memory of Processes

The functions “VirtualAllocEx” and “WriteProcessMemory” are used to allocate a memory region in the target process and write the arbitrary code. Therefore in order to be able to detect the payload the memory of the process must be examined. The PowerShell script “Get-InjectedThread” has retrieved previously that the thread 2792 is possibly associated with a memory region that code is executed.

Searching for strings in the memory of the process will unveil the presence of Meterpreter. The “metsrv.x64.dll” corresponds to the actual Meterpreter service. The “ReflectiveLoader” is the technique used by Meterpreter to load the “metsrv.x64.dll” into the memory of the process. The “WS2_32.dll” (windows socket library) is a legitimate DLL which handles network connections and is also used by Meterpreter. There is also a TCP connection to a foreign host.

Meterpreter was used as an example a sophisticated adversary could use various techniques to hide their implant and the connection therefore detection should not focus on the above strings. The “COMPlus_GCName” and the path of the garbage collector DLL also appear in memory regions of the target process.

Even though the name of the DLL file, the path, the process and the .NET application are completely arbitrary the “COMPlus_GCName” is a fixed string. Pentest Laboratories developed a YARA rule which can detect this technique by looking at processes that contain the string “COMPus_GCName“.

yara64.exe -s -r dotnet-core.yara "856"

Paul Laine in his proof of concept used the technique process hollowing to inject code into a legitimate process since the process is created in a suspended state, memory regions are not mapped to a file and are replaced by the actual shellcode. The hollows_hunter binary developed by hasherezade can be used to scan all running processes in order to detect malicious implants that are using the process hollowing technique. Executing the following command will detect the process with PID 856 (iexplore.exe) as suspicious.

hollows_hunter64.exe /pname iexplore.exe

An alternative option to “hollows_hunter” is PE-Sieve which has the ability to scan all the processes of the system in order to detect implants. This tool will also dump on the disk the memory regions that contain the malicious code for further analysis.

In this scenario the shellcode was generated by Metasploit Framework and a Meterpreter session was obtained. Even though Metasploit will not be a C2 that a sophisticated actor would use detection of Meterpreter can be achieved by using the Meterpreter Payload Detection. The tool is written in .NET and uses a Meterpreter signature to perform the detection.

Yara

The following YARA rule can detect processes that contain the “COMPlus_GCName” in their memory regions which is used by adversaries to perform the evasion.

rule COMPlus : COMPlus
{
 meta:
   Author = "netbiosX"
   Company = "pentestlaboratories.com"
   threat_level = 3
   in_the_wild = true

 strings:
    $a = "COMPlus_GCName"

 condition:
    $a
}

Sysmon

Exploitation of the directory traversal vulnerability in the .NET Core creates the following Sysmon events:

EventEvent ID
Process Create1
Network Connection3
Create Remote Thread8
Process Accessed10
Registry Value Set13

Toolkit

The following table contains the tools and scripts that have been used during this threat hunting activity.

NameDescription
Get-InjectedThreadDetects arbitrary process threads
Hollows HunterDetects potentially malicious implants
PE-SieveDetects malware running on system
Meterpreter Payload DetectionDetects Meterpreter in processes
Process HackerMonitor system resources

If you are interested to learn more about how Pentest Laboratories and our custom cyber attack scenarios can improve your organisation readiness against cyber threats pleaseĀ contact us.