
MySQL Community Server 26.7.0 - 高 - SET ROLE ALL EXCEPT leftover FILE - mysqld UID write
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · mysql-set-role-leftover
クラス: 権限の残留 (mysqld UID としての FILE、OS LPE ではない) 到達範囲: リモート
MySQL Community Server mysqld 26.7.0 (06a5c1c) - Oracle
SET ROLE ALL EXCEPT rfile (またはデフォルトロールが存在しない状態での SET ROLE DEFAULT) はアクティブロールのリストをクリアし、その後 checkout_access_maps() が set_master_access(user->access) を呼ばずに戻る。CURRENT_ROLE() は NONE となる。ロールが集約した静的なグローバルビット (FILE、PROCESS、SUPER など) は m_master_access に残る。check_access はその残留を読み取る。ラボ: 残留した FILE が mysqld UID として INTO OUTFILE を書き込む。
SET ROLE NONE は ACL_USER::access を復元するパスである。動的権限 (SYSTEM_USER) は失われる。DB レベルの残留はすでに修正済み (Bug#35386565)。デフォルトアカウントにはロールがない。
| ID | CVE 未割り当て |
| クラス | 権限の残留 (mysqld UID としての FILE、OS LPE ではない) |
| 到達範囲 | リモート (認証済み SQL) |
| CWE | CWE-269 |
| CVSS | High: 8.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N |
| 製品 | MySQL Community Server mysqld |
| 影響を受けるバージョン | 26.7.0 (06a5c1c99c377fc41b2eba1ea244e8b220bdc3c8) |
| 認証 | 認証済み。被害者は静的なグローバル ACL を持つロール (ラボでは FILE) を付与されている |
| ライセンス | GNU Affero GPL v3.0 |
| ラボ | 127.0.0.1 のみ。証拠ファイル。残留 FILE 書き込み。 |
FILE (または他の静的なグローバルビット) を持つロールを付与されたアカウントを保持する。そのロールに SET ROLE し、その後 SET ROLE ALL EXCEPT でそれを除外する。CURRENT_ROLE() は NONE を報告する。SELECT 'witness' INTO OUTFILE は依然として secure_file_priv 配下で mysqld UID として書き込む。
SET ROLE ALL EXCEPT dangerous_role や SET ROLE DEFAULT でサンドボックス化し、その後 CURRENT_ROLE() を信頼するアプリケーションは、依然としてそれらの静的ビットを持っている。SET ROLE NONE は実際にそれらを失わせる。
この残留は、アカウントがロールを通じて一度も持ったことのない FILE を付与するものではない。非アクティブ化後に FILE を失わせることに失敗しているのである。
3 つのクライアント残留と同じ 26.7.0 の調査。デフォルトデーモンの未公開 Crit/High は空だった。ACL / ロールには依然としてこの空ロールの早期リターンが残っていた。
void Security_context::checkout_access_maps(void) {
if (m_acl_map != nullptr) {
get_global_acl_cache()->return_acl_map(m_acl_map);
m_acl_map = nullptr;
}
if (m_active_roles.size() == 0) return;
// ...
}
activate_role_all (ALL EXCEPT) と空の activate_role_default がその checkout を呼び出す。その後 activate_role_none が set_master_access(user->access) を行う。
すでに記録済みの誤った道: 最初の残留 SELECT note FROM lab.t INTO OUTFILE は 1142 を返した (db_acl() キャッシュ 0)。定数の SELECT 'witness' INTO OUTFILE が FILE のオラクルである。
cd lab
./run.sh
イメージ mysql:26.7.0。公開 127.0.0.1:18630。ロール rfile は FILE を持つ。被害者は GRANT SELECT ON lab.* と GRANT rfile を持ち、file_priv=N、デフォルトロールなし。ログイン時の outfile は 1227。SET ROLE rfile で outfile は成功。SET ROLE ALL EXCEPT rfile で CURRENT_ROLE() は NONE となり、残留 outfile が /var/lib/mysql-files/MYSQL-SET-ROLE-LEFTOVER-WITNESS を書き込む。SET ROLE NONE で再び 1227。
SUCCESS mysql-set-role-leftover before-file=denied with-role=yes leftover-role=NONE leftover-file=yes after-none=denied dump=26.7.0 image=mysql:26.7.0 MYSQL-SET-ROLE-LEFTOVER-WITNESS
m_active_roles が空の場合、checkout_access_maps() は SET ROLE NONE がすでに行っているように set_master_access(user->access) を行うべきである。空の ALL EXCEPT / DEFAULT は以前の集約マップを保持すべきではない。
06a5c1c99c377fc41b2eba1ea244e8b220bdc3c8)sql/auth/sql_security_ctx.cc checkout_access_mapssql/auth/roles.cc activate_role_all / activate_role_none