# CVE-2021-45467: CWP CentOS Web Panel - preauth RCE

Null-byte bypass of stristr() dot filter in CWP loader.php enables local file inclusion, chained with an API file-write to achieve preauth root RCE.

- Payout: Research
- Severity: critical
- Program: CentOS Web Panel
- Credited: PWNAI Research
- Disclosed: 2022-01-22
- CVE: CVE-2021-45467, CVE-2021-45466
- Write-up quality: 8/10
- Original: https://pwn.ai/blog/cve-2021-45467-cwp-centos-web-panel-preauth-rce
- Library page: https://bugbountylibrary.com/r/blog%3Apwn-ai-blog-cve-2021-45467-cwp-centos-web-panel-preauth-rce
- Tags: domain:web impact:privesc impact:rce kind:research platform:research sev:critical tech:php technique:chained technique:fuzzing technique:source-review vuln:auth-bypass vuln:path-traversal vuln:rce

**Target:** PHP web hosting panel (loader.php, API endpoint)
**Root cause:** stristr() lowercases input and ignores null bytes but still counts their length, so `.%00./` passes the '..' check while include()/require() resolve it as `../`; a separate API file-write lets attacker-controlled content land in a file.
**Steps:**
1. Fuzz dot-filter bypass; discover `.%00./` passes stristr('..') but include() treats it as `../`
2. `GET /user/loader.php?api=1&scripts= .%00./.%00./api/account_new_create&acc=guadaapi&ip=192.168.1.1&keyapi=OCTAGON` registers attacker API key
3. `GET /api/?key=OCTAGON&api=add_server&DHCP=&fileFinal=/` writes attacker content to authorized_keys in /resources/
4. Include the written file via the same LFI payload to execute commands as root
**How found:** Read loader.php's GETSecurity() dot filter, reasoned about PHP's C-level stristr() lowercasing behavior, fuzzed unicode case-folding (no dot equivalents), then fuzzed for sequences that bypass the consecutive-dot check, yielding `.%00./`.
**Exploitation:** Preauth attacker uses null-byte LFI to reach the API registration script and plant an API key, then uses the authenticated API's add_server file-write to drop a malicious authorized_keys, then re-includes it via LFI to execute arbitrary commands as root.
**Escalation:** LFI alone is read-only; chaining with API key registration and API file-write escalates to root RCE.
**Insight:** When a filter uses stristr()/strstr() but the sink is include()/require(), test null-byte and case-folding differentials: the filter counts bytes the filesystem ignores. Also, a read-only LFI can be escalated by using it to reach non-webroot scripts (like API registration) that grant write primitives.
