Overview
The message format module handles serialization, encryption, and framing of C2 protocol messages. It implements a secure binary wire format with a 7-byte header followed by encrypted payload. File:common/message_format.py
Wire Format
Constants
Protocol magic bytes for frame identification
Current protocol version
Struct format for header: big-endian uint16 + uint8 + uint32
Total header size in bytes
Message Types
Agent initial check-in message
Agent polling for new tasks
Agent task execution results
Server task dispatch to agent
Agent heartbeat message
Terminate agent session
Core Functions
pack()
Serialize, encrypt, and frame a payload dictionary into a C2 envelope.Message payload to pack (must be JSON-serializable)
32-byte encryption key
Complete binary envelope ready for transmission
- JSON-serialize the payload dict
- Apply padding using active traffic profile
- Encrypt with AES-GCM
- Prepend nonce to ciphertext
- Build 7-byte header with magic, version, and body length
- Concatenate header + body
ProtocolError- If payload is not a dict, empty, or not JSON-serializableCryptoError- If encryption fails
unpack()
Validate, decrypt, and deserialize a raw C2 envelope into a dictionary.Raw binary envelope received from network
32-byte decryption key (must match the key used for packing)
Deserialized payload dictionary
- Validate frame has minimum length (7 bytes header + 12 nonce + 16 tag)
- Unpack and verify header (magic, version, body_length)
- Extract nonce and ciphertext from body
- Decrypt and verify authentication tag
- Strip padding
- Parse JSON and validate it’s a dict
ProtocolError- If frame is truncated, has bad magic, unsupported version, or invalid JSONCryptoError- If authentication tag verification fails (tampered data or wrong key)
Message Builders
All message builders return a dictionary with mandatory fields:msg_type: Message type identifiersession_id: Session identifier (if applicable)timestamp: Unix timestamp (int)nonce: UUID hex for replay protectionpayload: Type-specific payload data
build_checkin()
Build an agent check-in message.Agent hostname
Current username
Operating system information
Agent version string
Beacon jitter percentage (0-100)
Message dict with
msg_type='CHECKIN' and agent info in payloadbuild_task_pull()
Build a task polling message.Agent session identifier
Message dict with
msg_type='TASK_PULL'build_task_result()
Build a task execution result message.Agent session identifier
Task identifier
Standard output from command execution
Standard error from command execution
Process exit code
Task execution time in milliseconds
Message dict with
msg_type='TASK_RESULT' and execution detailsInternal Functions
_base_payload()
Internal function - not part of public API
msg_type: Message type (validated againstVALID_MSG_TYPES)session_id: Optional session identifiertimestamp: Current Unix timestampnonce: UUID for replay protectionpayload: Empty dict (populated by specific builders)
Security Features
Authenticated Encryption
All messages use AES-256-GCM for confidentiality and authenticity
Replay Protection
Each message includes a unique UUID nonce stored server-side
Length Obfuscation
Padding applied before encryption to hide plaintext size
Version Control
Protocol version in header enables future evolution
Error Handling
ProtocolError
ProtocolError
Raised for:
- Invalid payload structure
- Frame too short for header
- Bad magic bytes
- Unsupported protocol version
- Truncated frames
- Invalid JSON after decryption
CryptoError
CryptoError
Raised for:
- Authentication tag verification failure
- Tampered ciphertext
- Wrong decryption key
Dependencies
See Also
- Cryptography - Encryption and key derivation
- Padding Strategy - Traffic analysis resistance
- Traffic Profile - Configurable traffic patterns