Custom C2 Framework
A custom Command and Control framework built from scratch, featuring a Python Flask team server, cross-compiled Go implants with AES-256-GCM encryption, HTTPS certificate pinning, browser profile spoofing, and full OPSEC hardening across network, binary, and host detection surfaces.
Phase 1 and Phase 2 are complete. For the full technical breakdown, read the two-part series: C2 Development from Scratch: Phase 1 Teardown covers the core architecture, and Fixing Every IOC: Phase 2 Walkthrough walks through the OPSEC hardening of every detection surface identified in Phase 1.
Overview
This is a custom Command and Control framework I built from scratch to understand how C2 communication works at the implementation level. It uses a pull-based HTTP(S) polling architecture: a Python/Flask team server handles tasking and agent management, while cross-compiled Go implants execute on target hosts across Windows, Linux, and macOS.
The server compiles agents on demand with operator-specified configuration baked directly into the binary at build time: callback URL, jitter range, persistence method, AES-256-GCM encryption key, TLS certificate pin, browser profile, and randomized API paths. There is no config file on disk, and sensitive strings are XOR-obfuscated so nothing appears in plaintext via strings or Ghidra.
Phase 1 built the core architecture: communication, execution, file transfer, persistence, and cleanup. Phase 2 hardened every detection surface identified in Phase 1: encrypted payloads, HTTPS with certificate pinning, browser-accurate User-Agent spoofing, direct process execution, COM-based persistence, API authentication, server header masking, and randomized endpoint paths. Phase 3 targets deeper evasion: TLS fingerprint spoofing, in-memory execution, and interactive sessions.
Architecture
I’m not an artist.
┌──────────────┐ ┌───────────────┐
│ Operator │ HTTPS + API Key │ Team Server │
│ (Dashboard) ├─────────────────────────►│ (Python) │
└──────────────┘ └───────┬───────┘
│
┌──────────────────────┼
│ HTTP(S) Polling │ SQLite DB
│ AES-256-GCM │
┌─────▼─────┐ ┌─────▼─────┐
│ Implant │ │ Implant │ │ | | |
│ (Golang) │ │ (Golang) │ │ | | |
└───────────┘ └───────────┘
Key Features
- Encrypted Pull-Based Beaconing: Implants sleep on a randomized jitter interval, check in over AES-256-GCM encrypted payloads, retrieve pending tasks, execute them, and report results. No persistent connections, no plaintext on the wire.
- HTTPS with Certificate Pinning: Self-signed TLS with SPKI SHA-256 pin verification baked into each agent at compile time. The agent bypasses the OS CA store and verifies the server’s certificate directly against the embedded pin.
- Cross-Platform Implants: Written in Go, statically linked with CGO disabled. Compiles to a standalone binary for Windows, Linux, or macOS with zero external dependencies.
- Dynamic Payload Builder: The team server compiles agents on demand. Encryption keys, jitter range, server URL, persistence method, browser profile, TLS pin, and randomized API paths are all injected as Go literals at build time. Sensitive values are XOR-obfuscated so nothing survives binary analysis.
- Browser Profile Spoofing: Five validated browser fingerprints (Chrome/Win, Chrome/Linux, Firefox/Win, Firefox/Linux, Safari/macOS) applied via a custom HTTP transport. Each profile includes correct UA strings, client hints, Sec-Fetch metadata, and context-aware header switching between navigation and fetch requests.
- Dual Execution Modes: Direct process execution (no shell in the process tree) as the default, with an opt-in shell mode for pipes and redirects. The operator controls the OPSEC trade-off per command.
- Stealthy Persistence: Windows uses the Task Scheduler COM API (no
schtasks.exeorreg.exechild process). Linux uses a systemd user service. Both operate under benign names via XOR-obfuscated labels. Legacy methods (Registry Run Key, cron) are still available as conscious trade-offs. - Operator Dashboard: Single-page web UI with API key authentication for real-time agent management, command execution, file staging, loot retrieval, build deployment, and TLS certificate management.
- Server Hardening: Timing-safe API key auth on all operator endpoints,
nginx/1.24.0server header spoofing, randomized agent-facing URL paths, and per-build encryption key isolation.
Implant Capabilities
| Capability | Status |
|---|---|
| HTTP(S) Beaconing with Range-Based Jitter | ✅ Complete |
| AES-256-GCM Payload Encryption | ✅ Complete |
| HTTPS with SPKI Certificate Pinning | ✅ Complete |
| Browser Profile Spoofing (5 Profiles, Context-Aware Headers) | ✅ Complete |
| Direct Process Execution (No Shell in Process Tree) | ✅ Complete |
| Shell Execution (Opt-In for Pipes/Redirects) | ✅ Complete |
Stateful Working Directory (cd Tracking) | ✅ Complete |
| Bidirectional File Transfer (Multipart/Form) | ✅ Complete |
| Persistence: Windows Scheduled Task via COM API | ✅ Complete |
| Persistence: Linux Systemd User Service | ✅ Complete |
| Persistence: Registry Run Key / Cron (Legacy) | ✅ Complete |
| Forensic Self-Destruct and Cleanup | ✅ Complete |
| XOR String Obfuscation (No Plaintext in Binary) | ✅ Complete |
| Cover-Story Function Naming (Endpoint Telemetry Theme) | ✅ Complete |
| Binary Hardening (Strip, Trimpath, No Build ID) | ✅ Complete |
| Dynamic Cross-Compilation (Windows/Linux/macOS) | ✅ Complete |
| TLS/JA3 Fingerprint Spoofing | 📅 Planned (Phase 3) |
| In-Memory Payload Execution | 📅 Planned (Phase 3) |
| Traffic Shaping (Mimic Benign Profiles) | 📅 Planned (Phase 3) |
| Interactive Shell Sessions | 📅 Planned (Phase 3) |
| Agent Chaining / Relay | 📅 Planned (Phase 3) |
| macOS Persistence (LaunchAgent) | 📅 Planned (Phase 3) |
Technical Stack
- Team Server: Python 3, Flask, SQLite3, cryptography (AES-256-GCM, X.509)
- Implant: Go 1.25 (statically compiled, stripped symbols), go-ole (Windows COM), x/sys (Windows syscalls)
- Operator Frontend: HTML5, vanilla JavaScript
- Build Pipeline: Go cross-compiler invoked server-side via
subprocess, targetingGOOS/GOARCHcombinations with compile-time config injection and XOR obfuscation