Sniffs outbound traffic for suspicious, beacon-like callbacks, because if it keeps coming back on schedule, it's probably not breakfast.
Bacon Sampler is a lightweight outbound-connection catcher that sniffs the sizzle of your network traffic and flags suspicious "beacon-like" behavior - those periodic, low-and-slow callbacks that malware loves to phone home with.
It passively monitors outbound connections and DNS lookups, then highlights patterns like steady intervals, repeated destinations, weird jitter, and consistent byte sizes, basically anything that looks less like normal browsing and more like a bot checking in for instructions.
Think of it as a Beacon Scanner, but tastier: if something keeps coming back at the same time every time... we're sampling the bacon.
- Pcap capture with optional netstat PID correlation
- Reverse DNS and GeoIP (offline database or free online lookup)
- Filters for protocol, remote port ranges, and IP CIDRs
- Group summaries (by remote IP, process, or country) with optional top N
- Beacon-like activity detection (low-and-slow callbacks)
- Pattern detection for suspicious connection + DNS query behavior
- CSV/JSON exports with derived summary files
- Optional HTML report with all tables
- Windows 11
- Python 3.10+
- Npcap (recommended) with "Install Npcap in WinPcap API-compatible Mode"
- GeoIP database for offline IP country lookup:
- MaxMind GeoLite2 Country (
.mmdb) or DB-IP Lite (.mmdb) - IP2Location LITE (
.BIN)
- MaxMind GeoLite2 Country (
- Run PowerShell as Administrator for full visibility
pip install -r requirements.txtDownload a GeoIP database and note the path:
- GeoLite2 or DB-IP Lite (
.mmdb) - IP2Location LITE (
.BIN)
If you prefer a free online lookup, you can skip this and use --geoip-online.
List interfaces:
python capture_outbound.py --list-interfacesPick an interface by index:
python capture_outbound.py --interface 0Use multiple interfaces (repeatable):
python capture_outbound.py --interface "Ethernet" --interface "Wi-Fi"Or with comma-separated names:
python capture_outbound.py --interfaces "Ethernet,Wi-Fi"Pcap-only capture (A) with offline GeoIP:
python capture_outbound.py --mode pcap --duration 20 --interface "Ethernet" --geoip-db "C:\Path\GeoLite2-Country.mmdb"Pcap + netstat correlation (B) with offline GeoIP:
python capture_outbound.py --mode pcap_plus_netstat --duration 20 --interface "Ethernet" --geoip-db "C:\Path\GeoLite2-Country.mmdb"Pcap + netstat union (A+B):
python capture_outbound.py --mode both --duration 20 --interface "Ethernet" --geoip-db "C:\Path\GeoLite2-Country.mmdb"Online GeoIP (free, rate-limited, cached to disk):
python capture_outbound.py --mode pcap --duration 20 --interface "Ethernet" --geoip-online ipapiOnline GeoIP with IPinfo token:
$env:IPINFO_TOKEN="your_token_here"
python capture_outbound.py --mode pcap --duration 20 --interface "Ethernet" --geoip-online ipinfoOr pass the token explicitly:
python capture_outbound.py --mode pcap --duration 20 --interface "Ethernet" --geoip-online ipinfo --geoip-online-token "your_token_here"Tune online GeoIP timeout and retries:
python capture_outbound.py --mode pcap --duration 20 --interface "Ethernet" --geoip-online ipapi --geoip-timeout 2.5 --geoip-retries 1Disable reverse DNS (faster runs):
python capture_outbound.py --mode pcap --duration 20 --interface "Ethernet" --no-dnsTune DNS timeout:
python capture_outbound.py --mode pcap --duration 20 --interface "Ethernet" --dns-timeout 0.5Limit capture by packet count:
python capture_outbound.py --mode pcap --duration 60 --packet-limit 5000Filter by protocol, remote port, and IP CIDR:
python capture_outbound.py --filter-protocol tcp --filter-port 80,443,1000-2000 --allow-ip 1.2.3.0/24 --deny-ip 1.2.3.4/32Group summaries and top N:
python capture_outbound.py --group-by remote_ip,process --top 10Track total bytes per connection:
python capture_outbound.py --mode pcap --duration 20 --interface "Ethernet" --track-bytesDisable progress output:
python capture_outbound.py --no-progressDisable console output:
python capture_outbound.py --no-consolePcap + netstat union (A+B) + Online GeoIP + Write a pcap + CSV + HTML:
python capture_outbound.py --mode both --duration 20 --interface "Ethernet,Wi-Fi" --geoip-online ipapi --pcap-out "C:\Path\capture.pcap" --csv "C:\Path\outbound.csv" --html "C:\Path\outbound.html"Pcap-only + output folder + custom CSV/JSON names:
python capture_outbound.py --mode pcap --duration 20 --interface "Ethernet" --output-dir "C:\Path\Reports" --csv "C:\Path\Reports\outbound.csv" --json "C:\Path\Reports\outbound.json"Beacon-like activity detection (low-and-slow callbacks):
python capture_outbound.py --duration 300 --beacon-min-duration 120 --beacon-min-interval 60 --beacon-max-interval 1800 --beacon-max-jitter 10 --beacon-min-packets 6 --beacon-max-rate 0.05Pattern detection (steady intervals, jitter, repeated destinations, consistent sizes):
python capture_outbound.py --duration 300 --track-bytes --pattern-high-jitter 120 --pattern-repeat-destination 4 --pattern-max-byte-jitter 64 --dns-pattern-min-queries 4Tight beacon + pattern thresholds with filtering:
python capture_outbound.py --duration 600 --filter-protocol tcp --filter-port 443 --track-bytes --beacon-min-duration 180 --beacon-min-interval 90 --beacon-max-interval 900 --beacon-max-jitter 5 --beacon-min-packets 8 --pattern-high-jitter 60 --pattern-repeat-destination 5 --pattern-max-byte-jitter 32DNS-focused capture (fast DNS lookup + DNS patterns):
python capture_outbound.py --duration 180 --dns-timeout 0.25 --dns-pattern-min-queries 5 --pattern-repeat-destination 3- Console table by default
- CSV:
outbound_connections.csv - JSON:
outbound_connections.json - HTML:
--html "report.html" - Beacon findings:
*_beacon_findings.csv/*_beacon_findings.json - Connection patterns:
*_connection_patterns.csv/*_connection_patterns.json - DNS patterns:
*_dns_patterns.csv/*_dns_patterns.json - Unique connections:
*_unique_connections.csv/*_unique_connections.json - Unique processes:
*_unique_processes.csv/*_unique_processes.json - Group summaries:
*_group_remote_ip*.csv/json,*_group_process*.csv/json,*_group_country*.csv/json
Custom CSV/JSON output paths:
python capture_outbound.py --mode pcap --duration 20 --interface "Ethernet" --csv "C:\Path\outbound.csv" --json "C:\Path\outbound.json"Send all outputs to a folder:
python capture_outbound.py --mode pcap --duration 20 --output-dir "C:\Path\Reports"Write HTML output:
python capture_outbound.py --html "outbound.html"Write a pcap file:
python capture_outbound.py --mode pcap --duration 20 --interface "Ethernet" --pcap-out "capture.pcap"--mode {pcap,pcap_plus_netstat,both}: Capture strategy (default:pcap)--duration SECONDS: Capture duration (default:15)--packet-limit COUNT: Stop after N packets (0= unlimited)--list-interfaces: Show Npcap interfaces and exit--interface NAME: Capture interface name (repeatable)--interfaces "NAME,NAME": Comma-separated interface names--filter-protocol tcp,udp: Protocol filter (repeat or comma-separated)--filter-port 80,443,1000-2000: Remote port filters--allow-ip CIDR: Allow remote IP CIDR(s)--deny-ip CIDR: Deny remote IP CIDR(s)--group-by remote_ip,process,country: Group summary output--top N: Limit group summaries to top N rows--beacon-min-duration SECONDS: Minimum duration for beacon detection--beacon-min-packets COUNT: Minimum packet count for beacon detection--beacon-min-interval SECONDS: Minimum average interval for beacon detection--beacon-max-interval SECONDS: Maximum average interval for beacon detection--beacon-max-jitter SECONDS: Maximum interval jitter for beacon detection--beacon-max-rate PPS: Maximum packets per second for beacon detection--pattern-high-jitter SECONDS: Interval jitter threshold for randomized patterns--pattern-repeat-destination COUNT: Minimum connections to flag repeated destinations--pattern-max-byte-jitter BYTES: Maximum byte size range for consistency--dns-pattern-min-queries COUNT: Minimum DNS queries to flag patterns--csv PATH: CSV output path (default:outbound_connections.csv)--json PATH: JSON output path (default:outbound_connections.json)--html PATH: HTML report output path--pcap-out PATH: Write captured packets to pcap--output-dir PATH: Write all output files into this directory--no-console: Disable console table output--no-progress: Disable progress output--log-json: Emit warnings/errors as JSON lines to stderr--track-bytes: Track total bytes per connection when available--geoip-db PATH: GeoIP database path (.mmdbor IP2Location.BIN)--geoip-db-type {auto,maxmind,dbip,ip2location}: GeoIP DB type (default:auto)--geoip-online {ipapi,ip-api,ipinfo}: Use free online GeoIP service (rate-limited)--geoip-online-token TOKEN: API token for online GeoIP provider (e.g. IPinfo)--geoip-cache-path PATH: Override online GeoIP cache JSON path--geoip-timeout SECONDS: Online GeoIP request timeout (default:3.0)--geoip-retries COUNT: Online GeoIP retry attempts (default:2)--no-dns: Disable reverse DNS lookup--dns-timeout SECONDS: DNS lookup timeout (default:2.0)
Main outputs (--csv/--json) include fields:
protocol,local_ip,local_portremote_ip,remote_port,remote_hostname,remote_fqdn,remote_countrypid,process_name,packet_countduration_seconds,avg_interval_seconds,interval_jitter_secondsfirst_seen,last_seen,sourcebyte_count(when--track-bytesis enabled)
Derived outputs include:
- Unique connections:
remote_ip,remote_port,remote_hostname,remote_fqdn,remote_country - Unique processes:
pid,process_name,connection_count,unique_remote_ips - Group summaries: counts and unique metrics per
remote_ip,process, orcountry - Beacon findings: main output fields plus
beacon_reason - Connection patterns: main output fields plus
pattern_type/pattern_reason,byte_min/byte_max/byte_range(with--track-bytes), and destination totals - DNS patterns:
dns_query,query_count, resolver IP/port, pattern details, andbyte_min/byte_max/byte_range(with--track-bytes)
- Use Administrator PowerShell to capture elevated traffic and map PIDs.
--mode pcap_plus_netstatonly enriches captured connections with PID/process data.--mode bothadds netstat-only connections to the final output.- If packet capture fails or Npcap/scapy is missing, the script falls back to
netstat-only results and exits with code
2after writing outputs. --log-jsonformats warnings/errors as JSON lines (useful for ingestion).--durationis in seconds.--packet-limitstops capture after N packets even if duration remains.--no-dnsskips reverse DNS resolution (hostname/FQDN will be blank).--dns-timeoutcontrols DNS lookup timeouts (seconds).- Online GeoIP results are cached to
geoip_online_cache.jsonin the output directory (or working directory) unless overridden with--geoip-cache-path. --geoip-db-type autouses file extension:.mmdb-> MaxMind/DB-IP,.BIN-> IP2Location.- IPinfo returns ISO country codes (e.g.
US) instead of full country names. - DNS pattern detection is derived from DNS query packets captured in pcap mode.
- If
--geoip-dbis omitted, theremote_countrycolumn is left empty unless--geoip-onlineis used. - If both
--geoip-dband--geoip-onlineare set, the database is used. --filter-portapplies to the remote port (outbound destination).--track-bytesaddsbyte_countcolumns and enables size-consistency patterns.