Blue Teaming

7 min read

How to track WSL2 activity with API hooking

A methodology for identifying significant Win32 APIs and achieving comprehensive visibility into all activities executed within WSL2.

IamRoot avatar

IamRoot,
Jul 18
2023

As threat actors persistently monitor the WSL (Windows Subsystem for Linux) attack surface for emerging advancements, we aim to share our research on tracking the interactive usage of WSL2 when used by local users or attackers with an established connection on the victim machine. 

In this blog post, we will utilize API Monitor for manual analysis of API calls and employ Frida, similar to EDR solutions, for API hooking. Through this, we will showcase some intriguing Win32 APIs that can be intercepted to track WSL2 activity.

Practice these techniques in a real environment 

 

Forela Corporation heavily depends on the utilization of the Windows Subsystem for Linux (WSL), and currently, threat actors are leveraging this feature—taking advantage of its elusive nature that makes it difficult for defenders to detect.

In response, the red team at Forela has executed a range of commands using WSL2 and shared API logs for analysis. Your mission?

Help the team find out what's going on & how to contain the incident by analyzing the logs. 

Problem statement

Microsoft's release of WSL2 brought significant architectural changes when compared with its previous version of WSL. 

The primary difference between WSL1 and WSL2 is the use of virtualization technology with an actual Linux kernel based on the source code available at kernel.org. Whereas, WSL1 uses pico processes and two pico providers: lxss.sys and lxcore.sys

The pico processes are the programs that the user interacts with from inside the WSL1 environment and the two pico providers translate between Linux processes and the Windows NT kernel.

Due to the security implications associated with using this feature, researchers have explored how native Windows logging can offer visibility into the activity of both WSL1 and WSL2. 

For instance, when using WSL1 Sysmon can log process creation and also the command-line events executed by the user but when it comes to the usage of WSL2 Sysmon only logs whenever the user tries to access Windows utilities through its shell. 

Nevertheless, due to WSL2's reliance on virtualization technology, Windows lacks visibility into Linux commands and their behavior when used by both users and potential attackers within an interactive WSL2 terminal. 

Despite this challenge, organizations can leverage the Win32 APIs mentioned in this blog to achieve comprehensive visibility into all activities executed within WSL2.

Analysis

Our objective for this analysis is to present a methodology and thought process for identifying significant Win32 APIs amidst the noise, enabling effective monitoring of WSL2 activity. The analysis is divided into two parts: 

  • Part one: will primarily examine the behavior of WSL2 when interacted with by a local user. 

  • Part two: will center around attackers who utilize an established Command and Control communication channel to launch WSL2.

Interactive Local User

The first step involves monitoring the behavior of the process wsl.exe running from the C:\Program Files\WindowsAPP\* directory. This can be accomplished by launching it from the command prompt and subsequently tracking its activity using the tool API monitor.

tracking wsl2 activity png one

From the screenshot above, it is evident how the first keystroke from the command hostname was transformed into a new character string using Win32 functions such as WideCharToMultiByte and RtlUnicodeToUTF8N. Subsequently, after the translation, the keystroke “h” was written to the console using the Win32 function WriteFile.

Having identified the functions for monitoring keystrokes, we can now utilize this Frida script to hook our APIs and log the keystrokes made by the user. The script below hooks RtlUnicodeToUTF8N and logs the fourth argument from the function:

var pRtlUnicodeToUTF8N = Module.getExportByName(null, "RtlUnicodeToUTF8N");

Interceptor.attach(pRtlUnicodeToUTF8N, {

    onEnter: function(args)

    {

console.log('RtlUnicodeToUTF8N()');

console.log("¦- KeyStroke: " + Memory.readUtf16String(args[3]).charAt(0) + "\n");

    }

});
 

With Frida set up, notice how the keystrokes are outputted in the console:

wls ss2

Now that we have gained an understanding of the behavior of WSL2 when executing Linux commands, let's explore what happens when a local user runs Windows commands using the WSL2 shell. To analyze this behavior, we will drop all previous API calls inside the tool API monitor and execute the command powershell.exe pwd:

screenshot #3

From the above screenshot, we can observe that this time the string function responsible for converting the source string to the new character string is RtlUTF8ToUnicodeN but not RtlUnicodeToUTF8N. To further analyze this behavior, we can once again utilize the Frida script with a modification to hook the RtlUTF8ToUnicodeN API and log its fourth argument:

var pRtlUTF8ToUnicodeN = Module.getExportByName(null, "RtlUTF8ToUnicodeN");

Interceptor.attach(pRtlUTF8ToUnicodeN, {

    onEnter: function(args)

    {

console.log('RtlUTF8ToUnicodeN()');

console.log("¦- KeyStroke: " + Memory.readUtf8String(args[3]) + "\n");

    }

});
wls ss4

As depicted, we successfully captured the entire command-line utilized by the user, including the accessed tool's path via the WSL2 shell.

In this section, we demonstrated how hooking into Win32 functions such as RtlUnicodeToUTF8N, RtlUTF8ToUnicodeN, or WideCharToMultiByte, can be used for tracking the WSL activity, enabling the monitoring of any unusual behavior when employing this feature within our environment.

In the next section, we will delve into the behavior of WSL2 when an attacker initiates a WSL shell through an established connection over a Command and Control server.

Interactive attacker

For this section, we have already established a connection to one of the victim machines in our lab using a payload generated by the Sliver C2 framework. Following a similar approach to our previous analysis, we will initiate WSL from the attacker machine and begin monitoring the wsl.exe process as seen in the image below:

wsl2 screenshot

In the screenshot above, we can see that no string functions were triggered. However, there were instances of ReadFile and WriteFile functions being invoked by the process. 

Upon analyzing these APIs, we discovered that the WriteFile function can be intercepted to capture the commands executed by the attacker machine. To achieve this, let's utilize the following Frida script, which will log the hexadecimal buffer of the WriteFile API on the console:

var writeFile = Module.getExportByName(null, "WriteFile");

Interceptor.attach(writeFile, {

    onEnter: function(args)

    {

        console.log("Buffer dump:\n" + hexdump(args[1]));

    }

});
wsl ss 6

As observed, by intercepting the WriteFile API, we are not only able to capture the executed commands but also obtain the output generated by the attacker's command.

Enhancing WSL2 Visibility through API Hooking

In this blog post, we have utilized the concept of API hooking to analyze the behavior of WSL2. It is important to note that while this research provides insights into the current state of these behaviors within WSL, updates to WSL2 and Windows may require further revisions. 

Despite the challenges involved in monitoring the interactive usage of WSL, organizations can achieve comprehensive visibility into their computer activities by correlating native Windows logging with the data captured through API hooking, as demonstrated in this blog post. 

References

Author bio: Kartik Durg (iamroot), Defensive Content Engineer, Hack The Box

Kartik is a cybersecurity professional with a strong passion for adversary simulation and threat analysis, boasting over six years of experience. Beginning as a blue teamer, he honed his defensive security skills before transitioning into offensive security, providing him with a comprehensive understanding of both sides of the cybersecurity landscape.

Throughout his career in offensive security, Kartik has conducted successful penetration tests and devoted significant efforts to simulate threat actors like Fin7/Carbanak, Wizard Spider, Sandworm, and Turla. Through these simulations, he has actively contributed to enhancing cybersecurity defenses and fortifying organizations against real-world threats.

Joining Hack The Box as a Defensive Content Engineer in early 2023, Kartik is dedicated to creating tailored blue team content that meets the specific needs of the broader blue team community.

You can connect with him on LinkedIn.

 

Hack The Blog

The latest news and updates, direct from Hack The Box