
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
Class: SQLi Reach: Remote
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 がそれを補間する。余分な行が登録 DB から返ってくる。
| 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 |
| Product | Moodle |
| Affected | 5.2.3 タグ v5.2.3 (344232c15336c71b80f9aca8359ce0e0a9f3d116)。プラグイン enrol_database が有効である必要がある。 |
| Auth | 編集権限を持つ教師 (コース idnumber、デフォルトのローカルマップ) |
| License | GNU Affero GPL v3.0 |
| Lab | 127.0.0.1 のみ |
enrol_database が有効なサイトの編集権限を持つ教師は、コースの idnumber を設定することで外部登録データベースに対して SQL を注入する。その後 Cron sync_enrolments がその SQL を実行する。
| 権限 | メソッド / シンク | 偵察 / 完全性 / 可用性 | ラボ実証または推測 |
|---|---|---|---|
| 外部登録 SELECT に SQL フラグメントを混入させる | Cron sync_enrolments -> db_get_sql($table, array($coursefield=>$course->mapping), ...) -> $extdb->Execute($sql) | クエリ文字列の完全性 | ラボ実証済み。連結 SQL は WHERE courseid = 'LABCOURSE\'' OR 1=1 -- ' |
| その外部 DB 上の他コースの登録行を読み取る | 文字列を閉じた後の同じ SELECT | 偵察 | ラボ実証済み。クリーン: 1 行 teacher-local。注入: MOODLE-ENROL-DATABASE-SQLI-WITNESS を含む 2 行 |
| プラグインがオフのときクエリをスキップする | 同じガジェット、plugin=off | n/a | ラボ実証済み クローズ。executed=false、空の SQL、0 行 |
| 同じペイロードをバインドパラメータとして保持する | MSA-26-0005 の auth_db 残存: Execute($sql, [$value]) | n/a | ラボ実証済み クローズ。style=param は 0 行を返し、SQL には ? が含まれる |
| 余分な行に記載された Moodle ユーザーを登録 / 登録解除 / ロール割り当てする | Cron が requestedenrols を適用した後 | 登録の完全性 | 推測。ラボは登録 DB 上の余分な行で停止する |
| 登録 DB ユーザーとしての FILE / INTO OUTFILE | そのアカウントが FILE を持つ場合の同じシンク | その DB ホストの完全性 / 可用性 | 推測。実証されていない。OS LPE ではない |
| 学生が制御する経路 | 管理者が localuserfield=email (または類似) をマップした場合のみ | n/a | 推測。デフォルト経路は教師の idnumber |
この残存でクローズ: Moodle コア $DB、プラグイン無効 (クエリなし)、未認証アクセス、OS シェル、スタッククエリ (この mysqli ガジェットは単一ステートメント)。enrol_database のないデフォルト Moodle はこのバグではない。
同じピンの残存: Blackboard img ファイル読み取り、grades feedback IDOR、非表示の成績項目。
MSA-26-0042/0043 の後、moodle/moodle v5.2.3 をピン留めした。MSA-26-0005 はプレースホルダで auth_db をクローズした。同じ種類の外部 DB と通信し、依然として db_addslashes を持つため enrol_database を開いた。
dbsybasequoting はデフォルトで 0 なので、' のみが二重化される。idnumber 内のバックスラッシュ-クォートが MySQL 文字列を閉じる。
すでに記録済みの誤った道: Moodle コア $DB をシンクとして扱うこと (そうではない)、FILE が MySQL 権限として存在するためにこれを OS LPE と呼ぶこと (実証されておらず、この残存ではない)、学生メールをデフォルトマップとすること (管理者が localuserfield を変更する必要がある)。リバースシェル。芝居。
ピンビルダーの忠実なガジェットであり、完全な Moodle PHP アプリではない。php:8.3-cli がコピーされた db_get_sql / db_addslashes / db_encode を提供する。mysql:8.0 が 2 つの登録行を保持する。
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 を参照。ループバックラボのみ。無保証。