Moodle 5.2.3 - 高危 - 远程 - IDOR - core_grades_get_feedback 跳过独立小组检查
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · moodle-grades-feedback-idor
Moodle LMS 5.2.3 - Moodle
类别: IDOR 可达性: 远程
core_grades_get_feedback 仍然只调用 require_capability('gradereport/grader:view')。其他成绩 Web 服务在 MSA-26-0016 / MDL-88667 之后增加了 groups_user_groups_visible / groups_group_visible。这个 AJAX 服务没有。返回的 JSON 包含 feedbacktext、fullname、picture 以及第一个身份字段。
一个处于 Separate groups 中、没有 accessallgroups 的非编辑教师,POST 另一个学生的 userid,即可读取该组的反馈。
| ID | 暂无 CVE |
| CWE | CWE-863 / CWE-200 |
| CVSS | 中危:4.3 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N |
| 产品 | Moodle |
| 受影响版本 | 5.2.3 标签 v5.2.3 (344232c15336c71b80f9aca8359ce0e0a9f3d116) |
| 认证 | 拥有 gradereport/grader:view、没有 moodle/site:accessallgroups 的非编辑教师。课程处于 Separate groups。 |
| 许可证 | GNU Affero GPL v3.0 |
| 实验环境 | 仅 127.0.0.1 |
写入者:一名注册在 Separate-groups 课程中的非编辑教师,仅属于 Group A,拥有 grader 查看权限且没有 access-all-groups。他们选取另一名已注册学生的 userid(连续整数)并调用该 AJAX 服务。不是 RCE。不是 LPE。不是成绩写入。
| 权限 | 方法 / 汇聚点 | 侦察 / 完整性 / 可用性 | 实验验证或推断 |
|---|---|---|---|
| 读取另一组的成绩反馈 | POST /lib/ajax/service.php?sesskey= core_grades_get_feedback {courseid, userid, itemid} | 侦察 | 实验验证。HTTP 200,error=false,feedbacktext 包含 MOODLE-GRADES-FEEDBACK-IDOR-WITNESS |
| 读取该学生的身份字段和显示名称 | 同一响应 additionalfield / fullname / picture | 侦察 | 实验验证。[email protected],fullname=Student Bravo |
在同一课程中遍历连续的 userid 值 | 同一方法,猜测 id | 侦察 | 推断。实验使用了预置的 Group B id |
| 通过同级选择器列出 Group B | core_grades_get_gradable_users {courseid, groupid=B} | 不适用 | 实验验证已关闭。cannotaccessgroup |
| 学生调用同一反馈服务 | student 角色,相同参数 | 不适用 | 实验验证已关闭。nopermissions |
| 同组反馈(Group A 学生) | 教师为 Student Alpha 调用 | 侦察(预期内) | 实验验证允许。HTTP 200,error=false |
| PHP RCE / OS LPE / 成绩写入 | 不适用 | 不适用 | 已关闭。此遗留问题是对反馈和个人资料字段的读取 |
默认 Moodle 未启用 Separate groups,或教师已拥有 moodle/site:accessallgroups,则不属于此遗留问题。拥有该权限的编辑教师本就能看到所有组。
同一版本的遗留问题:Blackboard img 文件读取、enrol_database SQLi、隐藏成绩项。
在 MSA-26-0042/0043 之后,我锁定了 moodle/moodle v5.2.3。MSA-26-0016 关闭了其他成绩 Web 服务上的组检查。get_feedback.php 不在该集合中。grader UI 已加固。这个 AJAX 服务没有。
已记录的弯路:把同级 get_gradable_users 的遗漏当作全部问题(那个已经抛出 cannotaccessgroup);因为载荷中带有 itemid 就称其为成绩写入(该服务是读取);把学生当作攻击者(nopermissions)。一个反弹 shell。作秀。
在 php:8.3-cli + MariaDB 11.4 上运行实时 Moodle v5.2.3。种子数据构建一个 Separate-groups 课程,教师仅属于 Group A,学生 B 仅属于 Group B,对 moodle/site:accessallgroups 设置 CAP_PREVENT,以及一个手动成绩项,其反馈即为见证字符串。how=live。
Compose 将 ../../vendors/moodle/src 绑定挂载为 /opt/moodle-pin(路径相对于 lab/docker-compose.yml)。将 moodle/moodle 标签 v5.2.3 克隆到该路径,或将卷指向你的检出目录。Moodle 源码树不在此包中。
python3 moodle-grades-feedback-idor-Abraxas-Labs.py
或
cd lab
./run.sh
目标仅限 http://127.0.0.1:19580。Compose 项目 moodle-grades-feedback-idor。运行后栈会拆除。
SUCCESS moodle-grades-feedback-idor how=live pin=v5.2.3 teacher-role=teacher accessallgroups=no groupmode=1 feedback-has-witness=yes [email protected] sibling-group-b=cannotaccessgroup student-call=nopermissions MOODLE-GRADES-FEEDBACK-IDOR-WITNESS
在 validate_context / require_capability 之后,加载课程和目标用户,然后除非 groups_user_groups_visible($course, $userid) 且目标已注册,否则拒绝。与 MDL-88667 之后的 gradereport_user 和 core_grades_get_gradable_users 形式相同。
get_feedback.phpget_gradable_users.phpGNU Affero GPL v3.0。参见 LICENSE。仅限回环实验环境。无担保。