
Moodle 5.2.3 - Hoch - Remote - IDOR - core_grades_get_gradeitems listet versteckte Bewertungselemente auf
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · moodle-grades-gradeitems
Moodle LMS 5.2.3 - Moodle
Klasse: IDOR Reichweite: Remote
core_grades_get_gradeitems ist Ajax plus der offizielle Mobile-Service, ohne capabilities-Schlüssel in services.php. validate_context ist das einzige Gate. Dann gibt grade_item::fetch_all jedes Item im Kurs aus. Der array_filter entfernt GRADE_TYPE_NONE, Kategorie-Items und das Kurs-Item. Hidden ist nicht in diesem Filter. Das Schwester-Item core_grades_get_grade_tree erfordert bereits moodle/grade:viewall.
Ein eingeschriebener Student sendet per POST {courseid} und erhält Namen von versteckten Grade-Items, die die Studenten-Notenbuch-UI weiterhin verbirgt.
| ID | noch keine CVE |
| CWE | CWE-862 / CWE-200 |
| CVSS | Medium: 4.3 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N |
| Produkt | Moodle |
| Betroffen | 5.2.3 Tag v5.2.3 (344232c15336c71b80f9aca8359ce0e0a9f3d116) |
| Auth | eingeschriebener Student (moodle/grade:view; ohne viewall / viewhidden) |
| Lizenz | GNU Affero GPL v3.0 |
| Lab | nur 127.0.0.1 |
Schreiber: ein eingeschriebener Student im Kurs. Er sendet per POST den AJAX-Service mit {courseid}. Die Antwort enthält Namen, IDs und Kategorien. Das Rückgabe-Schema enthält keine Punkte. Kein RCE. Kein LPE. Kein Schreiben von Punkten.
| Privileg | Methode / Sink | Recon / Integrität / Verfügbarkeit | Lab-belegt oder abgeleitet |
|---|---|---|---|
| Name, ID und Kategorie eines versteckten Grade-Items lesen | POST /lib/ajax/service.php?sesskey= core_grades_get_gradeitems {courseid} | Recon | Lab-belegt. HTTP 200, Namen enthalten MOODLE-GRADES-GRADEITEMS-WITNESS |
| Name, ID und Kategorie eines sichtbaren Grade-Items lesen | Gleiche Antwort | Recon (für Lehrer vorgesehen) | Lab-belegt. Namen enthalten Visible Lab Assignment |
| Derselbe Katalog über den offiziellen Mobile-Service | Gleiche Klasse, services enthält MOODLE_OFFICIAL_MOBILE_SERVICE | Recon | Abgeleitet aus services.php. Lab nutzte AJAX. |
Sequenzielle courseid-Werte für Kurse durchlaufen, die der Student betreten kann | Gleiche Methode, geratene IDs | Recon | Abgeleitet. Lab nutzte die geseedete Kurs-ID 2 |
| Das versteckte Item in der Studenten-Notenbuch-UI sehen | GET /grade/report/user/index.php?id= | n/a | Lab-belegt geschlossen. hidden-in-ui=False, visible-in-ui=True |
| Aufruf ohne Session | AJAX mit einem Dummy-sesskey | n/a | Lab-belegt geschlossen. servicerequireslogin |
| Aufruf als eingeloggter Benutzer, der nicht eingeschrieben ist | Outsider-AJAX, gleiche courseid | n/a | Lab-belegt geschlossen. requireloginerror |
| Punkte anderer Studenten lesen oder Noten schreiben | n/a | n/a | Geschlossen. Rückgabe-Schlüssel sind id, itemname, category |
| PHP RCE / OS LPE | n/a | n/a | Geschlossen. Dieser Überrest ist ein Katalog-Lesen |
Ein Lehrer oder Manager, der bereits moodle/grade:viewall hat, sieht den Katalog ohnehin. Gast- / nicht authentifizierte Aufrufer benötigen weiterhin einen Kurskontext.
Gleiche Pin-Überreste: Blackboard img file read, enrol_database SQLi, grades feedback IDOR.
Ich habe moodle/moodle v5.2.3 nach MSA-26-0042/0043 gepinnt. Grade-Webservices lagen in diesem MSA-Fenster. get_gradeitems.php hat weiterhin kein require_capability. Die Studenten-UI verbarg das Item bereits. Der AJAX-Katalog tat es nicht.
Bereits dokumentierte Irrwege: unauth AJAX 200 als Leak zu behandeln (Body ist servicerequireslogin); dies als Score-IDOR zu bezeichnen, weil der Methodenname grade enthält (Schema enthält nur Namen); zu erwarten, dass get_grade_tree derselbe Überrest ist (es erfordert bereits viewall). Eine Reverse Shell. Theater.
Live Moodle v5.2.3 auf php:8.3-apache + MariaDB 11.4. Das Seed schreibt labstudent ein, lässt laboutsider außerhalb des Kurses und erstellt ein sichtbares manuelles Item plus ein verstecktes Item, dessen Name der Witness ist. run.sh kopiert einen lokalen Pin oder git clone --depth 1 --branch v5.2.3. Der Moodle-Baum ist nicht in diesem Pack enthalten.
python3 moodle-grades-gradeitems-Abraxas-Labs.py
oder
cd lab
./run.sh
Ziel nur http://127.0.0.1:19590. Compose-Projekt moodle-grades-gradeitems. Der Stack wird nach dem Lauf abgebaut.
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
Nach validate_context dieselbe Cap wie bei get_grade_tree erfordern: require_capability('moodle/grade:viewall', $context). Außerdem versteckte Items verwerfen, es sei denn der Aufrufer hat moodle/grade:viewhidden. Einen Behat/PHPUnit-Fall hinzufügen: eingeschriebener Student, verstecktes manuelles Item, core_grades_get_gradeitems muss dieses Item auslassen (oder 403). Die Studenten-Notenbuch-UI verbirgt es bereits.
get_gradeitems.phpget_grade_tree.phpservices.php (core_grades_get_gradeitems, keine capabilities)GNU Affero GPL v3.0. Siehe LICENSE. Nur Loopback-Lab. Keine Gewährleistung.