#!/usr/bin/env bash # ============================================================================= # THE ANALYZER v1.0 — Autonomous Bug Bounty Analysis Engine # Authorized Bug Bounty Use Only # ============================================================================= set -euo pipefail # === Setup === # Set up path, resolving symlinks __ANALYZER_SRC="${BASH_SOURCE[0]}" if command -v readlink &>/dev/null; then while [ -h "$__ANALYZER_SRC" ]; do __ANALYZER_SRC="$(readlink "$__ANALYZER_SRC")" [[ "$__ANALYZER_SRC" != /* ]] && __ANALYZER_SRC="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/$__ANALYZER_SRC" done fi SCRIPT_DIR="$(cd "$(dirname "$__ANALYZER_SRC")" && pwd 2>/dev/null)" || SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" unset __ANALYZER_SRC export ANALYZER_DIR="$SCRIPT_DIR" export VECTORS_DIR="$ANALYZER_DIR/vectors" export ENGINE_DIR="$ANALYZER_DIR/engine" export LIB_DIR="$ANALYZER_DIR/lib" export REPORTS_DIR="$ANALYZER_DIR/reports" # Source core source "$LIB_DIR/colors.sh" source "$LIB_DIR/utils.sh" source "$ENGINE_DIR/discovery.sh" source "$ENGINE_DIR/recon.sh" source "$ENGINE_DIR/ollama-brain.sh" source "$ENGINE_DIR/reporter.sh" mkdir -p "$REPORTS_DIR" # === Banner === show_banner() { clear echo -e "${BRIGHT_RED}" echo ' ████████╗██╗ ██╗███████╗ █████╗ ███╗ ██╗ █████╗ ██╗ ██╗███████╗ ' echo ' ╚══██╔══╝██║ ██║██╔════╝ ██╔══██╗████╗ ██║██╔══██╗██║ ██║╚══███╔╝ ' echo ' ██║ ███████║█████╗ ███████║██╔██╗ ██║███████║███████║ ███╔╝ ' echo ' ██║ ██╔══██║██╔══╝ ██╔══██║██║╚██╗██║██╔══██║██╔══██║ ███╔╝ ' echo ' ██║ ██║ ██║███████╗ ██║ ██║██║ ╚████║██║ ██║██║ ██║███████╗ ' echo ' ╚═╝ ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ ' echo '' echo -e " ${BRIGHT_YELLOW}Autonomous Bug Bounty Analyzer v1.0${NC}" echo -e " ${DIM}Authorized Testing Only${NC}" echo '' } # === Interactive mode === interactive_mode() { show_banner echo -e " ${BOLD}${BRIGHT_CYAN}Welcome to The Analyzer${NC}" separator echo '' echo -e " ${GREEN}1${NC}. Quick Scan — Fast recon + auto-vector selection" echo -e " ${GREEN}2${NC}. Deep Scan — Full recon, all vectors, exhaustive" echo -e " ${GREEN}3${NC}. Custom Scan — Pick your own vectors" echo -e " ${GREEN}4${NC}. List Vectors — Show all 21 attack vectors" echo -e " ${GREEN}5${NC}. View Reports — Browse past results" echo -e " ${DIM}q${NC}. Quit" echo '' read -p " ${ICON_ARROW} Choose mode [1]: " mode mode="${mode:-1}" echo '' read -p " ${ICON_ARROW} Target URL (e.g., https://example.com): " target # Validate if [ -z "$target" ]; then print_error "Target URL required!" exit 1 fi # Add protocol if missing [[ "$target" != http* ]] && target="https://${target}" echo '' print_info "Target set: ${BOLD}$target${NC}" echo '' case "$mode" in 1) quick_scan "$target" ;; 2) deep_scan "$target" ;; 3) custom_scan "$target" ;; 4) list_vectors && exit 0 ;; 5) view_reports && exit 0 ;; *) quick_scan "$target" ;; esac } # === Quick Scan === quick_scan() { local target="$1" local report=$(init_report "$target") local total_findings=0 local total_vulns=0 echo -e "\n${BRIGHT_CYAN}${BOLD}═══ QUICK SCAN MODE ═══${NC}\n" # Step 1: Check connectivity print_step 1 5 "Checking target..." if ! target_alive "$target"; then print_error "Target unreachable!" exit 1 fi print_ok "Target is alive" # Step 2: Discovery — find real URLs, forms, params to attack print_step 2 5 "Discovering attack surface" discover_target "$target" # Step 3: Recon print_step 3 5 "Reconnaissance" recon_target "$target" "$report" # Step 4: Ollama decides print_step 4 5 "Ollama brain selecting vectors" local decision=$(ollama_decide "$target") echo '' echo -e "${MAGENTA}${ICON_BRAIN} Ollama's Strategy:${NC}" echo "$decision" | head -20 local selected=$(parse_decision "$decision") if [ -z "$selected" ]; then print_warn "Ollama didn't pick specific vectors. Running default set." selected="21 1 2 3 4" # nuclei + sqli + xss + lfi + cmdi fi echo '' print_info "Running vectors: $(echo $selected | tr '\n' ' ')" echo '' # Step 5: Run vectors print_step 5 5 "Executing attack vectors" run_vectors "$target" "$report" $selected # Generate final report total_findings=$(ls "$REPORTS_DIR"/.finding_*.txt 2>/dev/null | wc -l | tr -d ' ') total_vulns=$total_findings generate_report "$target" "$report" "$total_vulns" html_report "$report" > /dev/null cleanup_findings } # === Deep Scan === deep_scan() { local target="$1" local report=$(init_report "$target") echo -e "\n${BRIGHT_RED}${BOLD}═══ DEEP SCAN MODE — ALL VECTORS ═══${NC}\n" # Step 1: Connectivity print_step 1 3 "Checking target..." if ! target_alive "$target"; then print_error "Target unreachable!" exit 1 fi print_ok "Target is alive" # Step 2: Full recon print_step 2 3 "Deep reconnaissance" recon_target "$target" "$report" # Step 3: Run ALL vectors print_step 3 3 "Running all 21 attack vectors" local all_vectors=$(seq 1 21 | tr '\n' ' ') run_vectors "$target" "$report" $all_vectors # Generate report local total_findings=$(ls "$REPORTS_DIR"/.finding_*.txt 2>/dev/null | wc -l | tr -d ' ') generate_report "$target" "$report" "$total_findings" html_report "$report" > /dev/null cleanup_findings } # === Custom Scan === custom_scan() { local target="$1" local report=$(init_report "$target") echo -e "\n${BRIGHT_BLUE}${BOLD}═══ CUSTOM SCAN MODE ═══${NC}\n" echo -e "Available vectors:" list_vectors echo '' read -p " ${ICON_ARROW} Vector numbers (space-separated, e.g., 1 3 5 12): " vector_input local selected=${vector_input:-"1 2 3 4 5"} print_step 1 3 "Checking target..." if ! target_alive "$target"; then print_error "Target unreachable!" exit 1 fi print_ok "Target is alive" print_step 2 3 "Quick recon" recon_target "$target" "$report" print_step 3 3 "Running selected vectors" run_vectors "$target" "$report" $selected local total_findings=$(ls "$REPORTS_DIR"/.finding_*.txt 2>/dev/null | wc -l | tr -d ' ') generate_report "$target" "$report" "$total_findings" html_report "$report" > /dev/null cleanup_findings } # === Run Vectors === run_vectors() { local target="$1" local report="$2" shift 2 local vectors=("$@") local total=${#vectors[@]} local current=0 local total_findings=0 for num in "${vectors[@]}"; do num=$(echo "$num" | xargs) # trim [ -z "$num" ] && continue current=$((current + 1)) # Find the vector file local vf="$VECTORS_DIR/$(printf "%02d" $num)-"*.sh if [ ! -f "$vf" ]; then # Try without the glob vf="" for f in "$VECTORS_DIR"/$(printf "%02d" $num)-*.sh; do [ -f "$f" ] && vf="$f" && break done fi if [ ! -f "$vf" ] || [ -z "$vf" ]; then print_skip "Vector $num — file not found" continue fi local vec_name=$(basename "$vf" .sh | sed 's/^[0-9]*-//') echo '' separator echo -e " ${CYAN}[${current}/${total}]${NC} ${BOLD}${vec_name}${NC}" separator # Source and run source "$vf" # The vector function name follows pattern: vector_ local func_name="vector_$(echo "$vec_name" | tr '-' '_' | sed 's/injection/inj/;s/traversal/trav/;s/redirect/oredir/;s/condition/race/;s/exposure/gitex/;s/misconfiguration/cors/;s/abuse/apiab/;s/upload/fileup/;s/fil/backup/')" # Map vector names to function names case $num in 1) func_name="vector_sqli_v2" ;; 2) func_name="vector_xss_v2" ;; 3) func_name="vector_lfi_v2" ;; 4) func_name="vector_cmdi" ;; 5) func_name="vector_ssrf" ;; 6) func_name="vector_oredir" ;; 7) func_name="vector_dtrav" ;; 8) func_name="vector_ssti" ;; 9) func_name="vector_xxe" ;; 10) func_name="vector_idor" ;; 11) func_name="vector_csrf" ;; 12) func_name="vector_jwt" ;; 13) func_name="vector_graphql" ;; 14) func_name="vector_apiab" ;; 15) func_name="vector_fileup" ;; 16) func_name="vector_backup" ;; 17) func_name="vector_gitex" ;; 18) func_name="vector_cors" ;; 19) func_name="vector_race" ;; 20) func_name="vector_nosqli" ;; 21) func_name="vector_nuclei" ;; esac if declare -f "$func_name" >/dev/null; then $func_name "$target" "$report" local vfindings=$? total_findings=$((total_findings + vfindings)) else print_error "Function $func_name not found in $vf" fi done return $total_findings } # === View Reports === view_reports() { echo -e "\n${BOLD}Past Reports:${NC}\n" shopt -s nullglob local reports=("$REPORTS_DIR"/*.md) shopt -u nullglob if [ ${#reports[@]} -eq 0 ]; then print_info "No reports yet" return fi local i=0 for r in "${reports[@]}"; do [ ! -f "$r" ] && continue i=$((i + 1)) local name=$(basename "$r") local target=$(grep "^**Target:**" "$r" | sed 's/.*\*\*Target:\*\* //') local date=$(grep "^**Date:**" "$r" | sed 's/.*\*\*Date:\*\* //') local vulns=$(grep -c "^### [0-9]" "$r" 2>/dev/null || echo 0) echo -e " ${CYAN}[$i]${NC} ${BOLD}$name${NC}" echo -e " Target: ${target:-N/A} | Date: ${date:-N/A} | Vulns: ${BRIGHT_RED}$vulns${NC}" done echo '' read -p " ${ICON_ARROW} Open report number (or Enter to skip): " rnum if [ -n "$rnum" ] && [ "$rnum" -ge 1 ] 2>/dev/null; then local idx=$((rnum - 1)) shopt -s nullglob local reports_arr=("$REPORTS_DIR"/*.md) shopt -u nullglob if [ "$idx" -lt "${#reports_arr[@]}" ]; then cat "${reports_arr[$idx]}" local html="${reports_arr[$idx]%.md}.html" echo '' print_info "HTML: $html" fi fi } # === Cleanup === cleanup_findings() { rm -f "$REPORTS_DIR"/.finding_*.txt "$REPORTS_DIR"/.recon_*.txt "$REPORTS_DIR"/.sqlmap_*.txt 2>/dev/null } # === CLI Mode (non-interactive) === cli_mode() { show_banner case "${2:-quick}" in quick|q) quick_scan "$1" ;; deep|d|all) deep_scan "$1" ;; custom|c) shift custom_scan "$1" ;; list|l) list_vectors ;; *) quick_scan "$1" ;; esac } # === Entry Point === check_deps if ! check_ollama; then print_warn "Ollama unavailable. Running without AI brain (default vectors)." export NO_OLLAMA=true fi if [ $# -ge 1 ]; then # CLI mode: ./analyzer [quick|deep|custom] cli_mode "$@" else interactive_mode fi