
MySQL Community Server 26.7.0 — высокий — SET ROLE ALL EXCEPT оставшийся FILE — запись от UID mysqld
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · mysql-set-role-leftover
Класс: Остаточные привилегии (FILE от имени UID mysqld; не 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 записывает INTO OUTFILE от имени UID mysqld.
SET ROLE NONE — это путь, который восстанавливает ACL_USER::access. Динамические привилегии (SYSTEM_USER) сбрасываются. Остаток на уровне БД уже закрыт (Bug#35386565). У учётных записей по умолчанию ролей нет.
| ID | CVE пока нет |
| Класс | Остаточные привилегии (FILE от имени UID mysqld; не 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 всё ещё записывает от имени UID mysqld в пределах secure_file_priv.
Приложение, которое изолирует через SET ROLE ALL EXCEPT dangerous_role или SET ROLE DEFAULT, а затем доверяет CURRENT_ROLE(), всё ещё обладает этими статическими битами. SET ROLE NONE действительно их сбрасывает.
Остаток не предоставляет FILE учётной записи, которая никогда не получала его через роль. Он не сбрасывает FILE после деактивации.
Та же охота на 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 ok. 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_master_access(user->access) так же, как это уже делает SET ROLE NONE. Пустой ALL EXCEPT / DEFAULT не должен сохранять предыдущую агрегированную карту.
06a5c1c99c377fc41b2eba1ea244e8b220bdc3c8)sql/auth/sql_security_ctx.cc checkout_access_mapssql/auth/roles.cc activate_role_all / activate_role_none