Loading...
Loading...
Analyzes malware command-and-control (C2) communication protocols to understand beacon patterns, command structures, data encoding, and infrastructure. Covers HTTP, HTTPS, DNS, and custom protocol C2 analysis for detection development and threat intelligence. Activates for requests involving C2 analysis, beacon detection, C2 protocol reverse engineering, or command-and-control infrastructure mapping.
npx skill4agent add mukul975/anthropic-cybersecurity-skills analyzing-command-and-control-communicationscapydpktrequestsC2 Communication Channels:
━━━━━━━━━━━━━━━━━━━━━━━━━
HTTP/HTTPS: Most common; uses standard web traffic to blend in
Indicators: Regular POST/GET requests, specific URI patterns, custom headers
DNS: Tunneling data through DNS queries and responses
Indicators: High-volume TXT queries, long subdomain names, high entropy
Custom TCP/UDP: Proprietary binary protocol on non-standard port
Indicators: Non-HTTP traffic on high ports, unknown protocol
ICMP: Data encoded in ICMP echo/reply payloads
Indicators: ICMP packets with large or non-standard payloads
WebSocket: Persistent bidirectional connection for real-time C2
Indicators: WebSocket upgrade followed by binary frames
Cloud Services: Using legitimate APIs (Telegram, Discord, Slack, GitHub)
Indicators: API calls to cloud services from unexpected processes
Email: SMTP/IMAP for C2 commands and data exfiltration
Indicators: Automated email operations from non-email processesfrom scapy.all import rdpcap, IP, TCP
from collections import defaultdict
import statistics
import json
packets = rdpcap("c2_traffic.pcap")
# Group TCP SYN packets by destination
connections = defaultdict(list)
for pkt in packets:
if IP in pkt and TCP in pkt and (pkt[TCP].flags & 0x02):
key = f"{pkt[IP].dst}:{pkt[TCP].dport}"
connections[key].append(float(pkt.time))
# Analyze each destination for beaconing
for dst, times in sorted(connections.items()):
if len(times) < 3:
continue
intervals = [times[i+1] - times[i] for i in range(len(times)-1)]
avg_interval = statistics.mean(intervals)
stdev = statistics.stdev(intervals) if len(intervals) > 1 else 0
jitter_pct = (stdev / avg_interval * 100) if avg_interval > 0 else 0
duration = times[-1] - times[0]
beacon_data = {
"destination": dst,
"connections": len(times),
"duration_seconds": round(duration, 1),
"avg_interval_seconds": round(avg_interval, 1),
"stdev_seconds": round(stdev, 1),
"jitter_percent": round(jitter_pct, 1),
"is_beacon": 5 < avg_interval < 7200 and jitter_pct < 25,
}
if beacon_data["is_beacon"]:
print(f"[!] BEACON DETECTED: {dst}")
print(f" Interval: {avg_interval:.0f}s +/- {stdev:.0f}s ({jitter_pct:.0f}% jitter)")
print(f" Sessions: {len(times)} over {duration:.0f}s")# HTTP-based C2 protocol analysis
import dpkt
import base64
with open("c2_traffic.pcap", "rb") as f:
pcap = dpkt.pcap.Reader(f)
for ts, buf in pcap:
eth = dpkt.ethernet.Ethernet(buf)
if not isinstance(eth.data, dpkt.ip.IP):
continue
ip = eth.data
if not isinstance(ip.data, dpkt.tcp.TCP):
continue
tcp = ip.data
if tcp.dport == 80 or tcp.dport == 443:
if len(tcp.data) > 0:
try:
http = dpkt.http.Request(tcp.data)
print(f"\n--- C2 REQUEST ---")
print(f"Method: {http.method}")
print(f"URI: {http.uri}")
print(f"Headers: {dict(http.headers)}")
if http.body:
print(f"Body ({len(http.body)} bytes):")
# Try Base64 decode
try:
decoded = base64.b64decode(http.body)
print(f" Decoded: {decoded[:200]}")
except:
print(f" Raw: {http.body[:200]}")
except:
passKnown C2 Framework Signatures:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Cobalt Strike:
- Default URIs: /pixel, /submit.php, /___utm.gif, /ca, /dpixel
- Malleable C2 profiles customize all traffic characteristics
- JA3: varies by profile, catalog at ja3er.com
- Watermark in beacon config (unique per license)
- Config extraction: use CobaltStrikeParser or 1768.py
Metasploit/Meterpreter:
- Default staging URI patterns: random 4-char checksum
- Reverse HTTP(S) handler patterns
- Meterpreter TLV (Type-Length-Value) protocol structure
Sliver:
- mTLS, HTTP, DNS, WireGuard transport options
- Protobuf-encoded messages
- Unique implant ID in communication
Covenant:
- .NET-based C2 framework
- HTTP with customizable profiles
- Task-based command execution
PoshC2:
- PowerShell/C# based
- HTTP with encrypted payloads
- Cookie-based session management# Extract Cobalt Strike beacon configuration from PCAP or sample
python3 << 'PYEOF'
# Using CobaltStrikeParser (pip install cobalt-strike-parser)
from cobalt_strike_parser import BeaconConfig
try:
config = BeaconConfig.from_file("suspect.exe")
print("Cobalt Strike Beacon Configuration:")
for key, value in config.items():
print(f" {key}: {value}")
except Exception as e:
print(f"Not a Cobalt Strike beacon or parse error: {e}")
PYEOF# Infrastructure mapping
import requests
import json
c2_indicators = {
"primary_c2": "185.220.101.42",
"domains": ["update.malicious.com", "backup.evil.net"],
"ports": [443, 8443],
"failover_dns": ["ns1.malicious-dns.com"],
}
# Enrich with Shodan
def shodan_lookup(ip, api_key):
resp = requests.get(f"https://api.shodan.io/shodan/host/{ip}?key={api_key}")
if resp.status_code == 200:
data = resp.json()
return {
"ip": ip,
"ports": data.get("ports", []),
"os": data.get("os"),
"org": data.get("org"),
"asn": data.get("asn"),
"country": data.get("country_code"),
"hostnames": data.get("hostnames", []),
"last_update": data.get("last_update"),
}
return None
# Enrich with passive DNS
def pdns_lookup(domain):
# Using VirusTotal passive DNS
resp = requests.get(
f"https://www.virustotal.com/api/v3/domains/{domain}/resolutions",
headers={"x-apikey": VT_API_KEY}
)
if resp.status_code == 200:
data = resp.json()
resolutions = []
for r in data.get("data", []):
resolutions.append({
"ip": r["attributes"]["ip_address"],
"date": r["attributes"]["date"],
})
return resolutions
return []# Suricata rules for the analyzed C2
cat << 'EOF' > c2_detection.rules
# HTTP beacon pattern
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"MALWARE MalwareX C2 HTTP Beacon";
flow:established,to_server;
http.method; content:"POST";
http.uri; content:"/gate.php"; startswith;
http.header; content:"User-Agent: Mozilla/5.0 (compatible; MSIE 10.0)";
threshold:type threshold, track by_src, count 5, seconds 600;
sid:9000010; rev:1;
)
# JA3 fingerprint match
alert tls $HOME_NET any -> $EXTERNAL_NET any (
msg:"MALWARE MalwareX TLS JA3 Fingerprint";
ja3.hash; content:"a0e9f5d64349fb13191bc781f81f42e1";
sid:9000011; rev:1;
)
# DNS beacon detection (high-entropy subdomain)
alert dns $HOME_NET any -> any any (
msg:"MALWARE Suspected DNS C2 Tunneling";
dns.query; pcre:"/^[a-z0-9]{20,}\./";
threshold:type threshold, track by_src, count 10, seconds 60;
sid:9000012; rev:1;
)
# Certificate-based detection
alert tls $HOME_NET any -> $EXTERNAL_NET any (
msg:"MALWARE MalwareX Self-Signed C2 Certificate";
tls.cert_subject; content:"CN=update.malicious.com";
sid:9000013; rev:1;
)
EOF| Term | Definition |
|---|---|
| Beaconing | Periodic check-in communication from malware to C2 server at regular intervals, often with jitter to avoid pattern detection |
| Jitter | Randomization applied to beacon interval (e.g., 60s +/- 15%) to make the timing pattern less predictable and harder to detect |
| Malleable C2 | Cobalt Strike feature allowing operators to customize all aspects of C2 traffic (URIs, headers, encoding) to mimic legitimate services |
| Dead Drop | Intermediate location (paste site, cloud storage, social media) where C2 commands are posted for the malware to retrieve |
| Domain Fronting | Using a trusted CDN domain in the TLS SNI while routing to a different backend, making C2 traffic appear to go to a legitimate service |
| Fast Flux | Rapidly changing DNS records for C2 domains to distribute across many IPs and resist takedown efforts |
| C2 Framework | Software toolkit providing C2 server, implant generator, and operator interface (Cobalt Strike, Metasploit, Sliver, Covenant) |
C2 COMMUNICATION ANALYSIS REPORT
===================================
Sample: malware.exe (SHA-256: e3b0c44...)
C2 Framework: Cobalt Strike 4.9
BEACON CONFIGURATION
C2 Server: hxxps://185.220.101[.]42/updates
Beacon Type: HTTPS (reverse)
Sleep: 60 seconds
Jitter: 15%
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
URI (GET): /dpixel
URI (POST): /submit.php
Watermark: 1234567890
PROTOCOL ANALYSIS
Transport: HTTPS (TLS 1.2)
JA3 Hash: a0e9f5d64349fb13191bc781f81f42e1
Certificate: CN=Microsoft Update (self-signed)
Encoding: Base64 with XOR key 0x69
Command Format: [4B length][4B command_id][payload]
COMMAND SET
0x01 - Sleep Change beacon interval
0x02 - Shell Execute cmd.exe command
0x03 - Download Transfer file from C2
0x04 - Upload Exfiltrate file to C2
0x05 - Inject Process injection
0x06 - Keylog Start keylogger
0x07 - Screenshot Capture screen
INFRASTRUCTURE
Primary: 185.220.101[.]42 (AS12345, Hosting Co, NL)
Failover: 91.215.85[.]17 (AS67890, VPS Provider, RU)
DNS: update.malicious[.]com -> 185.220.101[.]42
Registrar: NameCheap
Registration: 2025-09-01
DETECTION SIGNATURES
SID 9000010: HTTP beacon pattern
SID 9000011: JA3 TLS fingerprint
SID 9000013: C2 certificate match