#!/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"