SKILLS/analyzing-command-and-control-communication/SKILL.md
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 skillsauth add pinkpixel-dev/skills-collection-1 analyzing-command-and-control-communicationInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Do not use for general network anomaly detection; this is specifically for understanding known or suspected C2 protocols from malware analysis.
scapy, dpkt, and requests for protocol analysis and replayDetermine the protocol and transport used for C2 communication:
C2 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 processes
Characterize the periodic communication pattern:
from 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")
Reverse engineer the message format from captured traffic:
# 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:
pass
Match observed patterns to known C2 frameworks:
Known 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
Document the full C2 infrastructure and failover mechanisms:
# 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 []
Build detection rules based on analyzed C2 characteristics:
# 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) |
Context: A malware sample communicates with its C2 server using an unknown binary protocol over TCP port 8443. The protocol needs to be decoded to understand the command set and build detection signatures.
Approach:
Pitfalls:
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
testing
When the user wants a full ASO health audit, review their App Store listing quality, or diagnose why their app isn't ranking. Also use when the user mentions "ASO audit", "ASO score", "why am I not ranking", "listing review", or "optimize my app store page". For keyword-specific research, see keyword-research. For metadata writing, see metadata-optimization.
testing
Clarify requirements before implementing. Use when serious doubts arise.
tools
Complete reference and build guide for ASI:One (ASI1) — the AI platform by Fetch.ai built for agentic, Web3-native applications. Use this skill IMMEDIATELY and ALWAYS when the user mentions ASI1, ASI:One, Fetch.ai AI API, building with ASI1, integrating ASI:One, asking about ASI1 models, tool calling with ASI1, ASI1 image generation, ASI1 agentic LLM, Agentverse, uagents, Agent Chat Protocol, structured output with ASI1, or OpenAI-compatible wrappers for ASI1. Also trigger when the user says things like "use ASI1 instead of OpenAI", "build an app with ASI:One", "ASI1 API", or references docs.asi1.ai. This skill covers everything needed to build production apps - setup, all models, all API features, tool calling, image gen, agentic orchestration, structured data, session management, streaming, LangChain integration, uagents / Agent Chat Protocol, and TypeScript/Node.js patterns.
data-ai
When the user wants to analyze their own app's actual performance data from App Store Connect — real downloads, revenue, IAP, subscriptions, trials, or country breakdowns synced via Appeeky Connect. Use when the user asks about "my downloads", "my revenue", "how is my app performing", "ASC data", "sales and trends", "my subscription numbers", "App Store Connect metrics", or wants to compare periods or top markets. For third-party app estimates, see app-analytics. For subscription analytics depth, see monetization-strategy.