ba5143b560
Active modules (9 files in modules/active/): - bettercap_mgr: Central bettercap orchestrator with REST API health monitoring, event stream parsing, crash recovery with corrective gratuitous ARPs, caplet management, and process disguise - arp_spoof: Thin bettercap wrapper for ARP spoofing with OPSEC warnings - dns_poison: DNS poisoning with zone template loading support - dhcp_spoof: DHCPv6 spoofing via bettercap for rogue DNS injection - evil_twin: hostapd-based rogue AP with captive portal and dnsmasq, iptables redirect, credential capture via HTTP POST handler - ipv6_slaac: IPv6 SLAAC spoofing via bettercap + mitm6 WPAD abuse - responder_mgr: Responder subprocess manager with hash file monitoring, NTLMv1/v2 parsing, session log scanning, relay target coordination - mitmproxy_mgr: Transparent proxy with addon scripts, tier checking (OPi Zero 3+ only), iptables setup, credential/token extraction - ntlm_relay: ntlmrelayx wrapper with multi-protocol relay (SMB, LDAP, LDAPS, HTTP, MSSQL, ADCS), Responder exclusion coordination, SOCKS Templates (9 files): - 4 captive portals: corporate SSO, guest WiFi, Outlook/M365, VPN (self-contained HTML with inline CSS, realistic login forms) - 2 DNS zones: redirect-all and selective Jinja2 template - 2 hostapd configs: open AP and WPA2-PSK Jinja2 templates - 1 Responder.conf Jinja2 template with protocol toggles Operator scripts (6 files in scripts/operator/): - pull_data.sh: rsync structured data over WireGuard/Tailscale - extract_files.sh: tshark HTTP/SMB/FTP/TFTP file extraction - extract_print_jobs.sh: TCP/9100 print job reconstruction + PDF convert - extract_emails.sh: SMTP email extraction with attachment detection - crack_hashes.sh: Export creds to hashcat format, optional auto-crack - generate_report.py: SQLite-to-Markdown/HTML engagement report generator
153 lines
5.3 KiB
Bash
Executable File
153 lines
5.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# BigBrother Operator Script — Extract Print Jobs from PCAPs
|
|
#
|
|
# Reconstructs print jobs from TCP/9100 (JetDirect/RAW) traffic captured
|
|
# in PCAPs. Converts PCL/PostScript to PDF using Ghostscript.
|
|
#
|
|
# Print traffic is often unencrypted and contains sensitive documents:
|
|
# HR letters, financial reports, legal docs, network diagrams, etc.
|
|
#
|
|
# Usage: ./extract_print_jobs.sh <pcap_dir> [output_dir]
|
|
#
|
|
# Requires: tshark, ghostscript (gs)
|
|
|
|
set -euo pipefail
|
|
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
CYAN='\033[0;36m'
|
|
NC='\033[0m'
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Arguments
|
|
# ---------------------------------------------------------------------------
|
|
|
|
PCAP_DIR="${1:-}"
|
|
OUTPUT_DIR="${2:-$(pwd)/print-jobs-$(date +%Y%m%d-%H%M%S)}"
|
|
|
|
if [[ -z "$PCAP_DIR" ]]; then
|
|
echo -e "${RED}Usage: $0 <pcap_dir> [output_dir]${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ ! -d "$PCAP_DIR" ]]; then
|
|
echo -e "${RED}[-] PCAP directory not found: $PCAP_DIR${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Check dependencies
|
|
for tool in tshark gs; do
|
|
if ! command -v "$tool" &>/dev/null; then
|
|
echo -e "${RED}[-] $tool not found${NC}"
|
|
case "$tool" in
|
|
tshark) echo " Install with: apt install tshark" ;;
|
|
gs) echo " Install with: apt install ghostscript" ;;
|
|
esac
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
mkdir -p "$OUTPUT_DIR"/{raw,pdf,metadata}
|
|
|
|
echo -e "${CYAN}[*] BigBrother Print Job Extraction${NC}"
|
|
echo -e " PCAP dir: ${PCAP_DIR}"
|
|
echo -e " Output: ${OUTPUT_DIR}"
|
|
echo ""
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Extract print streams from PCAPs
|
|
# ---------------------------------------------------------------------------
|
|
|
|
JOB_COUNT=0
|
|
PDF_COUNT=0
|
|
|
|
for pcap in "$PCAP_DIR"/*.pcap "$PCAP_DIR"/*.pcapng; do
|
|
[[ -f "$pcap" ]] || continue
|
|
basename_pcap=$(basename "$pcap")
|
|
echo -e "${YELLOW}[*] Scanning: ${basename_pcap}${NC}"
|
|
|
|
# Check if this PCAP has any port 9100 traffic
|
|
has_print=$(tshark -r "$pcap" -Y "tcp.port == 9100" -c 1 2>/dev/null | wc -l)
|
|
if [[ "$has_print" -eq 0 ]]; then
|
|
echo -e " (no print traffic)"
|
|
continue
|
|
fi
|
|
|
|
# Extract TCP streams on port 9100
|
|
# Get unique stream indices for print traffic
|
|
streams=$(tshark -r "$pcap" -Y "tcp.dstport == 9100 && tcp.len > 0" \
|
|
-T fields -e tcp.stream 2>/dev/null | sort -un)
|
|
|
|
for stream_id in $streams; do
|
|
JOB_COUNT=$((JOB_COUNT + 1))
|
|
raw_file="$OUTPUT_DIR/raw/job_${JOB_COUNT}_stream${stream_id}.raw"
|
|
pdf_file="$OUTPUT_DIR/pdf/job_${JOB_COUNT}_stream${stream_id}.pdf"
|
|
meta_file="$OUTPUT_DIR/metadata/job_${JOB_COUNT}.txt"
|
|
|
|
# Extract the raw print data from the TCP stream
|
|
tshark -r "$pcap" -q -z "follow,tcp,raw,${stream_id}" 2>/dev/null | \
|
|
grep -E '^[0-9a-fA-F]+$' | xxd -r -p > "$raw_file" 2>/dev/null || true
|
|
|
|
if [[ ! -s "$raw_file" ]]; then
|
|
rm -f "$raw_file"
|
|
JOB_COUNT=$((JOB_COUNT - 1))
|
|
continue
|
|
fi
|
|
|
|
file_size=$(stat -c %s "$raw_file" 2>/dev/null || echo 0)
|
|
echo -e " Stream $stream_id: ${file_size} bytes"
|
|
|
|
# Record metadata (source/dest IPs, timestamps)
|
|
tshark -r "$pcap" -Y "tcp.stream == ${stream_id}" -c 1 \
|
|
-T fields -e ip.src -e ip.dst -e frame.time 2>/dev/null > "$meta_file" || true
|
|
echo "Raw file: $raw_file" >> "$meta_file"
|
|
echo "Size: $file_size bytes" >> "$meta_file"
|
|
|
|
# Detect format and convert to PDF
|
|
file_magic=$(head -c 20 "$raw_file" | cat -v 2>/dev/null || echo "")
|
|
|
|
if echo "$file_magic" | grep -q "%!PS\|%PDF\|^-E"; then
|
|
# PostScript or PDF — convert with Ghostscript
|
|
gs -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile="$pdf_file" \
|
|
"$raw_file" 2>/dev/null && {
|
|
PDF_COUNT=$((PDF_COUNT + 1))
|
|
echo -e " ${GREEN}Converted to PDF: $(basename $pdf_file)${NC}"
|
|
} || {
|
|
echo -e " ${RED}Ghostscript conversion failed${NC}"
|
|
}
|
|
elif echo "$file_magic" | grep -qi "^.E.*HP\|PCL\|PJL"; then
|
|
# PCL/PJL — try Ghostscript PCL interpreter
|
|
gs -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile="$pdf_file" \
|
|
"$raw_file" 2>/dev/null && {
|
|
PDF_COUNT=$((PDF_COUNT + 1))
|
|
echo -e " ${GREEN}Converted PCL to PDF: $(basename $pdf_file)${NC}"
|
|
} || {
|
|
echo -e " ${YELLOW}PCL conversion failed (raw data preserved)${NC}"
|
|
}
|
|
else
|
|
echo -e " ${YELLOW}Unknown format — raw data preserved${NC}"
|
|
echo "Format: unknown (magic: $(head -c 10 "$raw_file" | xxd -p 2>/dev/null))" >> "$meta_file"
|
|
fi
|
|
done
|
|
done
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Summary
|
|
# ---------------------------------------------------------------------------
|
|
|
|
echo ""
|
|
echo -e "${GREEN}[+] Print job extraction complete${NC}"
|
|
echo -e " Print jobs found: ${JOB_COUNT}"
|
|
echo -e " Converted to PDF: ${PDF_COUNT}"
|
|
echo ""
|
|
|
|
if [[ $JOB_COUNT -gt 0 ]]; then
|
|
echo -e "${CYAN}[*] Output:${NC}"
|
|
echo " Raw data: $OUTPUT_DIR/raw/"
|
|
echo " PDFs: $OUTPUT_DIR/pdf/"
|
|
echo " Metadata: $OUTPUT_DIR/metadata/"
|
|
echo ""
|
|
ls -lhS "$OUTPUT_DIR/pdf/" 2>/dev/null | tail -20 | sed 's/^/ /'
|
|
fi
|