During the past few months, we have been monitoring the dotRunpeX malware, its usage in the wild, and infection vectors related to dozens of campaigns. The monitoring showed that this new dotnet injector is still evolving and in high development. We uncovered several different methods of distribution where in all cases, the dotRunpeX was a part of the second-stage infection. This new threat is used to deliver numerous different malware families, primarily related to stealers, RATs, loaders, and downloaders.
The oldest sample related to the new version of dotRunpeX is dated 2022-10-17. The first public information about this threat is dated 2022-10-26.
The main subject of this research is an in-depth analysis of both versions of the dotRunpeX injector, focusing on interesting techniques, similarities between them, and an introduction to the PoC technique used to analyze a new version of dotRunpeX as it is being delivered virtualized by a customized version of KoiVM .NET protector.
DotRunpeX is a new injector written in .NET using the Process Hollowing technique and used to infect systems with a variety of known malware families. Although this injector is new, there are some connections to its older version sharing some similarities. The name of this injector is based on its version information which is the same for both dotRunpeX versions, consistent across all samples we analyzed and containing ProductName – RunpeX.Stub.Framework
.
While we have been monitoring this threat, we spotted a few publicly shared pieces of information, mainly by independent researchers, that were related to the functionality of dotRunpeX but misattributed to a different well-known malware family.
We are aware of a publication about one campaign delivering this threat, but our findings and conclusions based on the report below slightly differ. By monitoring this threat for a few months, we got enough information to differentiate the first-stage loaders from the second stage (dotRunpeX) with no signs of the relation between them. We revealed the connections to its older version, the distribution of numerous malware families, and several different techniques used as a vector of infection.
Among the variety of downloaders and cryptocurrency stealers, we spotted these known malware families delivered by dotRunpeX:
From the timeline perspective, based on the compilation timestamps of dotRunpeX samples that did not appear to be altered, this new threat became popular mainly during November 2022 and January 2023. What could be just an interesting coincidence or just some kind of sign of attackers waiting under the Christmas tree is that we did not see a lot of samples compiled during December 2022.
DotRunpeX injector commonly comes as a second stage of the original infection. The typical first stages are very different variants of .NET loaders/downloaders. The first-stage loaders are primarily being delivered via phishing emails as malicious attachments (usually as a part of “.iso”, “.img”, “.zip”, and “.7z”) or via websites masquerading as regular program utilities. Apart from the most common infection vectors, the customers of dotRunpeX are not ashamed to abuse Google Ads or even target other potential attackers via trojanized malware builders.
Example phishing email Transaction Advice 502833272391_RPY - 29/10/2022
delivering the first stage loader as a part of malicious “.7z” attachment that results in loading of dotRunpeX (SHA256: “457cfd6222266941360fdbe36742486ee12419c95f1d7d350243e795de28200e”).
Example phishing websites – masquerading regular program utilities (Galaxy Swapper, OBS Studio, Onion Browser, Brave Wallet, LastPass, AnyDesk, MSI Afterburner) and delivering the first stage loaders that result in dotRunpeX infection in a part of the second stage.
Website masquerading as Galaxy Swapper: https://www.galaxyswapper[.]ru/
Download redirects to https://gitlab[.]com/forhost1232/galaxyv19.11.14/-/raw/main/GalaxyV19.11.14.zip
.
Website masquerading as LastPass Password Manager: http://lastpass[.]shop/en/
The fake website of LastPass Password Manager was already down at the time of the investigation. Still, we can confirm that the fake software was downloaded from the “Final URL” https://gitlab[.]com/forhost1232/lastpassinstaller/-/raw/main/LastPassInstaller.zip
.
The GitLab page https://gitlab[.]com/forhost1232
contained dozens of programs trojanized by dotRunpeX malware.
All of the trojanized programs on the previously mentioned GitLab page contain the main .NET application enlarged with an overlay to avoid scanning with sandboxes very likely.
The mentioned .NET applications with overlay are the typical first stages, behaving as dotnet loaders with simple obfuscation. These different variants of loaders use reflection to load the dotRunpeX injector in the second stage. Some of them are very simple, and some are more advanced.
Simple first-stage loader (direct usage of method System.Reflection.Assembly.Load()
):
An example of a more advanced first-stage loader (using AMSI Bypass and DynamicMethod
to load and execute the second stage via reflection) can be seen below. The advantage of this kind of advanced loader is that there is no direct reference to System.Reflection.Assembly.Load()
method so it could possibly avoid detection of engines relying on static parsing of .NET metadata.
Deobfuscated form of the latter one could be seen in the picture below:
Programmatic way of second-stage extraction (dotRunpeX stage) from these kinds of loaders could be simply implemented using AsmResolver and reflection as shown below.
Important to note that those examples of phishing websites leading to the GitLab page were related to just one campaign where the dotRunpeX injector was always responsible for injecting Redline malware with C2 – 77.73.134.2
.
In addition to the most common vectors of infection mentioned earlier, we observed quite an interesting case of infection vector, where a customer of dotRunpeX was probably bored enough to target ordinary victims and decided to target other potential attackers. Something that is supposed to be a Redline builder Redline_20_2_crack.rar
(SHA256: “0e40e504c05c30a7987785996e2542c332100ae7ecf9f67ebe3c24ad2468527c”) was trojanized with a downloader that uses a reflection to load dotRunpeX as a hidden “added feature” of the builder.
It turned out that during the building process of the Redline, configured to your needs, one will also get another Redline sample, probably the one that you didn’t desire, as a gift embedded in the dotRunpeX.
GetDelegateForFunctionPointer()
) – but using decoy syscall routineИисус.sys
translated as “jesus.sys”BIDEN_HARRIS_PERFECT_ASSHOLE
to hold the encrypted payload to be injectedFor the analysis of the older version of dotRunpeX, sample SHA256: “65cac67ed2a084beff373d6aba6f914b8cba0caceda254a857def1df12f5154b” was used. This sample is a 64-bit executable file “.exe” written in .NET, implementing custom obfuscation – only obfuscations of names. The version information is consistent across all samples we analyzed, and we can notice the ProductName – RunpeX.Stub.Framework
that could be some kind of first hint that we are dealing with a dotnet injector.
For simplicity, we partly deobfuscated the names of methods, their arguments, and local variables. Right in the Main()
method, we can see simple XOR decryption of the resource BIDEN_HARRIS_PERFECT_ASSHOLE
that contains an encrypted payload to be injected. The resource name was consistent across all samples we analyzed.
We can also see the namespace UACBypass
with the class name UAC
. This class implements UAC (User Account Control) bypass method, but it is not configured to use in this sample.
Method Inject()
is implementing a code injection technique called “Process Hollowing”. We can notice spawning a process in a suspended state right in the picture below.
This technique is nothing new in the world of malware development. Still, there is something interesting we can immediately spot once we check P/Invoke (technology that allows access to structs, callbacks, and functions in unmanaged libraries from managed code) defined methods of this sample. These methods can be seen in the ImplMap
table, which is a part of .NET metadata.
Certain WIN APIs or NT APIs must be used to perform the Process Hollowing technique. And as we saw in the ImplMap
table, some of the most crucial APIs are missing. To be more specific, we cannot see any APIs related to unmapping and writing to remote process memory. The reason behind this is the usage of the D/Invoke framework to call certain NT API routines that could usually trigger attention.
D/Invoke contains powerful primitives that may be combined intelligently to dynamically invoke unmanaged code from disk or memory with careful precision. It relies on the usage of the dotnet method GetDelegateForFunctionPointer()
and corresponding delegates definitions.
In this case, NT APIs ZwOpenSection
, ZwMapViewOfSection
, ZwUnmapViewOfSection
, NtClose
, NtWriteVirtualMemory
, NtResumeThread
, and RtlMoveMemory
are implemented via D/Invoke. The corresponding definitions of delegates can be seen below.
What is even more interesting, 4 NT APIs (ZwUnmapViewOfSection
, NtWriteVirtualMemory
, NtResumeThread
, RtlMoveMemory
) implemented via D/Invoke are using something that could be considered as an added PoC technique and is not a part of the original D/Invoke framework – syscall patching. For example, we can check how NtWriteVirtualMemory
invocations are implemented via a method called CallNtWriteVirtualMemory()
.
First, what we can see is an altered usage of the D/Invoke framework in the method MapDllandGetProcAddress()
. Each time this method is invoked, it will remap the specified library and obtain the desired function’s address. Before returning the address of the desired function, pointer arithmetic is used to move the pointer by 4 bytes so it points to the address of the syscall number. In this case, the “ntdll.dll” module gets remapped, returning the address of the NT API routine NtWriteVirtualMemory
altered by 4 bytes offset.
The remapping of the module is used as an AV-evasion and Anti-Debug technique, as it results in unhooking and removing all set software breakpoints. The obtaining address of a certain native function is implemented via typical D/Invoke implementation – DynGetProcAddress()
, which is responsible for in-memory parsing of the PE structure to find the address of the specified routine.
Now back to the exciting part. As we can see in this case, DynGetProcAddress()
is also used to find the address of NT API NtAddBootEntry
, and we can call it a decoy routine. The decoy routine address will be used for syscall patching.
NtWriteVirtualMemory
routine altered by 4 bytes offset (address of syscall number)NtAddBootEntry
NtWriteVirtualMemory
(even though the syscall number is DWORD, these 2 bytes are enough and represent the syscall number of NtWriteVirtualMemory
) to byte field SyscallStub
(this field contains syscall stub code)NtAddBootEntry
with byte field SyscallStub
Disassembling the default value of the SyscallStub
makes it even more apparent why exactly 2 bytes are getting replaced with bytes from the altered address of the NtWriteVirtualMemory
routine. These 2 bytes represent the syscall number of certain real function to be called.
Simply said, once the NtWriteVirtualMemory
function is called, the only thing we will see from user mode will be an invocation of NtAddBootEntry
.
We can use WinDbg “kernel mode debugging” to verify the mentioned execution flow. We can see that NT API NtAddBootEntry
with the original syscall number 0x6a (on our target system) is used as a patched decoy routine. In the case where NtWriteVirtualMemory
needs to be called, the syscall number of the decoy routine is patched with syscall number 0x3a (NtWriteVirtualMemory
syscall number on our target system) and gets called.
For the analysis of the new version of dotRunpeX, sample SHA256: “44a11146173db0663a23787bffbb120f3955bc33e60e73ecc798953e9b34b2f2” was used. This sample is a 64-bit executable file “.exe” written in .NET, protected by KoiVM. The version information is the same as in the case of an older version of dotRunpeX and is consistent across all samples we analyzed. We can notice the ProductName – RunpeX.Stub.Framework
again.
Right after opening the sample in dnSpyEx and leading to the entrypoint function – _sb()
method, we can immediately confirm that this new version of dotRunpeX is protected by the KoiVM virtualizer. Despite the fact that most of the IL code is virtualized, we can still spot invocation of P/Invoke defined method CreateProcess
that is used in a way to create a process in a suspended state – typically used for code injection technique “Process Hollowing”.
After investigating more what was left lying around in .NET metadata, specifically in the ImplMap
table, to find out what other methods are defined as P/Invoke and very likely used by this sample, we are getting surprisingly even more exciting findings than in the case of the older version of dotRunpeX. Apparently, the sample will perform not just code injection but also loading and communicating with the driver.
The next that we immediately noticed is the usage of the same resource name as in the case of the older version – BIDEN_HARRIS_PERFECT_ASSHOLE
– that contains an encrypted payload to be injected. The resource name was consistent across all samples we analyzed. Obviously, the decryption routine is hidden behind the code virtualization, but an educative guess will lead us to a simple XOR decryption routine using a password expressing the secret desires of the author – I_LOVE_HENTAIU2
.
Unfortunately, as dotRunpeX is still in high development and adding new features, the latest samples utilizing this injector changed the decryption scheme (no more simple XOR) to omit static extraction of embedded payloads.
As we pointed out before, the IL code is protected by the KoiVM virtualizer, so to continue with our analysis, we needed to come up with some approach to deal with the protected code and get something meaningful from that in a reasonable time. First, what came to our mind was to use a publicly available open-source KoiVM de-virtualizer called OldRod. This tool is fully workable for the vanilla version of KoiVM. It is even developed in a way that defeats some simple modifications of the original version of KoiVM (such as signature modifications of the methods in VMEntry
class or changes in the default #Koi
stream name).
Unfortunately for us, we are dealing with a customized version of KoiVM that modified the protector in a way that is not so simple to defeat. The original implementation of KoiVM defines 119 constant variables that are used to virtualize the code. These constants are used to define registers, flags, opcodes, etc. Assigned values of these constants are used for the proper execution of the virtualized code and are also needed for the de-virtualization process.
When using the vanilla version of KoiVM, the resulting constants appear in the compiled, protected sample inside the Constants
class as fields in the exact same order with ascending values of tokens. The order of constants and their corresponding tokens inside the compiled binary is something OldRod depends on.
Although the OldRod tool is an absolute masterpiece and can deal with a custom order of constants when providing a custom constants mapping via configuration file (--config
option), finding out the correct mapping of those constants could not be as simple as it sounds. Sometimes when a constant’s order is handmade change, it could be not so hard to map them correctly by analyzing their usage in code. Unfortunately, in the case of dotRunpeX, we can immediately see that values of those constants are affected by runtime arithmetic assignments (no problem to defeat this programmatically), but even worse is that they are scrambled in a very effective way that makes the correct mapping hard enough to consider this approach as not usable for getting some results in a reasonable time.
Even though we pointed out several facts about the extreme hardness of devirtualization, with precise code analysis and some hard moments during the constants mapping via their appropriate handlers, we were able to fully devirtualize the code. Despite the fully devirtualized code, we were still left with a non-fully runnable .NET Assembly that was still obfuscated with ConfuserEx obfuscator. To continue our madness, we were able to get rid of this obfuscation too.
To give a little spoiler about the functionality of the dotRunpeX injector and its use of procexp driver, fully devirtualized and deobfuscated code related to driver routines can be seen below.
Driver loading/unloading:
Communication with procexp device:
The process of devirtualization and deobfuscation is a subject to consider for its own blog post and won’t be covered further.
Normally, when it is impossible to devirtualize the code in a reasonable time, we are still left with few other options. The first of the options, quite a common approach when dealing with virtualized code, is to go with dynamic analysis using a debugger, DBI (Dynamic Binary Instrumentation), hooking, and WIN API tracing. As we are dealing with dotnet code, another approach to come out with could be some PoC using some knowledge from the .NET internals world. As researchers who love to bring something new to the community, we decided to combine both of these approaches, which resulted in developing new tools that were approved to be very effective.
To get more information about the code functionality, we started with the dynamic analysis approach using x64dbg. As we pointed out before, the ImplMap
table containing P/Invoke-defined methods seems to be a good starting point for setting breakpoints in the debugger. Automating the process of parsing out the P/Invoke defined methods and converting it to x64dbg script leads us to the first tool we developed, called “ImplMap2x64dbg”.
Python script that uses dnfile module to properly parse .NET executable files and their metadata. This tool creates an x64dbg script for setting breakpoints on defined ImplMap
(P/Invoke) methods of the .NET executable. This script can be downloaded in the last section of the article.
import dnfile, sys, os def Main(): if(len(sys.argv) != 2 or sys.argv[1] == '-h' or sys.argv[1] == '--help'): print("Description: Creates x64dbg script for setting breakpoints on defined ImplMap (PInvoke) methods of .NET executable") print(f"Usage: {os.path.basename(sys.argv[0])} <filepath>\n") sys.exit() file_path = sys.argv[1] script_path = file_path + "_x64dbg.txt" dn_file = dnfile.dnPE(file_path) if(dn_file.net is None or dn_file.net.metadata is None): print(f"{sys.argv[1]} is NOT a .NET executable !!!\n") sys.exit() if(dn_file.net.mdtables.ImplMap is None): print(f".NET executable '{sys.argv[1]}' has NO ImplMap !!!\n") sys.exit() # Getting all ImplMap methods and module scope implmap_table = dn_file.net.mdtables.ImplMap.rows implmap_modules = [] implmap_methods = [] [implmap_modules.append(row.ImportScope.row.Name.lower().replace(".dll", "")) for row in implmap_table if (row.ImportScope.row.Name.lower().replace(".dll", "") not in implmap_modules)] [implmap_methods.append(row.ImportName) for row in implmap_table if (row.ImportName not in implmap_methods)] # Creation of x64dbg script x64dbg_script = "; Replace charset depending APIs - ex. CreateProcess -> CreateProcessA or CreateProcessW !!!\n" for module in implmap_modules: x64dbg_script += f"loadlib {module}\n" for method in implmap_methods: x64dbg_script += f"SetBPX {method}\n" with open(script_path, "wt",encoding="utf-8") as f_scr:f_scr.write(x64dbg_script) print(f"x64dbg script created: '{script_path}'") if __name__ == '__main__': Main()
Processing our dotRunpeX sample with “ImplMap2x64dbg” will result in the x64dbg script:
; Replace charset depending APIs - ex. CreateProcess -> CreateProcessA or CreateProcessW !!! loadlib kernel32 loadlib ntdll loadlib user32 loadlib advapi32 SetBPX VirtualAllocEx SetBPX CreateProcessA SetBPX CreateProcessW SetBPX CreateRemoteThread SetBPX Wow64SetThreadContext SetBPX Wow64GetThreadContext SetBPX NtResumeThread SetBPX ZwUnmapViewOfSection SetBPX NtWriteVirtualMemory SetBPX MessageBoxA SetBPX MessageBoxW SetBPX GetModuleHandleA SetBPX GetModuleHandleW SetBPX FindWindowA SetBPX FindWindowW SetBPX GetProcAddress SetBPX GetFileAttributesA SetBPX GetFileAttributesW SetBPX ShowWindow SetBPX SetForegroundWindow SetBPX Wow64DisableWow64FsRedirection SetBPX Wow64RevertWow64FsRedirection SetBPX CreateFileA SetBPX CreateFileW SetBPX RtlInitUnicodeString SetBPX NtLoadDriver SetBPX NtUnloadDriver SetBPX OpenProcessToken SetBPX LookupPrivilegeValueA SetBPX LookupPrivilegeValueW SetBPX AdjustTokenPrivileges SetBPX CloseHandle SetBPX NtQuerySystemInformation SetBPX DeviceIoControl SetBPX GetProcessHeap SetBPX HeapFree SetBPX HeapAlloc SetBPX RtlCopyMemory
We focused mainly on certain WIN/NT APIs such as CreateProcessW
, NtWriteVirtualMemory
,CreateFileA
, CreateFileW
, NtLoadDriver
, NtQuerySystemInformation
, and DeviceIoControl
as they are the interesting ones related to driver and process injection routines.
The first interesting WIN API call we can see is CreateFileW
which is used to create a file in path C:\Users\XXX\AppData\Local\Temp\Иисус.sys
.
If we check the created file Иисус.sys
(from the Russian language translated as “jesus.sys”), we will immediately find out it is a valid Process Explorer driver, version 16.43.
We can see routine NtLoadDriver
responsible for loading this driver where the argument points to DriverServiceName
– \Registry\Machine\System\CurrentControlSet\Services\TaskKill
that specifies a path to the driver’s registry key.
Connecting to the process explorer device follows.
One of the dotRunpeX AV-evasion techniques is killing a hardcoded list of Anti-Malware services with the help of a process explorer driver (procexp.sys). The reason behind the usage of process explorer driver is that the Anti-Malware service usually runs as a protected process, more specifically as PPL, to avoid disabling protection on the system caused by malicious activity. It is possible to abuse vulnerable versions of the procexp driver to close object handles of the protected process. Once enough handles are closed, the specific protected process will be killed. All samples we analyzed were abusing version 16.43 of this driver which is also the latest version vulnerable to this technique.
To obtain information about object handles, dotRunpeX uses NT API NtQuerySystemInformation
with specified SystemInformationClass
0x10 that points to the undocumented structure [SYSTEM_HANDLE_INFORMATION
]. This way, it finds all handles that belong to the protected process.
To process object handles of protected process, dotRunpeX uses WIN API DeviceIoControl
to send IOCTL directly to the vulnerable procexp driver. The IOCTL “2201288708” (IOCTL_CLOSE_HANDLE
) is in RDX
register, and procexp driver routine processing this request is responsible for closing certain object handle of the specified process, regardless of whether the specified process is protected or not. Once enough object handles are closed, the Anti-Malware service is killed.
We could also see that register R8
(lpInBuffer
) points to data required to close the object handle. This data structure could be defined as follows:
typedef struct _ioControl { ULONGLONG ulPID; PVOID lpObjectAddress; ULONGLONG ulSize; ULONGLONG ulHandle; } PROCEXP_DATA_EXCHANGE, *PPROCEXP_DATA_EXCHANGE;
Let’s compare the procexp driver version used by all samples of dotRunpeX (version 16.43 – compiled 2021-08-17) and the latest version of the procexp driver (version 17.02 – compiled 2022-11-10). We can immediately spot the added patching code that is responsible for disabling the possibility of closing object handles of protected processes.
This technique of closing object handles of protected processes using the process explorer driver is well documented and part of an open-source project called Backstab. Process explorer drivers version 17.0+ are already patched.
After killing specific protected processes, Process Hollowing is what follows using WIN API CreateProcessW
to start the process as suspended (in this case C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe
) and direct NT API NtWriteVirtualMemory
to write embedded payload of dotRunpeX into the newly created remote process.
It turned out that with an approach of dynamic analysis that focused on the native layer and certain usage of WIN/NT APIs, we got some interesting findings of this virtualized dotnet injector that could be used for automation and mass processing:
Encouraged by these findings, we can move forward to some automation using knowledge from the .NET internals world. When we are talking about dotnet, we can immediately think of code being managed by .NET runtime. More things are being managed, and among them is one very important for our further process, and that is so-called “Memory Management”. The types of memory in dotnet are stack and .NET heap. In the dotnet world, we do not need to bother with memory allocation/deallocation because these routines are handled by .NET runtime and garbage collector. Memory management of dotnet somehow needs to know what to allocate, where, and how; the same goes for deallocation/freeing of memory. Allocation on the .NET heap occurs once we talk about reference types inheriting from System.Object
(class, object, string…). These objects are saved on the .NET heap, and for the purpose of their automatic management, they are accompanied by certain metadata information such as their type, references, and size. Even better, the automatic memory deallocation of no longer referenced objects does not occur immediately – the garbage collector takes care of this in some time intervals, which could be several minutes. Particular objects like “static objects” survive garbage collections and live till the application ends.
This means that if we could enumerate objects on the .NET heap, we could also get information related to their types and size that can serve for their appropriate reconstruction. Creating this kind of tool would be very likely time-consuming, but luckily for us, there is already created dotnet process and crash dump introspection open-source library ClrMD Microsoft.Diagnostics.Runtime
developed by Microsoft that could be used precisely for object reconstruction from .NET heap. Why is that so important?
In a certain moment of dotRunpeX execution, embedded payload, procexp driver, and some kind of config must appear in a decrypted state. Their content will likely be assigned to some object allocated on the .NET heap. For these, we could expect byte array byte[]
or string
. That also means that if we could control the execution of dotRunpeX and suspend it in a state we assume to be the right moment for those object reconstructions, we would be able to get all that we need in a decrypted state.
One of the right moments for suspending and introspecting the dotRunpeX process could be an invocation of WIN API CreateProcessW
used for Process Hollowing. This was approved to be the correct assumption and led us to develop the hooking library “CProcessW_Hook” exactly for this purpose.
Native hooking library using minhook framework (The Minimalistic x86/x64 API Hooking Library for Windows). The code provided below serves the purpose of hooking the WIN API function CreateProcessW
, which is used in the dotRunpeX injector for process creation that is later used as a target for code injection (PE Hollowing). Once the CreateProcessW
function is hooked and called in the target process, the whole process gets suspended to introspect. Certain process creations are filtered (powershell, conhost) as they can be spawned for other functionalities of dotRunpeX according to config (example modification of Windows Defender settings). We need to suspend the process only in a state before performing code injection (where all required objects are already decrypted on the .NET heap).
#include <windows.h> #include <string.h> #include "pch.h" #include "MinHook.h" #pragma warning(disable : 4996) #if defined _M_X64 #pragma comment(lib, "libMinHook.x64.lib") #elif defined _M_IX86 #pragma comment(lib, "libMinHook.x86.lib") #endif typedef LONG (__stdcall* NTSUSPENDPROCESS)(HANDLE ProcessHandle); typedef BOOL (__stdcall* CREATEPROCESSW)(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION); CREATEPROCESSW fpCreateProcessW = NULL; __declspec(dllexport) void __cdecl Decoy() { Sleep(1000); } int __stdcall DetourCreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation) { LPCWSTR ignoredProcess[2] = { L"powershell", L"conhost" }; for (int i = 0; i < 2; i++) { if (wcsstr(_wcslwr(lpApplicationName), ignoredProcess[i])) { return fpCreateProcessW(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation); } } HMODULE hNtdll = GetModuleHandleA("ntdll.dll"); if (!hNtdll) { ExitProcess(0); } NTSUSPENDPROCESS NtSuspendProcess = (NTSUSPENDPROCESS)GetProcAddress(hNtdll, "NtSuspendProcess"); if (!NtSuspendProcess) { CloseHandle(hNtdll); ExitProcess(0); } HMODULE cProcess = GetCurrentProcess(); if (!cProcess) { CloseHandle(hNtdll); ExitProcess(0); } NtSuspendProcess(cProcess); ExitProcess(0); return 1; } BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: if (MH_Initialize() != MH_OK) { return 1; } if (MH_CreateHook(&CreateProcessW, &DetourCreateProcessW, (LPVOID*)(&fpCreateProcessW)) != MH_OK) { return 1; } if (MH_EnableHook(&CreateProcessW) != MH_OK) { return 1; } case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; }
We could see that all hooking logic is executed right upon loading this library inside the function DllMain()
. Another important thing to note is that we defined the export function Decoy()
, which won’t be ever executed or called but is needed later on for our preinjection technique.
With the hooking library “CProcessW_Hook.dll” in its place, we can move on to create an injector and extractor. This points to the main tool provided below – dotRunpeX extractor “Invoke-DotRunpeXextract”.
PowerShell module that enables the extraction of payload, procexp driver, and config from dotRunpeX. The tool is written in PowerShell scripting language using preinjection of native hooking library “CProcessW_Hook.dll” (using AsmResolver) and .NET objects reconstruction from .NET heap (using ClrMD). It uses a dynamic approach for extraction, so samples are executed in a managed way (use only in VM). Using PowerShell 7.3+, clrMD v2.2.343001 (net6.0), AsmResolver v5.0.0 (net6.0).
We provide two versions of this tool that can be downloaded along with the hooking library in the last section of this article. One is created multi-threaded as a PowerShell module for the best performance and usage. The second version of this tool is a single-threaded script with the same functionality that could be used for simple debugging and troubleshooting and can more easily serve to create several snippets with similar functionality.
The whole code of this PowerShell module is annotated and commented on in a way to be easy to understand its core features. We will briefly describe the core functionality of this tool, like the preinjection technique of the hooking library using AsmResolver and implemented logic behind the extraction.
At first, this tool modifies the PE structure of dotRunpeX using AsmResolver. AsmResolver is well known for its capability to inspect dotnet executables and their related metadata, but it also allows access to low-level structures of PE to modify them. These PE structure modifications are used to implement our so-called PoC technique for the purpose of dll preinjection to a 64-bit dotnet executable. We are talking about adding a new import entry for the native hooking library into the .NET Assembly. Since dotRunpeX is a 64-bit executable, and it turned out that, unlike the 32-bit dotnet executables, the 64-bit ones don’t even have an import directory, we started building one from scratch right inside the function PatchBinaryWithDllInjection()
. In this function, we can see that we are creating new data sections, .idata
and .data
, where our newly built IDT (Import Directory Table) and IAT (Import Address Table) will be placed. To get our hooking library “CProcessW_Hook.dll” preinjected right upon process start and let the windows loader do for us the hard work, we are creating an import entry with exported function Decoy()
that was defined in the hooking library. As we are dealing with dotnet and adding native import, IL Only flag inside the .NET Directory is not true anymore and needs to be patched.
function PatchBinaryWithDllInjection($pathToSample, $patchedSample, $dllHookingName) { # Exported function name "Decoy" from hooking library will be used for Import Directory creation $symbolNameToImport = [AsmResolver.PE.PEImage]::FromFile($dllHookingName).Exports.Entries[0].Name # Decoy # We need to work with pefile layer to expose sections - creation of Import Directory and IAT $pefile = [AsmResolver.PE.File.PEFile]::FromFile($pathToSample) # Creation of Import Directory from scratch $impDirBuff = [AsmResolver.PE.Imports.Builder.ImportDirectoryBuffer]::new($false) $impModule = [AsmResolver.PE.Imports.ImportedModule]::new($dllHookingName) $symbol = [AsmResolver.PE.Imports.ImportedSymbol]::new(0,$symbolNameToImport) $impModule.Symbols.Add($symbol) $impDirBuff.AddModule($impModule) # Creation of ".idata" section where Import Directory will be placed $idataSection = [AsmResolver.PE.File.PESection]::new(".idata", [AsmResolver.PE.File.Headers.SectionFlags]::MemoryRead -bor [AsmResolver.PE.File.Headers.SectionFlags]::ContentInitializedData) $idataSection.Contents = $impDirBuff $pefile.Sections.Add($idataSection) # Creation of ".data" section where IAT will be placed $dataSection = [AsmResolver.PE.File.PESection]::new(".data", [AsmResolver.PE.File.Headers.SectionFlags]::MemoryRead -bor [AsmResolver.PE.File.Headers.SectionFlags]::MemoryWrite -bor [AsmResolver.PE.File.Headers.SectionFlags]::ContentInitializedData) $dataSection.Contents = $impDirBuff.ImportAddressDirectory $pefile.Sections.Add($dataSection) # Remove ASLR (no reloc) $pefile.OptionalHeader.DllCharacteristics = $pefile.OptionalHeader.DllCharacteristics -bxor [AsmResolver.PE.File.Headers.DllCharacteristics]::DynamicBase # Update offsets and RVA of newly created data sections (so we can work with them later on) $pefile.UpdateHeaders() # Update info about new data directories in context of pefile - Import Directory, IAT $pefile.OptionalHeader.DataDirectories[[AsmResolver.PE.File.Headers.DataDirectoryIndex]::ImportDirectory] = [AsmResolver.PE.File.Headers.DataDirectory]::new($idataSection.Rva, $idataSection.GetPhysicalSize()) $pefile.OptionalHeader.DataDirectories[[AsmResolver.PE.File.Headers.DataDirectoryIndex]::IatDirectory] = [AsmResolver.PE.File.Headers.DataDirectory]::new($dataSection.Rva, $dataSection.GetPhysicalSize()) $pefile.Write($patchedSample) # We need to do some custom patching of IL only flag inside .NET Directory (it is easier than making custom writer preserving all PE sections and meta) - we are adding native imports so IL only is not true anymore $dotnetDirectoryRVA = $pefile.OptionalHeader.DataDirectories[[AsmResolver.PE.File.Headers.DataDirectoryIndex]::ClrDirectory].VirtualAddress $dotnetDirectoryFileOffset = $pefile.RvaToFileOffset($dotnetDirectoryRVA) $dotnetDirectoryILFlagsFileOffset = $dotnetDirectoryFileOffset + 16 $filestream = [System.IO.FileStream]::new($patchedSample, [System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite) $filestream.Position = $dotnetDirectoryILFlagsFileOffset $filestream.Write([byte[]]::new(4), 0, 4) # Wipe the IL only flags $filestream.Close() }
A comparison of the dotRunpeX sample before and after the described modification of the PE structure can be seen in the picture below.
Now, we get to the state where our modified binary could be executed. With the hooking library in its place, the dotRunpeX process gets suspended right during the call to WIN API CreateProcessW
. This exact routine is implemented in the function StartProcessWaitSuspended()
.
function StartProcessWaitSuspended($patchedSample) { $process = [System.Diagnostics.Process]::Start($patchedSample) while ($process.Threads.Where{$_.ThreadState -ne [System.Diagnostics.ThreadState]::Wait -and $_.WaitReason -ne [System.Diagnostics.ThreadWaitReason]::Suspended}) { Start-Sleep -Milliseconds 500 $process.Refresh() } return $process }
Once the process is suspended, it is ready to be introspected. The whole logic behind the introspection of the dotRunpeX process can be seen in the function GetPayloadAndConfig()
. In this function, we use the clrMD library to attach to the desired process and enumerate all System.Byte[]
objects that are currently allocated on the .NET heap. To reconstruct the payload intended to be injected, we have implemented some dummy logic to find byte array objects larger than 1KB and starting with the “MZ” header. Despite the fact how it sounds, it has proven to be enough to fulfill our needs.
The logic behind finding the object corresponding to the process explorer driver and config is slightly different. First of all, the procexp driver and constants related to the config are saved in the same object. We assume that this is a result of the combination of usage KoiVM virtualizer and ConfuserEx obfuscator together as ConfuserEx usually puts defined constants to one blob of byte array and resolves them during the runtime once they are needed. After the logic finds this kind of byte blob, it separates the process explorer driver and config and pushes the config for further processing.
function GetPayloadAndConfig($process) { # DataTarget is our suspended process $dataTarget = [Microsoft.Diagnostics.Runtime.DataTarget]::AttachToProcess($process.Id, $false) Start-Sleep -Seconds 1 # Better to wait for ClrMD - to properly initialize DataTarget $clrInfo = $dataTarget.ClrVersions[0] $clrRuntime = $clrInfo.CreateRuntime() # Getting all byte array objects from .NET Heap and sort them by size descending $objects = $clrRuntime.Heap.EnumerateObjects().ToArray().Where{$_.Type.Name -eq "System.Byte[]"} | Sort-Object -Property Size -Descending # Find payload to be injected - should be the largest byte array containing PE $payload = @() foreach ($object in $objects) { # Check if byte array possible valid PE if($object.AsArray().Length -gt 1024) { if((Compare-Object ($object.AsArray().ReadValues[byte](0,2)) ([byte[]] 0x4d,0x5a)).Length -eq 0) { $payload = $object.AsArray().ReadValues[byte](0, $object.AsArray().Length) break } } } if(-not $payload){Write-Host "Payload to be injected NOT found in sample:"$process.MainModule.ModuleName"!!!" -ForegroundColor Red} # Find procexp driver + config (first 8 bytes of byte array skipped -> should be related to procexp PE size) $procexpAndConfig = @() foreach ($object in $objects) { # Check if byte array possible procexp PE and config if($object.AsArray().Length -gt 1024) { if((Compare-Object ($object.AsArray().ReadValues[byte](8,2)) ([byte[]] 0x4d,0x5a)).Length -eq 0) { $procexpAndConfig = $object.AsArray().ReadValues[byte](0, $object.AsArray().Length) break } } } if(-not $procexpAndConfig) { Write-Host "Procexp driver + config NOT found in sample:"$process.MainModule.ModuleName"!!!" -ForegroundColor Red $procexp = $null $config = $null return $payload, $procexp, $config } # Process procexp and config $procexpSize = [bitconverter]::ToInt32($procexpAndConfig[4..7], 0) $procexp = $procexpAndConfig[8..($procexpSize+7)] $config = $procexpAndConfig[($procexpSize +8)..$procexpAndConfig.Length] return $payload, $procexp, $config }
The so-called config is actually a bunch of constants where some of them serve as a configuration of dotRunpeX. This config needs to be parsed in the function ParseConfig()
as it appears to be in some kind of structure where every string is preceded with its length and if needed, padded to have length divisible by 4, as shown in the picture below.
function ParseConfig($config) { $memStream = [System.IO.MemoryStream]::new($config, $true) $strLength = [byte[]]::new(4) $parsedConfig = "" while ($memStream.Position -lt $memStream.Length) { $memStream.Read($strLength, 0, 4) | Out-Null $length = [bitconverter]::ToInt32($strLength, 0) $buffer = [byte[]]::new($length) $memStream.Read($buffer , 0, $length) | Out-Null $parsedConfig += [System.Text.Encoding]::UTF8.GetString($buffer) + "`n" if(($memStream.Position % 4) -ne 0) { $memStream.Position += 4 - ($memStream.Position % 4) } } $memStream.Close() return $parsedConfig }
Once we have properly parsed the config, it is saved with extracted payload and process explorer driver, the suspended process gets killed, and the modified dotRunpeX sample is removed.
Example execution of “Invoke-DotRunpeXextract” and mass processing of samples could be seen below (2min GIF):
Figure 52: Execution of “Invoke-DotRunpeXextract” (2min GIF)
As pointed out before, “Invoke-DotRunpeXextract” will produce a payload to be injected, procexp driver, and parsed constants values where some of them could be referred to as config. Example config file content for our analyzed sample of the dotRunpeX:
False True SOFTWARE\Microsoft\Windows\CurrentVersion\Run C14615024653444192E5F79157E215D3 " I_LOVE_HENTAIU2 C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe Error 2345RTProtect 2345SafeCenterSvc 2345SafeSvc 2345SafeTray kxetray kxescore kxemain kwsprotect64 kscan HipsTray HipsDaemon 360sd 360rp QQPCTray QQPCRTP 360tray 360leakfixer 360Safe ZhuDongFangYu MultiTip AvastSvc sched avp McSvHost avconfig bdagent MsMpEng wireshark MpCmdRun ndd32 nod32 nod32krn eguiProxy ekrn Software\Classes\ms-settings\shell\open\command DelegateExecute cmd.exe /C computerdefaults.exe Run without emulation Select * from Win32_ComputerSystem Manufacturer microsoft corporation Model VIRTUAL vmware VirtualBox This file can't run into Virtual Machines. root\CIMV2 SELECT * FROM Win32_VideoController Name VMware VBox Run using valid operating system SbieDll.dll USER SANDBOX VIRUS MALWARE SCHMIDTI CURRENTUSER \VIRUS SAMPLE C:ile.exe Afx:400000:0 HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0 Identifier VBOX HARDWARE\Description\System SystemBiosVersion VideoBiosVersion VIRTUALBOX SOFTWARE\Oracle\VirtualBox Guest Additions noValueButYesKey C:\WINDOWS\system32\drivers\VBoxMouse.sys VMWARE SOFTWARE\VMware, Inc.\VMware Tools HARDWARE\DEVICEMAP\Scsi\Scsi Port 1\Scsi Bus 0\Target Id 0\Logical Unit Id 0 HARDWARE\DEVICEMAP\Scsi\Scsi Port 2\Scsi Bus 0\Target Id 0\Logical Unit Id 0 SYSTEM\ControlSet001\Services\Disk\Enum 0 SYSTEM\ControlSet001\Control\Class\{4D36E968-E325-11CE-BFC1-08002BE10318}\0000 DriverDesc SYSTEM\ControlSet001\Control\Class\{4D36E968-E325-11CE-BFC1-08002BE10318}\0000\Settings Device Description InstallPath C:\PROGRAM FILES\VMWARE\VMWARE TOOLS\ C:\WINDOWS\system32\drivers\vmmouse.sys C:\WINDOWS\system32\drivers\vmhgfs.sys kernel32.dll wine_get_unix_file_name QEMU \\.\ROOT\cimv2 Description VM Additions S3 Trio32/64 S3 Trio32/64 VirtualBox Graphics Adapter VMware SVGA II noKey Fatal 'Error C:\windows\system32\cmd.exe /K "fodhelper.exe" C:\windows\temp \ .inf REPLACE_COMMAND_LINE /au cmstp {ENTER} [version] Signature=$chicago$ AdvancedINF=2.5 [DefaultInstall] CustomDestination=CustInstDestSectionAllUsers RunPreSetupCommands=RunPreSetupCommandsSection [RunPreSetupCommandsSection] ; Commands Here will be run Before Setup Begins to install REPLACE_COMMAND_LINE taskkill /IM cmstp.exe /F [CustInstDestSectionAllUsers] 49000,49001=AllUSer_LDIDSection, 7 [AllUSer_LDIDSection] "HKLM", "SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\CMMGR32.EXE", "ProfileInstallPath", "%UnexpectedError%", "" [Strings] ServiceName="CorpVPN" ShortSvcName="CorpVPN" c:\windows\system32\cmstp.exe Windows 1 Windows 8 Windows 7 fodhelper Software\Classes\exefile\shell\open\command slui Software\Classes\mscfile\shell\open\command eventvwr HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion ProductName HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Notifications\Settings\Windows.SystemToast.SecurityAndMaintenance Enabled HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System EnableLUA powershell Software\Classes\Folder\shell\open\command SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths Add-MpPreference -ExclusionPath " " -Force Иисус.sys \Registry\Machine\System\CurrentControlSet\Services\TaskKill System\CurrentControlSet\Services\TaskKill \??\ Type ErrorControl Start ImagePath \\.\ SeDebugPrivilege SeLoadDriverPrivilege \KnownDlls\ ntdll.dll ZwOpenSection ZwMapViewOfSection NtClose ZwUnmapViewOfSection MZ _4 BIDEN_HARRIS_PERFECT_ASSHOLE
We can easily spot configuration strings related to persistence settings, resource name and its decryption key (where .NET resource contains payload to be injected), target binary for the payload to be injected in, Anti-Malware service names to be killed, UAC bypass, Anti-VM, Anti-Sandbox, procexp driver installation path and its name, etc.
We provide two versions of this tool that can process just one sample or mass-process the directory of samples. For the best performance, the multi-threaded PowerShell module is recommended use. Still, for troubleshooting, simple modification, and easy debugging, we are also providing a single-threaded script with the same functionality as we expect soon some modification in dotRunpeX code where appropriate changes in the code of the tool or hooking library would be needed.
By monitoring this new threat for several months, we got deep insight into its evolution, delivery methods, and how it was abused to deliver a wide scale of different malware families.
Over time, we consider dotRunpeX to be in high development adding new features on regular bases and getting more popularity and attention every day. Because of the rising usage of this injector, we developed and provided several tools to automate the analysis of this virtualized dotnet code.
Some of the developed tools described in this report introduced PoC methods and can serve for developing other tools with similar functionality. We showed how open-source libraries such as AsmResolver and clrMD could be used in a real-world example to support the research and to help with the reverse engineering of protected code.
In this report, we provided an in-depth analysis of both versions of the dotRunpeX injector, the similarities between them, and described the main interesting techniques they use, such as abuse of the vulnerable process explorer driver, code virtualization caused by the usage of KoiVM protector, modification of D/Invoke framework with decoy syscall patching.
Our analysis and conclusions are based on dozens of campaigns we spotted in the wild and hundreds of samples that were mass processed.
Because of the high development of dotRunpeX, we believe that provided tools would need some modification soon as a reaction to changes in dotRunpeX. Still, with provided source codes, it should be relatively easy to work around these changes for other researchers.
Check Point customers remain protected from the threats described in this blog, including all its variants. Check Point’s Threat Emulation protects networks against unknown threats in web downloads and e-mail attachments. The Threat Emulation engine picks up malware at the initial phase before it enters the network. The engine quickly quarantines and runs the files in a virtual sandbox environment, which imitates a standard operating system, to discover malicious behavior at the exploit phase.
Harmony Email & Office deploys between the inbox and its native security. The solution secures inbound, outbound, and internal email from phishing attacks that evade platform-provided solutions and email gateways. It works with these other solutions and doesn’t require any MX record changes that broadcast security protocols to hackers.
SHA256 Hash | Version | Malware family of embedded payload |
---|---|---|
1e7614f757d40a2f5e2f4bd5597d04878768a9c01aa5f9f23d6c87660f7f0fbc | OLD | Lokibot |
68ae2ee5ed7e793c1a49cbf1b0dd7f5a3de9cb783b51b0953880994a79037326 | OLD | Lokibot |
317e6817bba0f54e1547dd9acf24ee17a4cda1b97328cc69dc1ec16e11c258fc | OLD | Redline |
65cac67ed2a084beff373d6aba6f914b8cba0caceda254a857def1df12f5154b | OLD | SnakeKeylogger |
81763d8e3b42d07d76b0a74eda4e759981971635d62072c8da91251fc849b91e | OLD | SnakeKeylogger |
0e11704fcc3c36832ba98b80ea44a3013660d1ed3fb48158b982fed9f9050391 | NEW | AgentTesla |
0f9e27ec1ed021fd7375ca46f233c06b354d12d57aed44132208cd9308bfee11 | NEW | AgentTesla |
881a337aa85a4b01c08706ab941573c5dc9b76ea0e4e1c2693a9b4aa4453ec8c | NEW | AgentTesla |
feae44d8927dd41feaed997b3dbf7b41933496d6285b79554b83e72ae8a045c4 | NEW | AgentTesla |
1c1fcc4133af77f07d0c0299d0320aa9f447748ebead74b429f73c44d950e38b | NEW | AgentTesla |
35c11f7315d2e5d04d783de4314d8cde2def382f1e3fc49ccc555337c54d63cc | NEW | AgentTesla |
4068637c121888476533a3bbb16bec6bc3b4f81f7b9de635ef3576d56dc54c75 | NEW | AgentTesla |
40df5a6e6dcadbe576ce4a8b01cfb82bf3f56a87bae674200e60814eab666c6d | NEW | AgentTesla |
8a0d6e40e545d40956194230f03608859f2a47420a9b11b199142641bc6419ee | NEW | AgentTesla |
7c3803c09a0370aa6484d8ad2f5690b96212d98e45fc8f9cb6022f87dff637fc | NEW | AgentTesla |
93e2ea6f021951369028b73637d9558c8baf3c99d9de1a2a60c1461cb9d571bf | NEW | AgentTesla |
d95298befdde567b31571d16f327840fa0f0dd9c54bf876531820910418a52b6 | NEW | AgentTesla |
149af913afd7eb2773386d14e88a46449cbc9096e0748cfbaa2e061b59525bf0 | NEW | AgentTesla |
a73f134ab62a5c23a8c8bafabbfbd5e0408c826ba5418488639724708ec5ef28 | NEW | AgentTesla |
aca4d6278f31f374262e0388d16ee6fdcdbbad8257374f1feaabf75b0ec23157 | NEW | AgentTesla |
50451fda27fd8569c7b32bfe82197b82a8637cac928164e1b091a389060e957e | NEW | AgentTesla |
9ed8eeb1db8909c96a958d91213093d2488dc172a8d22ba62657b9bfeb044fec | NEW | AgentTesla |
6c08c0654726c2f793b5191d5e7c74fdf3a2461118a45aa8527a0a30e3f256fd | NEW | AgentTesla |
283cd48dc1368b6852c2f3168bf7a78ad593df010d9a67ed1c938508da5de783 | NEW | AgentTesla |
b019a0535ca7466d7884825542ac6910fe037913118e1136dcac7e9ef3dc0dc9 | NEW | AgentTesla |
b1c9b356c50230629c4697b0527fd7a0fa8d6f0e8342a1eb5b5a4f90d8f0eb86 | NEW | AgentTesla |
5bbd9513f0872d23ca43dd553a63a12882be274fef983fab427721257d60eaec | NEW | AgentTesla |
9d9940b60809e3c10cd4540f8e589626a293244a999bea16c259f9712969a742 | NEW | AgentTesla |
cd4c821e329ec1f7bfe7ecd39a6020867348b722e8c84a05c7eb32f8d5a2f4db | NEW | AgentTesla |
cddf8b8da972cb2e560c70d01366f582445441864fcff884b8194eb6c21a768c | NEW | AgentTesla |
6c367333c677c2268df9deaff6ad4e711e73e53504aa1aa845bebfbfe635f1d2 | NEW | ArrowRAT |
5e3588e8ddebd61c2bd6dab4b87f601bd6a4857b33eb281cb5059c29cfe62b80 | NEW | AsyncRat |
244f2d4f3c34d00babef5f1765e91c0abda9dbd1d131fc93ecb48c91ecc801a8 | NEW | AsyncRat |
95793df9284fe35c0491e5cfa36bc8f49fd426ccdf35f5fe2f098e07d160a4dc | NEW | AveMaria/WarzoneRAT |
55ee7efcb3d1d2e0eac0ecadd651d6a299de82d94347ef9862bc981ae619532b | NEW | BitRAT |
13081992c0ef5c52c2b6224f3ff1ab38160bca9424e7c0470e0c175c920bdc9d | NEW | Cryptocurrency Stealer |
0daef2c2bf086312037ebc91beec0302a7e4d1750f260d02bf815bd13c611559 | NEW | Downloader |
331ad58c524100da7e459e5c3943e970414617f60b3ed0f1a74f3bf189aafea7 | NEW | Downloader |
44a11146173db0663a23787bffbb120f3955bc33e60e73ecc798953e9b34b2f2 | NEW | Downloader |
03fcbab82603df2858f7d6fefdb6ae3cc8e17393af6d44f24634d28fccf3f181 | NEW | Formbook |
373a86e36f7e808a1db263b4b49d2428df4a13686da7d77edba7a6dd63790232 | NEW | Formbook |
50ec8a9e59e1bcb0a41477e20f5bb809a80329d56e20cf99e93d756b9e0ceefc | NEW | Formbook |
41ea8f9a9f2a7aeb086dedf8e5855b0409f31e7793cbba615ca0498e47a72636 | NEW | Formbook |
76e129552a30fa5c914d9f946f40b2ec2bbbbeb4e5e2f324e70455725030e157 | NEW | Formbook |
8fa81f6341b342afa40b7dc76dd6e0a1874583d12ea04acf839251cb5ca61591 | NEW | Formbook |
ae4f3b6c43d5ea8ee68d862362d4e8d7b317889eb9abead948a9b791ad9d7071 | NEW | Formbook |
b4c876d1797efbef614b44e52482c835c32e8ee020975a30fa2d25ed9cf8aa2b | NEW | Formbook |
d5eda02ff2f05d1e0d06a69018de463ab36497048a1ef2b69af93aa76ccfc07d | NEW | Formbook |
fa3a9fc2adf9d1ca812e0951e21bf72ba3ec9ceb1c0cf0bfc0171b6d4adadf83 | NEW | Formbook |
1f2ffabb3b89e6083ca5de70f5d718295c7a633c2d957da7c4469de059efde2c | NEW | Formbook |
bd133efea4b865f42eb05e0c92e3ab3b58ac087c0682ea9112b96596a7111ff6 | NEW | Formbook |
e6da2d860bd2d0e8b56737b4c8c47cdeea78a404cd0d6fa5a26cbb5ac7682d1d | NEW | Formbook |
d87a200a26d07a64272e93fb3ae8f8d9e4d34bdfedb0cf7c685a6c97912e967f | NEW | LgoogLoader |
7120cf1ad3fdcae7ba6956749a8988e8181837a05948b432cec6ae11229b1d12 | NEW | LgoogLoader |
304847c69875ec59995fbb453f8d1106f80c5eb380ae6b8676e76f5372290194 | NEW | NetWire |
25fbe0ff3274b4bc981fa6ec0459e9b95cec6397194e10ea6287bf4b899a9b07 | NEW | PrivateLoader |
1bc7fc0a4796f7780223b4f0bf8d6816b3721f0b52eedc0df9a32dc4ea4829e8 | NEW | PrivateLoader |
75236a06aadafc69cc5aa8032468869fb868a9a100b687f19c66be03410c2487 | NEW | PrivateLoader |
ee0d55b9a2d03c5bea9f69f98b042ab7b3064366f335a8a53096387876bf48d7 | NEW | PrivateLoader |
8de23e90bac05911cbfb6b036c6808ce7c244e4e875cb7edcdb90f75e89e5476 | NEW | PrivateLoader |
10bbfa36ddd8ea6038e2071320ee84f7a9208a5be3a4dda448e83393cdf39a4d | NEW | PrivateLoader |
ff72f619907a25f3d99f0c3aa84710c6ff6cb4c3fd8ebad14f85f96c6da49222 | NEW | PrivateLoader |
242e1c82269725c01108e52376be8ddad39ab29da49356d10e527af6d78058f5 | NEW | PrivateLoader |
ae4d2054a6e1f9ba2c269eace61aac7259adb0645d18da82779717d83174837d | NEW | PrivateLoader |
bf7b127b1bb81b68439851386cd3d1600bb8b9ec56135e668a88062d913410dd | NEW | PrivateLoader |
b8bb071899ae7bd16a328c0998b3cd40261d61e564ac77f9bf3e495fab0ad267 | NEW | QuasarRAT |
17af8118607b9fc1f7b6aa82fd72f4fc115320d293e103dfe356706bb7c581b7 | NEW | RecordBreaker – Raccoon Stealer 2.0 |
366284c1a0577937c86744349ac47e6e578da500ada3deb857ff233d9851ee6b | NEW | RecordBreaker – Raccoon Stealer 2.0 |
3e50f0eaf02d12653d5f757372240adcb5c16a5ab647a667637ba4c50d37aaad | NEW | RecordBreaker – Raccoon Stealer 2.0 |
47849f610a30d72660b1725a0b18d78c5204257b3740641727bdcbfd1ebd466a | NEW | RecordBreaker – Raccoon Stealer 2.0 |
507f413ac42df115988df498a90fc1ae610cafb66cb30a3a7de53e71ec90e7cd | NEW | RecordBreaker – Raccoon Stealer 2.0 |
57f261cc442dd9a4f1cd4ffd281c9855f4f9a736abffaf539d9df2a6ea0dd409 | NEW | RecordBreaker – Raccoon Stealer 2.0 |
76eed1849d0a0474f9e0a58afcda2cc1ea7af316535b4b4b27ff810a162d4f8f | NEW | RecordBreaker – Raccoon Stealer 2.0 |
855b2e04c323a269d3731c093f0bc80ab3497a69ab8d2967847451a87f04fb0a | NEW | RecordBreaker – Raccoon Stealer 2.0 |
87134629723b2c6f4d0a74c35fdce89653471d9880b23f4faea6664ae151db0e | NEW | RecordBreaker – Raccoon Stealer 2.0 |
8bcc23ec881d61839fc57e8ec7425ac5ed625425fbf265fcb53ad73a73825b18 | NEW | RecordBreaker – Raccoon Stealer 2.0 |
9177ba0c649f08fa6367d04091a7672fedb82215b26e08346645544f0631ebfd | NEW | RecordBreaker – Raccoon Stealer 2.0 |
9246ed27032429f234888b2713529001344850c608cab9f5ab7274195d330bec | NEW | RecordBreaker – Raccoon Stealer 2.0 |
a487e959e59bc9500c43ac270eaf345eaf28173b07ed7dd82b2495aa19cdab88 | NEW | RecordBreaker – Raccoon Stealer 2.0 |
ada1679a193c9b17b206b3d9ff2a19d64c6c8c5f882a321381c9d5347a8b4b3e | NEW | RecordBreaker – Raccoon Stealer 2.0 |
c1be6f792bd51d23d848e54cd217bdf9edcbb2b89df741190929f6fa327a10cb | NEW | RecordBreaker – Raccoon Stealer 2.0 |
db8ed3e6dd7e6818046e7ee1e9c6c91f98aa5ce3113b14fb1c85a50a45569b18 | NEW | RecordBreaker – Raccoon Stealer 2.0 |
ddae8737d7cc35a87274a26b886e6b48ae947aa849c3d7ecb84de6f6d553aa96 | NEW | RecordBreaker – Raccoon Stealer 2.0 |
efa9a303af112ffb6737846755e3a995510fd65b6ced9032dc68cd7bbe4c307d | NEW | RecordBreaker – Raccoon Stealer 2.0 |
20b5c7f210320cf23a63ac7f76086a6e257dd0c248d77deff444cb3dcf624799 | NEW | RecordBreaker – Raccoon Stealer 2.0 |
f0ee1ddb789207c2000f728f6adabbe344ded7cba0804926a7cfc53bdbbc54eb | NEW | RecordBreaker – Raccoon Stealer 2.0 |
f440309e372551fb6ee00ecca71a70a1b8b7e077fe61b0687411147b582ab415 | NEW | RecordBreaker – Raccoon Stealer 2.0 |
21a570237cdacdb8c69679e59c4dba6aa05f123f9db7470ec34e2f4024c3646b | NEW | RecordBreaker – Raccoon Stealer 2.0 |
4e8bf8c770727a3b0f551adcff2716c941234708e679c868ce42532714a29d27 | NEW | RecordBreaker – Raccoon Stealer 2.0 |
3c0c55b4ce2d90448949980fbca1fa447832f67fb864472551513b6e4eff5304 | NEW | RecordBreaker – Raccoon Stealer 2.0 |
61b5b6a513be380d50282c1c8391a5362d746bd70506343d04bda3751c3b25de | NEW | RecordBreaker – Raccoon Stealer 2.0 |
a4d455f65bb4d2dde03a0686433b6d515c71b5655fa78b86a4f9bdae503c1295 | NEW | RecordBreaker – Raccoon Stealer 2.0 |
c9d36fcce70893aa16a846b48009bbd8b46fc11c6821b750083a9c89669038cc | NEW | RecordBreaker – Raccoon Stealer 2.0 |
04a1021d0880a4f13ed8693dfe65889a5f827fe5ee9369abbc00b58efc40e69b | NEW | Redline |
13eb08dda92356f21888d95a6611a46728dfcefcdf769e7edad1a70e958e5367 | NEW | Redline |
20330ec79f6c6edce8c3d87e3340aebc60f528d3751339e57437b178b9cb914d | NEW | Redline |
22962d59a066795696464868700fa7d3f735bfdb494a7a879fb54668a0ca3d46 | NEW | Redline |
2b1be3ea73921adde804b85e93817869556fa9919bf7a528639a796e27351755 | NEW | Redline |
301be47a8fefa749d904425b43ae459249e2b44ff62051f3a5529d6222259f42 | NEW | Redline |
410b032a8635fba6cc30f0c2049a53f93b98128388a4a7ce2c3a0bfb33591f9f | NEW | Redline |
43d49812cc723b3c24ca7048faa859800c7e303e074243e4348f65d34127367b | NEW | Redline |
47c765ad0baae96498e05e3f0984002cbce6b3f1bacd1cf238681a677c2f8036 | NEW | Redline |
482765b55aecbf24eb102f531afb6c8905ab7a058a447d217be70984f15b4573 | NEW | Redline |
50b7e742eea52e18cf908cd676b87c0f145ecc3ff9692b01c90c47750fe989a7 | NEW | Redline |
70a6d43a56d267aa4fdac5a96722a2ff05e2ac1cc9ba996d173f0b3252e09898 | NEW | Redline |
7263336f1ec49f936501c508a9edf072a81002e64e52a1ed0cafb1378bb07a2a | NEW | Redline |
770e7d287fe352f12757ebfbb4502b10f61001630d70ddf414157b12e1f5e9a3 | NEW | Redline |
87f5b4385a2a87229b6c448a3b4b19a7e75fe6bc607dffc0e1f860e9e4499eca | NEW | Redline |
adc5669dd1153111f4cc07714599145a775d8c260c1acae9c142280147d1793a | NEW | Redline |
b80b3dae21d54eb9ccde40b9ba728ba3d45a73e0fc91adae3d7c375208631527 | NEW | Redline |
e35547cfb6ae3fe18df6d887334952e7a38cc51a230f02c7f62a5fef083de7cf | NEW | Redline |
f570b6c46a5bb5a8757b1125c7d4b5d4aca2c7e9354ed1d34b78fd4f08280e30 | NEW | Redline |
f6aba045ca29ba39bbdcb2f8bde63efc971d138f88bf03aea2d13ddec88a0483 | NEW | Redline |
fefb4288cb41fcca85cd50653093d7b27c9c51769b03f72adf951c5a1f111ddf | NEW | Redline |
f79273a1efb664d81f68e808b9ec963bfeb79d63bd277108863d6ae3c4801a9e | NEW | Redline |
24c870202b3aedfcd28a8afb93b5212b791c265abd872ef94e44401d1ca309ad | NEW | Redline |
417c3f327c2d8b54ec72a5a89280fecb589a3e0b89c281bbc077d7de445cc76b | NEW | Redline |
948416d3aeae6f31df3341118a25a4231a7eed23b3db73a022e9da70734163c9 | NEW | Redline |
71cc196ad2103a1facd81f2b8bd985273f682019b2a88841d2f34ecc373d1d69 | NEW | Redline |
7bdb945f2dab863a299e26ab4c6dfb1e4f7321c38fe101224252d993495bc157 | NEW | Redline |
0bb4d022d6007fcaf1d0707b646063b4b66cf5177da6a1fc6c5d0fc217501d6f | NEW | Redline |
0e918ad3e7ad983ecf6c3238991c13a230acc897193e0ad360d2eeaab42bf078 | NEW | Redline |
f413dbf6764bc73ab94428831e0ce3fc0369856aa50c4f9c0f5948eac85d2d08 | NEW | Redline |
670a96324222e6bb02bd36c7e5b100fb5d52d2d59891bd9599b1a47438ac9578 | NEW | Redline |
9049d536e6da46b63c562197ab92f511d5f5e2883eb8bf29f72217282ae25772 | NEW | Redline |
116d81561faa8c8a9cf4fbc947e9eee11185f3960daead8179a968dea143bfd0 | NEW | Redline |
9984a21c06fea77e96ba410cffb99de530201ef0c74f3e8b38b3afd4fdf0b333 | NEW | Redline |
bcc80eabe068cbbe38fa37b58e67fee54af75fa9e8a1fc30d93b7d30886d05da | NEW | Redline |
202570439b32480e6df232977d5435be9be94822c75f89b09f571e5b03f8c9ab | NEW | Redline |
96b5ea21a2556486cebbed76711a8bbae42de1e97e3311213833c6567a4fbbdc | NEW | Redline |
35c53663294e5476315853228b4ae642f552c6c6b1253412a7f981c7ddf3d0b7 | NEW | Remcos |
8c451b84d9579b625a7821ad7ddcb87bdd665a9e6619eaecf6ab93cd190cf504 | NEW | Remcos |
7d8c18056e86a3b8c32b524f9de009ced61caf463abe1bca285fa305d4b5616a | NEW | Rhadamanthys |
a2e9a2389faf04b67fbbd6fc71134860a145db7643d88ba312390493d5619302 | NEW | Rhadamanthys |
9f96e5bc9ffc9742cb10384566dc7fb232e0f0d633e643bd487b747b6e88f369 | NEW | Rhadamanthys |
71ecfddc7fe52a10bdf79c39cf9a1d911257ed0deee1bfef21386053bfe88110 | NEW | Rhadamanthys |
96e49a5ac188d49003b2fe77ad8a4c8866a94cc828dc6172d9a13a8c26e49b9b | NEW | Rhadamanthys |
5474d15059ca4213ab1c13fba25ab8ba38559cac7ec2ab336d2411b90eab1217 | NEW | SnakeKeylogger |
eb2e2ac0f5f51d90fe90b63c3c385af155b2fee30bc3dc6309776b90c21320f5 | NEW | SnakeKeylogger |
02355d3fee5e217b25f9210ad0f6bacc3807b6ef1a59aa4d428c01017dcbcf28 | NEW | Vidar |
05f9553616bb5fdbf37bd4036c210929e08d7181de898c1bea1bdae7afb0766f | NEW | Vidar |
0c857501e3851072db666386136929c06bcf4c8d3160b41b7d82a3ce9afca1be | NEW | Vidar |
3418a369486e9bf2b57023dc0b02cb00f12a5214fca8bae20ff93586cc8c678a | NEW | Vidar |
363c46dfb252d7c40d9c3bb63bdc40c2eff0ce16c0c1b77f507d73058104c6e1 | NEW | Vidar |
4c17f7ee55f9bf6fa9acaeeb9574feab39ba4a3cccd4426dfa85aaf58b90ae73 | NEW | Vidar |
4d4f97f1621334e4075e0229265ac6c5da14754eff1378a7d77ea6d3821e8a33 | NEW | Vidar |
87b92fcd04f69f9c132c9f350dbb3686888a5e388b1f787f6a658f09582c0da6 | NEW | Vidar |
99e733391ac499e78e535a98551c4d27408abfad4e56fe4c46956636655df29c | NEW | Vidar |
b67bc78347918209973d633287c4e1f514a0917b8678c2cf2066ba80b2004f78 | NEW | Vidar |
c6e0a5e947e9f23cd0af6fa8bd44411a12212ab1de5007036926089800ac8692 | NEW | Vidar |
cb014704f53d5da64964c2b0bfc7e13bbdf389555294c6f6c98c2527f6406d6d | NEW | Vidar |
d55f6b273254d2be71991cdbdb288cc94a7bc715c4be7ad97c0e1625bc0f2696 | NEW | Vidar |
d6fd4a75e32f78817f84de3dcb9e3fd767f602b7da1edecd06391ff62a481571 | NEW | Vidar |
e56c525248b1f9201cddcf1802377a7157029e8935696d1a9d9169e1d0501fa4 | NEW | Vidar |
e6a2575c893868e3d8ea5982699c9c2b75a07b8ec092b0cb26d7b5c3c2640f33 | NEW | Vidar |
ec875c5901e28a04b199f577b16a8ba6ac8c9ab7e90bc51a5809f668882ba54f | NEW | Vidar |
b4a57b62569ee1ccb1c2dae148488dc9e37d738f0fed4f0a6e144caeb910f546 | NEW | Vidar |
f9c25b4755ab54ff3f8d827b6422d43ed14dbd03fd4faa266348eee177f7957f | NEW | Vidar |
fa258b12d3f4ca1503379a4f6a800bdb1d589ef15ab8bfc20d452f70c8a0745c | NEW | Vidar |
fcc4c20c07fdf816b7cc6dfba34d42af827ecf01e9972f266ac395e54db028af | NEW | Vidar |
a19cabf8ce0a8012dedbf65855981db1efa3b9773365554401a74bfb7a45490f | NEW | Vidar |
7f801c77fb61cc8d5c03e9fa3068163b595f5bf8c176628398bbbea5aa0a1b74 | NEW | Vidar |
63de4552312345e055236c82ecdc55c2bc8b3c37f363cb081f8f788b5203d759 | NEW | Vidar |
2478cd52847146b34cae6b768c794210838a3002a622ce61c2f90d075f6e0e65 | NEW | Vidar |
c5646cc9fe486f0644067fc294f83eb6a39ce6f28eea3708c9bf49e244acc0f9 | NEW | Vidar |
fc99e6083b1dcbe72fb818dbd53903f30c312731f2cfc8607f9d2bf2586be1ee | NEW | XWorm |
rule injector_ZZ_dotRunpeX { meta: description = "Detects new version of dotRunpeX - configurable .NET injector" author = "Jiri Vinopal (jiriv)" date = "2022-10-30" hash1 = "373a86e36f7e808a1db263b4b49d2428df4a13686da7d77edba7a6dd63790232" // injects Formbook hash2 = "41ea8f9a9f2a7aeb086dedf8e5855b0409f31e7793cbba615ca0498e47a72636" // injects Formbook hash3 = "5e3588e8ddebd61c2bd6dab4b87f601bd6a4857b33eb281cb5059c29cfe62b80" // injects AsyncRat hash4 = "8c451b84d9579b625a7821ad7ddcb87bdd665a9e6619eaecf6ab93cd190cf504" // injects Remcos hash5 = "8fa81f6341b342afa40b7dc76dd6e0a1874583d12ea04acf839251cb5ca61591" // injects Formbook hash6 = "cd4c821e329ec1f7bfe7ecd39a6020867348b722e8c84a05c7eb32f8d5a2f4db" // injects AgentTesla hash7 = "fa8a67642514b69731c2ce6d9e980e2a9c9e409b3947f2c9909d81f6eac81452" // injects AsyncRat hash8 = "eb2e2ac0f5f51d90fe90b63c3c385af155b2fee30bc3dc6309776b90c21320f5" // injects SnakeKeylogger strings: // Used ImplMap imports (PInvoke) $implmap1 = "VirtualAllocEx" $implmap2 = "CreateProcess" $implmap3 = "CreateRemoteThread" $implmap4 = "Wow64SetThreadContext" $implmap5 = "Wow64GetThreadContext" $implmap6 = "NtResumeThread" $implmap7 = "ZwUnmapViewOfSection" $implmap8 = "NtWriteVirtualMemory" $implmap9 = "MessageBox" // ImplMap not presented in all samples - maybe different versions? $implmap10 = "Wow64DisableWow64FsRedirection" $implmap11 = "Wow64RevertWow64FsRedirection" $implmap12 = "CreateFile" $implmap13 = "RtlInitUnicodeString" $implmap14 = "NtLoadDriver" $implmap15 = "NtUnloadDriver" $implmap16 = "OpenProcessToken" $implmap17 = "LookupPrivilegeValue" $implmap18 = "AdjustTokenPrivileges" $implmap19 = "CloseHandle" $implmap20 = "NtQuerySystemInformation" $implmap21 = "DeviceIoControl" $implmap22 = "GetProcessHeap" $implmap23 = "HeapFree" $implmap24 = "HeapAlloc" $implmap25 = "GetProcAddress" $implmap26 = "CopyMemory" // ImplMap added by KoiVM Protector used by this injector $modulerefKernel1 = "Kernel32" $modulerefKernel2 = "kernel32" $modulerefNtdll1 = "Ntdll" $modulerefNtdll2 = "ntdll" $modulerefAdvapi1 = "Advapi32" $modulerefAdvapi2 = "advapi32" $regPath = "\\Registry\\Machine\\System\\CurrentControlSet\\Services\\TaskKill" wide // Registry path for installing Sysinternals Procexp driver $rsrcName = "BIDEN_HARRIS_PERFECT_ASSHOLE" wide $koiVM1 = "KoiVM" $koiVM2 = "#Koi" condition: uint16(0) == 0x5a4d and uint16(uint32(0x3c)) == 0x4550 and ($regPath or $rsrcName or 1 of ($koiVM*)) and 24 of ($implmap*) and 1 of ($modulerefKernel*) and 1 of ($modulerefNtdll*) and 1 of ($modulerefAdvapi*) }
rule injector_ZZ_dotRunpeX_oldnew { meta: description = "Detects new and old version of dotRunpeX - configurable .NET injector" author = "Jiri Vinopal (jiriv)" date = "2022-10-30" hash1_New = "373a86e36f7e808a1db263b4b49d2428df4a13686da7d77edba7a6dd63790232" // injects Formbook hash2_New = "41ea8f9a9f2a7aeb086dedf8e5855b0409f31e7793cbba615ca0498e47a72636" // injects Formbook hash3_New = "5e3588e8ddebd61c2bd6dab4b87f601bd6a4857b33eb281cb5059c29cfe62b80" // injects AsyncRat hash4_New = "8c451b84d9579b625a7821ad7ddcb87bdd665a9e6619eaecf6ab93cd190cf504" // injects Remcos hash5_New = "8fa81f6341b342afa40b7dc76dd6e0a1874583d12ea04acf839251cb5ca61591" // injects Formbook hash6_New = "cd4c821e329ec1f7bfe7ecd39a6020867348b722e8c84a05c7eb32f8d5a2f4db" // injects AgentTesla hash7_New = "fa8a67642514b69731c2ce6d9e980e2a9c9e409b3947f2c9909d81f6eac81452" // injects AsyncRat hash8_New = "eb2e2ac0f5f51d90fe90b63c3c385af155b2fee30bc3dc6309776b90c21320f5" // injects SnakeKeylogger hash1_Old = "1e7614f757d40a2f5e2f4bd5597d04878768a9c01aa5f9f23d6c87660f7f0fbc" // injects Lokibot hash2_Old = "317e6817bba0f54e1547dd9acf24ee17a4cda1b97328cc69dc1ec16e11c258fc" // injects Redline hash3_Old = "65cac67ed2a084beff373d6aba6f914b8cba0caceda254a857def1df12f5154b" // injects SnakeKeylogger hash4_Old = "68ae2ee5ed7e793c1a49cbf1b0dd7f5a3de9cb783b51b0953880994a79037326" // injects Lokibot hash5_Old = "81763d8e3b42d07d76b0a74eda4e759981971635d62072c8da91251fc849b91e" // injects SnakeKeylogger strings: // Used ImplMap imports (PInvoke) $implmap1 = "VirtualAllocEx" $implmap2 = "CreateProcess" $implmap3 = "CreateRemoteThread" $implmap4 = "Wow64SetThreadContext" $implmap5 = "Wow64GetThreadContext" $implmap6 = "RtlInitUnicodeString" $implmap7 = "NtLoadDriver" $implmap8 = "LoadLibrary" $implmap9 = "VirtualProtect" $implmap10 = "AdjustTokenPrivileges" $implmap11 = "GetProcAddress" $modulerefKernel1 = "Kernel32" $modulerefKernel2 = "kernel32" $modulerefNtdll1 = "Ntdll" $modulerefNtdll2 = "ntdll" $regPath = "\\Registry\\Machine\\System\\CurrentControlSet\\Services\\TaskKill" wide // Registry path for installing Sysinternals Procexp driver $rsrcName = "BIDEN_HARRIS_PERFECT_ASSHOLE" wide $koiVM1 = "KoiVM" $koiVM2 = "#Koi" condition: uint16(0) == 0x5a4d and uint16(uint32(0x3c)) == 0x4550 and ($regPath or $rsrcName or 1 of ($koiVM*)) and 9 of ($implmap*) and 1 of ($modulerefKernel*) and 1 of ($modulerefNtdll*) }