The Analyzer v1.0 — autonomous bug bounty engine with 20 attack vectors and Ollama brain
This commit is contained in:
368
analyzer
Executable file
368
analyzer
Executable file
@@ -0,0 +1,368 @@
|
||||
#!/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/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 20 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 4 "Checking target..."
|
||||
if ! target_alive "$target"; then
|
||||
print_error "Target unreachable!"
|
||||
exit 1
|
||||
fi
|
||||
print_ok "Target is alive"
|
||||
|
||||
# Step 2: Recon
|
||||
print_step 2 4 "Reconnaissance"
|
||||
recon_target "$target" "$report"
|
||||
|
||||
# Step 3: Ollama decides
|
||||
print_step 3 4 "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 top 5."
|
||||
selected="1 2 3 4 5"
|
||||
fi
|
||||
|
||||
echo ''
|
||||
print_info "Running vectors: $(echo $selected | tr '\n' ' ')"
|
||||
echo ''
|
||||
|
||||
# Step 4: Run vectors
|
||||
print_step 4 4 "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 20 attack vectors"
|
||||
local all_vectors=$(seq 1 20 | 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_<shortname>
|
||||
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" ;;
|
||||
2) func_name="vector_xss" ;;
|
||||
3) func_name="vector_lfi" ;;
|
||||
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" ;;
|
||||
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 <url> [quick|deep|custom]
|
||||
cli_mode "$@"
|
||||
else
|
||||
interactive_mode
|
||||
fi
|
||||
Reference in New Issue
Block a user