How each (EXM)DR does this is different depending on the company that developed it, but they all do share some common core practices. One of these is how they hook into processes to monitor memory for malicious activity. As threat actors became more sophisticated in their methods (like using “fileless malware”), EDR applications had to shift away from just looking at file writes onto disk, or PE (portable executable) launches from disk. They now had to monitor memory space, script engine launch and execution as well as a host of other things. The attack chain became more complicated and harder to track, but for the most part EDR companies were up to the task. Of course, nothing lasts forever and most EDR solutions cannot monitor everything.
As with most attack profiles, they evolve over time. Threat actors are always going to look to find a way around current protection methods and activities. It was only a matter of time before someone sat down and looked at exactly how modern EDRs work. Once they put their finger on this, they can quickly identify a way to avoid what is being looked at. It is similar to identifying the pattern of “bad guys” in a video game. Once you know the timing of them moving/looking around, you can plot your path to remain hidden.
In this case, the people that have found the path is a Security Company called Security Joes, the fruit of their labor, is called Process Mockingjay. Here the researchers identified how modern EDR works, core parts of process injection, and then looked to find the clear path between the two. The two core components they found in most process injections are allocating memory space and then setting Read-Write-Execute (RWX) permissions on the allocated space. The downside of these techniques is that they use two Syscalls that are heavily monitored for suspicious activity (NtWriteVirtualMemory and NtProtectVirtualMemory). With the pattern of the enemies noted, the Security Joes team went to work.
The need was to find PE files at the OS level that already had the right permissions for their associated memory space (RWX). Once something like this was identified, it could potentially eliminate the monitored syscalls. While the team did not list a DLL that was native to the OS which had the required permissions, they did find on in Visual Studio 2022 msys-2.0.dll. This file had the needed RWX permissions and a nice amount of space (16KB) to play in. After identifying the target DLL, the team went about finding an injection method that did not involve heavily monitored calls, they found two.
The first method leveraged two common Windows API calls (LoadLibraryW and GetModuleMemoryInformation). The team used a custom application to load the targeted DLL into memory and then use the open memory space provided to inject their code. There was no need to allocate memory or change permissions as the msys-2.0.dll had already done that and is a trusted process. To test if this worked, the Security Joes team then used Hell’s Gate EDR unhooking. In incredibly simplistic terms, Hell’s Gate relies on loading a clean copy of the NTDLL.DLL to identify system call numbers for PE files. Once those numbers are known you can eliminate the hooks that EDRs use to monitor memory and nullify them.
The complete process to achieve this can be described as follows:
1. Custom application loads vulnerable DLL using LoadLibraryW.
2. Location of the RWX section is resolved using the base address of the DLL and the offset of section.
3. A clean copy of NTDLL.DLL is loaded from the disk, and the system call numbers for the desired syscalls are obtained.
4. The addresses of the test instructions after the jmp added by the EDR are retrieved from the NTDLL.DLL in-memory copy (hooked by the EDR).
5. Using the addresses of the test instructions and the syscall numbers, we assemble our stubs in the RWX area of the vulnerable DLL.
6. When the stub is executed, it prepares the syscall number in the EAX register, as usual, and immediately jumps to the address of the corresponding test instruction for the chosen system call, bypassing the EDR verification step.
After this test was completed, the team went on to see if they could load a shell into memory using the same process. Long story short, that worked as well.
The second method the Joes team found was a remote process injection method. This one relied on finding other binaries that relied on msys-2.0.dll for operation. The binary they found was also part of Visual Studio 2022 (ssh.exe). The connection here is via the utilization of msys-2.0.dll for POSIX emulation (running a binary not designed for Windows). Here the team also used custom code to launch ssh.exe as a child process using the API call CreateProcessW. The attack pattern here does not involve creating a new thread in the target process. Instead, the process executes the injection code on its own removing another potential detection point for EDR. Step two is to move the payload into the vulnerable memory space. This is done through the OpenProcess and WriteProcessMemory APIs.
The complete process to achieve this can be summarized as follows:
1. Custom application is executed.
2. Trusted application (ssh.exe) using DLL msys-2.0.dll is launched as a child process.
3. Custom application opens a handle to the target process (ssh.exe).
4. Code to be injected is copied into the RWX section of msys-2.0.dll.
5. Trusted application executes the injected code during its normal execution flow.
6. Additional DLL MyLibrary.dll is loaded by the shellcode injected in the RWX section.
7. Back connect shell session is stablished.
Now, both techniques are impressive and show how reliance on EDR, XDR, and/or MDR can give a false sense of security. However, in reading the research paper I found a few items to note. The first is that mysy-2.0.dll does not appear to be a native DLL to the core Windows operating system. I did a search for it on multiple operating systems and did not see it. This means that it only comes with the installation of an additional application. This does not mean that another DLL with the right permissions does not existing native to the OS which they mention, but that could be the case. The second is the use of the WriteProcessMemory API in the remote injection technique. While this might avoid detection by many existing EDRs there are a couple that do look for this pattern regardless of the PE that is trying to run this. Cylance Protect is one of them that looks at this function and could potentially detect it. The third item of note is the need for the custom software/code to be run on the machine to perform the attack in question. From a logical perspective, unless a machine is already compromised and the EDR is unhooked, the custom code needed to run this should be detected and an alert raised at the minimum. After all the attacker has to execute the command/code locally on the device to load the DLL and inject the payload into memory etc. This leaves an opportunity for detection during the initial access phase. Products like Cylance Protect, Sentinel One and others can be configured to detect this type of file on-write or to detect this code execution if it is a pivot from a script (like PowerShell or JavaScript).
This is not to say that these techniques are not dangerous. They are very dangerous and illustrate exactly how open the Windows environment can be to a threat actor that is sophisticated. Although this flaw might have been detected by a security research team, there is no doubt in my mind that threat actors are already aware of this flaw and might currently use it in sophisticated attack campaigns already underway. That being said there is a potential for detection and response, if your systems are configured correctly and your security teams are properly experienced and trained to identify the proper attack patterns. Simply having an (EXM)DR solution in your environment is not enough anymore. It takes long term management and adjustment to ensure it is configured to identify and respond to the latest shift in the threat landscape. Security Joes themselves recommend an augmentation to the common defensive techniques including like dynamic analysis, run-time behavior monitoring etc. The good news there is that many existing products have these built in, they just need to be properly set up and then get fed to a team that can identify a potentially malicious pivot and stop it.
Stay safe out there