
Moodle 5.2.3 - 높음 - 원격 - IDOR - core_grades_get_gradeitems가 숨겨진 성적 항목을 나열함
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · moodle-grades-gradeitems
분석 문서: https://abraxaslabs.tech/research/moodle-grades-gradeitems
Moodle LMS 5.2.3 - Moodle
분류: IDOR 도달 범위: 원격
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 | 중간: 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) |
| 인증 | 등록된 학생 (moodle/grade:view; viewall / viewhidden 없음) |
| 라이선스 | GNU Affero GPL v3.0 |
| 실습 환경 | 127.0.0.1 전용 |
작성자: 해당 코스에 등록된 학생. {courseid}와 함께 AJAX 서비스를 POST합니다. 응답은 이름, ID, 카테고리입니다. 반환 스키마에는 점수가 없습니다. RCE가 아닙니다. LPE가 아닙니다. 점수 쓰기도 아닙니다.
| 권한 | 메서드 / 싱크 | 정찰 / 무결성 / 가용성 | 실습 입증 또는 추론 |
|---|---|---|---|
| 숨김 성적 항목의 이름, id, 카테고리 읽기 | POST /lib/ajax/service.php?sesskey= core_grades_get_gradeitems {courseid} | 정찰 | 실습 입증. HTTP 200, 이름에 MOODLE-GRADES-GRADEITEMS-WITNESS 포함 |
| 표시되는 성적 항목의 이름, id, 카테고리 읽기 | 동일 응답 | 정찰 (교사용으로 의도됨) | 실습 입증. 이름에 Visible Lab Assignment 포함 |
| 공식 모바일 서비스를 통한 동일 카탈로그 | 동일 클래스, services에 MOODLE_OFFICIAL_MOBILE_SERVICE 포함 | 정찰 | services.php에서 추론. 실습은 AJAX 사용. |
학생이 입장할 수 있는 코스에 대해 순차적 courseid 값 탐색 | 동일 메서드, id 추측 | 정찰 | 추론. 실습은 시드된 코스 id 2 사용 |
| 학생 성적표 UI에서 숨김 항목 보기 | GET /grade/report/user/index.php?id= | 해당 없음 | 실습 입증 차단됨. hidden-in-ui=False, visible-in-ui=True |
| 세션 없이 호출 | 더미 sesskey로 AJAX | 해당 없음 | 실습 입증 차단됨. servicerequireslogin |
| 등록되지 않은 로그인 사용자로 호출 | 외부인 AJAX, 동일 courseid | 해당 없음 | 실습 입증 차단됨. requireloginerror |
| 다른 학생의 점수 읽기 또는 성적 쓰기 | 해당 없음 | 해당 없음 | 차단됨. 반환 키는 id, itemname, category |
| PHP RCE / OS LPE | 해당 없음 | 해당 없음 | 차단됨. 이 잔여 취약점은 카탈로그 읽기임 |
이미 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는 코스에서 제외하며, 눈에 보이는 수동 항목과 이름이 증거인 숨겨진 항목을 생성한다. 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와 동일한 권한 제한을 요구합니다: 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를 참조하세요. 루프백 실습 환경 전용. 보증 없음.