应检查mysql.user、mysql.db、mysql.procs_priv等表及角色权限,用SHOW GRANTS逐个验证,因Super_priv字段不实时、权限可分散或间接继承。

查哪些用户有 SUPER 或 ALL PRIVILEGES 权限
MySQL 中“最高权限”没有官方定义,但实际运维中通常指能执行 SUPER(如 kill 线程、修改全局变量)、GRANT OPTION(授予权限给他人)或 ALL PRIVILEGES ON *.* 的用户。仅看 user 表里的 Super_priv 字段是不够的——因为权限可能分散在 mysql.db、mysql.tables_priv 等表,也可能通过角色(MySQL 8.0+)间接获得。
- 先快速筛出显式拥有全局超级权限的账号:
SELECT user, host FROM mysql.user WHERE Super_priv = 'Y' OR Grant_priv = 'Y' OR (Select_priv = 'Y' AND Insert_priv = 'Y' AND Update_priv = 'Y' AND Delete_priv = 'Y' AND Create_priv = 'Y' AND Drop_priv = 'Y');
- 再检查是否有人被授予了
ALL PRIVILEGES ON *.*(比字段更准):SELECT DISTINCT User, Host FROM mysql.user u JOIN mysql.procs_priv p ON u.User = p.User AND u.Host = p.Host WHERE p.Grant_priv = 'Y' AND p.Proc_priv LIKE '%Execute%';
—— 这类语句不全,真正可靠的方式是用SHOW GRANTS逐个查,但批量检测只能靠解析mysql.user+mysql.db的组合逻辑 - MySQL 8.0+ 用户还可能通过角色获得高权限:
SELECT r.role, r.host, u.user, u.host FROM mysql.role_edges r JOIN mysql.user u ON r.from_host = u.host AND r.from_user = u.user;
然后对每个role再查SHOW GRANTS FOR 'role_name'@'%'
为什么不能只查 SELECT * FROM mysql.user WHERE user = 'root'
很多环境里 root 账号早已被禁用或限制为 localhost,而真正拥有高权限的是类似 'admin'@'%'、'dba'@'192.168.%' 甚至 'monitor'@'%' WITH GRANT OPTION 这样的账号。更危险的是:有些账号看似权限字段全为 N,却在 mysql.db 表中对 mysql 库有 Create_priv='Y',配合 INSERT 就能往 user 表写新 root。
-
mysql.user表只存全局权限,不反映库/表级授权叠加效果 - 字段值(如
Super_priv)不会自动同步更新——比如你用GRANT SUPER ON *.* TO ...后没FLUSH PRIVILEGES,字段仍显示N,但权限已生效 - MySQL 5.7 及以前版本,
password字段存在,但 5.7+ 改用authentication_string;直接SELECT * FROM mysql.user容易漏看关键字段
用 SHOW GRANTS 逐个验证才靠谱
字段和表只是快照,SHOW GRANTS 是 MySQL 实际校验权限时的真实依据,也是唯一能暴露隐式权限(如通过角色继承、列级权限组合)的方法。
- 列出所有非空账号并生成检查命令:
SELECT CONCAT('SHOW GRANTS FOR ''', user, '''@''', host, ''';') AS cmd FROM mysql.user WHERE user != '';把结果复制进客户端执行 - 重点关注输出里是否含:
GRANT ALL PRIVILEGES ON *.*、WITH GRANT OPTION、GRANT PROXY ON、GRANT ROLE(8.0+) - 遇到
ERROR 1141 (42000)不代表账号不存在,可能是你当前用户没权限查它——换root或带SELECT权限的账号重试
容易被忽略的权限逃逸点
有些账号表面权限很低,但配合特定操作可提权。例如:
-
FILE权限 + 可写目录 → 用SELECT ... INTO OUTFILE写 shell 或覆盖配置文件 -
CREATE ROUTINE+EXECUTE→ 创建函数调用系统命令(需secure_file_priv配合) -
PROCESS权限 → 能看到其他用户明文 SQL,包括SET PASSWORD或连接字符串 - MySQL 8.0 默认启用
caching_sha2_password插件,但若账号仍用mysql_native_password认证,且密码强度弱,远程爆破风险更高——这不算“权限”,却是 root 检测方案必须联动的安全上下文
检测 root 级账号不是查一个字段的事,得把 user 表、db 表、procs_priv 表、角色关系、认证插件、甚至 secure_file_priv 配置全串起来看。漏掉任意一环,都可能把真凶当成普通用户。


















