murrez / php2shell
git clone https://github.com/murrez/php2shell.git
PoC for CVE-2026-109618 / CVE-2026-109619 (php2shell): PHP session.upload_progress UAF. check = GET fingerprint + bulk JSONL; exploit = smart 618 (multi-path trigger) or 619 with --call. Stdlib only.
+21
stars, 24h · #1,801
+48
stars, 7 days · #4,192
+48
stars, 30 days · #13,745
48
★ total · +48% this week
21
forks · 0 open issues
Star history (as recorded here)
LanguagePython
LicenseMIT
Created2026-10-21 (2d ago)
Last push2d ago
Watchers0
OwnerUser
Links
README excerpt
# php2shell — CVE-2026-109618 / CVE-2026-109619 Python PoC for the **session.upload_progress** multipart timing issue (research name: **php2shell**). PHP core RCE pair (CVSS 9.2 vendor rating); this repo provides **passive fingerprinting (`check`)** and **active trigger / primitive tests (`exploit`)**. Banner match alone does not mean remote RCE — that needs a lab (`--monitor`) or build-specific **619** offsets. **Authorized testing only.** --- ## GitHub About (Description) [code] Topics: `cve`, `cve-2026-109618`, `cve-2026-109619`, `php2shell`, `php`, `security-research`, `poc` --- ## Requirements - Python 3.8+ - Stdlib only (no `pip install`) [code] --- ## Quick start [code] Windows **cmd.exe**: colors are auto-disabled if VT mode is unavailable; use `--no-color` explicitly if you still see `←[96m` garbage. Bulk lists with 25+ lines use **compact** one-line output. --- ## Files | Path | Role | |------|------| | `poc.py` | CLI | | `php2shell_core.py` | HTTP, multipart builders, fingerprint, 618/619 bodies | | `php2shell_exploit.py` | Smart 618 (paths × variants, scoring) | | `EXPLOIT.md` | Verdict glossary + research pointers | | `targets.example.txt` | Example `-f` input | | `SECURITY.md` / `GITHUB.md` | Scope + publish checklist | --- ## CLI [code] | Mode | Default | Sends | |------|---------|--------| | `check` | no | GET only | | `exploit` | **yes** | POST multipart | | `build` | no | Local file only | Common flags: `-f` list file, `-o` output, `--json`, `-q`, `--timeout 10`, `--workers 8`, `-f` domains (one per line or CSV `domain` column). --- ## Check mode Passive exposure scan. **Does not** send the stall exploit or prove UAF. ### Single host [code] Reads `X-Powered-By` and up to ~8 KB of body. Parses only strings that look like **`PHP/x.y.z`** banners (avoids mistaking WordPress `6.8.11` for PHP). ### Bulk [code] - `example.com` → `https://example.com/` - CSV header `domain` is skipped - **≥25 targets:** compact lines (below) - `-o` append per host (interrupt-safe) - Final **Summary:** counts by status Example line: `[4/1790] [branch_only] https://yoplait.fr PHP 8.4.?` ### JSON `status` field | Status | Meaning | |--------|---------| | `likely_vulnerable` | Full patch level in banner, below emergency fix for that branch | | `branch_only` | Banner like `PHP/8.4` only — patch unknown, **not** counted as vulnerable | | `patched` | At/above 8.2.35, 8.3.36, 8.4.27, 8.5.12 | | `eol_or_unknown` | EOL branch (7.x, etc.) or unmapped | | `no_php_version` | No banner (CDN, `expose_php=Off`, …) | | `unreachable` | No usable HTTP response | ### Exit codes (check) | Code | Meaning | |------|---------| | 0 | Done; no `likely_vulnerable` | | 1 | All unreachable / empty input | | 2 | One or more `likely_vulnerable` | ### Limits CDN hides banners → `no_php_version` is not “safe”. Distro backports may lie on banner until you check `php -v` / package changelog on the box. Remote `