Connects to any signal across any vendor stack and powers adaptive AI Operatives that expose, detect, and neutralize cyberattacks.
Atlas Operations CenterSee what our SOC sees, review investigations, and see how we are protecting your business.
Technology IntegrationsAtlas connects to any signal across your current security tools. Whatever you're running, we're running with you.
Extend your team with immediate expertise, hands-on remediation, and the human accountability layer that boards, regulators, and cyber insurers require.
Threat Response UnitProactive threat intelligence, original threat research and a world-class team of seasoned industry veterans.
Response and RemediationPairs machine-speed containment with human judgment, delivering full threat response that's policy-bounded, reversible, and explainable.
MDR that moves first, multi-signal attack surface coverage, and 24/7 Elite threat hunters working as one continuous security program across any vendor stack.
Get unlimited Incident Response with threat suppression guarantee- anytime, anywhere.
Atlas Preempt deploys AI Operatives to continuously validate attack paths exposing attacker targets of opportunity before they take advantage.
Protect insurance operations from cyber attacks.
ConstructionSecure project data and jobsite operations.
FinanceDefend financial services from cyber disruption.
LegalSafeguard client data and legal operations.
ManufacturingStop threats before they disrupt production.
Private EquityProtect portfolio companies from cyber risk.
HealthcareDefend patient data and clinical operations.
RetailProtect customer data and retail operations.
Food SupplySecure the food supply chain from cyber threats.
Government and EducationProtect public sector and education systems.
Automotive DealershipsSecure dealership operations and customer data.
Stop ransomware before it spreads.
Identity ResponseStop identity-based cyberattacks.
Zero Day AttacksDetect and respond to zero-day exploits.
Cybersecurity ComplianceMeet regulatory compliance mandates.
Third-Party RiskDefend third-party and supply chain risk.
Cloud MisconfigurationEnd misconfigurations and policy violations.
Cyber RiskAdopt a risk-based security approach.
Mid-Market SecurityMid-market security essentials to prioritize.
Sensitive Data SecurityProtect your most sensitive data.
Cyber InsuranceMeet insurability requirements with MDR.
Cyber Threat IntelligenceOperationalize cyber threat intelligence.
Security LeadershipBuild a proven security program.
As of September 29th, 2026, eSentire has observed in-the-wild exploitation of CVE-2026-88771 and CVE-2026-88772, with identified attacks being traced back to early-September. CVE-2026-88771…
On September 27th, 2026, Citrix disclosed eight vulnerabilities impacting its Citrix NetScaler ADC and NetScaler Gateway products; two of which are zero-days. The first zero-day…
eSentire is a leader in Controlled Autonomy SecOps, protecting 2,000+ organizations across 35+ industries around the world. Founded in 2001, the company’s Controlled Autonomy SecOps operating model pairs agentic AI operatives with engineered human-judgment controls, delivering expert-depth security outcomes at machine speed without ceding accountability to opaque automation.
About Us Leadership Careers Event Calendar → Newsroom → Aston Villa Football Club →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.
Search our site
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.
On August 31, 2026, eSentire's Threat Response Unit (TRU) detected exploitation of zero-day vulnerabilities disclosed in our security advisory, PaperCut Discloses Zero-Day Vulnerabilities (CVE-2026-82078 and CVE-2026-81578), published on September 3, 2026 affecting a customer in the Education industry. In the intrusion, threat actors exploited an internet-facing print server running a vulnerable version of PaperCut MF to load an in-memory Java loader, which in turn deployed a web shell. Threat actors subsequently used the web shell to deploy a trojanized Microsoft Copilot binary carrying an AdaptixC2 implant.
AdaptixC2 is an open-source and highly modular post-compromise framework that provides a broad set of capabilities, including remote shell access, file management, reverse proxying, and modules for Active Directory attacks, credential harvesting, lateral movement, and more.
In this intrusion, threat actors used the lateral movement module to steal a token from a process running under a domain-privileged service account and move laterally to a domain controller. Once on the domain controller, TRU observed threat actors dumping credentials to obtain the service account's NTLM hash and enabling Windows Restricted Admin mode - a feature that allows RDP authentication using only an NTLM hash. Threat actors then remoted into the domain controller using the NTLM hash over RDP and dumped the domain's Active Directory NTDS.dit database in an attempt to collect password hashes for all domain accounts, facilitating further pass-the-hash lateral movement across the environment.
Threat actors exploited an internet-facing PaperCut MF server to deploy a loader and web shell, which they used to download a trojanized Microsoft Copilot binary carrying an AdaptixC2 implant from 47.79.64[.]225 (ASN 45102 Alibaba (US) Technology Co., Ltd.), then execute it. The implant established command-and-control with attacker infrastructure, then went dormant for roughly a day before the threat actors returned to conduct hands-on-keyboard activity. During this session, they performed network, host, and Active Directory discovery, then impersonated a domain-privileged service account to move laterally to a domain controller. On the domain controller, they harvested credentials from memory and the registry, enabled Windows Restricted Admin mode for pass-the-hash access over RDP, and extracted password hashes for the domain from NTDS.dit, achieving full compromise of the Active Directory environment.

The internet-facing print server was running vulnerable PaperCut MF version 24.0.2 (Build 69746). The figure below displays a sample entry found in PaperCut MF's server.log file, which contains several SQL statements with large, hex-encoded byte blobs. Each blob is preceded by the bytes 0xCAFEBABE, indicating it is a compiled Java class (Java bytecode).

Within the EDR portal, TRU observed the trojanized binary being written to disk and subsequently loaded by the PaperCut application (pc-app.exe):

Two first-stage loaders were discovered in PaperCut MF's server.log that are functionally identical and differ only in their servlet API import - jakarta.servlet.Filter for Tomcat 10+ and javax.servlet.Filter for Tomcat 9 and earlier - ensuring compatibility regardless of which Tomcat version the target PaperCut server is running.
Split payload chunks for the next stage arrived first in server.log, delivered via SQL injection through the card/ID lookup field seconds before each first-stage loader. The moment the loader class is loaded as a servlet filter, its static initializer locates numbered .bin chunk files (e.g., PjYyUnJn.0.bin, PjYyUnJn.1.bin), concatenates them, and loads the reassembled Java bytecode directly in-memory via MethodHandles.lookup().defineClass(). It then forces initialization of the loaded class with Class.forName(), triggering the second stage's static initializer. It cleans up by deleting itself and all .bin files. The loader writes basic status logging to pcxboot_l.txt in the webapp temp directory, recording lok bytes=N on success or lerr:<exception> on failure.

The second stage primarily functions as a web shell and supports several commands that are described below. Threat actors issue commands to the web shell via the X-Quad HTTP header.
The figure below shows the command-handling logic within the "doFilter" method. Several supported commands allow arbitrary JavaScript to be evaluated in-memory, a capability the threat actors used to download and execute an AdaptixC2 implant.

On initialization, the web shell injects itself at position 0 in the Jetty servlet filter chain, deletes lines in server.log that contain evidence of exploitation: cardID, XMLRPC, and UnsupportedClassVersionError, deletes all .bin chunk files and loader .class files from the lib directory, and cleans up files written by the loader from the webapp directory.

It also patches the vulnerability used for initial access by filtering non-C2 requests and checking the service parameter against a regex pattern - if the path segments don't match, the request is blocked with a 403 response (access denied).

Threat actors used AdaptixC2 to move laterally, first by locating the domain controllers via DNS SRV record lookups through nslookup. They then duplicated the token of a process running as a domain-privileged service account and used it to respawn the implant via CreateProcessAsUser. With the account's privileges, they copied the implant and a legitimate dependency to the target domain controller over the C$ administrative share, then executed it by hijacking the built-in PlugPlay service's binary path through a series of sc.exe commands.
The figure below shows an example of the AdaptixC2 context menu that appears when right-clicking a process entry, which exposes this token-stealing capability:

Once running under the service account, threat actors issued the following shell command to the implant to enumerate domain trusts:
The implant and dependency were then copied to the target domain controller via SMB admin share:
Threat actors then executed the implant on the domain controller by running a series of sc.exe commands to hijack its built-in PlugPlay service, replacing the service's binary path with the AdaptixC2 implant's path and starting the service. They then stopped the hijacked service, which does not terminate the already-running AdaptixC2 payload, and restored its original binary path to cover their tracks.
The following table lists reconnaissance related commands executed by threat actors sending shell commands through the implant after it was running on the domain controller.
Next, threat actors began credential dumping through the implant, beginning with an attempt to dump the process memory of LSASS, and saving a copy of the SAM registry hive. The figure below displays the Creds-BOF tools that were likely used in this process from AdaptixC2's Extension-Kit: hashdump, nanodump*, and lsadump*.

Threat actors then used the implant to enable Windows Restricted Admin mode through the following command:
Using an NTLM hash recovered during the earlier credential dumping of LSASS memory and the SAM registry hive, and leveraging Restricted Admin mode, the threat actors authenticated to the domain controller over RDP in a pass-the-hash attack. Inside the RDP session, threat actors opened a command prompt and ran ntdsutil.exe to create a backup of the Active Directory database, writing a copy of NTDS.dit to C:\nbak\Active Directory\ntds.dit. This provided the threat actors with password hashes for every account in the domain, enabling further pass-the-hash attacks and lateral movement.
Threat actors then used the AdaptixC2 implant to drop 7-Zip to create an archive of the NTDS.dit database and the rest of the C:\nbak IFM output, including the required SYSTEM registry hive, into a single archive for exfiltration.
The figure below compares the legitimate Microsoft Copilot binary (version 144.0.3719.104, SHA-256: 861207a8973ab353910d746853b232429fbaaa621ff0ab2df182ffb7af75d6ec) and the trojanized copy when reviewed in Binary Ninja's sidebar graph. There is a clear size difference between the images, suggesting the PE image shrunk in size.

Closer inspection reveals several modifications were made to the legitimate Microsoft Copilot binary:

2. PE header mistakes made by the implant installer:
OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress was not updated to 0x3ADE00 (to account for the .rsrc section shrinking by 0x600 bytes) rather it remained stale with VirtualAddress as 0x3AE400.
OptionalHeader.CheckSum was updated by the implant installer to an invalid checksum, proved through the python code below, that displays the checksum parsed from the PE header, vs. the correct checksum of the image:
3. Patched C Runtime (CRT) call instruction - A call instruction within the CRT code was altered by replacing the displacement bytes of a legitimate function call so that execution was redirected to a trampoline function, which then calls the AdaptixC2 implant's entry-point.

4. Patched .text section contains AdaptixC2 implant - a total of 0x14600 bytes were replaced with the obfuscated, compiled AdaptixC2 implant in the .text section.
5. Updated the Optional Header's SizeOfInitializedData field - the implant installer replaced the original field's value of 0xE1800, with 0xE1200 (to account for the 0x600 byte decrease).

The figure below displays an error observed when the binary detonated in a public sandbox, "the code execution cannot proceed because msedge_elf.dll was not found." This error message indicates the payload failed to detonate due to the missing dll, and the dll found in the intrusion is the legitimate, signed msedge_elf.dll with SHA-256: c59edcfa37db923d3a6a4739d073aee9f54383505d196d36de2e8834aa3c2378.

The main routine of the AdaptixC2 implant, shown in the figure below, is located at offset 0x24789C. This routine and other functions within the patched byte range were compiled using an obfuscating compiler - likely a derivative of OLLVM.

In the flattened function's prologue, the dispatcher's initial state is established by seeding two general-purpose registers - for instance, rdi and r14. These registers serve as state variables throughout the function's lifetime. On each loop back into the dispatcher, the state is derived by XOR-ing these two registers together, producing a single 64-bit value that the dispatcher uses to resolve which original basic block to execute next.
Also shown in the figure below, each flattened function's prologue contains a magic constant used in modular arithmetic to "decode" the comparison state value against which the current state is checked.

The following Python code solves for the small displacement value added to the magic constant to derive the initial state, which can be seen in the next figure within the dispatcher's comparison tree.

This section describes how the flattener manages unconditional and conditional state transitions.
The original basic block computes the next dispatcher state before jumping directly back to the dispatcher. It accomplishes this by overwriting the same two state-holding registers, e.g. r14 and rdi, with new values, pre-computed chosen so that their XOR product is the corresponding next original block.

Conditional transitions are handled through CMOVcc instructions. The preceding original block's logic sets CPU flag(s), but instead of a Jcc directing control flow, a CMOVcc selectively overwrites one half of the state register pair (e.g. rdi) based on the original branch predicate - while the other half (e.g. r14) remains constant. This causes the XOR product to resolve to one of two possible successor states depending on whether the condition was met, both paths converging with an unconditional jump back to the dispatcher.
In the example shown below, 0xdc0d12ef805e92ba is the conditionally assigned state component, derived from a preceding test eax, eax instruction. If the Zero Flag is set (ZF=1), a cmove node overwrites one half of the register pair with this value before unconditionally jumping back to the dispatcher.

Thanks to LLMs, solving control flow flattening has become considerably less tedious in recent years, particularly once concrete characteristics of the flattening scheme are provided to the LLM as context. By supplying the information discussed in previous parts of this blog to a frontier LLM, we were able to easily extend our DispatchThis sample plugin for Binary Ninja to handle this particular shape. The plugin computes the state transitions to the next original basic block(s) and replaces the original MLIL block expressions with MLIL_GOTO for unconditional transitions, or MLIL_IF for conditional ones, pointing to the associated next-state original blocks. The figure below shows the result of applying the plugin to the function, which was fully unflattened - effectively restoring the program's original control flow prior to obfuscation.

Two samples discovered during the intrusion overwrite fields in the PEB of the running process to store a pointer to a global context buffer, which contains configuration information, resolved API pointers, and other data.

Conversely, the second AdaptixC2 sample (PulseSecure.exe) overwrites the "SubSystemData" field in the PEB at offset 0x28:

The implant walks through the list of loaded modules, computing a DJB2 hash of each module's BaseDllName field in order to locate the desired one. Threat actors made a slight modification to the hashing routine by changing the default seed value from 0x624 to 0xF070DD, likely to evade existing static detections. The routine responsible for this logic is shown in the figure below; it takes a single parameter representing the target hash and resolves it to the corresponding module's base address.

For each module, the implant walks through its Export Address Table (EAT) and hashes the export names using the same DJB2 algorithm - although the disassembly for this routine slightly differs from the previous one:

The full list of 145 APIs resolved by the implant are as follows:
Resolved APIs are stored into designated slots within the global context, as shown in the figure below, where each resolved function pointer is written to a specific offset. For example, the pointer for WideCharToMultiByte is stored at r14+0x290.

Throughout the code, wrapper functions are used to call these resolved APIs indirectly. For example, the function shown below first retrieves the global context pointer, then fetches the API table pointer, and finally calls the resolved WideCharToMultiByte function through qword [rax+0x290].

The Python code below reproduces the DJB2 hashing algorithm used by the implant in the API hashing process, beginning with code that closely mirrors the disassembly, followed by a simplified version.
Threat actors introduced several customizations to the beacon source code to encrypt the C2 address, user agent, and other configuration parameters via XOR. The C2 address observed in the implant was, "156.227.0[.]13" (ASN 149440 Evoxt Sdn. Bhd.).

The implant uses HTTP for command-and-control communication. The figure below shows the initial HTTP POST request sent to the C2 server, which includes a custom Authorization header changed from the default X-Beacon-Id header. This header contains Base64-encoded and RC4-encrypted victim device registration data transmitted during the implant's check-in with the AdaptixC2 server. The request also includes a customized User-Agent header, changed from the default Mozilla/5.0 (Windows NT 6.2; rv:20.0) Gecko/20121202 Firefox/20.0 to Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36, effectively making the request appear as if it was sent by Google Chrome.

The RC4 key needed to decrypt the encoded/encrypted value is stored within the binary as a series of mov instructions that copy the RC4 key byte-by-byte into a newly allocated buffer. The buffer pointer is stored in the global context and used to encrypt the device registration data during check-in with the AdaptixC2 Server.

The figure below displays the decrypted contents of the registration packet when decrypted using CyberChef.

The figure below displays each field within the registration data and includes:

Although we were unable to capture additional communications from this implant beyond the initial check-in, the figure below shows an example response from an AdaptixC2 server. In the response, the JSON data field contains encrypted command data from the C2 server. This ciphertext can be decrypted in CyberChef using RC4 with the session key extracted from the check-in request, which itself was decrypted using the RC4 key embedded in the malware. Decrypting this field reveals the AdaptixC2 server sent a COMMAND_SHELL_WRITE command to run ipconfig.

Commands sent by the AdaptixC2 server are processed through a switch statement. The figure below shows a truncated portion of the unflattened switch statement, which closely mirrors constants and functions defined in the public AdaptixC2 repository.

To learn how eSentire can help you find exposures and defend your organization, connect with an eSentire Security Specialist now.
GET STARTEDThe 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.