学习管理系统Moodle核心代码安全审计

admin 2025年6月9日21:32:22评论10 views字数 6633阅读22分6秒阅读模式
学习管理系统Moodle核心代码安全审计
学习管理系统Moodle核心代码安全审计
Moodle的安全防线被轻易突破,SSRF漏洞再次成为攻击者的“入场券”!
学习管理系统Moodle核心代码安全审计

在网络安全的世界里,每一个漏洞都可能成为攻击者突破防线的入口。最近,Quarkslab的安全研究人员在对Moodle(一款广泛使用的开源学习管理系统)进行审计时[1],发现了一个严重的逻辑漏洞,该漏洞允许攻击者绕过所有限制,利用SSRF(服务器端请求伪造)漏洞。这一发现不仅揭示了Moodle在安全防护上的薄弱环节,也提醒了我们对逻辑漏洞的重视。今天,我们将深入探讨这一漏洞的细节,以及它是如何被发现和利用的。

学习管理系统Moodle核心代码安全审计
一、什么是Moodle?
Moodle[2]是一个开源的学习管理系统(LMS),被教育机构、组织和公司用来创建、管理和提供在线课程和培训计划。它提供了一个平台来构建和组织学习内容,如讲座、测验、作业和论坛,并允许学生访问这些材料,完成任务,并与导师和同学互动。
学习管理系统Moodle核心代码安全审计
二、背景
作为一项审计的一部分,作者成功获得了凭证,从而能够认证到客户的Moodle实例(v4.4.3,在审计时为最新版本)。除了获取关于客户内部组织的信息之外,作者还尝试查看是否可以通过远程执行代码来破坏该实例。尽管没有发现任何简单的漏洞可以获取目标上的远程代码执行(RCE),但作者识别出了一个TOC-TOU逻辑错误,该错误允许我们利用SSRF,从而绕过现有的安全机制。
“如果实例托管在AWS上并配置为使用IMDSv1(实例元数据服务),可以将此SSRF转换为远程代码执行(RCE)。”
学习管理系统Moodle核心代码安全审计
学习管理系统Moodle核心代码安全审计
三、缺陷
当审计Moodle核心源代码(版本4.4.3)时,作者发现所有从用户提供的URL中获取信息的功能都受到此逻辑缺陷的影响。
利用Calendar功能时的调用堆栈示例
学习管理系统Moodle核心代码安全审计

calendar/import.php

moodleform->get_data() (formslib.php)

  • moodleform->is_validated() (formslib.php)
  • moodleform->validate_defined_fields() (formslib.php)
  • core_calendarlocaleventformsmanagesubscriptions->validation() (calendar/classes/local/event/forms/managesubscriptions.php)
  • calendar_get_icalendar() (calendar/lib.php)
  • curl::get() (lib/filelib.php)
  • curl::request() (lib/filelib.php)
  • curl::check_securityhelper_blocklist() (lib/filelib.php)
  • curl_security_helper::url_is_blocked() (lib/classes/files/curl_security_helper.php)
  • curl_security_helper::host_is_blocked() (lib/classes/files/curl_security_helper.php)
  • curl_security_helper::host_explicitly_blocked() (lib/classes/files/curl_security_helper.php)
  • curl_security_helper::get_host_list_by_name() (lib/classes/files/curl_security_helper.php)
  • gethostbynamel()
  • curl_security_helper::address_explicitly_blocked() (lib/classes/files/curl_security_helper.php)
  • curl_exec()
当调用curl_exec()时,会执行一次DNS解析,以便curl能够访问URL中域名对应的IP地址。问题在于,我们(或攻击者)可以通过TOC-TOU攻击,在Moodle(更广泛地说是PHP)执行gethostbynamel()函数或curl_exec()函数时,对DNS解析做出不同的响应。
因此,作者的结论是,所有与IP相关的限制因此都被绕过了。另一方面,作者在进一步深入分析后发现,只能向80端口和443端口发起请求(分别通过HTTP和HTTPS协议)。
学习管理系统Moodle核心代码安全审计
四、开发图示例(TOC-TOU)
图显示了攻击者如何通过绕过限制,使Moodle向localhost(127.0.0.1)发送请求。
学习管理系统Moodle核心代码安全审计
学习管理系统Moodle核心代码安全审计
五、深入研究代码
让我们一起深入代码,了解作者是如何利用这个简单的逻辑漏洞的。作者以日历同步功能为例进行说明,但文件选择器(File picker)功能也同样受到影响,所有处理用户提供的URL的功能均存在此问题。
以文件calendar/import.php为例,该文件显示变量$formdata是通过用户(在本例中即为攻击者)提供的数据填充的。

件:calendar/import.php

<?php...$formdata = $form->get_data();...
在调用get_data()函数期间,用户提供的数据会像下面的代码片段所展示的那样被检查和验证。

文件:lib/formslib.php

函数:moodleform::get_data()

<?php...phpabstract class moodleform {    ...    function get_data() {        $mform =& $this->_form;        if (!$this->is_cancelled() and $this->is_submitted() and $this->is_validated()) {            ...        } else {            return NULL;        }    }    ...}...

文件:lib/formslib.php

函数:moodleform::is_validated()

文件:lib/formslib.php

函数:moodleform::validate_defined_fields()

文件:calendar/classes/local/event/forms/managesubscriptions.php

函数:core_calendarlocaleventformsmanagesubscriptions::validation()

从下面的代码中可以看到,当执行calendar_get_icalendar()函数时,用户提供的URL会被作为参数传递给curl对象。

文件:calendar/lib.php

函数:calendar_get_icalendar()

让我更深入地研究代码以了解发生了什么。

文件:lib/filelib.php

函数:curl::get()

在通过curl_exec()实际执行请求之前,会进行一些检查。

文件:lib/filelib.php

函数:curl::request()

以下每一个步骤都经过了分析,以确定如何绕过Moodle的安全机制。

文件lib/filelib.php

curl::check_securityhelper_blocklist()

url_is_blocked()中:

文件:lib/classes/files/curl_security_helper.php

函数:curl_security_helper::url_is_blocked()

host_is_blocked()

文件lib/classes/files/curl_security_helper.php

函数:curl_security_helper::host_is_blocked()

host_explicitly_blocked()中:

文件:lib/classes/files/curl_security_helper.php

函数curl_security_helper::host_explicitly_blocked()

get_host_list_by_name()

可以观察到,与URL中存在的域名相关联的IP地址解析是通过gethostbynamel()函数进行的。

文件lib/classes/files/curl_security_helper.php

函数:curl_security_helper::get_host_list_by_name()

该函数返回的IP或多个IP随后会被与一个黑名单进行比对。

address_explicitly_blocked()中:

文件:lib/classes/files/curl_security_helper.php

函数:curl_security_helper::address_explicitly_blocked()

阅读了所有这些代码后,我们能够确认可以利用该代码逻辑,因为在调用gethostbynamel()函数和调用curl_exec()函数之间存在一个利用窗口(时间窗口),从而导致了一个TOC-TOU漏洞。

学习管理系统Moodle核心代码安全审计
六、日历功能的利用

为了利用此漏洞,可以使用以下形式的URL:

  • http://<DOMAIN_UNDER_OUR_CONTROL>/AAAA?BBBB=CCCC(HTTP)
  • https://<DOMAIN_UNDER_OUR_CONTROL>/AAAA?BBBB=CCCC(HTTPS)

但审计还揭示了可以使用以下形式的URL:

  • webcal://<DOMAIN_UNDER_OUR_CONTROL>/AAAA?BBBB=CCCC(HTTP)

为处理程序webcal://会自动替换为http://,如下面的代码所示。

文件:calendar/classes/local/event/forms/managesubscriptions.php

功能:core_calendarlocaleventformsmanagesubscriptions::strip_webcal()

<?php...classmanagesubscriptions{    ...publicfunctiondefinition_after_data(){        $mform =& $this->_form;        $mform->applyFilter('url'static::class . '::strip_webcal');        $mform->applyFilter('url''trim');    }publicstaticfunctionstrip_webcal($url){if (strpos($url, 'webcal://') === 0) {            $url = str_replace('webcal://''http://', $url);        }return $url;    }...}...
学习管理系统Moodle核心代码安全审计

图注:漏洞利用日历功能

学习管理系统Moodle核心代码安全审计

图注:左侧是来自Web服务器(Moodle实例)的HTTP日志视图,右侧是恶意DNS服务器(托管在C2上)的视图。

学习管理系统Moodle核心代码安全审计
七、利用文件选择器功能

为支持作者自身的发现,作者还演示了如何利用文件选择器(File picker)功能,并通过SSRF发起的请求获取目标响应。

Moodle文件选择器中的“URL下载器”功能允许用户从外部URL添加文件,而不是直接从本地计算机上传文件。文件选择器是一个工具,允许用户(如教师、管理员、学生等)将文件上传到Moodle中,例如,用于添加文件到活动、资源或作业中。通常情况下,它允许你从本地计算机选择文件,或浏览 Moodle的文件系统。

URL下载器允许用户输入一个图片的URL(任何类型,例如png、jpg)以将该图片复制到Moodle中。此外,通过输入网页地址,该功能还可以用于获取整个网页中的所有图片。

学习管理系统Moodle核心代码安全审计

图注:使用文件选取器功能第1部分

学习管理系统Moodle核心代码安全审计

图注:使用文件选取器功能第2部分

学习管理系统Moodle核心代码安全审计

图注:使用文件选取器功能第3部分

假设在托管Moodle的Web服务器根目录下(例如一个AWS实例),存在像aaaa.jsonphpinfo.php这样的文件(例如在镜像sprintcube/docker-compose-lamp的Web根目录中常见的文件)。

为了利用这一功能,作者在自己的C2(命令与控制服务器)上托管一个test.html文件(HTML格式)。攻击者向Moodle指定一个HTML文件的URL,供其解析(以便Moodle提取其中的图片标签)。

<html><imgsrc="http://poc.ns.<DOMAIN_UNDER_OUR_CONTROL>/aaaa.json"></html>
攻击者向Moodle指定一个HTML文件的URL,供其解析(以便Moodle提取其中的图片标签)。
学习管理系统Moodle核心代码安全审计

图注:由Moodle下载和解析的C2上公开的HTML文件

攻击者要求Moodle下载该HTML文件中识别出的图片。

学习管理系统Moodle核心代码安全审计

图注:Moodle向URLhttp://poc.ns.<DOMAIN_UNDER_OUR_CONTROL>/phpinfo.php发送GET请

攻击者通过SSRF获取Moodle发送的HTTP GET请求的响应内容。

学习管理系统Moodle核心代码安全审计

图注:攻击者检索的响应内容

正如从Moodle Web服务器日志和C2服务器日志中所见,SSRF漏洞已被成功利用。

学习管理系统Moodle核心代码安全审计

图注:左侧是Moodle Web服务器日志,右侧是C2日志

如果文件test.html包含以下内容:

文件:test.html(托管在C2上)

<html><imgsrc="http://poc.ns.<DOMAIN_UNDER_OUR_CONTROL>/phpinfo.php"></html>

将采取以下步骤。

学习管理系统Moodle核心代码安全审计

图注:由Moodle下载和解析的C2上公开的HTML文件

学习管理系统Moodle核心代码安全审计

图注:Moodle向URLhttp://poc.ns.<DOMAIN_UNDER_OUR_CONTROL>/phpinfo.php发送GET请求

学习管理系统Moodle核心代码安全审计

图注:攻击者检索的响应内容

学习管理系统Moodle核心代码安全审计

图注:左侧是Moodle Web服务器日志,右侧是C2日志

因此,非常重要的一点是,如果Moodle托管在AWS上(通过IMDSv1),该漏洞可以被利用来实现远程代码执行(RCE)。

学习管理系统Moodle核心代码安全审计
八、概念验证(POC)
概念验证(Proof of Concept)只是一个用Python编写的简单DNS服务器,它会对第一次请求返回一个合法的IP地址,而对第二次(或第三次,具体取决于 TOC_TOU_CHECK变量的设置)针对同一域名的请求,则返回本地主机地址(127.0.0.1)。
如果你想测试下面的漏洞,你需要使用modulo值。例如,如果您想尝试通过导入日历功能触发SSRF,您需要将此值设置为3并替换:
 if TOC_TOU_CHECK % 3 == 0:

文件:server.py[3]

漏洞利用(流氓DNS)

学习管理系统Moodle核心代码安全审计
九、相关链接
[1]https://blog.quarkslab.com/auditing-moodles-core-hunting-for-logical-bugs.html
[2]https://moodle.org/
[3]https://blog.quarkslab.com/resources/2025-04-22_moodle/server.py
学习管理系统Moodle核心代码安全审计
山石网科是中国网络安全行业的技术创新领导厂商,由一批知名网络安全技术骨干于2007年创立,并以首批网络安全企业的身份,于2019年9月登陆科创板(股票简称:山石网科,股票代码:688030)。
现阶段,山石网科掌握30项自主研发核心技术,申请560多项国内外专利。山石网科于2019年起,积极布局信创领域,致力于推动国内信息技术创新,并于2021年正式启动安全芯片战略。2023年进行自研ASIC安全芯片的技术研发,旨在通过自主创新,为用户提供更高效、更安全的网络安全保障。目前,山石网科已形成了具备“全息、量化、智能、协同”四大技术特点的涉及基础设施安全、云安全、数据安全、应用安全、安全运营、工业互联网安全、信息技术应用创新、安全服务、安全教育等九大类产品服务,50余个行业和场景的完整解决方案。
学习管理系统Moodle核心代码安全审计

原文始发于微信公众号(山石网科安全技术研究院):学习管理系统Moodle核心代码安全审计

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年6月9日21:32:22
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   学习管理系统Moodle核心代码安全审计https://cn-sec.com/archives/4150980.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息