Files
Necropolis-C2/docs/protocol-spec.md
T
2026-07-07 04:50:23 +01:00

5.2 KiB

necropolis Protocol Specification

1. Peer Identity

1.1 Key Derivation

Operator Key: Ed25519 private key (operator.priv)
Operator PeerID: libp2p PeerID derived from operator.priv public key

Implant Key: Ephemeral Ed25519 (generated on first run)
Implant PeerID: libp2p PeerID from implant public key

1.2 Implant Certificate

On first execution, the implant generates:

  • implant.ed25519 - ephemeral keypair
  • Registration envelope signed by operator key (embedded at build time)

2. Topic Structure (PubSub Fallback)

Topics are used as a fallback when direct streams are unavailable. Topic IDs use short opaque prefixes to reduce wire fingerprinting.

/b/<operator-peerid>/bx         # Beacons — implants -> operator (pubsub fallback)
/c/<operator-peerid>/cx         # Commands — operator -> implant (pubsub fallback)
/t/<operator-peerid>/tx/<id>    # Per-implant task topics (pubsub fallback)
/necropolis/cmd/<id>/<nonce>    # DHT dead-drop — operator -> implant command envelopes

Primary communication uses direct libp2p streams (see section 4). DHT dead-drop is the 4th transport rung — implants poll /necropolis/cmd/<id>/<nonce> in sequence every 30s for signed command envelopes published by the operator.

Topic Authorisation

  • beacons topic: messages validated against implant's public key
  • Operator drops messages not signed by known implants on beacons

3. Envelope Format

All messages use Protocol Buffers. Message types use opaque Z-series identifiers.

package apb;

message Envelope {
  int64 ID = 1;
  uint32 Type = 2;
  bytes Data = 3;
  bytes Signature = 4;   // Signed by sender's key
  bytes SenderKey = 5;   // Public key of sender
  bytes Token = 6;       // Auth token (32 bytes, operator-specific)
}

The Token field carries a 32-byte random value generated per operator at first run. Implants embed it at build time and reject any Envelope with a mismatched token. This prevents unauthorized peers from sending commands even if the operator's Ed25519 public key is known.

// Z1 — Beacon register (async beacon mode)
message Z1 {
  string ID = 1;
  int64 Interval = 2;
  int64 Jitter = 3;
  Register Register = 4;  // commonpb.Register
  int64 NextCheckin = 5;
}

4. Protocol IDs

Direct libp2p streams use short protocol IDs:

Protocol ID Purpose
Beacon /bc/1.0.0 Persistent beacon stream (implant -> operator)
Command /bc/1.0.0/cmd Command delivery (operator -> implant)
Shell /x/sh/1.0.0 Interactive shell (Ctrl+] to exit)
Port forward /x/pf/1.0.0 TCP port forwarding
SOCKS /x/sk/1.0.0 SOCKS proxy tunnel

WSS connections use standard /dns4/<host>/tcp/443/wss/p2p/<peer-id> multiaddrs — no custom protocol ID.

5. Transport Chain

Implants attempt connections in order:

  1. Direct libp2p peer (-peer)
  2. WSS transport (-wss)
  3. DHT rendezvous discovery (goroutine, 15s)
  4. DHT dead-drop polling (goroutine, 30s) — signed command envelopes at /necropolis/cmd/<id>/<nonce>

6. Session Types

6.1 Beacon Mode (Persistent Stream)

  1. Implant opens persistent /bc/1.0.0 stream to operator (relay-aware, AllowLimitedConn)
  2. Implant sends signed Z1 (beacon register) on the stream every 10-15s
  3. A separate goroutine writes MsgTypeCover envelopes every 5s to prevent relay idle timeout
  4. Operator reads messages in a loop, updates LastCheckin, dispatches by type
  5. Results (MsgTypeLs, MsgTypePs, etc.) are sent on the same persistent stream
  6. If the stream dies, implant reconnects via DHT discovery + openBeaconStream

6.2 Command Delivery (Direct Stream)

  1. Operator opens a /bc/1.0.0/cmd stream to implant (relay-aware, AllowLimitedConn)
  2. Operator signs the envelope and writes it length-prefixed
  3. Implant reads, verifies signature against embedded operator pubkey, dispatches
  4. Implant processes the command and sends the result on the persistent beacon stream

6.3 Interactive Session Mode (Stream)

  1. Operator initiates direct libp2p stream to implant
  2. Bidirectional encrypted stream for shell/portfwd/socks
  3. Uses libp2p stream multiplexing
  4. In shell, type exit or press Ctrl+] to return to the operator prompt

7. Message Types

Type ID Direction Description
COVER 127 Implant -> Op Cover traffic (silently dropped by operator)
REGISTER 0 Implant -> Op Initial beacon/registration
TASK 2 Op -> Implant Execute command
TASK_RESULT 3 Implant -> Op Command output
SHELL 4 Bidirectional Interactive shell
DOWNLOAD 5 Implant -> Op File exfiltration
UPLOAD 6 Op -> Implant File deployment
SOCKS 7 Bidirectional SOCKS proxy tunnel
PORTFWD 8 Bidirectional Port forwarding
SCREENSHOT 9 Implant -> Op Screen capture
LS 10 Op -> Implant List directory
CD 11 Op -> Implant Change directory
PWD 12 Op -> Implant Print working directory
EXECUTE 13 Op -> Implant Run command
KILL 14 Op -> Implant Self-terminate
PS 15 Implant -> Op Process list result
DEADMAN 16 Op -> Implant Dead man switch
DISCONNECT 255 Bidirectional Clean close