Skip to main content
The listener is a TCP server that waits for the game client to connect and then gives you an interactive shell session. All shell commands, file downloads, and directory navigation run through this connection.
Run the listener only inside a dedicated VM or lab environment. The game establishes a real reverse shell. Never run on a production machine or shared network. See Lab Environment for setup guidance.

Start the listener

python tools/listener.py
The listener binds to 0.0.0.0:5050 using SO_REUSEADDR, so the port is immediately available again if you restart. It accepts one connection at a time (server.listen(1)). Once the game connects you will see:
========================================
 VIRUS HUNTER: MAJESTIC COMMAND CENTER 
========================================
[*] Awaiting connection on 0.0.0.0:5050
[+] SECURE LINK ESTABLISHED: 10.12.73.251:54321
[*] Privileged Shell Active. Full system access enabled.
[*] Controls: 'quit' to close, any other text to execute.
----------------------------------------

operator@system $
The prompt updates automatically as you navigate directories (see Prompt and directory tracking below).

Shell commands

The listener translates a small set of cross-platform commands before sending them to the remote host.
CommandDescription
lsList files in the current directory (maps to dir on Windows)
cd <path>Change directory — the session tracks state across commands
cat <file>View a file’s contents (maps to type on Windows)
pwdPrint the current working path
download <file>Transfer a file to downloads/ (relative to listener’s cwd) on the operator machine
quitEnd the session and close the connection
Any command not in the table above is forwarded to the remote shell as-is, so you can run arbitrary shell commands supported by the target OS.

File download workflow

1

Issue the download command

In the listener prompt, type:
download secrets.txt
2

Game packages the file

The game reads the file, base64-encodes it, and sends it wrapped in a protocol envelope:
[FILE_BEGIN:secrets.txt]<base64content>[FILE_END]
3

Listener decodes and saves

The listener detects the [FILE_BEGIN:...] tag, calls base64.b64decode, and writes the file to a downloads/ subdirectory relative to wherever you ran listener.py from:
./downloads/secrets.txt
The directory is created automatically if it does not exist.
4

Confirmation

The listener prints a confirmation line and returns you to the prompt:
[SYSTEM] SUCCESS: Downloaded secrets.txt to /path/to/downloads/secrets.txt

operator@target $
The downloads/ directory is created automatically on first use. The listener uses a 65536-byte receive buffer for large file transfers.

Prompt and directory tracking

The game sends [PATH: /current/dir] tags with every response. The listener strips these tags from displayed output and uses the path to update your prompt:
operator@target $ cd /var/log
operator@log $
The prompt format is operator@{dirname} $ where {dirname} is the last component of the remote path.

Heartbeat filtering

The game sends [HEARTBEAT] packets every 15 seconds to keep the connection alive. These packets are automatically stripped from all output — you will never see them in your terminal.

Response timeout

The listener waits up to 10 seconds for a response after sending a command. If no data arrives within that window, it prints a timeout notice and returns you to the prompt without dropping the connection.

Reconnection behavior

The listener runs an outer while True loop. When the connection drops (game exits, network interruption, etc.), the listener closes the old socket and immediately starts waiting for the next connection on the same port:
[-] Connection closed. Waiting for next connection...
[*] Listening on 0.0.0.0:5050
When a connection closes, the listener prints:
[*] Secure link terminated. Awaiting new connection...
You do not need to restart listener.py between game sessions.

Build docs developers (and LLMs) love