
Moodle 5.2.3 - 높음 - 원격 - IDOR - core_grades_get_gradeitems가 숨겨진 성적 항목을 나열함
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · moodle-grades-gradeitems
Moodle LMS 5.2.3 - Moodle
Class: IDOR Reach: Remote
core_grades_get_gradeitems는 ajax이자 공식 모바일 서비스이며, services.php에 capabilities 키가 없다. validate_context가 유일한 관문이다. 그런 다음 grade_item::fetch_all이 코스의 모든 항목을 덤프한다. array_filter는 GRADE_TYPE_NONE, 카테고리 항목, 코스 항목을 제거한다. 숨김은 그 필터에 없다. 형제 서비스인 core_grades_get_grade_tree는 이미 moodle/grade:viewall을 요구한다.
등록된 학생이 {courseid}를 POST하면 학생 성적표 UI가 여전히 숨기는 숨겨진 성적 항목의 이름을 얻는다.
| ID | 아직 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 |
| Product | Moodle |
| Affected | 5.2.3 태그 v5.2.3 (344232c15336c71b80f9aca8359ce0e0a9f3d116) |
| Auth | 등록된 학생 (moodle/grade:view; viewall / viewhidden 없음) |
| License | GNU Affero GPL v3.0 |
| Lab | 127.0.0.1 전용 |
작성자: 코스에 등록된 학생. 그들은 {courseid}와 함께 AJAX 서비스를 POST한다. 응답은 이름, ID, 카테고리다. 반환 스키마에는 점수가 없다. RCE가 아니다. LPE도 아니다. 점수 쓰기도 아니다.
| Privilege | Method / sink | Recon / integrity / availability | Lab-proven or inferred |
|---|---|---|---|
| 숨겨진 성적 항목의 이름, id, 카테고리 읽기 | POST /lib/ajax/service.php?sesskey= core_grades_get_gradeitems {courseid} | Recon | Lab-proven. HTTP 200, 이름에 MOODLE-GRADES-GRADEITEMS-WITNESS 포함 |
| 보이는 성적 항목의 이름, id, 카테고리 읽기 | 동일 응답 | Recon (교사용으로 의도됨) | Lab-proven. 이름에 Visible Lab Assignment 포함 |
| 공식 모바일 서비스를 통한 동일 카탈로그 | 동일 클래스, services에 MOODLE_OFFICIAL_MOBILE_SERVICE 포함 | Recon | services.php에서 추론. Lab은 AJAX 사용. |
학생이 입장할 수 있는 코스에 대해 순차적 courseid 값 탐색 | 동일 메서드, 추측한 id | Recon | 추론. Lab은 시드된 코스 id 2 사용 |
| 학생 성적표 UI에서 숨겨진 항목 보기 | GET /grade/report/user/index.php?id= | n/a | Lab-proven closed. hidden-in-ui=False, visible-in-ui=True |
| 세션 없이 호출 | 더미 sesskey로 AJAX | n/a | Lab-proven closed. servicerequireslogin |
| 등록되지 않은 로그인 사용자로 호출 | 외부인 AJAX, 동일 courseid | n/a | Lab-proven closed. requireloginerror |
| 다른 학생의 점수 읽기 또는 성적 쓰기 | n/a | n/a | Closed. 반환 키는 id, itemname, category |
| PHP RCE / OS LPE | n/a | n/a | Closed. 이 잔여물은 카탈로그 읽기다 |
이미 moodle/grade:viewall을 가진 교사나 관리자는 이미 카탈로그를 본다. 게스트 / 비인증 호출자는 여전히 코스 컨텍스트가 필요하다.
동일 핀 잔여물: Blackboard img 파일 읽기, enrol_database SQLi, grades feedback IDOR.
MSA-26-0042/0043 이후 moodle/moodle v5.2.3을 핀했다. 성적 웹 서비스가 그 MSA 윈도우에 있었다. get_gradeitems.php에는 여전히 require_capability가 없다. 학생 UI는 이미 항목을 숨겼다. AJAX 카탈로그는 그렇지 않았다.
이미 기록된 잘못된 방향: 비인증 AJAX 200을 유출로 취급(본문은 servicerequireslogin); 메서드 이름에 grade가 있다고 점수 IDOR로 부르기(스키마는 이름만); get_grade_tree가 같은 잔여물일 것이라 기대(이미 viewall을 요구함). 리버스 셸. 연극.
php:8.3-apache + MariaDB 11.4에서 라이브 Moodle v5.2.3. 시드는 labstudent를 등록하고, laboutsider를 코스에서 제외하며, 보이는 수동 항목과 이름이 witness인 숨겨진 항목을 생성한다. run.sh는 로컬 핀을 복사하거나 git clone --depth 1 --branch v5.2.3을 실행한다. Moodle 트리는 이 팩에 없다.
python3 moodle-grades-gradeitems-Abraxas-Labs.py
또는
cd lab
./run.sh
오직 http://127.0.0.1:19590만 대상으로 한다. Compose 프로젝트 moodle-grades-gradeitems. 실행 후 스택은 해체된다.
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
validate_context 이후, get_grade_tree와 동일한 cap을 요구하라: require_capability('moodle/grade:viewall', $context). 또한 호출자에게 moodle/grade:viewhidden이 없으면 숨겨진 항목을 제거하라. Behat/PHPUnit 케이스를 추가하라: 등록된 학생, 숨겨진 수동 항목, core_grades_get_gradeitems는 그 항목을 생략해야 한다(또는 403). 학생 성적표 UI는 이미 그것을 숨긴다.
get_gradeitems.phpget_grade_tree.phpservices.php (core_grades_get_gradeitems, capabilities 없음)GNU Affero GPL v3.0. LICENSE 참조. 루프백 랩 전용. 보증 없음.