Overview
The server main module implements the FastAPI application that receives and processes agent beacons. It handles all inbound C2 protocol messages including check-ins, task pulls, task results, and heartbeats. Source:server/server_main.py
Application Setup
FastAPI Application
- Disabled API documentation endpoints for operational security
- Async lifespan context manager for startup/shutdown
- Single
/beaconendpoint for all agent communication
Lifespan Management
- Initializes SQLite database connection
- Creates SessionManager instance
- Creates CommandQueue instance
- Restores active sessions from database
- Closes database connection cleanly
- Logs shutdown event
Global State
The server maintains shared state across all requests:Database instance for persistent storage
In-memory session state manager
Command queue manager for all active sessions
API Endpoints
POST /beacon
FastAPI Request object containing encrypted beacon payload
Encrypted response with status code:
200: Success with packed response body400: Bad request (invalid payload, unknown message type)409: Replay attack detected (duplicate nonce)413: Payload too large (exceeds MAX_BEACON_SIZE)500: Internal server error
- Size Check: Reject payloads larger than 262144 bytes (256 KB)
- Decryption: Unpack and decrypt payload using session key
- Replay Protection: Verify nonce hasn’t been seen in last 24 hours
- Dispatch: Route message to appropriate handler based on
msg_type - Response: Encrypt and return response payload
CHECKIN - New agent registration
CHECKIN - New agent registration
Agent sends initial check-in with system information. Server creates new session and returns assigned
session_id.Handler: _handle_checkin()TASK_PULL - Request pending commands
TASK_PULL - Request pending commands
Agent polls for pending tasks. Server returns next task from queue or no-task response.Handler:
_handle_task_pull()TASK_RESULT - Submit command output
TASK_RESULT - Submit command output
Agent submits task execution results. Server stores output and marks task complete.Handler:
_handle_task_result()HEARTBEAT - Keep-alive ping
HEARTBEAT - Keep-alive ping
Agent sends heartbeat to update last_seen timestamp. Server acknowledges.Handler:
_handle_heartbeat()Message Handlers
_handle_checkin()
Decrypted message payload containing:
hostname: Agent hostnameusername: Current usernameos: Operating system versionagent_ver: Agent version stringjitter_pct: Beacon jitter percentage
Source IP address from HTTP request
Response payload:
_handle_task_pull()
UUID of the agent session
Response payload with task dispatch or no-task message:Task Available:No Task:Session Terminated:Returns
None if session_id is invalid.- Updates
last_seentimestamp for session - Checks if session is still active in database
- Sends TERMINATE message if session was deactivated
- Peeks at next pending task without removing from queue
- Marks task as DISPATCHED when sent to agent
_handle_task_result()
UUID of the agent session
Decrypted message containing task results:
task_id: UUID of completed taskstdout: Command standard outputstderr: Command standard errorexit_code: Process exit codeduration_ms: Execution duration in milliseconds
Acknowledgment response:Returns
None if session_id is invalid._handle_heartbeat()
UUID of the agent session
Acknowledgment response:Returns
None if session_id is invalid.Dispatch Helper
_dispatch()
Message type from protocol: CHECKIN, TASK_PULL, TASK_RESULT, HEARTBEAT
UUID of the agent session (may be None for CHECKIN)
Decrypted message payload
Source IP address from HTTP request
Response payload dict to encrypt and return, or
None if unknown msg_typeCatch-All Route
Catch-All Handler
Status 404 with body:
{"error": "not found"}Constants
Maximum allowed beacon payload size in bytes (256 KB). Accommodates max stdout+stderr plus protocol overhead.
Running the Server
Entry Point
- Binds to all interfaces (0.0.0.0)
- Uses port from
config.BACKEND_PORT - Enables TLS unless behind Nginx reverse proxy
- Log level from
config.LOG_LEVEL
Behind Nginx
Runs without TLS. Nginx handles SSL/TLS termination on port 443.
Direct
Runs with TLS using certificates from
config.TLS_CERT_PATH.Security Features
Payload Size Limits
Payload Size Limits
Rejects payloads larger than 256 KB to prevent memory exhaustion attacks.
Replay Protection
Replay Protection
Every message includes a nonce. Server rejects duplicate nonces within 24-hour window.
Encryption
Encryption
All messages encrypted with AES-256-GCM using shared session key.
Minimal Attack Surface
Minimal Attack Surface
Only
/beacon endpoint exposed. All other paths return 404.No API Documentation
No API Documentation
Swagger and ReDoc endpoints disabled to avoid information disclosure.
Logging
Structured logging with contextual fields:- Server startup/shutdown
- Beacon received/unpacked
- Agent check-in
- Task dispatched
- Task result received
- Replay attempts
- Unpack failures
- Invalid sessions
Related
SessionManager
Session state management API
CommandQueue
Task queue management API
Database
Persistent storage API
Message Format
C2 protocol message format