php-filter-chain-oracle · git:20260504.2a64374 · 2026-05-04 · sha256 c6ecad4c760f67f2

php-filter-chain-oracle git:20260504.2a64374A

Immutable. This exact content is served forever at /api/v1/blob/c6ecad4c760f67f2.

---
name: php-filter-chain-oracle
description: Leak file contents via PHP filter chain error-based oracle using memory exhaustion differentials. Use when PHP target has file inclusion or php:// wrapper access, even without direct output.
---

# PHP Filter Chain Oracle

## Pattern
- PHP target with user-controlled path in `include`, `require`, `file_get_contents`, or `readfile`
- `php://filter` wrapper accepted (test: `php://filter/resource=/etc/passwd`)
- No direct file content output (blind LFI scenario)
- Differential error responses observable (500 vs 200, different error messages)

## Probe
Exploit `convert.iconv` filter chains to cause memory exhaustion conditionally on file content:
1. Chain `convert.iconv.UTF8.UCS-4LE` filters to expand data exponentially
2. Use `dechunk` filter as byte oracle — parses hex chars differently than non-hex
3. If target byte is hex `[0-9a-f]`: `dechunk` processes it, chain continues → memory exhaustion → 500
4. If target byte is non-hex: `dechunk` fails early → no exhaustion → 200
5. Use `convert.iconv.UNICODE.CP930` + `string.rot13` to shift non-leading bytes into detectable position

```
php://filter/convert.iconv.UTF8.UCS-4LE|convert.iconv.UTF8.UCS-4LE|...|dechunk/resource=/etc/passwd
```
Automate with: `php_filter_chains_oracle_exploit` (github.com/synacktiv/php_filter_chains_oracle_exploit)

## Indicators
- Differential response: 500 (memory limit) vs 200 for different filter chains
- Consistent oracle across repeated requests for same byte position
- Byte-by-byte file content reconstructable from error pattern

## Chain With
- ssti-error-based-detection (if PHP template engine found via file read)

## Reference
https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle