Moodle 5.2.3 - Alta - Remota - IDOR - core_grades_get_gradeitems enumera elementos de calificación ocultos
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · moodle-grades-gradeitems
Moodle LMS 5.2.3 - Moodle
Clase: IDOR Alcance: Remoto
core_grades_get_gradeitems es ajax más el servicio móvil oficial, sin clave capabilities en services.php. validate_context es la única barrera. Luego grade_item::fetch_all vuelca cada ítem del curso. El array_filter descarta GRADE_TYPE_NONE, los ítems de categoría y el ítem del curso. Oculto no está en ese filtro. El hermano core_grades_get_grade_tree ya requiere moodle/grade:viewall.
Un estudiante matriculado hace POST de {courseid} y obtiene los nombres de los ítems de calificación ocultos que la interfaz del libro de calificaciones del estudiante aún oculta.
| ID | sin CVE todavía |
| CWE | CWE-862 / 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 tag v5.2.3 (344232c15336c71b80f9aca8359ce0e0a9f3d116) |
| Auth | estudiante matriculado (moodle/grade:view; carece de viewall / viewhidden) |
| Licencia | GNU Affero GPL v3.0 |
| Lab | solo 127.0.0.1 |
Escritor: un estudiante matriculado en el curso. Hace POST al servicio AJAX con {courseid}. La respuesta son nombres, IDs y categorías. El esquema de retorno no tiene puntuaciones. No es RCE. No es LPE. No es una escritura de puntuación.
| Privilegio | Método / sink | Recon / integridad / disponibilidad | Probado en lab o inferido |
|---|---|---|---|
| Leer nombre, id y categoría de ítem de calificación oculto | POST /lib/ajax/service.php?sesskey= core_grades_get_gradeitems {courseid} | Recon | Probado en lab. HTTP 200, los nombres incluyen MOODLE-GRADES-GRADEITEMS-WITNESS |
| Leer nombre, id y categoría de ítem de calificación visible | Misma respuesta | Recon (previsto para profesores) | Probado en lab. los nombres incluyen Visible Lab Assignment |
| El mismo catálogo a través del servicio móvil oficial | Misma clase, services incluye MOODLE_OFFICIAL_MOBILE_SERVICE | Recon | Inferido de services.php. El lab usó AJAX. |
Recorrer valores secuenciales de courseid para cursos a los que el estudiante puede entrar | Mismo método, ids adivinados | Recon | Inferido. El lab usó el id de curso sembrado 2 |
| Ver el ítem oculto en la interfaz del libro de calificaciones del estudiante | GET /grade/report/user/index.php?id= | n/a | Probado en lab cerrado. hidden-in-ui=False, visible-in-ui=True |
| Llamar sin sesión | AJAX con un sesskey ficticio | n/a | Probado en lab cerrado. servicerequireslogin |
| Llamar como usuario autenticado que no está matriculado | AJAX de externo, mismo courseid | n/a | Probado en lab cerrado. requireloginerror |
| Leer puntuaciones de otros estudiantes o escribir calificaciones | n/a | n/a | Cerrado. Las claves de retorno son id, itemname, category |
| RCE de PHP / LPE de SO | n/a | n/a | Cerrado. Este remanente es una lectura de catálogo |
Un profesor o gestor que ya tiene moodle/grade:viewall ya ve el catálogo. Los llamadores invitados / no autenticados aún necesitan un contexto de curso.
Remanentes del mismo pin: Blackboard img file read, enrol_database SQLi, grades feedback IDOR.
Fijé moodle/moodle v5.2.3 después de MSA-26-0042/0043. Los servicios web de calificaciones estaban en esa ventana de MSA. get_gradeitems.php todavía no tiene require_capability. La interfaz del estudiante ya ocultaba el ítem. El catálogo AJAX no.
Caminos equivocados ya registrados: tratar el AJAX no autenticado 200 como la fuga (el cuerpo es servicerequireslogin); llamar a esto un IDOR de puntuación porque el nombre del método tiene grade (el esquema es solo nombres); esperar que get_grade_tree fuera el mismo remanente (ya requiere viewall). Una reverse shell. Teatro.
Moodle v5.2.3 en vivo sobre php:8.3-apache + MariaDB 11.4. La semilla matricula a labstudent, deja a laboutsider fuera del curso, y crea un ítem manual visible más un ítem oculto cuyo nombre es el testigo. run.sh copia un pin local o git clone --depth 1 --branch v5.2.3. El árbol de Moodle no está en este paquete.
python3 moodle-grades-gradeitems-Abraxas-Labs.py
o
cd lab
./run.sh
Objetivo solo http://127.0.0.1:19590. Proyecto de Compose moodle-grades-gradeitems. El stack se desmonta tras la ejecución.
SUCCESS moodle-grades-gradeitems student-ajax=200 hidden-in-ajax=yes hidden-in-ui=no visible-in-ajax=yes visible-in-ui=yes outsider-error=yes unauth-error=yes MOODLE-GRADES-GRADEITEMS-WITNESS
Después de validate_context, requerir la misma cap que get_grade_tree: require_capability('moodle/grade:viewall', $context). También descartar los ítems ocultos a menos que el llamador tenga moodle/grade:viewhidden. Añadir un caso de Behat/PHPUnit: estudiante matriculado, ítem manual oculto, core_grades_get_gradeitems debe omitir ese ítem (o 403). La interfaz del libro de calificaciones del estudiante ya lo oculta.
get_gradeitems.phpget_grade_tree.phpservices.php (core_grades_get_gradeitems, sin capabilities)GNU Affero GPL v3.0. Ver LICENSE. Solo lab en loopback. Sin garantía.