Moodle 5.2.3 - Alta - Remota - IDOR - core_grades_get_feedback omite las comprobaciones de grupos separados
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · moodle-grades-feedback-idor
Análisis: https://abraxaslabs.tech/research/moodle-grades-feedback-idor
Moodle LMS 5.2.3 - Moodle
Clase: IDOR Alcance: Remoto
core_grades_get_feedback todavía solo llama a require_capability('gradereport/grader:view'). Otros servicios web de calificaciones obtuvieron groups_user_groups_visible / groups_group_visible tras MSA-26-0016 / MDL-88667. Este servicio AJAX no lo hizo. El JSON regresa con feedbacktext, fullname, picture y el primer campo de identidad.
Un profesor sin permisos de edición en grupos separados, sin accessallgroups, envía por POST el userid de otro estudiante y lee la retroalimentación de ese grupo.
| ID | aún sin CVE |
| CWE | CWE-863 / CWE-200 |
| CVSS | Medio: 4.3 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N |
| Producto | Moodle |
| Afectado | 5.2.3 etiqueta v5.2.3 (344232c15336c71b80f9aca8359ce0e0a9f3d116) |
| Autenticación | profesor sin permisos de edición con gradereport/grader:view, sin moodle/site:accessallgroups. Curso en grupos separados. |
| Licencia | GNU Affero GPL v3.0 |
| Laboratorio | solo 127.0.0.1 |
Autor: un profesor sin permisos de edición inscrito en un curso de grupos separados, solo en el Grupo A, con vista de calificador y sin acceso a todos los grupos. Elige el userid de otro estudiante inscrito (enteros secuenciales) y llama al servicio AJAX. No es RCE. No es LPE. No es una escritura de calificaciones.
| Privilegio | Método / sink | Reconocimiento / integridad / disponibilidad | Probado en laboratorio o inferido |
|---|---|---|---|
| Leer la retroalimentación de calificaciones de otro grupo | POST /lib/ajax/service.php?sesskey= core_grades_get_feedback {courseid, userid, itemid} | Reconocimiento | Probado en laboratorio. HTTP 200, error=false, feedbacktext contiene MOODLE-GRADES-FEEDBACK-IDOR-WITNESS |
| Leer el campo de identidad y el nombre visible de ese estudiante | Misma respuesta additionalfield / fullname / picture | Reconocimiento | Probado en laboratorio. [email protected], fullname=Student Bravo |
Recorrer valores secuenciales de userid en el mismo curso | Mismo método, ids adivinados | Reconocimiento | Inferido. El laboratorio usó el id sembrado del Grupo B |
| Listar el Grupo B mediante el selector hermano | core_grades_get_gradable_users {courseid, groupid=B} | n/a | Probado en laboratorio cerrado. cannotaccessgroup |
| Un estudiante llama al mismo servicio de retroalimentación | rol de estudiante, mismos argumentos | n/a | Probado en laboratorio cerrado. nopermissions |
| Retroalimentación del mismo grupo (estudiante del Grupo A) | llamada del profesor para Student Alpha | Reconocimiento (previsto) | Probado en laboratorio permitido. HTTP 200, error=false |
| RCE en PHP / LPE en el SO / escritura de calificaciones | n/a | n/a | Cerrado. Este remanente es una lectura de retroalimentación y campos de perfil |
Un Moodle por defecto sin grupos separados, o un profesor que ya tiene moodle/site:accessallgroups, no corresponde a este remanente. Los profesores con permisos de edición que ya tienen esa capacidad ven todos los grupos.
Otros remanentes de la misma versión: lectura de archivos img de Blackboard, SQLi en enrol_database, elementos de calificación ocultos.
Fijé moodle/moodle v5.2.3 después de MSA-26-0042/0043. MSA-26-0016 cerró las comprobaciones de grupo en otros servicios web de calificaciones. get_feedback.php no estaba en ese conjunto. La interfaz del calificador fue reforzada. Este servicio AJAX no lo fue.
Errores ya registrados: tratar el fallo hermano de get_gradable_users como la historia completa (ese ya lanza cannotaccessgroup); llamar a esto una escritura de puntuación porque la carga útil nombra itemid (el servicio es una lectura); estudiante como atacante (nopermissions). Una reverse shell. Teatro.
Moodle v5.2.3 en vivo sobre php:8.3-cli + MariaDB 11.4. La semilla construye un curso de grupos separados, profesor solo en el Grupo A, estudiante B solo en el Grupo B, CAP_PREVENT en moodle/site:accessallgroups, y un ítem de calificación manual cuyo feedback es el testigo. how=live.
Compose monta mediante bind ../../vendors/moodle/src como /opt/moodle-pin (la ruta es relativa a lab/docker-compose.yml). Clona moodle/moodle con la etiqueta v5.2.3 en esa ruta, o apunta el volumen a tu checkout. El árbol de Moodle no está en este paquete.
python3 moodle-grades-feedback-idor-Abraxas-Labs.py
o
cd lab
./run.sh
Dirígete solo a http://127.0.0.1:19580. Compón el proyecto moodle-grades-feedback-idor. El stack se desmonta después de la ejecución.
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
Después de validate_context / require_capability, cargar el curso y el usuario objetivo, luego rechazar a menos que groups_user_groups_visible($course, $userid) y el objetivo esté matriculado. Misma forma que gradereport_user y core_grades_get_gradable_users después de MDL-88667.
get_feedback.phpget_gradable_users.phpGNU Affero GPL v3.0. Ver LICENSE. Solo laboratorio de loopback. Sin garantía.