Martin's Blog

Inside HackingTeam RCS: How Its Implant Protocol Compares with Modern C2 Frameworks

This post compares HackingTeam RCS with Cobalt Strike, Havoc, Outflank C2, and Brute Ratel C4. The comparison needs a warning before it needs a table. RCS was sold as a surveillance and investigation platform. The other products are command-and-control frameworks built primarily for authorized adversary simulation or red-team work. They overlap in endpoint control, asynchronous tasking, file transfer, extensibility, and operator collaboration, but they do not organize those capabilities around the same purpose or data model.

The RCS side of this post comes from static inspection of the frozen source revisions. No implant or collector was built or executed, no protocol endpoint was contacted, and no authentication material is reproduced here. The modern product side comes from vendor documentation available in September 2026. Where a vendor keeps implementation details private, the comparison records the public claim rather than filling the gap with third-party reverse engineering.

What the RCS implant actually synchronized

RCS did not expose a general interactive shell as its only abstraction. A synchronization was a structured exchange between an endpoint and a Collector, normally through an anonymizer chain. The Windows full core provides the most complete client-side counterpart in the frozen archive; the Collector provides the clearest server-side description. Other RCS platforms implemented related contracts, but this Windows/Collector pairing should not be projected onto every implant family or product release.

At a high level, one synchronization followed this state machine:

HTTP POST to an innocuous-looking path
  -> authenticate factory/build and device instance
  -> establish a short-lived encrypted session and cookie
  -> identify user, device, source and client version
  -> exchange configuration and queued requests
  -> upload locally staged, typed evidence records
  -> receive files or upgrade material when queued
  -> acknowledge completion and close the session

The Windows source assigns separate protocol commands to identity, configuration, evidence upload, file collection requests, filesystem browsing, upgrade delivery, log-status reporting, evidence purging, direct command requests, and session closure (core-win32/ASP.h:29-43). The injected communications component translates these exchanges across shared memory so the main core does not itself own the WinHTTP session (core-win32/ASP.cpp:1124-1230). That split is important for defenders: the network-capable process and the process performing collection need not be the same process.

The surrounding core consumes the results as product actions. It turns download requests into typed file evidence, filesystem requests into directory enumeration records, command requests into command-output evidence, and a new configuration into a checked replacement (core-win32/LOG.cpp:1687-1797). It also handles server-delivered support files and upgrades as a separate class from ordinary operator uploads (core-win32/LOG.cpp:1585-1683). Authentication can return a server-directed uninstall decision before normal synchronization begins (core-win32/LOG.cpp:1801-1868).

This is closer to a replication protocol for an evidence appliance than to a terminal session. Requests are queued centrally; the endpoint checks in, performs bounded work, packages results as evidence, and returns them in a later phase. The backend then indexes, enriches, alerts on, and displays that evidence inside a target and operation. The companion RCS book follows the record after it leaves the Collector in From Synchronization to Stored Evidence.

Authentication and message protection

The Collector distinguishes the compact Scout authentication form from the full-core form by message shape (rcs-collector/sync_protocol.rb:32-35). For the full-core path, both sides combine a customer/factory secret with fresh client and server contributions to derive a per-session key. The client also sends a nonce which the server must return under that session key. The Collector verifies that the build identifier, instance identifier, platform, and pre-shared configuration key agree before it creates a cookie-bound session (sync_protocol.rb:37-191).

Subsequent full-core records are binary command frames protected with AES-CBC under the session key and accompanied by a SHA-1 digest over the command and payload. The implementation adds a short random tail outside the encrypted, block-aligned message (core-win32/ASP.cpp:240-294,439-492). File evidence uses the same broad construction but carries an explicit payload length before the file body (ASP.cpp:495-575). The Collector reverses this framing and dispatches the command through a fixed command table.

Those mechanisms provide more structure than “encrypted HTTP,” but they are not equivalent to a modern authenticated-encryption channel. The source uses a fixed zero IV for these CBC operations, truncates the SHA-1-derived session material to the AES key length, and uses an unkeyed SHA-1 digest inside the encrypted frame. Confidentiality, peer recognition, replay handling, message integrity, and transport camouflage are separate properties here; the presence of AES does not settle all five.

The trust decision also includes topology. The inspected Collector rejects a direct synchronization when anonymizer version information is absent and checks whether the agent and anonymizer belong to the same “good” or “bad” side of the infrastructure (sync_protocol.rb:139-165). The edge is therefore part of authorization, not merely a transparent redirector.

Scout uses a distinct versioned, Base64-wrapped authentication structure and records an explicit Scout or Soldier level. It still derives a fresh session from pre-shared and client/server material, but the response and padding rules differ (sync_protocol.rb:194-358). A defender should consequently avoid one universal “RCS handshake” signature.

HTTP camouflage was bounded, not fully malleable

The inspected Windows core uses WinHTTP, adopts the current user’s proxy, PAC, or autodetection settings, and falls back to a direct connection. It sends POST requests to one of a compiled set of paths and presents a browser-like user agent (core-win32/ASP.cpp:639-736). The Collector answers unrecognized or invalid traffic with decoy content and only enters the sync parser for a valid POST (rcs-collector/http_controller.rb:19-49). Anonymizers can obscure the Collector and supply the topology metadata used by the trust check.

This is camouflage, but it is not the same abstraction as a contemporary profile language. URI choice, proxy behavior, random padding, decoy responses, and intermediary chains provide variation around a fixed binary protocol. The product does not expose a documented operator language for relocating metadata and output among arbitrary headers, parameters, cookies, and bodies. That difference strongly affects detection: an old RCS build can have more stable wire invariants than a framework designed to make the transaction shape an operator choice.

Normalizing unlike products

The following table compares product concepts, not brand prestige or claimed stealth. “Publicly documented” means the vendor describes the capability; it does not mean this research independently validated the implementation.

Dimension HackingTeam RCS (examined source) Cobalt Strike Havoc Outflank C2 Brute Ratel C4
Primary product model Surveillance case management and evidence collection Adversary simulation and post-exploitation Extensible C2 framework Commercial, OPSEC-focused red-team C2 within OST Commercial adversary-simulation C2
Endpoint concept Scout, Soldier, and platform-specific full cores tied to factories and targets Beacon sessions Demon agents Native implants; Windows mature, macOS/Linux supported Badger agents
Server/operator split Collector/anonymizer edge, protected database/workers, rich analyst console Team Server plus desktop client and APIs Teamserver plus client Linux/Docker TeamServer plus browser client Ratel Server plus Commander client
Work organization Group -> operation -> target -> factory/agent; evidence is first-class and retained Hosts, sessions, listeners, tasks, logs Agents, listeners, tasks, downloads and logs Engagement-oriented implant operations and automation Badgers, listeners, command queues, logs and downloads
Default interaction Periodic structured synchronization and typed evidence upload Sleep/check-in, retrieve tasks, return output Listener-driven check-in and task/output loop Asynchronous tasking and implant automation Sleep/check-in, queued commands and returned output
Public channel model Fixed binary protocol over HTTP POST with decoy paths and anonymizer chains HTTP(S), DNS, SMB/TCP and extensible/external channels Configurable listeners and service interfaces Public material emphasizes native cross-platform implants, proxying/linking and interoperability HTTPS and DNS-over-HTTPS are publicly described, with runtime profile switching
Traffic malleability Bounded URI/decoy/padding variation; no comparable public profile language in examined source Malleable C2 transforms transaction placement and appearance Profiles configure server, listeners and agent behavior; service APIs extend listeners Vendor emphasizes out-of-box OPSEC; detailed implant protocol remains customer documentation Vendor documents request/response/header malleability and different idle/task responses
Extensibility Product modules, configurations, actions, connectors and backend evidence processors Aggressor Script, BOFs, kits, External/User Defined C2, REST API Modules, external C2/service APIs and open source Python automation, BOF compatibility and cross-framework loading COFF/object execution, profiles and server-side command parsing are publicly described
Cross-platform emphasis Broad mobile and desktop surveillance coverage, uneven by source snapshot Mature Windows Beacon; other access through documented pivots/SSH workflows Public Demon implementation is Windows-centered Native Windows, macOS and Linux implants Public product material is strongly Windows-centered
Data semantics Typed evidence with acquisition/receipt time, target-scoped storage, search, relevance, notes, alerts and intelligence links Command/task output, downloads, credentials, screenshots and engagement logs Agent input/output, screenshots, downloads and server data Operational task/output workflow; public site does not claim an RCS-like evidence warehouse Command output, screenshots, downloads, credentials and operator logs
Governance surfaced in product Per-user roles, group-scoped investigations, audit and licensing, plus source-visible authorization gaps Multi-operator team server and activity/data model Multi-operator teamserver Screened commercial subscription and private customer ecosystem Commercial licensing and multi-operator Commander workflows

Cobalt Strike: the clearest protocol contrast

Cobalt Strike is the most useful comparison because its public documentation describes the transaction boundary directly. HTTP(S) Beacon normally retrieves tasks with GET and returns output with POST. A Malleable C2 profile controls how encrypted metadata, tasking, and output are transformed and placed in the HTTP transaction. Modern documentation also describes multiple host profiles, dynamic values, listener types, failover hosts, and a broad automation surface.

RCS and Beacon therefore share asynchronous tasking, proxy awareness, encrypted application data, file transfer, host metadata, server-side queues, and collaborative operators. Their centers of gravity differ. Beacon exposes a composable post-exploitation substrate. RCS exposes configured surveillance modules whose output becomes durable, typed evidence in a case hierarchy. Beacon’s network appearance is deliberately profile-driven; the examined RCS wire grammar is comparatively fixed even when its outer URI and edge path vary.

This makes product-name detection particularly weak for modern Cobalt Strike. A detector can sometimes identify a specific profile, certificate, payload configuration, or infrastructure mistake. It should not assume that a default GET/POST shape is a universal product invariant. By contrast, an RCS detector can combine stricter message-length, session sequence, Collector behavior, and backend evidence—while still treating each as version-specific.

Havoc: architectural similarity without the case system

Havoc’s public documentation presents a teamserver that owns listeners, interacts with agents, records their input and output, and serves operators. Its Yaotl profile configures teamserver and listener behavior, while service interfaces support external agents and listeners. That resembles the familiar C2 decomposition of agent, listener, teamserver, and client.

RCS has analogous physical roles—implant, anonymizer/Collector, backend, and Console—but assigns them different semantic weight. The RCS Collector is an edge gate and evidence relay. The protected backend creates targets, stores typed evidence per target, runs processing queues, and applies user/group visibility. Havoc’s public model is session- and task-centered, not a surveillance evidence-management platform.

Havoc is also open to direct code inspection, whereas the RCS comparison is a frozen historical snapshot and the other products disclose only part of their implementation. “More documented” must not be confused with “more detectable” or “less secure”; it means claims can be tested at a different evidentiary depth.

Outflank C2: a minimal stage that grew into an ecosystem

Outflank describes its C2 as beginning with a small initial-access stage and growing into a native Windows, macOS, and Linux framework. Its current public material emphasizes frequent releases, browser-based operation, Docker-based server deployment, Python automation, BOF compatibility, proxying/linking, and interoperability with Cobalt Strike. It explicitly positions Outflank C2 as an OPSEC-focused component of a larger commercial tooling ecosystem.

The superficial resemblance to RCS is cross-platform native implants behind a managed commercial service. The important difference is the product boundary. Outflank C2 is designed to compose with other red-team frameworks and tooling; RCS aimed to keep collection, evidence processing, investigation management, alerting, intelligence, audit, and infrastructure administration inside one surveillance product. Public Outflank material also does not expose enough of the implant’s cryptographic wire contract to support a field-by-field protocol comparison. The responsible conclusion is “not publicly established,” not an assumption that it resembles Beacon, Havoc, or RCS internally.

Brute Ratel C4: malleability and endpoint evasion as product features

Brute Ratel’s public release notes describe an explicitly Windows-focused Badger/Ratel Server/Commander architecture, HTTPS and DNS-over-HTTPS channels, request and response malleability, different idle and queued-command responses, sleep and jitter, proxy and pivot functions, object-file execution, and operator/download logs. Later releases emphasize changing memory and endpoint behavior in response to defensive telemetry.

RCS also tried to blend communications into ordinary web traffic and separated network communication into an injected host process. Yet its source reflects a different era and optimization target. The protocol’s random tail and decoy page complicate simple signatures, but the core grammar stays product-defined. Brute Ratel publicly treats network and in-memory variability as operator-facing product features. It is consequently unsafe to generalize a sample-specific Badger traffic pattern to the framework as a whole.

The data model again separates them. Commander presents sessions, task output, downloads, screenshots, credentials, queues, and operator logs. RCS turns many of the same raw collection classes into evidence objects attached to a person, operation, relevance score, analyst note, alert, and retention lifecycle.

What remains stable enough to defend on

Across all five products, brand signatures are less durable than behaviors and trust relationships. A useful defensive model separates four layers:

Layer Examples Expected stability
Product defaults Default paths, certificates, headers, sleep values or process choices Low; operators and releases change them
Protocol invariants Authentication ordering, framing constraints, task/output correlation, session identifiers Medium for a specific family/version; malleable frameworks intentionally reduce it
Endpoint behavior Periodic check-ins, queued task execution, memory-resident workers, proxy discovery, file staging, injected communications Medium; detectable through correlated telemetry rather than one API call
Operational architecture Redirector/edge chains, teamserver exposure, multi-user tasking, centralized downloads/logs, repeated domain and certificate lifecycle Often the most useful campaign-level layer, but rarely unique by itself

For historical RCS, defenders can additionally correlate endpoint behavior with Collector decoy behavior, anonymizer headers, factory/instance lifecycle, typed local log staging, server-directed purge/uninstall actions, and the backend’s distinctive target-scoped MongoDB collections. That end-to-end combination is far stronger than recognizing AES, SHA-1, HTTP POST, or a browser user agent.

For modern malleable C2, defenders should assume that URI, headers, request method, sleep, jitter, certificate, user agent, and body encoding may be operator-controlled. Detection should emphasize mismatches between claimed application behavior and endpoint/network reality: a process with no ordinary reason to beacon; periodic encrypted exchanges followed by process discovery, credential access, remote service creation, tunnelling, or unusual file reads; infrastructure that rotates like a redirector fleet; and task/output timing that joins endpoint events to egress bursts.

Limits of the comparison

This is not a ranking of stealth, security, or capability. The RCS sources span inconsistent years and versions. Cobalt Strike and Havoc expose substantially more public technical detail than Outflank C2. Brute Ratel publishes selective release notes while explicitly withholding some evasion changes. Product features change, operator profiles change them further, and unauthorized criminal use of a red-team tool does not change the vendor’s stated product purpose.

Most importantly, capability is not deployment. Source code for an RCS command does not prove that a customer enabled it. A vendor page describing a modern framework does not prove how a particular operator configured it. Attribution requires a combination of telemetry, infrastructure history, recovered configuration, server or endpoint artifacts, and human context.

Sources and evidence

#Hackingteam #Rcs #C2 #Malware-Analysis #Threat-Research #Cobalt-Strike #Havoc #Outflank #Brute-Ratel