mythic-c2 0.2.1

Mythic C2 agent library — message encoding, AES-256-CBC-HMAC crypto, and transport abstraction for the full agent lifecycle
Documentation

mythic-c2

Mythic C2 agent protocol library for Rust — message encoding/decoding, AES-256-CBC-HMAC encryption, and a transport abstraction layer.

#![no_std] compatible with alloc, suitable for embedded agent binaries.

Quick Start

use mythic::{Aes256HmacCrypto, C2Transport, MythicAgent, MythicError, TaskResponse};
use uuid::Uuid;

// Implement C2Transport for your channel (HTTP, DNS, WebSocket, etc.)
struct HttpC2 { key_b64: Option<String> }

impl C2Transport for HttpC2 {
    fn get_aes_psk(&self) -> Option<String>        { self.key_b64.clone() }
    fn checkin(&self, p: &str)       -> Result<String, MythicError> { /* POST ... */ Ok(String::new()) }
    fn get_tasking(&self, p: &str)   -> Result<String, MythicError> { /* GET  ... */ Ok(String::new()) }
    fn post_response(&self, p: &str) -> Result<String, MythicError> { /* POST ... */ Ok(String::new()) }
}

let payload_uuid = Uuid::parse_str("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee").unwrap();
let c2 = HttpC2 { key_b64: None };

// 1. Checkin
let agent = MythicAgent::easy_checkin(
    payload_uuid,
    &c2,
    vec!["10.0.0.1".into()],
    Some("linux".into()), Some("root".into()), Some("web01".into()),
    Some(1337), Some("x86_64".into()),
    None, None, None, None, None, None,
)
.unwrap();

// 2. Poll for tasks
let tasks = agent.get_tasking(1, &c2).unwrap();
for t in &tasks.tasks {
    // 3. Execute and respond
    agent.post_response(
        vec![TaskResponse::completed(t.id, "done")],
        &c2,
    ).unwrap();
}

Three API Levels

MythicAgent facade — high-level checkin / get_tasking / post_response:

let agent = MythicAgent::easy_checkin(
    uuid, &c2, vec!["10.0.0.1".into()], Some("linux".into()), Some("root".into()),
    Some("web01".into()), Some(1337), Some("x64".into()),
    None, None, None, None, None, None)?;
let tasks = agent.get_tasking(1, &c2)?;
agent.post_response(vec![TaskResponse::completed(task_id, "ok")], &c2)?;

Free functions — full control over every step:

let crypto = Aes256HmacCrypto::from_base64_key(key_b64)?;
let iv = c2.random_iv()?;
let pkt = encode_message(&req, uuid, &crypto, &iv)?;
let (_, resp) = decode_message::<RespCheckin>(&reply, Some(uuid), &crypto)?;

Raw types — use serde_json directly on any message struct:

let req = ReqCheckin::new(uuid, ips, os, user, host, pid, arch, ...);
let json = serde_json::to_vec(&req)?;

C2Transport Trait

Implement for any transport (HTTP, DNS, WebSocket, etc.). Three methods required; get_aes_psk, random_iv, and encrypted_exchange_check have sensible defaults:

use mythic::{C2Transport, MythicError};

// 加密 transport 必须覆盖 random_iv 提供真随机 IV
//  fn random_iv(&self) -> Result<[u8; 16], MythicError> { getrandom::getrandom(&mut iv)?; Ok(iv) }

impl C2Transport for HttpTransport {
    fn get_aes_psk(&self) -> Option<String>               { Some("q83v...".into()) }

    fn checkin(&self, pkt: &str)       -> Result<String, MythicError> { ... }
    fn get_tasking(&self, pkt: &str)   -> Result<String, MythicError> { self.checkin(pkt) }
    fn post_response(&self, pkt: &str) -> Result<String, MythicError> { self.checkin(pkt) }
}

get_aes_psk() and encrypted_exchange_check() default to None / false — override only when needed.

Three Communication Scenarios

Scenario C2 config Flow
Plaintext get_aes_psk = None checkinget_taskingpost_response
Static key get_aes_psk = Some(key) AES-256-CBC-HMAC encrypted versions of the above
RSA EKE get_aes_psk = Some(key), exchange = true RSA staging → checkin (types defined, RSA crypto not yet implemented)

See examples/mythic_facade.rs for the full agent lifecycle.

Wire Format

Base64( UUID(36) + [ IV(16) + ciphertext + HMAC-SHA256(32) ] )
  • Plaintext: the encrypted portion is replaced with the raw JSON bytes.
  • Encrypted: AES-256-CBC with PKCS7 padding, encrypt-then-MAC with HMAC-SHA256.
  • UUID: hyphenated UUIDv4 string (36 ASCII characters).

Feature Status

Feature Status
Plaintext comms Complete
Static AES-256-CBC-HMAC Complete
RSA staging key exchange Types defined, RSA crypto not yet implemented
Translation-container staging Types defined
Checkin / get_tasking / post_response Complete
File download (agent→mythic) Types defined
File upload (mythic→agent) Types defined
P2P / delegate messages Types defined
SOCKS / RPFWD / interactive Types defined
Hooking features (file browser, credentials, keylogs, etc.) Types defined

License

GPL-3.0-only