有这么一个场景:
漏扫发现一些mysql的漏洞, 有server层的, 也有驱动层的. server层升级成本太高, 周期较长. 故可以先处理一下驱动相关的漏洞. 比如存在这么一个漏洞:CVE-2025-21548
这个漏洞影响驱动版本小于等于 9.1.0的, 造成的影响是DOS. 具体咋个实现的,咱也不需要知道, 我们只需要找到有这个漏洞的客户端并做好相关处理即可.
我们要查找客户端的驱动版本, 大概有如下3条路可选:
前两者不太容易走, 我们就选择最后一条(作为一个DBA,自个在服务端查找客户端驱动版本信息还不是手到擒来,前提是有这么个信息).
回顾下以前的mysql连接相关知识:
我们知道 客户端发送的账号密码相关信息是在 HandshakeResponse 包里面. 该包信息如下:
对象 | 大小(字节) | 描述 |
---|---|---|
client_flag | 4 | 客户端的capability_flags |
max_packet_size | 4 | 最大包大小,默认16MB |
character_set | 1 | 客户端的字符集(collate) |
filler | 23 | 填充0x00*23 (凑满32字节..) |
username | 0x00结尾 | 客户端登录的用户名 |
auth_response_length | 1 | 加密密码长度(要求client_flag不含CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA ) |
auth_response | auth_response_length | 加密的密码(这里只看mysql_native_password的情况) |
database | 0x00结尾 | 数据库名字(要求client_flag含CLIENT_CONNECT_WITH_DB ) |
client_plugin_name | 0x00结尾 | 密码加密插件名字 |
attrs | 一些自定义属性,json格式的(要求CLIENT_CONNECT_ATTRS ) |
最后一个attrs 看起来比较像包含我们需要的信息, 我们查看它包含的场景信息如下:
_pid, _platform, _os, _client_name, os_user, _client_version, cprogram_name
唉, 不是有个_client_version么, 这个应该就是了. 我们再抓包看下
果然这个就是驱动的版本信息, 既然我们已经发送驱动版本信息给server端了, 那server是保存在哪的呢?
既然这个字段是关于属性的, 那大概率相关的表/字段也和attr相关. 我们使用如下SQL查找相关表
select TABLE_SCHEMA,TABLE_NAME,COLUMN_NAME from information_schema.columns where (table_name like '%%attr%' or column_name like '%attr%') and table_schema in ('sys','mysql','performance_schema','information_schema');
果然找到了performance_schema.session_connect_attrs
和performance_schema.session_account_connect_attrs
比较复合我们预期.
查阅官网, 发现前者更符合我们的期望. 查看该表信息:
(root@127.0.0.1) [(none)]> select * from performance_schema.session_connect_attrs;
+----------------+--------------------+------------------------+------------------+
| PROCESSLIST_ID | ATTR_NAME | ATTR_VALUE | ORDINAL_POSITION |
+----------------+--------------------+------------------------+------------------+
| 17 | _pid | 13371 | 0 |
| 17 | _platform | x86_64 | 1 |
| 17 | _os | Linux | 2 |
| 17 | _client_name | libmysql | 3 |
| 17 | os_user | root | 4 |
| 17 | _client_version | 8.0.28 | 5 |
| 17 | program_name | mysql | 6 |
| 23 | _pid | 15571 | 0 |
| 23 | _platform | x86_64 | 1 |
| 23 | _client_version | 8.0.28 | 2 |
| 23 | _os | Linux | 3 |
| 23 | _client_name | libmysql | 4 |
| 23 | _source_host | ddcw21 | 5 |
| 23 | _connector_version | 8.0.28 | 6 |
| 23 | _connector_license | GPL-2.0 | 7 |
| 23 | _connector_name | mysql-connector-python | 8 |
+----------------+--------------------+------------------------+------------------+
客户端驱动版本信息这不就来了么, 还有processlist_id, 我们稍微关联下表就能 查询到 驱动版本低于9.1.0的连接了.
select a.id,a.user,a.host,a.db,b.ATTR_NAME,b.ATTR_VALUE,b.ORDINAL_POSITION from information_schema.processlist as a left join (select * from performance_schema.session_connect_attrs where ATTR_NAME='_connector_version' and ATTR_VALUE <= '9.1.0' and PROCESSLIST_ID in (select PROCESSLIST_ID from performance_schema.session_connect_attrs where ATTR_NAME='_connector_name' and ATTR_VALUE='mysql-connector-python')) as b on a.id=b.processlist_id where b.ATTR_NAME is not null;
吼吼, 我们找到了客户端的驱动版本信息, 那问题又来了, 怎么修复呢?
我这里只考虑了python版的驱动 ATTR_VALUE='mysql-connector-python' 实际使用时,根据自己情况来调整.
要处理这个漏洞的话, 最稳妥的方法就是老老实实的升级, 但我是谁啊, 能老实吗? 或者修改驱动版本信息
升级的话, 周期太长, 而且还可能存在兼容性问题. 所以我们选择后者, 修改驱动包的版本信息... 以python版的驱动mysql-connector-python为例. 我们只需要编辑文件mysql/connector/version.py
修改里面的版本信息如下:
VERSION = (9, 9, 99, '', 1)
然后重启应用(不管选哪种都涉及到应用重启)再次查看, 发现驱动版本已更新(新得不得了)
这下看它还能不能扫出漏洞 -_-
这种影响不大的漏洞, 通常不需要管, 非要管的话, 注意做好相关测试, 尤其是兼容性(稳定性可能不好测). 如果不能升级,又想解决漏洞的话, 就只有修改客户端服务端的版本了(前提是数据库服务器一定得在内网, 应用账号的权限也要最小化控制).(屏蔽漏扫也是不错的选择)
本文涉及到的知识和脚本都是之前的内容, 有兴趣的可以自己去翻一翻以前的文章.
参考:
https://www.cve.org/CVERecord?id=CVE-2025-21548
https://www.oracle.com/security-alerts/cpujan2025.html
https://dev.mysql.com/doc/refman/8.0/en/performance-schema-session-account-connect-attrs-table.html
https://dev.mysql.com/doc/refman/8.0/en/performance-schema-session-connect-attrs-table.html
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。