npx skills add mukul975/Anthropic-Cybersecurity-SkillsMITRE ATT&CK
When to Use
- SIEM alerts on anomalous network traffic patterns requiring deeper investigation
- C2 beaconing is suspected and needs confirmation through packet-level analysis
- Data exfiltration volume or destination must be quantified from network evidence
- Lateral movement between systems needs to be traced through network connections
- An IDS/IPS alert requires packet-level validation to confirm or dismiss
Do not use for host-based forensic analysis (process execution, file system artifacts); use endpoint forensics tools instead.
Prerequisites
- Full packet capture (PCAP) infrastructure or on-demand capture capability (network tap, SPAN port)
- Wireshark installed on the analysis workstation with appropriate display filters knowledge
- Zeek (formerly Bro) deployed for network metadata generation (conn.log, dns.log, http.log, ssl.log)
- NetFlow/IPFIX collection from network devices for traffic flow analysis
- Network architecture diagram showing VLAN layout, firewall placement, and monitoring points
- Threat intelligence feeds for correlating observed network indicators
Workflow
Step 1: Capture or Acquire Network Traffic
Obtain the relevant traffic data for the investigation:
Live Capture (if incident is active):
# Capture on specific interface filtering by host
tcpdump -i eth0 -w capture.pcap host 10.1.5.42
# Capture C2 traffic to specific external IP
tcpdump -i eth0 -w c2_traffic.pcap host 185.220.101.42
# Capture with rotation (1GB files, keep 10)
tcpdump -i eth0 -w capture_%Y%m%d%H%M.pcap -C 1000 -W 10From Existing Infrastructure:
- Export PCAP from full packet capture appliance (Arkime/Moloch, ExtraHop, Corelight)
- Pull Zeek logs from the Zeek cluster for the investigation timeframe
- Export NetFlow data from network devices for high-level traffic analysis
Step 2: Identify C2 Communications
Detect command-and-control traffic patterns:
Beaconing Detection (Zeek conn.log):
# Extract connections to external IPs with regular intervals
cat conn.log | zeek-cut ts id.orig_h id.resp_h id.resp_p duration orig_bytes resp_bytes \
| awk '$4 ~ /^185\.220/' | sort -t. -k1,1n -k2,2nWireshark Beacon Analysis:
# Filter for traffic to suspected C2 IP
ip.addr == 185.220.101.42
# Filter HTTPS traffic to non-standard ports
tcp.port != 443 && ssl
# Filter DNS queries for suspicious domains
dns.qry.name contains "evil" or dns.qry.name matches "^[a-z0-9]{32}\."
# Filter HTTP POST (common C2 check-in method)
http.request.method == "POST" && ip.dst == 185.220.101.42Beaconing characteristics to identify:
- Regular time intervals between connections (e.g., every 60 seconds with 10-15% jitter)
- Consistent packet sizes in requests and responses
- HTTPS to external IPs not associated with legitimate CDNs or services
- DNS queries with high entropy subdomains (DNS tunneling indicator)
Step 3: Analyze Lateral Movement Traffic
Trace adversary movement between internal systems:
Key protocols for lateral movement detection:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
SMB (TCP 445): PsExec, file share access, ransomware propagation
RDP (TCP 3389): Remote desktop sessions
WinRM (TCP 5985): PowerShell remoting
WMI (TCP 135): Remote command execution
SSH (TCP 22): Linux lateral movement
DCE/RPC (TCP 135): DCOM-based lateral movementWireshark Filters for Lateral Movement:
# SMB lateral movement
smb2 && ip.src == 10.1.5.42 && ip.dst != 10.1.5.42
# RDP connections from compromised host
tcp.dstport == 3389 && ip.src == 10.1.5.42
# Kerberos ticket requests (potential pass-the-ticket)
kerberos.msg_type == 12 && ip.src == 10.1.5.42
# NTLM authentication (potential pass-the-hash)
ntlmssp.auth.username && ip.src == 10.1.5.42Step 4: Detect Data Exfiltration
Identify unauthorized data transfers leaving the network:
# Identify large outbound transfers in Zeek conn.log
cat conn.log | zeek-cut ts id.orig_h id.resp_h id.resp_p orig_bytes \
| awk '$5 > 100000000' | sort -t$'\t' -k5 -rn
# DNS tunneling detection (high volume of TXT queries)
cat dns.log | zeek-cut query qtype | grep TXT | cut -f1 \
| rev | cut -d. -f1,2 | rev | sort | uniq -c | sort -rn | head
# Unusual protocol usage (ICMP tunneling, DNS over HTTPS)
cat conn.log | zeek-cut proto id.resp_p orig_bytes | awk '$1 == "icmp" && $3 > 1000'Wireshark Exfiltration Filters:
# Large HTTP POST uploads
http.request.method == "POST" && tcp.len > 10000
# FTP data transfers
ftp-data && ip.src == 10.0.0.0/8
# DNS with large TXT responses (tunneling)
dns.resp.type == 16 && dns.resp.len > 200Step 5: Extract and Correlate IOCs
Pull network-based indicators from traffic analysis:
- External IP addresses contacted by compromised hosts
- Domains resolved via DNS during the incident timeframe
- URLs accessed via HTTP/HTTPS (if SSL inspection is in place)
- TLS certificate details (subject, issuer, serial number, JA3/JA3S hashes)
- User-Agent strings from HTTP requests
- File transfers captured in PCAP (extract using Wireshark Export Objects)
Step 6: Document Network Forensic Findings
Compile analysis into a structured report with evidence references:
- Reference specific PCAP files, frame numbers, and timestamps for each finding
- Include packet captures of key evidence as screenshots or exported PDFs
- Map network activity to the incident timeline
- Correlate network findings with host-based evidence from endpoint forensics
Key Concepts
| Term | Definition |
|---|---|
| PCAP (Packet Capture) | File format storing raw network packets captured from a network interface for offline analysis |
| Beaconing | Regular, periodic network connections from a compromised host to a C2 server, identifiable by consistent timing intervals |
| JA3/JA3S | TLS client and server fingerprinting method based on the ClientHello and ServerHello parameters; unique per application |
| NetFlow/IPFIX | Network traffic metadata (source, destination, ports, bytes, duration) collected by routers and switches without full packet capture |
| DNS Tunneling | Technique encoding data in DNS queries and responses to exfiltrate data or maintain C2 through DNS protocol |
| Network Tap | Hardware device that creates an exact copy of network traffic for monitoring without impacting network performance |
| Zeek Logs | Structured metadata logs generated by the Zeek network analysis framework covering connections, DNS, HTTP, SSL, and more |
Tools & Systems
- Wireshark: Open-source packet analyzer for deep inspection of network protocols at the packet level
- Zeek (formerly Bro): Network analysis framework generating structured metadata logs from live or captured traffic
- Arkime (formerly Moloch): Open-source full packet capture and search platform for large-scale network forensics
- NetworkMiner: Network forensic analysis tool for extracting files, images, and credentials from PCAP files
- RITA (Real Intelligence Threat Analytics): Open-source beacon detection and DNS tunneling analysis tool for Zeek logs
Common Scenarios
Scenario: Confirming C2 Beaconing and Quantifying Exfiltration
Context: EDR detects a suspicious process on a workstation but cannot determine the volume of data exfiltrated. Network team provides PCAP from the full packet capture appliance covering the incident timeframe.
Approach:
- Filter PCAP to traffic from the compromised host IP to external destinations
- Identify the C2 channel by analyzing connection timing patterns (beacon detection)
- Extract TLS certificate and JA3 hash from the C2 connection for IOC generation
- Calculate total bytes transferred to C2 infrastructure over the incident duration
- Check for additional exfiltration channels (DNS tunneling, cloud storage uploads)
- Extract any unencrypted files transferred using Wireshark Export Objects feature
Pitfalls:
- Analyzing only HTTP traffic when C2 is operating over HTTPS without SSL inspection
- Missing DNS tunneling because the data volume per query is small (but total over time is significant)
- Not correlating network timestamps with endpoint timestamps (timezone mismatches)
- Overlooking legitimate cloud services abused for exfiltration (OneDrive, Google Drive, Dropbox)
Output Format
NETWORK TRAFFIC ANALYSIS REPORT
=================================
Incident: INC-2025-1547
Analyst: [Name]
Capture Source: Arkime full packet capture
Analysis Period: 2025-11-15 14:00 UTC - 2025-11-15 18:00 UTC
Total PCAP Size: 4.7 GB
C2 COMMUNICATIONS
Source: 10.1.5.42 (WKSTN-042)
Destination: 185.220.101.42:443 (HTTPS)
Beacon Interval: 60 seconds ± 12% jitter
Sessions: 237 connections over 4 hours
JA3 Hash: a0e9f5d64349fb13191bc781f81f42e1
TLS Certificate: CN=update.evil[.]com (self-signed)
Total Data Sent: 147 MB (outbound)
Total Data Recv: 2.3 MB (inbound - commands)
LATERAL MOVEMENT
10.1.5.42 → 10.1.10.15 (SMB, TCP 445) - 14:35 UTC
10.1.5.42 → 10.1.10.20 (RDP, TCP 3389) - 14:42 UTC
10.1.5.42 → 10.1.1.5 (LDAP, TCP 389) - 15:10 UTC
EXFILTRATION SUMMARY
Protocol: HTTPS to C2 server
Volume: 147 MB outbound
Duration: 14:23 UTC - 18:00 UTC
Files Extracted: [list if recoverable from unencrypted channels]
DNS ANALYSIS
Suspicious Queries: 0 DNS tunneling indicators
DGA Detection: 0 algorithmically generated domains
EVIDENCE REFERENCES
PCAP File: INC-2025-1547_capture.pcap (SHA-256: ...)
Zeek Logs: /logs/zeek/2025-11-15/ (conn.log, ssl.log, dns.log)References and resources
Everything below is rendered for inspection. Script files are read-only and never run.
References 1
api-reference.md2.8 KB
API Reference: Network Traffic Incident Analysis
tshark - CLI Wireshark
Basic Syntax
tshark -r <pcap_file> [options]Display Filters
tshark -r capture.pcap -Y "ip.addr==10.0.0.5"
tshark -r capture.pcap -Y "tcp.port==445" # SMB
tshark -r capture.pcap -Y "http.request" # HTTP requests
tshark -r capture.pcap -Y "dns.qr==0" # DNS queries
tshark -r capture.pcap -Y "tcp.flags.syn==1 && tcp.flags.ack==0" # SYN onlyField Extraction
tshark -r capture.pcap -T fields -e ip.src -e ip.dst -e tcp.dstport \
-Y "tcp.flags.syn==1"Statistics
tshark -r capture.pcap -q -z conv,ip # IP conversations
tshark -r capture.pcap -q -z endpoints,ip # IP endpoints
tshark -r capture.pcap -q -z io,stat,60 # I/O stats per minute
tshark -r capture.pcap -q -z http,tree # HTTP request tree
tshark -r capture.pcap -q -z dns,tree # DNS query treeObject Export
tshark -r capture.pcap --export-objects "http,/tmp/http_objects"
tshark -r capture.pcap --export-objects "smb,/tmp/smb_objects"Zeek - Network Security Monitor
PCAP Analysis
zeek -r capture.pcap
zeek -r capture.pcap local # With local policy scriptsOutput Logs
| Log File | Content |
|---|---|
conn.log |
TCP/UDP/ICMP connections |
dns.log |
DNS queries and responses |
http.log |
HTTP requests |
ssl.log |
TLS/SSL handshakes |
files.log |
File transfers |
notice.log |
Security notices |
Zeek-Cut Field Extraction
cat conn.log | zeek-cut id.orig_h id.resp_h id.resp_p proto service
cat dns.log | zeek-cut query qtype_name answers
cat http.log | zeek-cut host uri method user_agentSuricata - IDS/IPS
PCAP Analysis
suricata -r capture.pcap -l /tmp/output -k none
suricata -r capture.pcap -S custom.rules -l /tmp/outputOutput Files
| File | Content |
|---|---|
fast.log |
One-line alert format |
eve.json |
JSON event log (detailed) |
stats.log |
Engine performance statistics |
Lateral Movement Ports
| Port | Service | Significance |
|---|---|---|
| 445 | SMB | File shares, PsExec, WMI |
| 3389 | RDP | Remote Desktop |
| 5985/5986 | WinRM | PowerShell Remoting |
| 22 | SSH | Secure Shell |
| 135 | RPC | DCOM, WMI |
| 139 | NetBIOS | Legacy file sharing |
Scapy - Packet Analysis (Python)
PCAP Reading
from scapy.all import rdpcap, IP, TCP
packets = rdpcap("capture.pcap")
for pkt in packets:
if IP in pkt and TCP in pkt:
print(pkt[IP].src, pkt[TCP].dport)NetworkMiner - Artifact Extraction
Syntax
NetworkMiner --inputfile capture.pcap --outputdir /tmp/artifactsExtracts: files, images, credentials, sessions, DNS, parameters
Scripts 1
agent.py7.6 KB
#!/usr/bin/env python3
"""Network traffic incident analysis agent using scapy and tshark for PCAP investigation."""
import subprocess
import os
import sys
import json
import statistics
from collections import defaultdict
try:
from scapy.all import rdpcap, IP, TCP, DNS
HAS_SCAPY = True
except ImportError:
HAS_SCAPY = False
def run_tshark(pcap_path, display_filter, fields):
"""Run tshark with a display filter and extract specific fields."""
cmd = ["tshark", "-r", pcap_path, "-Y", display_filter, "-T", "fields"]
for f in fields:
cmd += ["-e", f]
cmd += ["-E", "separator=|"]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
rows = []
if result.returncode == 0:
for line in result.stdout.strip().splitlines():
parts = line.split("|")
if len(parts) == len(fields):
rows.append(dict(zip(fields, parts)))
return rows
def get_pcap_summary(pcap_path):
"""Get high-level PCAP statistics."""
cmd = ["tshark", "-r", pcap_path, "-q", "-z", "conv,ip"]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
return result.stdout if result.returncode == 0 else ""
def detect_lateral_movement(pcap_path):
"""Detect potential lateral movement patterns (SMB, RDP, WinRM, SSH)."""
lateral_ports = {"445": "SMB", "3389": "RDP", "5985": "WinRM", "5986": "WinRM-S",
"22": "SSH", "135": "RPC", "139": "NetBIOS"}
connections = run_tshark(pcap_path, "tcp.flags.syn==1 && tcp.flags.ack==0",
["ip.src", "ip.dst", "tcp.dstport"])
lateral = []
for conn in connections:
port = conn.get("tcp.dstport", "")
if port in lateral_ports:
lateral.append({
"src": conn["ip.src"],
"dst": conn["ip.dst"],
"port": port,
"service": lateral_ports[port],
})
return lateral
def detect_data_exfiltration(pcap_path, threshold_mb=10):
"""Detect potential data exfiltration based on outbound data volume."""
cmd = ["tshark", "-r", pcap_path, "-q", "-z", "conv,ip"]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
suspects = []
if result.returncode == 0:
for line in result.stdout.splitlines():
parts = line.split()
if len(parts) >= 8 and "<->" in line:
try:
ip_a = parts[0]
ip_b = parts[2]
bytes_a_to_b = int(parts[4]) if parts[4].isdigit() else 0
bytes_b_to_a = int(parts[7]) if len(parts) > 7 and parts[7].isdigit() else 0
total_bytes = bytes_a_to_b + bytes_b_to_a
if total_bytes > threshold_mb * 1024 * 1024:
suspects.append({
"ip_a": ip_a,
"ip_b": ip_b,
"bytes_a_to_b": bytes_a_to_b,
"bytes_b_to_a": bytes_b_to_a,
"total_mb": round(total_bytes / (1024 * 1024), 2),
})
except (ValueError, IndexError):
continue
return suspects
def detect_beaconing(pcap_path, min_conns=10):
"""Detect periodic beaconing patterns from TCP connections."""
if not HAS_SCAPY:
return []
packets = rdpcap(pcap_path)
conn_times = defaultdict(list)
for pkt in packets:
if IP in pkt and TCP in pkt and (pkt[TCP].flags & 0x02):
key = f"{pkt[IP].src}->{pkt[IP].dst}:{pkt[TCP].dport}"
conn_times[key].append(float(pkt.time))
beacons = []
for key, times in conn_times.items():
if len(times) < min_conns:
continue
intervals = [times[i+1] - times[i] for i in range(len(times)-1)]
avg = statistics.mean(intervals)
std = statistics.stdev(intervals) if len(intervals) > 1 else 0
jitter = (std / avg * 100) if avg > 0 else 0
if 5 < avg < 7200 and jitter < 30:
beacons.append({
"flow": key,
"connections": len(times),
"avg_interval": round(avg, 1),
"jitter_pct": round(jitter, 1),
})
return beacons
def extract_dns_queries(pcap_path):
"""Extract DNS queries and identify suspicious patterns."""
queries = run_tshark(pcap_path, "dns.qr==0",
["ip.src", "dns.qry.name", "dns.qry.type"])
return queries
def detect_ids_alerts(pcap_path):
"""Run Suricata on the PCAP and extract alerts."""
import tempfile
suricata_output = os.environ.get("SURICATA_OUTPUT_DIR", os.path.join(tempfile.gettempdir(), "suricata_output"))
os.makedirs(suricata_output, exist_ok=True)
cmd = ["suricata", "-r", pcap_path, "-l", suricata_output, "-k", "none"]
subprocess.run(cmd, capture_output=True, timeout=120)
alerts = []
alert_file = os.path.join(suricata_output, "fast.log")
if os.path.exists(alert_file):
with open(alert_file, "r") as f:
for line in f:
alerts.append(line.strip())
return alerts
def extract_http_objects(pcap_path, output_dir):
"""Extract HTTP objects (files) from the PCAP."""
os.makedirs(output_dir, exist_ok=True)
cmd = ["tshark", "-r", pcap_path, "--export-objects", f"http,{output_dir}"]
subprocess.run(cmd, capture_output=True, timeout=60)
exported = []
if os.path.exists(output_dir):
for f in os.listdir(output_dir):
filepath = os.path.join(output_dir, f)
exported.append({"filename": f, "size": os.path.getsize(filepath)})
return exported
def generate_incident_report(pcap_path, beacons, lateral, exfil, dns_queries):
"""Generate a network incident analysis report."""
report = {
"pcap": pcap_path,
"pcap_size_mb": round(os.path.getsize(pcap_path) / (1024*1024), 1),
"findings": {
"beacons_detected": len(beacons),
"lateral_movement_flows": len(lateral),
"exfiltration_suspects": len(exfil),
"dns_queries": len(dns_queries),
},
"beacons": beacons,
"lateral_movement": lateral[:10],
"exfiltration": exfil,
}
return report
if __name__ == "__main__":
print("=" * 60)
print("Network Traffic Incident Analysis Agent")
print("Beaconing, lateral movement, exfiltration detection")
print("=" * 60)
pcap = sys.argv[1] if len(sys.argv) > 1 else None
if pcap and os.path.exists(pcap):
print(f"\n[*] Analyzing: {pcap}")
print(f"[*] Size: {os.path.getsize(pcap)/(1024*1024):.1f} MB")
print("\n--- Beacon Detection ---")
beacons = detect_beaconing(pcap)
for b in beacons:
print(f" [!] {b['flow']}: interval={b['avg_interval']}s "
f"jitter={b['jitter_pct']}% ({b['connections']} conns)")
print("\n--- Lateral Movement Detection ---")
lateral = detect_lateral_movement(pcap)
for l in lateral[:10]:
print(f" [!] {l['src']} -> {l['dst']}:{l['port']} ({l['service']})")
print("\n--- Data Exfiltration Detection ---")
exfil = detect_data_exfiltration(pcap, threshold_mb=5)
for e in exfil:
print(f" [!] {e['ip_a']} <-> {e['ip_b']}: {e['total_mb']} MB")
print("\n--- DNS Queries ---")
dns = extract_dns_queries(pcap)
print(f" Total queries: {len(dns)}")
report = generate_incident_report(pcap, beacons, lateral, exfil, dns)
print(f"\n[*] Report summary: {json.dumps(report['findings'], indent=2)}")
else:
print(f"\n[DEMO] Usage: python agent.py <capture.pcap>")