Files
citrixpot/deploy/manual-test.sh
T

55 lines
3.2 KiB
Bash

#!/usr/bin/env bash
# Manual end-to-end probe of a deployed decoy. Read-only: every request is recorded as
# evidence; nothing is executed. Configure via environment (see .env.example).
# BASE_URL e.g. http://127.0.0.1:8443 or https://your-decoy.example
# HOST_HEADER Host header the edge proxy routes on (default: localhost)
set -u
B=${1:-${BASE_URL:-http://127.0.0.1:8443}}
H="Host: ${HOST_HEADER:-localhost}"
printf '\000\377MZ-inert-manual-payload\r\n' > /tmp/manual-payload.bin
printf -- '--testboundary\r\nContent-Disposition: form-data; name="file"; filename="../../manual-multipart.bin"\r\nContent-Type: application/octet-stream\r\n\r\nINERT-MULTIPART-BODY\r\n--testboundary--\r\n' > /tmp/manual-multipart.bin
code() {
local label=$1; shift
printf '%-42s -> %s\n' "$label" "$(curl -sS --max-time 10 -o /dev/null -w '%{http_code} %{size_download}b' "$@")"
}
echo "== target $B =="
code "GET / (login page)" -H "$H" "$B/"
code "GET /favicon.ico" -H "$H" "$B/favicon.ico"
code "GET background.jpg" -H "$H" "$B/logon/LogonPoint/receiver/images/common/ReceiverFullScreenBackground.jpg"
code "GET logo.png" -H "$H" "$B/vpn/media/citrixgateway_logo_white.png"
code "GET login.js" -H "$H" "$B/logon/LogonPoint/login.js"
code "HEAD /" -I -H "$H" "$B/"
code "GET /nonexistent" -H "$H" "$B/nonexistent"
code "GET path traversal" --path-as-is -H "$H" "$B/../../etc/passwd"
code "OPTIONS /" -X OPTIONS -H "$H" "$B/"
code "POST auth form" -H "$H" -H 'Content-Type: application/x-www-form-urlencoded' --data 'login=demo&passwd=demo' "$B/nf/auth/doAuthentication.do"
code "PUT binary payload" -X PUT -H "$H" -H 'Content-Type: application/octet-stream' --data-binary @/tmp/manual-payload.bin "$B/sample.bin"
code "POST multipart upload" -H "$H" -H 'Content-Type: multipart/form-data; boundary=testboundary' --data-binary @/tmp/manual-multipart.bin "$B/upload"
code "POST oversize body" -X POST -H "$H" -H 'Content-Length: 999999999' --max-time 4 "$B/"
code "POST ambiguous framing" -X POST -H "$H" -H 'Transfer-Encoding: chunked' -H 'Content-Length: 5' --data '0' "$B/"
code "GET injection in User-Agent" -H "$H" -A 'pitboss PPE unexpectedly died NSPPE;:`id>/netscaler/ns_gui/manual-test.txt`;# X' "$B/"
echo -n "auth XML body: "
curl -sS --max-time 8 -H "$H" -H 'Content-Type: application/x-www-form-urlencoded' --data 'login=x&passwd=y' "$B/nf/auth/doAuthentication.do" | head -c 160
echo
l=0; while [ $l -lt 12 ]; do l=$((l+1)); curl -sS --max-time 5 -o /dev/null -H "$H" --data 'login=a&passwd=b' "$B/nf/auth/doAuthentication.do"; done
echo "sent 12 rapid auth attempts (brute-force threshold is 10)"
python3 - "$B" "${HOST_HEADER:-localhost}" <<'PY'
import socket, sys, urllib.parse
url = urllib.parse.urlsplit(sys.argv[1])
host = sys.argv[2]
s = socket.create_connection((url.hostname, url.port or 80), timeout=8)
s.sendall(f'GET / HTTP/1.1\r\nHost: {host}\r\n\r\n'.encode()
+ f'GET /favicon.ico HTTP/1.1\r\nHost: {host}\r\nConnection: close\r\n\r\n'.encode())
data = b''
while True:
chunk = s.recv(65536)
if not chunk:
break
data += chunk
print(f'keep-alive pipelined -> {data.count(b"HTTP/1.1 ")} responses, {len(data)} bytes')
PY
echo "done"