v2: real exploitation — discovery phase, nuclei CVE scanning, SQLi/XSS/LFI rebuild
- New discovery engine (engine/discovery.sh): crawls target for real URLs, forms, parameters, and API endpoints before attacking - New nuclei vector (21): runs nuclei templates for real CVE detection (critical/high/medium severity) - Rebuilt SQLi vector: tests discovered forms and URL params with error-based and time-based blind payloads, sqlmap injection - Rebuilt XSS vector: multi-context payloads against discovered forms/params, confirms payload reflection - Rebuilt LFI vector: tests all discovered and common file parameters with traversal payloads, confirms by reading /etc/passwd - Updated main analyzer with 5-step pipeline: connectivity → discovery → recon → Ollama brain → exploitation
This commit is contained in:
199
engine/discovery.sh
Normal file
199
engine/discovery.sh
Normal file
@@ -0,0 +1,199 @@
|
||||
#!/usr/bin/env bash
|
||||
# The Analyzer v2 — Discovery Engine
|
||||
# Finds actual URLs, forms, parameters, and endpoints on the target
|
||||
# This feeds the exploit vectors with real attack surface
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "$SCRIPT_DIR/../lib/utils.sh"
|
||||
|
||||
discover_target() {
|
||||
local target="$1"
|
||||
local domain=$(get_domain "$target")
|
||||
local base=$(get_base "$target")
|
||||
local outfile="$REPORTS_DIR/.${domain}_discovery.txt"
|
||||
|
||||
print_info "Discovering attack surface on $target..."
|
||||
separator
|
||||
|
||||
local DISCOVERED_URLS=""
|
||||
local DISCOVERED_FORMS=""
|
||||
local DISCOVERED_PARAMS=""
|
||||
local DISCOVERED_ENDPOINTS=""
|
||||
|
||||
# 1. Crawl the homepage for links and forms
|
||||
print_sub "Crawling homepage for links..."
|
||||
local page=$(curl -s --connect-timeout 10 --max-time 20 -L "$target" 2>/dev/null)
|
||||
|
||||
if [ -z "$page" ]; then
|
||||
print_error "Cannot fetch target page"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Extract all internal links
|
||||
local links=$(echo "$page" | perl -nle 'while (/href="([^"]+)"/g) { print $1 }' | sort -u)
|
||||
local internal_links=""
|
||||
while IFS= read -r link; do
|
||||
[ -z "$link" ] && continue
|
||||
# Make absolute
|
||||
if [[ "$link" == /* ]]; then
|
||||
link="${base}${link}"
|
||||
elif [[ "$link" == http* ]]; then
|
||||
# External link — skip unless same domain
|
||||
local link_domain=$(echo "$link" | sed 's|https\?://||' | cut -d/ -f1)
|
||||
[[ "$link_domain" != "$domain" ]] && continue
|
||||
else
|
||||
link="${base}/${link}"
|
||||
fi
|
||||
internal_links+="$link\n"
|
||||
DISCOVERED_URLS+="$link\n"
|
||||
done <<< "$links"
|
||||
|
||||
local url_count=$(echo -e "$DISCOVERED_URLS" | grep -c .)
|
||||
print_ok "Found $url_count internal URLs"
|
||||
|
||||
# 2. Extract forms
|
||||
print_sub "Extracting forms..."
|
||||
local forms=$(echo "$page" | perl -0 -nle 'while (/<form[^>]*>.*?<\/form>/gs) { print $& }')
|
||||
local form_count=0
|
||||
while IFS= read -r form; do
|
||||
[ -z "$form" ] && continue
|
||||
form_count=$((form_count + 1))
|
||||
local form_action=$(echo "$form" | perl -nle 'print $1 if /action="([^"]*)"/')
|
||||
local form_method=$(echo "$form" | perl -nle 'print $1 if /method="([^"]*)"/' | tr '[:upper:]' '[:lower:]')
|
||||
local form_inputs=$(echo "$form" | perl -nle 'print $1 while /name="([^"]*)"/g')
|
||||
|
||||
# Make action URL absolute
|
||||
if [[ "$form_action" == / ]]; then
|
||||
form_action="$base/"
|
||||
elif [[ "$form_action" == /* ]]; then
|
||||
form_action="${base}${form_action}"
|
||||
elif [[ "$form_action" == http* ]] && ! echo "$form_action" | grep -qi "$domain"; then
|
||||
continue # skip external forms
|
||||
elif [ -z "$form_action" ]; then
|
||||
form_action="$target" # submits to current page
|
||||
fi
|
||||
|
||||
DISCOVERED_FORMS+="$form_count|$form_method|$form_action|$form_inputs\n"
|
||||
DISCOVERED_URLS+="$form_action\n"
|
||||
DISCOVERED_PARAMS+="$form_inputs\n"
|
||||
|
||||
print_info "Form #$form_count: [$form_method] $form_action -> params: $form_inputs"
|
||||
done <<< "$forms"
|
||||
|
||||
print_ok "Found $form_count form(s)"
|
||||
|
||||
# 3. Extract URL parameters from existing links
|
||||
print_sub "Finding URL parameters..."
|
||||
local url_params=$(echo -e "$DISCOVERED_URLS" | perl -nle 'while (/[?&]([^=]+)=/g) { print $1 }' | sort -u)
|
||||
while IFS= read -r p; do
|
||||
[ -z "$p" ] && continue
|
||||
DISCOVERED_PARAMS+="$p\n"
|
||||
done <<< "$url_params"
|
||||
|
||||
local param_count=$(echo -e "$DISCOVERED_PARAMS" | grep -c .)
|
||||
print_ok "Found $param_count parameter(s): $(echo -e "$DISCOVERED_PARAMS" | tr '\n' ' ')"
|
||||
|
||||
# 4. Check common API paths
|
||||
print_sub "Probing API endpoints..."
|
||||
local api_paths=(
|
||||
"/api" "/api/v1" "/api/v2" "/v1" "/v2"
|
||||
"/graphql" "/graph" "/gql"
|
||||
"/rest" "/swagger" "/openapi" "/docs"
|
||||
"/api/docs" "/api/swagger" "/api/openapi"
|
||||
)
|
||||
for path in "${api_paths[@]}"; do
|
||||
local code=$(http_check "${base}${path}")
|
||||
if [[ "$code" =~ ^[23] ]]; then
|
||||
DISCOVERED_ENDPOINTS+="${base}${path} (HTTP $code)\n"
|
||||
print_info "API: ${base}${path} (HTTP $code)"
|
||||
fi
|
||||
done
|
||||
|
||||
# 5. Check for JS files that might leak endpoints
|
||||
print_sub "Scanning JS for endpoint leaks..."
|
||||
local js_urls=$(echo "$page" | perl -nle 'print $1 while /src="([^"]*\.js[^"]*)"/g' | head -10)
|
||||
while IFS= read -r js; do
|
||||
[ -z "$js" ] && continue
|
||||
[[ "$js" == /* ]] && js="${base}${js}"
|
||||
[[ "$js" != http* ]] && continue
|
||||
local js_content=$(curl -s --connect-timeout 5 --max-time 10 "$js" 2>/dev/null)
|
||||
local leaked_endpoints=$(echo "$js_content" | perl -nle 'print $1 while m|["\x27](/api/[^"\x27]+)["\x27]|g' | sort -u | head -10)
|
||||
if [ -n "$leaked_endpoints" ]; then
|
||||
print_info "JS leak: $js"
|
||||
while IFS= read -r ep; do
|
||||
[ -z "$ep" ] && continue
|
||||
DISCOVERED_ENDPOINTS+="${base}${ep} (JS leak)\n"
|
||||
print_find " Leaked endpoint: ${ep}"
|
||||
done <<< "$leaked_endpoints"
|
||||
fi
|
||||
done <<< "$js_urls"
|
||||
|
||||
# 6. Save everything to a discovery file
|
||||
cat > "$outfile" << EOF
|
||||
TARGET=$target
|
||||
DOMAIN=$domain
|
||||
BASE=$base
|
||||
|
||||
URLS:
|
||||
$(echo -e "$DISCOVERED_URLS" | sort -u | grep -v '^$')
|
||||
|
||||
FORMS:
|
||||
$(echo -e "$DISCOVERED_FORMS" | sort -u | grep -v '^$')
|
||||
|
||||
PARAMS:
|
||||
$(echo -e "$DISCOVERED_PARAMS" | sort -u | grep -v '^$')
|
||||
|
||||
ENDPOINTS:
|
||||
$(echo -e "$DISCOVERED_ENDPOINTS" | sort -u | grep -v '^$')
|
||||
EOF
|
||||
|
||||
print_ok "Discovery complete. Saved to $(basename $outfile)"
|
||||
separator
|
||||
|
||||
# Summary
|
||||
local total_urls=$(echo -e "$DISCOVERED_URLS" | grep -c .)
|
||||
local total_forms=$(echo -e "$DISCOVERED_FORMS" | grep -c .)
|
||||
local total_params=$(echo -e "$DISCOVERED_PARAMS" | grep -c .)
|
||||
local total_eps=$(echo -e "$DISCOVERED_ENDPOINTS" | grep -c .)
|
||||
echo ""
|
||||
echo -e " ${BOLD}Discovery Summary:${NC}"
|
||||
echo -e " ${CYAN}URLs:${NC} $total_urls"
|
||||
echo -e " ${CYAN}Forms:${NC} $total_forms"
|
||||
echo -e " ${CYAN}Params:${NC} $total_params"
|
||||
echo -e " ${CYAN}Endpoints:${NC} $total_eps"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Get discovered data for a target
|
||||
get_discovered_urls() {
|
||||
local domain="$1"
|
||||
local file="$REPORTS_DIR/.${domain}_discovery.txt"
|
||||
if [ -f "$file" ]; then
|
||||
sed -n '/^URLS:/,/^FORMS:/p' "$file" | grep -v "^URLS:\|^FORMS:\|^\$"
|
||||
fi
|
||||
}
|
||||
|
||||
get_discovered_forms() {
|
||||
local domain="$1"
|
||||
local file="$REPORTS_DIR/.${domain}_discovery.txt"
|
||||
if [ -f "$file" ]; then
|
||||
sed -n '/^FORMS:/,/^PARAMS:/p' "$file" | grep -v "^FORMS:\|^PARAMS:\|^\$"
|
||||
fi
|
||||
}
|
||||
|
||||
get_discovered_params() {
|
||||
local domain="$1"
|
||||
local file="$REPORTS_DIR/.${domain}_discovery.txt"
|
||||
if [ -f "$file" ]; then
|
||||
sed -n '/^PARAMS:/,/^ENDPOINTS:/p' "$file" | grep -v "^PARAMS:\|^ENDPOINTS:\|^\$"
|
||||
fi
|
||||
}
|
||||
|
||||
get_discovered_endpoints() {
|
||||
local domain="$1"
|
||||
local file="$REPORTS_DIR/.${domain}_discovery.txt"
|
||||
if [ -f "$file" ]; then
|
||||
sed -n '/^ENDPOINTS:/,$p' "$file" | grep -v "^ENDPOINTS:\|^\$"
|
||||
fi
|
||||
}
|
||||
Reference in New Issue
Block a user