reverse-skills-max: initial public release (restored, redacted, hardened)

This commit is contained in:
baradok609hecl1pq6qi
2026-10-20 02:17:15 +03:00
commit da24c2bd20
2227 changed files with 443931 additions and 0 deletions

View File

@@ -0,0 +1,9 @@
Apache License 2.0 — see the repository root LICENSE file for the full text.
Copyright the AnalystAIPack contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0

View File

@@ -0,0 +1,101 @@
---
name: capturing-and-analyzing-malware-network-traffic
description: 'Captures and analyzes malware network traffic from a detonation: extracting C2
endpoints, HTTP/DNS patterns, TLS metadata (JA3/SNI), and beaconing from a PCAP to build
network IOCs and detection. Activates for requests to analyze malware PCAP, extract C2 from
traffic, or study network behavior.'
domain: cybersecurity
subdomain: malware-analysis
tags:
- malware
- network-analysis
- pcap
- c2
- dns
- beaconing
version: 1.0.0
author: analyst-ai-pack
license: Apache-2.0
mitre_attack:
- T1071.001
- T1071.004
- T1571
- T1095
d3fend:
- D3-NTA
- D3-NTPA
references:
- 'Wireshark User Guide — https://www.wireshark.org/docs/wsug_html_chunked/'
- 'Zeek documentation — https://docs.zeek.org/'
---
# Capturing and Analyzing Malware Network Traffic
## When to Use
- You detonated a sample and captured a PCAP on the services guest, and need to extract its
network behavior.
- You want C2 endpoints, HTTP/DNS patterns, TLS SNI/JA3, and beaconing intervals.
- You are turning traffic observations into network IOCs and detection signatures.
**Do not use** a single capture as the full C2 picture — staged samples reveal more on longer
runs or with the right context. Combine with binary config extraction.
## Prerequisites
- A PCAP captured from the isolated lab (capture on the analysis guest, not the victim).
- `tshark`/Wireshark, or Zeek for connection logs, or the bundled PCAP summarizer.
- The lab's simulated-internet IP so you can separate sample traffic from noise.
## Safety & Handling
- Capture from the services/analysis guest so the victim never hosts a sniffer.
- Defang all extracted domains/IPs/URLs before sharing.
## Workflow
### Step 1: Get a connection overview
Summarize conversations and protocols to see who talks to whom and how often:
```bash
python scripts/analyst.py summarize capture.pcap
```
### Step 2: Analyze DNS
List queried domains and resolved IPs. Look for DGA-like randomness, repeated NXDOMAIN, and
long TXT records (possible tunneling).
### Step 3: Inspect HTTP/HTTPS
For HTTP, examine URIs, methods, User-Agent (often unique/odd), and POST bodies. For HTTPS,
extract SNI and JA3/JA3S fingerprints since payloads are encrypted.
### Step 4: Detect beaconing
Compute inter-arrival times to the same destination. Regular intervals (with jitter) to one
host indicate C2 check-ins.
### Step 5: Build IOCs and detection
Produce a network IOC set (domains, IPs, URIs, JA3, User-Agent) and hand candidate signatures
to the Suricata/Zeek detection workflow.
## Validation
- Beaconing intervals are consistent and tied to a specific destination, not random browsing.
- Extracted SNI/JA3 reproduce across runs of the same sample.
- DNS and HTTP observations corroborate the C2 endpoints found in the binary's config.
## Pitfalls
- Mistaking simulated-internet responses for real C2 behavior; know your lab's IPs.
- Ignoring HTTPS because it is encrypted — SNI, JA3, and timing are still strong signals.
- Treating one short capture as complete; some C2 only beacons periodically.
## References
- See [`references/api-reference.md`](references/api-reference.md) for the PCAP summarizer and
beaconing detector.
- Wireshark and Zeek documentation (linked in frontmatter).

View File

@@ -0,0 +1,43 @@
# API Reference: Capturing and Analyzing Malware Network Traffic
## Overview
`scripts/analyst.py` summarizes a PCAP into top conversations, DNS queries, TLS SNI, and detects
beaconing by inter-arrival timing. It prefers `pyshark` (tshark) and falls back to a minimal
pure-Python classic-pcap parser for IPv4 conversations and beaconing.
## Dependencies
| Package | Version | Purpose |
|---------|---------|---------|
| pyshark | >= 0.6 | Rich packet parsing via tshark (optional) |
| (stdlib) | — | Minimal pcap parser, statistics |
## External tools
| Tool | Purpose |
|------|---------|
| tshark / Wireshark | Interactive and scripted PCAP analysis |
| Zeek | Connection, DNS, HTTP, and SSL logs from PCAP |
## Core functions
### `summarize(path)`
Dispatches to pyshark or the minimal parser; returns conversations, DNS/SNI (pyshark), and
beaconing.
### `_beaconing(timestamps_by_dst)`
Flags destinations with low-jitter regular intervals (likely C2 check-ins).
## Usage
```bash
pip install pyshark # optional; requires tshark on PATH
python scripts/analyst.py summarize capture.pcap
```
## Sources
- Wireshark User Guide — https://www.wireshark.org/docs/wsug_html_chunked/
- Zeek documentation — https://docs.zeek.org/
- libpcap classic file format (header/record layout)

View File

@@ -0,0 +1,124 @@
#!/usr/bin/env python3
"""Summarize a PCAP and detect beaconing.
Prefers ``pyshark`` (a tshark wrapper) for rich parsing; falls back to a minimal pure-Python
parser that reads the classic pcap format and tallies IPv4 conversations. Analyzes captured
traffic only — it never generates traffic.
"""
from __future__ import annotations
import argparse
import json
import statistics
import struct
import sys
from collections import defaultdict
def _beaconing(timestamps_by_dst: dict[str, list[float]]) -> list[dict]:
results = []
for dst, times in timestamps_by_dst.items():
if len(times) < 4:
continue
times = sorted(times)
deltas = [t2 - t1 for t1, t2 in zip(times, times[1:])]
mean = statistics.mean(deltas)
if mean <= 0:
continue
stdev = statistics.pstdev(deltas)
jitter = stdev / mean
if jitter < 0.25: # regular interval = likely beacon
results.append({"dst": dst, "count": len(times),
"interval_s": round(mean, 2), "jitter": round(jitter, 3)})
return sorted(results, key=lambda r: r["jitter"])
def summarize_with_pyshark(path: str) -> dict:
import pyshark # type: ignore
cap = pyshark.FileCapture(path, keep_packets=False)
convos: dict[tuple, int] = defaultdict(int)
times_by_dst: dict[str, list[float]] = defaultdict(list)
dns: set[str] = set()
sni: set[str] = set()
for pkt in cap:
try:
if hasattr(pkt, "ip"):
src, dst = pkt.ip.src, pkt.ip.dst
convos[(src, dst)] += 1
times_by_dst[dst].append(float(pkt.sniff_timestamp))
if hasattr(pkt, "dns") and hasattr(pkt.dns, "qry_name"):
dns.add(pkt.dns.qry_name)
if hasattr(pkt, "tls") and hasattr(pkt.tls, "handshake_extensions_server_name"):
sni.add(pkt.tls.handshake_extensions_server_name)
except AttributeError:
continue
cap.close()
return {
"engine": "pyshark",
"top_conversations": sorted(
[{"src": s, "dst": d, "packets": n} for (s, d), n in convos.items()],
key=lambda c: c["packets"], reverse=True)[:20],
"dns_queries": sorted(dns),
"tls_sni": sorted(sni),
"beaconing": _beaconing(times_by_dst),
}
def summarize_minimal(path: str) -> dict:
"""Minimal classic-pcap parser: IPv4 conversations and per-dst timestamps."""
with open(path, "rb") as fh:
data = fh.read()
if len(data) < 24:
raise ValueError("file too small to be a pcap")
magic = data[:4]
if magic in (b"\xd4\xc3\xb2\xa1", b"\xa1\xb2\xc3\xd4"):
endian = "<" if magic == b"\xd4\xc3\xb2\xa1" else ">"
else:
raise ValueError("not a classic pcap (try pyshark for pcapng)")
off = 24
convos: dict[tuple, int] = defaultdict(int)
times_by_dst: dict[str, list[float]] = defaultdict(list)
while off + 16 <= len(data):
ts_sec, ts_usec, incl, _orig = struct.unpack_from(endian + "IIII", data, off)
off += 16
pkt = data[off:off + incl]
off += incl
if len(pkt) < 14 + 20:
continue
eth_type = struct.unpack_from(">H", pkt, 12)[0]
if eth_type != 0x0800: # IPv4 only
continue
ip = pkt[14:]
src = ".".join(str(b) for b in ip[12:16])
dst = ".".join(str(b) for b in ip[16:20])
convos[(src, dst)] += 1
times_by_dst[dst].append(ts_sec + ts_usec / 1e6)
return {
"engine": "minimal",
"top_conversations": sorted(
[{"src": s, "dst": d, "packets": n} for (s, d), n in convos.items()],
key=lambda c: c["packets"], reverse=True)[:20],
"beaconing": _beaconing(times_by_dst),
"note": "install pyshark for DNS/TLS/HTTP detail and pcapng support",
}
def summarize(path: str) -> dict:
try:
return summarize_with_pyshark(path)
except ImportError:
return summarize_minimal(path)
def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(description="Summarize malware PCAP")
sub = parser.add_subparsers(dest="cmd", required=True)
p = sub.add_parser("summarize")
p.add_argument("pcap")
args = parser.parse_args(argv)
print(json.dumps(summarize(args.pcap), indent=2))
return 0
if __name__ == "__main__":
sys.exit(main())