
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 전용. Witness 파일. 잔존 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을 제거하지 못할 뿐입니다.
세 가지 클라이언트 잔존과 동일한 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 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