我的第一个CVE漏洞挖掘之旅

embedded/2025/3/11 1:02:55/

 目录:

      为什么选择 Moodle?

      我该从哪里开始?

      寻找漏洞

     源点(Sources)和同步点(Syncs)

      更大的影响

本文介绍我是如何在一个开源项目中找到我的第一个 CVE 漏洞(CVE-2025–26529)!

为什么选择 Moodle?

Moodle 是最广泛使用的学习管理系统(LMS)之一,它由 PHP 编写,被大量教育机构使用。如果你在过去几年中是学生或老师,那么你很可能用过它。

许多人可能都曾想过修改成绩、篡改作业提交,甚至做一些黑客操作。这正是我开始研究这个软件的动力之一。我一直希望能找到一个 0day,并提交给多个漏洞赏金计划。

我该从哪里开始?

在测试之前,下载源代码并在本地运行它非常重要。如果你想真正理解源代码,调试几乎是必不可少的,而且 PHP 代码的调试相对简单。

这是我第一次进行源代码审计,所以我尝试借鉴其他黑客的方法,并制定了一套自己的方法论。我的目标是找到一个未认证会话的漏洞,或者至少是一个访客用户可以利用的漏洞。

我首先以普通用户的身份浏览整个应用,以回忆它的功能和操作方式。

寻找漏洞

我决定通过调试正常的身份验证流程、身份验证插件、OAuth、SSO 等方式来寻找身份认证绕过漏洞。

我花了大约 20 个小时调试各种身份验证机制,分析身份验证插件如何与核心应用程序通信。在这个过程中,我学到了很多关于应用如何处理身份认证的信息,但并没有发现漏洞。

此外,我还抽出一些时间来调试那些引起我注意的功能,即使它们仅对普通认证用户(学生、教师等)可用。

源点(Sources)和同步点(Syncs)

在经过 30 小时的漏洞挖掘后,我尝试了一种不同的方法——寻找 源点(sources) 和 同步点(syncs)

源点(Sources) 是代码中外部数据进入应用程序的地方,比如用户输入、API 端点、Web 端点等。可以把它们看作是应用程序的“入口点”,用户可以在这些地方输入数据、读取数据或修改数据。

调试所有的源点是一项艰巨的任务,所以我决定只关注未认证用户或访客用户能访问的源点。我认为这是一种更有效的方式。

我分析了所有未认证的源点(身份认证本身也是一种源点)以及一些有趣的访客用户源点,虽然没有发现漏洞,但我记录了所有值得关注的功能和行为。

我知道如果深入研究每个源点,可能会花费大量时间,但我的目标只是对每个源点有一个基本的了解。

接下来,我开始寻找 同步点(Syncs)

同步点 是应用程序使用不受信任数据的地方,并且这些数据可能以危险的方式被利用,导致 SQL 注入(SQLi)、跨站脚本(XSS)或远程代码执行(RCE) 等漏洞。除了应用程序特定的函数外,每种编程语言都有自己的同步点。

在 PHP 中,诸如 system()file_get_contents()unserialize() 或 SQL 查询等函数都可能是有效的同步点。

寻找同步点的方法与寻找源点相反,这一方法基于先找到一个危险函数(例如 system()),然后进行“反向分析”,追溯它是如何连接到有效的源点的。

img

我搜索了所有危险的 PHP 函数,并对其进行反向追踪,以查找任何有效的源点,但没有发现任何漏洞。

之后,我开始寻找应用程序中特定可能存在风险的函数。在一番搜索后,我查看了 /report/loglive/index.php 这个管理日志路径。该路径用于显示 Moodle 中发生的多个事件的描述:

img

我首先想到的是寻找一种方法,在 Description 字段中注入 XSS 载荷。因此,我复制了其中一个 Description 值,并在源代码中搜索该文本,以追踪该字符串是如何生成的。

我发现这个描述文本:

img

是由以下代码创建的:

img

我发现每种事件类型都有一个名称、一个类,而每个类都有一个名为“get_description()”的方法,该方法使用当前对象的变量创建一个字符串,并在日志中显示该字符串。

在这个案例中,事件名称是“Dashboard viewed”,事件类是“dashboard_viewed”。

每个事件类的变量(如 $this->userid)是在创建新的事件对象时生成的。在这种情况下,每当用户访问仪表板时,都会创建一个 “dashboard_viewed” 对象。

img

源代码的流程如下所示:

img

在寻找向“get_description()”函数注入 XSS 载荷的方法之前,我需要先检查它是否存在 XSS 漏洞。于是,我将文本替换为一个简单的 XSS 载荷,然后重新加载页面。

img

img

成功了!这意味着“get_description()”是一个值得关注的同步点(sync)。于是,我检查了所有事件类中的“get_description()”函数。

img

很多函数出现在了列表中,每个事件类都有一个。我开始搜索那些可以注入XSS负载的函数。经过一番搜索,我找到了以下内容。

img

这个字符串是通过“receivedconfigkey”和“receivedbrowserkey”变量创建的。

这个事件类是在用户在“安全考试浏览器”功能内进行身份验证失败时创建的。

在解释什么是“安全考试浏览器”之前,我先解释一下它的使用背景。

Moodle有一个叫做QUIZ(测验)的功能,它是教师为学生创建的问题测试。

教师可以启用一个选项叫做“安全考试浏览器”,这个选项允许用户通过名为“安全考试浏览器”的软件访问测验,从而限制考试中的作弊行为。

如果启用了这个选项,用户需要提供一个“configKey”和“BrowserExamKey”才能进行QUIZ。当这些值无效时,会创建“access_prevented”对象(如你在之前的图片中所见)。

这意味着如果我们在“configKey”或“BrowserExamKey”中注入XSS负载,它将在管理员日志中创建XSS。

让我们来做吧。负载需要被注入到这个HTTP请求中的特定头部里。

img

这个请求用于访问启用了“安全考试浏览器”的QUIZ。

源代码的流程大致如下:

img

一旦发送该请求,事件应该会触发,我们应该在管理员页面看到XSS。

img

我们在管理员日志中找到了XSS,问题是利用这个漏洞需要访问学生账户并且有启用 SafeExamBrowser 的测验。所以我决定寻找一种从访客账户利用这个漏洞的方法。

更大的影响

SafeExamBrowser 无法从访客账户访问,因此我尝试搜索更多可以触发 XSS 的事件。

我没有找到任何可以用来创建 XSS 的事件,唯一的替代方案是一些通过变量 URL 创建字符串的事件。

img

URL 是可以注入的,但如果我创建一个带有 XSS payload 的 URL(web.com/),服务器总是会对 payload 进行 URL 编码(web.com/%3Cxss%3E)。

我查看了我的笔记,记得有一个端点存在 SSRF 问题,问题是这个 SSRF 不允许访问内部 IP。

img

img

我记得我曾尝试设置我自己的服务器 URL 并重定向到内部 IP:

img

img

但是,当重定向到内部 IP 时,这个事件被触发。

img

所以,我尝试将 XSS payload 设置在我服务器的重定向 URL 中,这样当 Moodle 访问我的服务器并重定向到 http://127.0.0.1/<img src onerror=alert(1)>时,它会因为是内部 URL 而阻止这个 URL,但是事件仍然会触发并带有 XSS payload。

img

我发送了请求,Moodle 到达了我的服务器,结果发生了这个。

img

最终,事实证明,当用户提供 URLs 时,它们总是经过 URL 编码,而服务器提供的 URLs 则不会。

利用这个 XSS 漏洞,我通过外泄 document.cookie 偷取了管理员的会话,成功实现了完全的管理员账户接管。

我通过 https://moodle.org/mod/page/view.php?id=8722 报告了这个漏洞。

现在,我拥有了我的 CVE。

https://moodle.org/mod/forum/discuss.php?d=466145#p1871275

img

申明:本账号所分享内容仅用于网络安全技术讨论,切勿用于违法途径,所有渗透都需获取授权,违者后果自行承担,与本号及作者无关   


http://www.ppmy.cn/embedded/171623.html

相关文章

【动手实验】TCP orphan socket 的产生与消亡

之前在实验中提到了 tcp_max_orphans 和 tcp_orphan_retries 两个参数&#xff0c;我们使用 ss -s 命令查看当前系统中的 socket 状态也有 orphan 状态的 socket&#xff0c;本篇文章我们就来分析下到底什么情况下的 socket 才会被视为 orphan socket。 # ubuntu node1 in ~ …

Calico-BGP FullMesh模式与RR模式 Day04

1. BGP协议简单介绍 BGP是什么&#xff1f;BGP是如何工作的&#xff1f; - 华为 Configure BGP peering | Calico Documentation 1.1 什么是BGP 边界网关协议&#xff08;BGP&#xff09;是一种用于在网络中的路由器之间交换路由信息的标准协议。每台运行 BGP 的路由器都有一…

彻底解决 k8s xxx 命名空间卡在 ​Terminating 的问题

前言 在 Kubernetes 集群管理中&#xff0c;命名空间&#xff08;Namespace&#xff09;卡在 Terminating 状态是一个常见但棘手的问题。这种状态通常由资源残留、Finalizers 未完成清理或控制器异常导致。本文将结合实践案例和底层原理&#xff0c;提供一套完整的解决方案&am…

从技术角度看大语言模型进化技术路线与落地应用详解:未来的最佳实践方向是什么?

文章大纲 **一、模型架构创新:从Transformer到下一代架构****二、训练与优化技术:从暴力Scaling到精细调控****三、数据与知识工程:从粗放喂养到智能增强****四、应用层进化:从通用能力到垂直场景突破****五、伦理与可持续性技术**未来技术路线图参考文献**一、大模型架构创…

Android paging初识

嗯&#xff0c;用户之前已经问过关于Android Paging库的问题&#xff0c;现在又提到了同样的困惑&#xff0c;可能说明他们在实际学习中遇到了困难&#xff0c;或者在项目应用过程中遇到了障碍。用户可能已经尝试过学习Paging库&#xff0c;但感觉复杂&#xff0c;导致犹豫是否…

软件测试的基础入门(二)

文章目录 一、软件&#xff08;开发&#xff09;的生命周期什么是生命周期软件&#xff08;开发&#xff09;的生命周期需求分析计划设计编码测试运行维护 二、常见的开发模型瀑布模型流程优点缺点适应的场景 螺旋模型流程优点缺点适应的场景 增量模型和迭代模型流程适应的场景…

clickhouse的优缺点

《ClickHouse的优缺点及成功案例分析》 当我们谈论数据库技术时&#xff0c;ClickHouse无疑是一个引人注目的名字。它是一种专为在线分析处理&#xff08;OLAP&#xff09;设计的列式数据库管理系统&#xff08;DBMS&#xff09;&#xff0c;由俄罗斯的Yandex公司开发。随着大…

Milvus JSON数据存储优化方案

无论是json数据还是string/varchar 类型数据,其长度都不能超过65536,这是根本,不像ES的text类型数据一样,可以无限长。 总结 数据类型适用场景最大长度STRINGMilvus <2.2.x 的短文本(<65KB)隐式 ≈65,535 字节VARCHAR(N)Milvus ≥2.2.x 的文本显式 N≤65,535 字符…