Building a Custom C2 Framework: Concepts and Evasion
Building a Custom C2 Framework: Concepts and Evasion
Command and Control (C2) frameworks are the backbone of red team operations. They provide the infrastructure for managing implants on compromised systems, executing post-exploitation tasks, and simulating the persistent access that real adversaries maintain during intrusions.
Understanding how C2 frameworks work is essential for both offensive and defensive security practitioners. For red teamers, it means being able to build or customize tooling that evades detection. For blue teamers, it means understanding the behaviors and patterns to detect.
This post covers the architecture, communication channels, and evasion concepts behind modern C2 frameworks. All examples are educational and conceptual — the goal is to deepen understanding, not provide weaponized code.
C2 Architecture Overview
A modern C2 framework consists of several interconnected components:
┌─────────────────────────────────────────────────────────┐
│ C2 TEAM SERVER │
│ │
│ ┌──────────┐ ┌──────────┐ ┌───────────────────────┐ │
│ │ Operator │ │ Listener │ │ Task Queue / │ │
│ │ Interface │◄─┤ Manager │◄─┤ Database │ │
│ │ (Web/CLI) │ │ │ │ │ │
│ └──────────┘ └────┬─────┘ └───────────────────────┘ │
│ │ │
└─────────────────────┼────────────────────────────────────┘
│
┌───────────┼───────────┐
│ │ │
┌─────┴────┐ ┌────┴─────┐ ┌──┴───────┐
│ HTTPS │ │ DNS │ │ SMB/Pipe │
│ Listener │ │ Listener │ │ Listener │
└─────┬────┘ └────┬─────┘ └──┬───────┘
│ │ │
┌─────┴────┐ ┌────┴─────┐ ┌──┴───────┐
│ Agent 1 │ │ Agent 2 │ │ Agent 3 │
│ (Target) │ │ (Target) │ │ (Target) │
└──────────┘ └──────────┘ └──────────┘
Core Components
Team Server: The central hub that manages all operations. It stores tasking queues, agent metadata, operator sessions, and engagement logs. In production C2 frameworks like Cobalt Strike and Mythic, this is typically a hardened Linux server with TLS-encrypted operator connections.
Listeners: Network services that wait for agent callbacks. Each listener is configured for a specific protocol (HTTPS, DNS, SMB) and handles the bidirectional communication between the team server and deployed agents.
Agents (Implants): The software running on compromised systems. An agent’s responsibilities include:
- Checking in with the team server on a defined interval (the “sleep” or “beacon” time)
- Retrieving and executing tasked commands
- Returning results to the team server
- Maintaining persistence if configured
- Evading endpoint detection
Operator Interface: The console or web UI that red team operators use to interact with agents, issue tasks, and review results.
Communication Channels
The choice of communication channel determines both the stealth and reliability of C2 operations. Each channel has trade-offs.
HTTPS Communication
HTTPS is the most common C2 channel because it blends with normal web traffic. The agent makes what appear to be standard web requests to the team server, which is often fronted by a legitimate-looking website or CDN.
Conceptual request/response flow:
Agent → Team Server:
POST /api/v2/status HTTP/1.1
Host: cdn-assets.legitimate-site.com
Content-Type: application/json
Cookie: session=<encrypted_agent_id>
{"data": "<base64_encoded_encrypted_checkin>"}
Team Server → Agent:
HTTP/1.1 200 OK
Content-Type: application/json
{"response": "<base64_encoded_encrypted_tasks>"}
Malleable profiles allow operators to customize every aspect of the HTTP transaction — URIs, headers, cookies, body format — to mimic legitimate application traffic. For example, configuring traffic to look like Google Analytics beacons or Slack API calls.
DNS Communication
DNS is a powerful covert channel because DNS queries are almost never blocked and often bypass network monitoring. The trade-off is bandwidth — DNS has strict message size limits.
How DNS C2 works conceptually:
- The agent encodes data into subdomain labels of a domain the operator controls
- The DNS query traverses the network’s DNS infrastructure to the authoritative nameserver (the C2 server)
- The C2 server responds with encoded tasking in DNS record data (TXT, CNAME, or A records)
Agent query: aGVsbG8gd29ybGQ.data.c2domain.com (TXT query)
Server response: TXT "dGFzazogd2hvYW1p" (encoded task)
DNS C2 is slow but extremely difficult to block without breaking legitimate DNS resolution. Detection relies on identifying anomalous DNS patterns: unusually long subdomain labels, high query volumes to a single domain, or TXT record queries that don’t match normal application behavior.
Named Pipes (SMB)
For internal lateral movement, agents can communicate through SMB named pipes rather than making external network connections. This is useful for agents on segmented network hosts that cannot reach the internet directly.
Agent A (internet-facing) ←→ Team Server via HTTPS
Agent A ←→ Agent B via named pipe \\.\pipe\custom_pipe_name
Agent A ←→ Agent C via named pipe \\.\pipe\custom_pipe_name
Agent A acts as a “pivot” or “relay,” forwarding traffic between the team server and internal agents. This chain can extend multiple hops deep into a network.
Payload Generation and Staging
Staged vs. Stageless Payloads
Staged payloads are small initial loaders (stagers) that download the full agent from the C2 server after execution. They’re smaller and easier to deliver but create an additional network transaction that can be detected.
Stageless payloads contain the full agent code in a single binary. They’re larger but don’t require a second network connection to become operational.
Staged:
[Stager (5KB)] → executes → downloads full agent (200KB) → runs agent
Stageless:
[Full Agent (200KB)] → executes → runs agent directly
Payload Formats
C2 frameworks typically support multiple output formats:
- Executable (.exe) — standalone binary
- DLL — loaded via DLL sideloading, rundll32, or reflective loading
- Shellcode — raw position-independent code, injected into memory
- Script-based — PowerShell, VBScript, HTA, or JScript loaders
- Document macros — embedded in Office documents (less effective post-2022 due to Microsoft’s macro blocking)
Evasion Concepts
Modern endpoint detection and response (EDR) products are sophisticated. Effective red team operations require understanding what defenders are looking for and how to avoid triggering those detections.
Antimalware Scan Interface (AMSI) Considerations
AMSI is a Windows interface that allows applications (particularly PowerShell, .NET, VBScript, and JScript) to submit content to antimalware products for scanning before execution. When a PowerShell script runs, AMSI inspects the deobfuscated content in memory, making traditional obfuscation less effective.
How AMSI works at a high level:
PowerShell Script
│
▼
┌──────────────┐
│ AMSI Scan │──→ AV/EDR Engine ──→ Block if malicious
│ (amsi.dll) │
└──────────────┘
│
▼ (if clean)
Execute script
Red team research has explored several approaches to AMSI, including:
- Patching the AMSI scan function in memory to return clean results
- Loading .NET assemblies in ways that avoid AMSI inspection
- Using languages and execution methods not covered by AMSI
From a defensive perspective, monitoring for AMSI tampering is critical. Windows Defender logs AMSI bypass attempts, and EDR products can detect common patching patterns through kernel-level telemetry.
Event Tracing for Windows (ETW) Considerations
ETW is the telemetry backbone of Windows. It provides structured event data to security tools, including .NET assembly loading events, process creation, network activity, and more. EDR products heavily rely on ETW providers for visibility.
Key ETW providers for security:
Microsoft-Windows-DotNETRuntime— .NET assembly load eventsMicrosoft-Windows-Kernel-Process— process creation/terminationMicrosoft-Windows-Threat-Intelligence— memory scanning and injection detectionMicrosoft-Antimalware-Scan-Interface— AMSI scan events
Red team research has explored techniques to blind specific ETW providers by patching the EtwEventWrite function or unregistering providers. Defenders should monitor for ETW tampering and consider kernel-mode telemetry sources that are harder to subvert from user-mode.
Sleep Obfuscation
When an agent is sleeping (waiting between check-ins), its code sits in memory. EDR products perform periodic memory scans looking for known malicious patterns. Sleep obfuscation encrypts or obfuscates the agent’s memory during sleep intervals so that static signatures don’t match.
Conceptual pseudocode:
function agent_sleep(duration):
// Encrypt the agent's memory region before sleeping
key = generate_random_key()
encrypted_memory = encrypt(agent_memory_region, key)
write_to_memory(agent_memory_region, encrypted_memory)
// Change memory permissions to non-executable
set_memory_protection(agent_memory_region, PAGE_READWRITE)
// Sleep for the configured interval
sleep(duration)
// Restore: decrypt and make executable again
set_memory_protection(agent_memory_region, PAGE_EXECUTE_READWRITE)
decrypted_memory = decrypt(agent_memory_region, key)
write_to_memory(agent_memory_region, decrypted_memory)
// Continue execution
resume_agent()
Advanced implementations use techniques like timer-based callbacks (CreateTimerQueueTimer) to handle the encryption/decryption cycle, avoiding the need for a dedicated thread that itself could be detected.
Syscall-Based Evasion
Many EDR products hook user-mode API functions in ntdll.dll to monitor process behavior. When a program calls NtAllocateVirtualMemory or NtWriteVirtualMemory, the EDR’s hook intercepts the call, inspects the arguments, and decides whether to allow it.
Red team research has explored direct and indirect syscall techniques that bypass these hooks by invoking the kernel directly, avoiding the hooked user-mode functions entirely.
Conceptual flow:
Normal execution:
Application → ntdll.dll (hooked by EDR) → kernel
Direct syscall:
Application → kernel (bypasses ntdll.dll hooks)
Defenders should be aware that syscall-based evasion exists and invest in kernel-mode telemetry (like the Microsoft-Windows-Threat-Intelligence ETW provider) that cannot be bypassed from user-mode.
Detection Opportunities for Blue Teams
Understanding offensive tooling directly improves defensive capabilities. Here are the key detection opportunities for each concept discussed:
Network-Level Detection
| Indicator | Detection Approach |
|---|---|
| C2 beaconing | Monitor for periodic connections to the same endpoint with consistent intervals (jitter analysis) |
| DNS tunneling | Alert on high-entropy subdomain labels, unusual TXT query volumes, or long DNS query strings |
| Domain fronting | Compare the TLS SNI field with the HTTP Host header — mismatches indicate fronting |
| Malleable C2 profiles | Use JA3/JA3S fingerprinting to identify known C2 TLS signatures |
Endpoint-Level Detection
| Indicator | Detection Approach |
|---|---|
| AMSI bypass | Monitor for patches to amsi.dll in process memory (Event ID 1116) |
| ETW tampering | Detect EtwEventWrite patching or provider unregistration |
| Sleep obfuscation | Periodic memory scans that detect encryption/decryption patterns, or monitor VirtualProtect call patterns (RW→RX transitions) |
| Process injection | Monitor for cross-process memory operations: VirtualAllocEx + WriteProcessMemory + CreateRemoteThread patterns |
| Syscall evasion | Kernel-level telemetry via the Threat Intelligence ETW provider; detect syscall instructions outside of ntdll.dll |
Behavioral Detection
Beyond individual indicators, focus on behavioral chains:
- A process that performs DNS lookups at regular intervals, modifies its own memory permissions, and spawns child processes in unusual ways is far more suspicious than any single action alone.
- MITRE ATT&CK mapping helps correlate individual detections into attack narratives. A single T1055 (Process Injection) alert might be a false positive, but T1055 followed by T1003 (Credential Dumping) followed by T1021 (Lateral Movement) tells a clear story.
Why Understanding Offense Improves Defense
There’s a persistent debate about whether defenders should study offensive techniques. My position is unequivocal: you cannot defend against what you don’t understand.
Security teams that understand C2 architecture can:
- Write better detection rules because they know what artifacts to look for
- Prioritize security investments based on which evasion techniques are most common in real attacks
- Validate their defenses by testing with realistic adversary emulation, not just compliance scanners
- Communicate risk more effectively to leadership because they can articulate specific attack scenarios
The best security programs invest in purple teaming — bringing offensive and defensive practitioners together to iteratively improve detection and response capabilities. Understanding C2 frameworks is foundational to that process.
Recommended Resources
For those looking to deepen their understanding of C2 concepts:
- The C2 Matrix (howto.thec2matrix.com) — a community-maintained comparison of C2 frameworks
- MITRE ATT&CK — specifically the Command and Control tactic (TA0011) for comprehensive technique documentation
- SpecterOps blog — research on Active Directory attack paths and offensive tooling
- Elastic Security Labs — defensive research including detection engineering for C2 and evasion techniques
- Red Team Village talks (DEF CON) — practitioner-focused presentations on C2 development and operations
Conclusion
C2 frameworks are complex systems that reflect the ongoing cat-and-mouse game between attackers and defenders. By understanding the architecture, communication methods, and evasion concepts, both red and blue teams can be more effective in their respective roles.
The key takeaway for defenders: invest in behavioral detection and kernel-level telemetry. Signature-based detection will always lag behind attacker innovation. The key takeaway for red teamers: understand what generates telemetry and design operations to minimize your footprint, because detection engineering is advancing rapidly.