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 in 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:
- Logs
- Processes
- 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.
Garbage Collector – Create Process
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.
Sysmon – Process Create
The “CustomGC.dll” allocates a virtual memory space (VirtualAllocEx) and writes the shellcode into the memory regions (WriteProcessMemory) of the target process.
Garbage Collector – Process Memory
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).
Sysmon – Process Accessed
The DLL uses the function “CreateRemoteThread” to create a a Thread within the target process that the arbitrary code will be injected.
Garbage Collector – Create Remote Thread
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.
Sysmon – Create Remote Thread
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.
Sysmon – Network Connection
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).
Sysmon – Registry Value Set
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
Get-InjectedThread – PowerShell Script
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.
Legitimate Internet Explorer Process Arbitrary Internet Explorer Process
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.
Memory Regions
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 – Strings in Memory Indicators
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.
COMPlus_GCName – Memory
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"
Yara – Detection
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
Hollows Hunter – Detection
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.
PE-Sieve
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.
Meterpreter Payload 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:
Event | Event ID |
Process Create | 1 |
Network Connection | 3 |
Create Remote Thread | 8 |
Process Accessed | 10 |
Registry Value Set | 13 |
Toolkit
The following table contains the tools and scripts that have been used during this threat hunting activity.
Name | Description |
Get-InjectedThread | Detects arbitrary process threads |
Hollows Hunter | Detects potentially malicious implants |
PE-Sieve | Detects malware running on system |
Meterpreter Payload Detection | Detects Meterpreter in processes |
Process Hacker | Monitor 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.