Moodle 5.2.3 — высокий уровень — удалённо — SQLi — enrol_database объединяет idnumber курса в SQL
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · moodle-enrol-database-sqli
Moodle LMS 5.2.3 - Moodle
Класс: SQLi Доступ: Удалённый
enrol_database::db_get_sql по-прежнему экранирует слэшами и конкатенирует. MSA-26-0005 / MDL-88138 параметризовал auth_db как Execute($sql, [$value]). Этот плагин не скопировал такую форму. Значения по умолчанию в настройках: dbsybasequoting=0, localcoursefield=idnumber. Точка сброса — внешняя база данных зачисления. Ядро Moodle $DB на этом пути не задействовано.
Преподаватель с правом редактирования на сайте с включённым enrol_database задаёт idnumber курса. Cron интерполирует его. Из базы зачисления возвращаются лишние строки.
| ID | CVE пока нет |
| CWE | CWE-89 |
| CVSS | High: 8.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N |
| Продукт | Moodle |
| Затронуто | тег 5.2.3 v5.2.3 (344232c15336c71b80f9aca8359ce0e0a9f3d116). Плагин enrol_database должен быть включён. |
| Аутентификация | преподаватель с правом редактирования (idnumber курса, локальное сопоставление по умолчанию) |
| Лицензия | GNU Affero GPL v3.0 |
| Лаборатория | только 127.0.0.1 |
Преподаватель с правом редактирования на сайте с включённым enrol_database внедряет SQL во внешнюю базу данных зачисления, задавая idnumber курса. Затем cron sync_enrolments выполняет этот SQL.
| Привилегия | Метод / точка сброса | Разведка / целостность / доступность | Доказано в лаборатории или предположено |
|---|---|---|---|
| Вставить SQL-фрагмент во внешний SELECT зачисления | Cron sync_enrolments -> db_get_sql($table, array($coursefield=>$course->mapping), ...) -> $extdb->Execute($sql) | Целостность строки запроса | Доказано в лаборатории. Конкатенированный SQL: WHERE courseid = 'LABCOURSE\'' OR 1=1 -- ' |
| Прочитать строки зачисления других курсов во внешней БД | Тот же SELECT после закрытия строки | Разведка | Доказано в лаборатории. Чисто: 1 строка teacher-local. Инъекция: 2 строки, включая MOODLE-ENROL-DATABASE-SQLI-WITNESS |
| Пропустить запрос, когда плагин выключен | Тот же гаджет, plugin=off | н/д | Доказано в лаборатории закрыто. executed=false, пустой SQL, 0 строк |
| Передать ту же полезную нагрузку как связанный параметр | Остаток auth_db от MSA-26-0005: Execute($sql, [$value]) | н/д | Доказано в лаборатории закрыто. style=param вернул 0 строк, SQL содержит ? |
| Зачислить / отчислить / назначить роли пользователям Moodle, указанным в лишних строках | После того как cron применит requestedenrols | Целостность зачислений | Предположено. Лаборатория останавливается на лишних строках в базе зачисления |
| FILE / INTO OUTFILE от имени пользователя базы зачисления | Та же точка сброса, если у этой учётной записи есть FILE | Целостность / доступность этого хоста БД | Предположено. Не продемонстрировано. Не OS LPE |
| Путь, контролируемый студентом | Только если администратор сопоставит localuserfield=email (или аналогично) | н/д | Предположено. Путь по умолчанию — idnumber преподавателя |
Закрыто на этом остатке: ядро Moodle $DB; плагин отключён (нет запроса); неаутентифицированный доступ; оболочка ОС; составные запросы (этот гаджет mysqli — одиночный оператор). Moodle по умолчанию без enrol_database — это не данный баг.
Другие остатки того же пина: чтение файла img Blackboard, IDOR обратной связи оценок, скрытые элементы оценок.
Я зафиксировал moodle/moodle v5.2.3 после MSA-26-0042/0043. MSA-26-0005 закрыл auth_db с помощью плейсхолдера. Я открыл enrol_database, потому что он общается с таким же типом внешней БД и всё ещё содержит db_addslashes.
dbsybasequoting по умолчанию равен 0, поэтому удваивается только '. Обратный слэш перед кавычкой в idnumber закрывает строку MySQL.
Уже зафиксированные неверные пути: считать точкой сброса ядро Moodle $DB (это не так); называть это OS LPE, потому что FILE существует как привилегия MySQL (не продемонстрировано, не этот остаток); email студента как сопоставление по умолчанию (администратор должен изменить localuserfield). Обратная оболочка. Театр.
Точный гаджет сборщиков пина, а не полноценное PHP-приложение Moodle. php:8.3-cli обслуживает скопированные db_get_sql / db_addslashes / db_encode. mysql:8.0 содержит две строки зачисления.
python3 moodle-enrol-database-sqli-Abraxas-Labs.py
или
cd lab
./run.sh
Цель только http://127.0.0.1:19570. Проект Compose moodle-enrol-database-sqli. Стек разбирается после запуска.
SUCCESS moodle-enrol-database-sqli how=gadget plugin-off=no-query clean-rows=1 inject-rows=2 sql-concat=yes param-rows=0 extra=yes sink=enrol-db MOODLE-ENROL-DATABASE-SQLI-WITNESS
Скопируйте параметризованные запросы из auth_db (MDL-88138). Передавайте сопоставленное значение курса / пользователя как Execute($sql, [$value]). Не конкатенируйте db_addslashes в '$value'. Добавьте тест, что кавычка в idnumber курса не возвращает строки из других курсов.
lib.php (db_get_sql, db_addslashes, sync_enrolments)auth_dbGNU Affero GPL v3.0. См. LICENSE. Только лаборатория на loopback. Без гарантий.