Skip to content
php2shell

php2shell

Sploitus • October 21, 2026

- discovers versioned and unversioned PHP binaries across `PATH` and common locations;

- executes a small read-only PHP expression to collect the exact runtime version, SAPI,

loaded `php.ini`, and relevant temporary-mitigation settings;

- records Debian, RPM, or Alpine package provenance when available;

- compares PHP 8.2–8.5 against the official fixed-release boundaries;

- identifies PHP 5.4–8.1 as affected/EOL while warning possible vendor backports;

- keeps **affected version**, **patched**, **unknown**, and **operational error** distinct;

- passively reads `X-Powered-By` and `Server` headers with same-origin redirects only;

- scans target lists concurrently with bounded workers, timeout, and target-count limits;

- requires an explicit authorization acknowledgement before network traffic;

- hunts offline logs for upload-progress, multipart-session, OOM, worker-crash,

heap-corruption, and use-after-free indicators without printing raw log lines;

- optionally snapshots process lineage for shells and network tools directly spawned

by PHP-FPM, Apache, LiteSpeed, CGI, or FrankenPHP workers;

- supports a no-traffic dry run and offline single-version assessment;

- emits human-readable text, stable JSON, and GitHub-compatible SARIF 2.1.0;

- has no runtime dependencies beyond Python 3.10 or newer.

From a source checkout, `./phpscanner.py` is also available as a convenience launcher.

Discover and inspect local PHP installations:

Inspect explicit binaries and write JSON:

The configuration observations are not treated as fixes. PHP states that an

updated runtime is the only complete mitigation. After updating, restart or

redeploy every FPM, Apache, CGI, FrankenPHP, or LiteSpeed worker.

Preview a target list without sending traffic:

php2shell-audit remote --target-file targets.txt --dry-run

Send one bounded `HEAD` request to each authorized target:

--acknowledge-authorization I_HAVE_AUTHORIZATION

--format sarif --output php2shell.sarif \

--acknowledge-authorization I_HAVE_AUTHORIZATION

Remote output is intentionally low-confidence. Headers may be absent, forged,

cached, or inserted by a proxy, and vendors can backport fixes without changing

the upstream-looking version. An `UNKNOWN` result is not a clean bill of health.

php2shell-audit version 8.4.27 --format json

Inspect explicit logs or bounded directories without sending network traffic:

--format json --output php2shell-hunt.json

Compressed `.gz` logs are supported. The scanner caps the number of files and

bytes read, never emits raw log lines or process arguments, and records a

SHA-256 digest for every matching line. Findings are triage leads—not proof of

exploitation—and should be correlated with surrounding requests, worker logs,

container telemetry, and file changes. See

[docs/INCIDENT_RESPONSE.md](docs/INCIDENT_RESPONSE.md).

PHP 8.1 and older are end-of-life upstream. Some distribution or LTS vendors

may ship backports, which must be confirmed against that vendor's advisory.

The convention matches `jwt-audit`, `oidc-audit`, and `noirspect`:

| `0` | No affected version was detected and no operational error occurred. |

| `1` | Invalid input or an operational error prevented a complete check. |

| `2` | One or more affected versions were detected. |

`UNKNOWN` alone exits `0` because it is not a confirmed finding. Consumers

must still inspect the structured summary and should not interpret unknown as patched.

Tests use subprocess and HTTP fakes and never external targets.

This is a version and provenance scanner, not an exploit verifier. Even a local

version comparison cannot prove exploitability because downstream vendors and

private builds may backport patches. Conversely, failure to observe a remote

PHP header proves nothing. See [docs/METHODOLOGY.md](docs/METHODOLOGY.md).

Public exploit research was reviewed to improve defensive coverage, including

[ikow/php2shell-poc](

[eness/php2shell-CVE-2026-109618-CVE-2026-109619-PoC](

and [Zer061/CVE-2026-109618](

Their payload builders and active triggers are deliberately not included.

Sources: [PHP security announcement](

[CVE-2026-109618 advisory](

and [CVE-2026-109619 advisory](

Created and maintained by [Liam Giannini]( of

[Webcracy.ch]( Licensed under the MIT License.

Extracted Entities