Skip to main content

Server Internals

The C2 server (server.js) is the relay between the attacker's browser and the rootkit kernel module. It manages three concurrent services in a single process.

TCP Server (Rootkit Side)

The TCP server listens on port 4242 and accepts a single connection from the rootkit at a time.

Connection Handling

When the rootkit connects:

  1. The server stores the socket reference and the remote IP.
  2. A rootkit_status message is broadcast to all connected browser clients.
  3. Incoming data is line-buffered: bytes are accumulated until a newline (\n) is found, then processed as a complete message.

Message Decoding

All incoming data from the rootkit is ROT64-encoded. The server decodes each chunk immediately upon reception:

Rootkit → [ROT64 encoded bytes] → TCP Server → [decode] → plain text → process

Protocol Messages

The server recognizes two special messages from the rootkit by inspecting the decoded text:

Message content (contains)Action
[+] Authentification réussieBroadcasts auth_result with success: true
[-] Mot de passe incorrectBroadcasts auth_result with success: false

All other messages are forwarded as output to the browser clients.

Disconnection

When the rootkit disconnects, the server:

  • Clears the socket reference.
  • Broadcasts a rootkit_status with connected: false.
  • The rootkit will automatically reconnect after 5 seconds (handled by the kernel module).

HTTP Server (Static Files)

A minimal static file server on port 8080 serves the Web UI from the public/ directory. It supports the following MIME types:

ExtensionContent-Type
.htmltext/html; charset=utf-8
.csstext/css
.jsapplication/javascript
.icoimage/x-icon
.pngimage/png

Requests to / are mapped to index.html.

WebSocket Server (Browser Bridge)

The WebSocket server runs on the same HTTP server (port 8080) and handles real-time communication with the attacker's browser.

On Connection

When a browser client connects, the server immediately sends the current rootkit status so the UI can update without waiting for a state change.

Messages from Browser to Server

The browser sends JSON messages with a type field:

auth

Authenticates the attacker to the rootkit.

{ "type": "auth", "password": "my_secret_password" }

The server:

  1. Validates the rootkit is connected.
  2. Validates the password is not empty.
  3. Hashes the password with SHA-256.
  4. Sends the hash (ROT64-encoded) to the rootkit with a trailing newline.

command

Sends a shell command to the rootkit for execution.

{ "type": "command", "cmd": "ls -la /root" }

The server:

  1. Validates the rootkit is connected.
  2. Broadcasts an echo message to all browser clients (so the command appears in the terminal).
  3. Sends the command (ROT64-encoded) to the rootkit with a trailing newline.

Messages from Server to Browser

TypeFieldsDescription
rootkit_statusconnected, ipRootkit connection state changed
auth_resultsuccessAuthentication succeeded or failed
echodataEcho of a command sent by any browser
outputdataOutput line from the rootkit
errormessageError message (rootkit unreachable, etc.)

ROT64 Cipher Implementation

The server implements the same ROT64 cipher as the kernel module to encode/decode traffic:

// Encode: shift each byte forward by 64 (mod 256)
buf[i] = (buf[i] + 64) & 0xff;

// Decode: shift each byte back by 64 (mod 256)
out[i] = (out[i] - 64 + 256) & 0xff;

This must match the kernel module's rot64_encrypt / rot64_decrypt functions exactly, otherwise communication will be garbled.

Graceful Shutdown

The server handles SIGINT (Ctrl+C) by:

  1. Destroying the rootkit socket if connected.
  2. Closing both TCP and HTTP servers.
  3. Exiting the process.