直接查 mysql.user 表 authentication_string 字段,用 TRIM() 去空格后判断长度为 0 或值为 ''、'*',可快速识别空密码和占位符账号;再对 mysql_native_password 用户筛短哈希(如 '*1'),定位超短原始密码。

直接查 mysql.user 表的 authentication_string 字段,配合长度判断和哈希比对,5 分钟内就能筛出 90% 的弱口令账户——不需要爆破、不依赖工具、不翻日志。
查空密码和占位符账号(最危险的两类)
空密码或未设密码的账号可免密登录,是最高危配置。MySQL 5.7+ 已弃用 password 字段,必须查 authentication_string;但字段值可能被空格填充伪装成“非空”,所以得用 TRIM() 包裹。
-
authentication_string = '':明示空密码,可直连 -
authentication_string = '*':旧版未加密占位符,等效于无密 - 必须用具备
SELECT ON mysql.*权限的账号执行(通常是root)
执行这条语句:
SELECT host, user, plugin, authentication_string FROM mysql.user WHERE LENGTH(TRIM(authentication_string)) = 0 OR authentication_string IN ('', '*');筛短哈希值识别极短原始密码(初筛 mysql_native_password 用户)
MySQL 默认插件 mysql_native_password 下,合法强密码哈希固定为 41 位(如 '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9')。若 authentication_string 长度明显小于 32(比如 '*1'、'*0'),基本可断定原始密码是 ''、'1'、'0' 这类超短口令。
- 仅适用于
plugin = 'mysql_native_password'的用户;caching_sha2_password用户哈希是 72 位 Base64,此法无效 - 先排除
''和'*',再用LENGTH(authentication_string) 筛选,避免误判 - 这不是确证,只是高概率提示,需后续哈希比对确认
执行示例:
SELECT host, user, plugin, authentication_string FROM mysql.user WHERE plugin = 'mysql_native_password' AND LENGTH(authentication_string) < 32 AND authentication_string NOT IN ('', '*');比对预计算哈希值确认常见弱口令(精准命中)
明文虽不可见,但 MySQL 认证插件哈希逻辑确定,可预先生成 '123456'、'password'、'admin' 等常见弱口令的哈希串,做精确匹配。关键前提是:先确认目标用户的 plugin,再用对应哈希值筛查。
-
mysql_native_password下'123456'的哈希是'*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' -
caching_sha2_password下同一明文哈希完全不同(72 位 SHA256 Base64),不能混用 - 生产环境建议禁用
caching_sha2_password的明文传输模式(即关闭caching_sha2_password_auto_generate_rsa_keys=OFF并配 RSA 加密)
执行示例:
SELECT host, user, plugin, authentication_string FROM mysql.user WHERE plugin = 'mysql_native_password' AND authentication_string IN ( '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9', -- 123456 '*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19', -- password '*AAB0484EA8719F782B12F5E181243E343312410A' -- 12345678);
别漏掉“静默弱口令”:结合时间戳与策略字段交叉验证
有些账号哈希看起来正常,但因长期不更新、策略宽松,实际已沦为“静默弱口令”。这类风险不会体现在哈希值上,需从 password_last_changed、password_expired 和 validate_password_policy 交叉验证。
-
password_last_changed超过 180 天未更新,且validate_password_policy = 0(LOW),说明策略形同虚设 -
password_expired = 'Y'但未强制重置,可能被绕过使用旧凭证 - 查策略全局配置:
SHOW VARIABLES LIKE 'validate_password%';,重点看validate_password_policy和validate_password_length
执行示例(查陈旧高危组合):
SELECT host, user, plugin, password_last_changed, password_expired, authentication_string FROM mysql.user WHERE password_last_changed < DATE_SUB(NOW(), INTERVAL 180 DAY) AND (SELECT @@validate_password_policy) = 0;
真正容易被忽略的是:很多 DBA 查完 authentication_string 就以为结束了,却没意识到 password_last_changed 和 validate_password_policy 的组合才是长期风险的温床——它不触发告警,但让任何一次社工或泄露都变成实质威胁。


















