Skip to content
Exploit for Improperly Controlled Sequential Memory Allocation in Php

Exploit for Improperly Controlled Sequential Memory Allocation in Php

Sploitus • October 22, 2026

| A | FPM 8.2.34 `:18080` | **OK** | `uid=33(www-data)` through session injection + LFI |

| A | FPM 8.2.35 `:18082` | **OK** | same, confirming this chain is not fixed by the PHP patch |

| C | FPM 8.2.34 `:18080` | **OK** | `__destruct` gadget fired after the handler mismatch |

| D | mod_php 8.2.34 `:18081` | **partial** | OOM in the multipart parser; **no code execution attempted** |

| E | FPM 8.2.34 `:18080` | **not reproduced** | producer OOM observed, stale consumer state not reproduced |

Unit tests cover the request builders, the WAF, the guard and all four

verifiers. The end-to-end outputs are in [docs/VERIFICATION.md](docs/VERIFICATION.md).

Requirements: Go 1.22+ and Docker (for the lab only).

git clone

docker compose -f lab/docker-compose.yml up -d

go run ./cmd/php2shell verify chain-e # experimental, may fail

`verify all` expects the default lab ports. Use `--fpm-target` and

| `--target` | ` | target base URL |

| `--allow-public` | `false` | allow a non-local target (authorized systems only) |

| `--command` | `id` | command executed by chains A/C |

| `--session-dir` | `/tmp/sessions` | `session.save_path` on the target |

| `--stall` | `true` (chain A) | hold the upload open while triggering the LFI |

| `--attempts` | `3` | retries for race-dependent steps |

| `--headers`, `--header-size` | `30000`, `512` | chain D OOM amplification |

| `--size` | `24 MiB` | chain E seeded session size |

# A: default cleanup=On target, with a stalled upload

php2shell verify chain-a --target

# A: target with session.upload_progress.cleanup=Off

php2shell verify chain-a --target --stall=false

# C: lab endpoints with different serialize_handler values

php2shell verify chain-c --target --attempts 5

php2shell verify chain-d --target

php2shell verify chain-e --target --size 25165824

Exit codes: `0` all selected chains confirmed, `1` at least one failed,

`2` usage error. `verify all` currently exits `1` because chain E is not

confirmed; run the individual commands if you need a green run.

Chain C interpolates the command into a serialized gadget, so it must not

contain `"`, `\` or NUL bytes. Chain A passes the command as a query parameter

Run the WAF as a reverse proxy in front of the lab (or any PHP upstream):

- a `PHPSESSID` form field (session id in the body);

- `<?` or `|O:` / `|a:` / `|C:` / `|s:` in an upload filename;

- optionally, a chunked multipart body (`--block-chunked`).

`--log-only` observes without blocking. A blocked request returns `403` with a

php2shell rules check # UUID/ID validation and duplicates

The ModSecurity rules use `ARGS_POST` and `FILES_NAMES` (not `REQUEST_BODY`,

which is usually empty for multipart). Enable `SecRequestBodyAccess On`; the

response rule also needs `SecResponseBodyAccess On`.

| Service | Image | Host port | Purpose |

|---------|-------|-----------|---------|

| `fpm` | `php:8.2.34-fpm` | `:18080` via nginx | vulnerable FPM target |

| `fpm-patched` | `php:8.2.35-fpm` | `:18082` via nginx | patched differential target |

| `apache` | `php:8.2.34-apache` | `:18081` | mod_php target (chain D) |

| `nginx` | `nginx:1.27-alpine` | `:18080`, `:18082` | FastCGI front end |

Endpoints include `/index.php` (session), `/vuln.php?page=` (LFI), `/app/` and

`/api/` (`.user.ini` handler mismatch), `/nosession.php` and

`/seed_session.php` (lab-only chain E seeder). See [lab/README.md](lab/README.md).

The compose file is committed, so `docker compose up -d` works without a setup

script. `lab/setup.sh` is only a convenience wrapper.

- No target lists, no CIDR scans, no concurrency across hosts.

- No WAF evasion, payload encoding, or persistence.

- No exploit for chain B: it needs PHP-side code execution, not an HTTP client.

- Chains D and E do not produce code execution here; they demonstrate the crash

- [GHSA-w8hw-w9fx-j79w]( — CVE-2026-109618

- [GHSA-6wmf-4rv5-p3rp]( — CVE-2026-109619

- [PHP security release](

- [SANS ISC diary](

- [Original Python research](

MIT. Use only against systems you are authorized to test.

Extracted Entities