Appendix F: IOC Catalogue
This catalogue turns the reconstruction into defensive leads. It covers the RCS operator/backend platform and the deployment edge visible in the examined source. It is not a universal signature for HackingTeam products, and it does not claim to identify every implant, customer configuration, successor product, or later version.
An indicator’s value depends on where it is observed. A TLS issuer can be seen on a network sensor. A REST path normally requires TLS termination. A service name requires host telemetry or a forensic image. A MongoDB collection shape requires database access. The tables preserve that sensor position together with provenance and false-positive limits.
Confidence has the following meaning:
- high — a distinctive combination directly supported by original source, installer material, or a matching lab artifact;
- medium — useful in the stated sensor position but plausibly shared by other custom or legacy systems; and
- low — a triage lead that needs independent RCS-specific evidence.
Do not block or attribute solely on a low-confidence item. Even a high- confidence technical match identifies software or infrastructure, not the customer, operator, legal authority, target, or successful use.
Highest-value combinations
| Combination | Sensor | Provenance | Confidence | Why it matters |
|---|---|---|---|---|
Default CA issuer containing both Root Certification Authority and ACME Corp, long-lived leaf, and adjacent RCS REST/WSS behavior | TLS/network | SOURCE + LAB | High for an unchanged default | The issuer fields are generic separately; service behavior supplies specificity |
Cleartext X-Auth-Frontend on an internal HTTP flow to a collector, corroborated by collector/database topology | Network or proxy log | SOURCE | High | The header names an RCS frontend trust mechanism; redact its credential value |
C:\RCS\DB with RCSMasterConfig, RCSMasterRouter, or RCSShard, plus matching Mongo service paths | Windows host | SOURCE | High | Exact root, service names, and process layout form a distinctive installer cluster |
| RCS licence YAML schema beside database launchers and certificate-generation source | File scan/forensic image | SOURCE | High | Multi-field content rules avoid relying on a generic filename |
evidence.<target-id>, aggregate.<target-id>, and paired grid.<target-id>.files/.chunks collections beside items, audit, and signatures | MongoDB/backup | SOURCE + LAB | High | The coordinated target-scoped family is much stronger than MongoDB alone |
Several RCS-specific REST nouns in one authenticated session, such as /agent/filesystems, /collector/del_logs, /backuparchive, /injector/add_rule, and /shard | TLS-terminated HTTP | SOURCE + LAB | High | Route clustering is stronger than /auth/login or JSON field names alone |
These combinations are starting points for confirmation. Preserve surrounding transactions, process state, certificates, database metadata, and timestamps before taking disruptive action.
Network and service topology
| Port or relationship | Expected role | Provenance | Standalone confidence | Caveat |
|---|---|---|---|---|
| TCP 443 | Database HTTPS REST; also collector-to-database login | SOURCE + LAB | Low | Ordinary HTTPS; configurable |
| TCP 444 | Database WSS, normally REST port plus one | SOURCE + LAB | Low to medium as a pair | Port is non-unique and may be proxied |
| TCP 442 | Worker evidence ingress | SOURCE + LAB | Low by port; higher with framing and host evidence | Lab keeps it internal; exposure is deployment-dependent |
| TCP 80 | Collector public listener and backend-to-collector frontend requests | SOURCE | Low | No collector was run; HTTP is ubiquitous |
| TCP 4499 on loopback | Collector-to-network-controller service | SOURCE | Medium on a matching collector host | Configurable; remote exposure would differ from the examined default |
| TCP 27017/27018/27019 | Mongo router, shard server, and configuration server | SOURCE + LAB | Medium as a co-located trio | Standard MongoDB roles; network placement varies |
The book’s host ports 127.0.0.1:44443 and 127.0.0.1:44444 are lab
mappings, not original RCS indicators. Likewise, container names such as
rcs-db-lab:9.2, the private Compose network, and port 8080 belong to the
reconstruction only.
TLS and HTTP
| Indicator | Provenance | Confidence | Companion evidence | False-positive or evasion note |
|---|---|---|---|---|
CA subject includes CN=Root Certification Authority and O=ACME Corp | SOURCE; lab-generated example | Medium alone; high in combination | Ten-year leaf, RCS ports/routes, host artifacts | Operators can replace certificates; both strings occur elsewhere |
| Database leaf common name set to configured server name/address | SOURCE | Low | Issuer cluster and adjacent WSS | Fully configurable |
Collector certificate common name collector | SOURCE | Low to medium | Matching CA, component login, host role | Generic word |
| Certificate validity of 3,650 days | SOURCE | Low | Default issuer and RCS topology | Common in old appliances |
Every backend REST response sets Server: nginx although the application is EventMachine | SOURCE + LAB | Low alone | RCS route, error body, TLS and process evidence | Real nginx and many applications use the same banner |
| Sparse nginx-styled 403/404 body from the backend | SOURCE + LAB | Low | Banner plus application-specific route behavior | Easily copied and affected by proxies |
X-Auth-Frontend request header | SOURCE | High | Direction from database toward collector; topology records | Header value is a credential and should not be retained in ordinary alerts |
| Collector empty status 444/connection close after invalid traffic | SOURCE | Low | Repeated behavior, collector host evidence, RCS-specific traffic | Ordinary nginx configurations use 444; wire outcome can be only a close |
Collector HACK ALERT logs after unauthorized privileged methods or traversal attempts | SOURCE | Medium to high on host | Collector configuration/process and matching network time | Log strings can be copied or disabled |
The old WebSocket stack also has a case-sensitive handshake quirk: proxied
Connection: Upgrade works where a lowercase value can be dropped. It was
reproduced while building the web port. Treat it as a version-specific
diagnostic clue, not a durable network signature; intermediaries routinely
normalize headers.
REST and application behavior
The original REST shape is /<controller>/<action>[/<id>]. A login request is
POST /auth/login with user, pass, and version JSON fields. That pattern
is only medium confidence and normally invisible without TLS termination.
Stronger hunting looks for several of these less common paths in one service:
| Route or behavior | Meaning | Provenance | Caution |
|---|---|---|---|
/agent/status first synchronization followed by an agent name ending in (N) | Factory-to-agent clone lifecycle | SOURCE + LAB | A request or name shows backend registration, not real-device attribution |
/agent/filesystems, /agent/exec, /agent/upload, /agent/download | Queued operator request surfaces | SOURCE + LAB | A queued request proves intent, not delivery or execution |
/evidence, /evidence/body, /grid/<id>?target_id=... | Evidence metadata/body and target GridFS access | SOURCE + LAB | Requires authorization and sensor visibility |
/collector/log/<id>, /collector/del_logs, topology tasks | Frontend monitoring and log lifecycle | SOURCE + WEB PORT | UI rendering alone does not prove edge services ran |
/injector/add_rule, /injector/logs/<id> | Network Injector configuration/log surface | SOURCE + WEB PORT | Do not infer a successful injection from stored rules |
/connector with a changing queue-derived status | Evidence export state | SOURCE + WEB PORT | A connector record may be disabled or synthetic |
/shard and /shard/<id> returning raw Mongo shard/dbStats structure | Backend topology view | SOURCE + LAB | Database-administration tools can expose similar nouns |
/evidence/sync_history returning a 404 while adjacent 9.6 console calls it | 9.2.3/9.6 pairing gap | SOURCE + LAB | Narrow version fingerprint, not universal RCS behavior |
Successful sessions use a UUID-like session cookie. Failed login bodies such
as INVALID_ACCOUNT and EXPIRED_ACCOUNT are product clues but should not be
actively elicited on an unknown system. An authentication attempt changes
server state and can notify or disconnect an operator.
Collector and anonymizer leads
The collector defaults to database host name rcs-server, database port 443,
public port 80, controller port 4499, and 30-second heartbeat/controller
intervals. Candidate configuration commonly refers to config.yaml, a
database certificate, a server-signature file, a public directory, local
cache, and component logs.
The examined anonymizer source uses the program name bbproxy, compile-time
prefix /opt/bbproxy, and tunable files named version, cookie, key,
proxyport, and nexthop. It adds X-Forwarded-For and
X-Proxy-Version when those headers are absent. The RCS manual instead
documents an installed /opt/rcsanon service listening on port 443. That
difference is a version/package clue: search for both families and preserve
the exact executable and configuration before deciding which snapshot fits.
Neither X-Forwarded-For nor X-Proxy-Version is unique. The source proxy
preserves client-supplied versions, so their values are also weak attribution
evidence unless a trusted upstream sanitized them.
Implant-side source describes short encrypted authentication posts and build- randomized URI/cookie names. Because no implant-to-collector session was run, this catalogue does not promote body length or a “static-looking site” into a standalone production signature. Use those traits only as scoped hunting hypotheses with corroborating collector evidence.
Windows backend host artifacts
| Artifact | Provenance | Confidence | Notes |
|---|---|---|---|
C:\RCS\DB, with adjacent C:\RCS\Ruby, C:\RCS\Collector, C:\RCS\Java, or C:\RCS\Python | SOURCE installer/manual | High as a cluster | A research copy can reproduce the path |
Services RCSMasterConfig, RCSMasterRouter, RCSShard | SOURCE installer | High | Combine with Mongo image paths under the RCS root |
Firewall group RCS Firewall Rules and rule prefix RCS_FWD | SOURCE installer | High | Preserve full rule command, creator, and timestamps |
AppCompat Layers value for C:\RCS\Ruby\bin\ruby.exe with DisableNXShowUI | SOURCE installer | High | Encoded in a Sigma rule in Appendix G |
config/, certs/, cores/, exploits/, log/err/, backup/, and Mongo data/config trees under the RCS installation | SOURCE + MANUAL | Medium to high as a structure | Individual directory names are generic |
rcs.lic beside RCS configuration and service files | SOURCE | Medium by name; high by schema | Match content schema, not filename alone |
| Bundled HASP support files and installer | SOURCE | Medium | Hardware-licence path is optional |
The original source contains embedded licence and dongle material. The book does not repeat secret values as IOCs. On a seized authorized host, hash and restrict those files; do not copy credential values into shared alerting systems.
Licence and configuration schema
The RCS 9 licence is YAML with a distinctive combination of fields including serial, maintenance, platform entitlements, collector/anonymizer limits, hostname synchronization, correlation, deletion, signature, and integrity. The accompanying YARA rule requires several fields together and bounds file size.
Default backend configuration includes names for the CA, database certificate and key, listening port, heartbeat interval, backup directory, and shard. Most names are individually generic. Their value is in co-location with licence, service, certificate, and MongoDB evidence.
The default bootstrap administrator name and password are security findings, not recommended detection probes. Do not attempt them against a candidate. The presence of a default account in a preserved database can support a finding after authorized offline analysis, but an interactive login mutates sessions and audit state.
MongoDB and evidence storage
RCS target data forms coordinated collection families:
evidence.<24-hex-target-id>
aggregate.<24-hex-target-id>
grid.<24-hex-target-id>.files
grid.<24-hex-target-id>.chunks
Evidence collections use shard key {type, da, aid}, and aid is stored as a
string in the original model. Binary evidence metadata points into the paired
target GridFS bucket. These are high-value forensic indicators when found with
global collections such as items, users, groups, sessions, audit,
signatures, status, collectors, injectors, connectors, and task or
alert queues.
Collection names alone still require care. A researcher could recreate them, and a backup may contain a partial or migrated database. Confirm indexes, field shape, ObjectId relationships, application files, and version evidence. Use read-only queries against a forensic clone; do not compact, repair, restore, or recalculate statistics on original evidence.
Behavioral and state indicators
Two lab-observed behaviors can assist diagnosis:
- A second login for the same username deletes the earlier session and queues a user-addressed logout push, so consoles can unexpectedly eject one another.
- In the reconstructed 9.2.3/9.6 pairing, the database component’s Monitor status can become stale after several minutes while REST, WSS, and push remain functional.
Both are low-confidence outside an already corroborated installation. Many systems enforce one session per user, and monitoring bugs are common. They are most useful for explaining observations, not finding RCS from scratch.
Explicit non-indicators
Do not treat any of the following as sufficient evidence:
Server: nginx, nginx-styled error pages, or HTTP 444 alone;- port 80, 443, 444, 442, 4499, or MongoDB ports alone;
- Ruby, EventMachine, MongoDB, nginx, a ten-year certificate,
ACME Corp,collector,backup, orconfigalone; - generic anonymizer certificate names such as
server,test,apache,nginx,web,www, ordefault; - the fictional names Operation Nightjar, A. Moretti, or R. Bianchi;
- host ports 44443/44444,
console-web,rcs-db-lab:9.2, or Docker Compose; or - the presence of exploit-source names without matching package, version, host, or case evidence.
The last group prevents the lab itself from contaminating historical hunts. Maintain explicit allowlists for authorized reconstruction systems and keep research traffic out of production detection corpora where possible.
Triage sequence
- Preserve the triggering event and its sensor position.
- Add one independent layer: network, host, database, certificate, or source artifact.
- Compare the exact version and deployment mode with the fidelity map.
- Exclude authorized research and forensic replay.
- Acquire passively before any login or API request.
- Separate platform identification, platform compromise, target compromise, and attribution.
- Record absent expected evidence and plausible configuration changes.
The source rule files and current validation status are reproduced in Appendix G. They remain experimental until their target engines and representative negative corpora have been exercised.
Sources and evidence
docker-lab/IOCs.md, originalrcs-db,rcs-collector,rcs-anonymizer, installer, and database-model source.- Chapters 5, 7, 9, 10, 12, and 13 for certificates, storage, edge behavior, security findings, detection confidence, and preservation.
research/hackingteam-rcs/detections/for the experimental source rules and validation ledger.- LIMITATION: no collector/anonymizer/injector execution or implant PCAP; no claim of unique attribution from a single configurable default.
↑ HackingTeam's RCS: Bringing a Commercial Spyware Platform Back to Life