freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

等保测评2.0:MySQL身份鉴别(上)
2020-02-27 08:00:17

一、 说明

本篇文章主要说一下MySQL数据中身份鉴别控制点中a测评项的相关知识点和理解。

二、 MySQL用户

2.1. 用户身份标识

MySQL数据库对于用户的标识和其它数据库有些不一样,不仅仅是用户名,而是username + host。

MySQL数据中user表的一部分字段如下:

这三个用户的用户名虽然都是root,但其实是三个不同的用户,其密码也是单独设置的。

查询当前登录账户,也可以看到用户的标识组成为username+host:

2.2. 登录匹配机制

既然用户的标示是两个字段的组合,匹配的时候也要这两个字段都匹配上了才行,这里我简单的说一说(根据官方文档)。

当客户端对MySQL发起连接后,MySQL会先对user表进行排序,然后从第一行开始,逐行与传入的host、username进行匹配,当匹配到了某一行之后,就不往下继续匹配了。(如果任何一行都无法匹配,则登录失败)

此时,再来对比传入的口令和存储的口令是否一致,如果口令一致,那么该行即为这次登陆后所使用的行(用户身份)。

如果不一致,则登录失败。

举个例子,如果用户表如下所示:

那么当验证时,会首先对其进行排序,排序如下:

注意,Host字段可以使用匹配符%,%则代表匹配任何Ip地址。另外,空字符串也代表匹配任何Ip地址。

而User字段不使用匹配符%,但是如果为空字符串,则代表匹配任何用户名。

MySQL排序时是先对Host进行排序,然后才是User。

Host的排序为明确的值排在前面,比如文字主机名和IP地址即为明确的地址值,所以%和空字符串排在它们之后,其中空字符串又排在%之后。

当Host字段向同时,则对User字段进行排序,对于User字段也是明确的值排在前面,所以在排序结果图中,root@localhost排在了@localhost(空字符串用户名)的前面。

如果Host字段和User字段都一样,那么排序的顺序是不确定的(可能和创建该用户的先后有关)。

所以客户端连接MySQL数据库时,使用给定的用户名,不一定会以该用户名的身份登入数据库。

比如使用用户名jeffrey和它的口令,在本地的mysql中进行登录时,会按照排序结果图中,一行行的去匹配:

对于第一行,客户端的Host(localhost或者127.0.0.1)可以和Host字段的localhost匹配上,但是User不一样,无法完全匹配,所以往下走。

对于第二行,客户端的Host(localhost或者127.0.0.1)可以和Host字段的localhost匹配上,而第二行的用户名是空字符串,可以匹配任何用户名,所以也能匹配jeffrey,如果口令一致,则完成了匹配,到此匹配过程结束。

这样,虽然使用了用户名jeffrey,但最后却会以@localhost的身份登入数据库。

最后,User表的口令字段可以为空字符串,这代表口令为空字符串,而不是与任何口令都匹配。

2.3. 查询当前用户

MySQL中存在user()函数和current_user()函数。

user()函数会显示你当前的登录用户具体是使用了什么用户名和什么ip地址去进行登录的。(注,ip地址是指连接数据库的客户端的ip地址,不是自己设置的值)

例子如下:

这里代表在ip地址为192.168.203.132的客户端上,使用用户名test对MySQL数据库进行了连接。

current_user()函数会显示你最终使用的用户身份(也就是最后匹配到的那一行),例子如下:

也就是,最后在User表中匹配到了Host字段为192.168.%.%、User字段为test的那一行,以test@192.168..%.%的用户身份登录了MySQL数据库。

2.4. 口令字段

在MySQL5.7之前,User表中的口令字段为Password,从MySQL5.7开始,口令字段变成了authentication_string。

不过在MySQL5.7之前,比如MySQL5.5.53,也存在着authentication_string字段,不知道其用途是什么。

三、测评项a

a)应对登录的用户进行身份标识和鉴别,身份标识具有唯一性,身份鉴别信息具有复杂度要求并定期更换;

3.1. 测评项要求1

应对登录的用户进行身份标识和鉴别

对于MySQL来说,如上文所言,用户的身份标识为username + host,鉴别就是通过username + host + password来进行登录验证。

所以,对于这个要求,就是不能出现空用户名、空密码、任意host的用户,也就是鉴别的因素三者同时皆空。

其中任何一个不为空或%(对Host而言),则都算实现了鉴别(部分鉴别)。

3.2. 测评项要求2

身份标识具有唯一性

对于MySQL来说,如上文所言,用户的身份标识为username + host,MySQL并没有禁止出现完全一样的username + host行,所以这里是可能出现身份标识不唯一的情况的。

在安装MySQL完成后,会存在3个默认账户,如下:

这三个用户的User都是root,虽然Host看上去不一样,实际上也都是本机地址。

127.0.0.1就是本地的ip地址,localhost则是在hosts文件里(linux系统中)和ip地址进行了映射,其实映射的还是127.0.0.1地址,至于::1应该是ipv6格式的本机地址。

::1这个我不知道要如何才能连上,当用户名为root的行只剩下host值为::1的行的时候,使用用户名root怎么连都不可能连上。

对于127.0.0.1和localhost,在windows系统上没啥区别,登录时其排序是不确定的(对于这种,应该是谁先创建谁在前)。

对于127.0.0.1和localhost,好像在linux上有一点区别:MySQL主机127.0.0.1与localhost区别总结

从正常的业务需求来说,明显这三个用户的身份标识是不唯一的,应该删掉::1和另外一个。

3.3. 测评项要求3

身份鉴别信息具有复杂度要求

这个要从两个方面看,我个人觉得两个方面都符合才能算达到要求。

第一个方面即实际的口令是否具有一定的复杂度,也即口令至少8位,且包含大写字母、小写字母、数字、特殊字符这四类字符种的三种,且口令不包含简单排列规律,如admin!@#123此类弱口令。

第二个方面即MySQL是否进行了口令复杂度策略的设置,强制要求口令具有一定的复杂度,也即在MySQL中使用了validate_password插件。

这时候,可以用以下命令查看该插件的相关参数:

为了达到要求,参数需要进行设置(初级教程):

各个参数的代表的意思:mysql之validate_password_policy

他这里说得挺详细的,我这里就不写了。

3.4. 测评项要求4

要求并定期更换

和口令复杂度一样,一个方面是看实际的口令更换周期,这里可以通过访谈相关人员来得知,也可以通过查看user表中的password_last_changed字段(注意,只有高于某个版本的MySQL才有这个字段)。

而MySQL中的口令更换策略,则和版本有一些关系。

从MySQL5.6.6开始,User表中多了一个password_expired字段,默认值是N,当设置为Y后,则这个用户还是可以登陆到MySQL服务器,但是在用户未设置新密码之前不能运行任何查询语句,而且会得到如下错误消息提示:

mysql> SHOW DATABASES;

ERROR 1820 (HY000): You must SET PASSWORD before executing this statement

Keep in mind that this does not affect any current connections the account has open.

所以对于这个版本,定期修改口令的策略需要通过定时器任务等方式来实现了。

而从5.7.4这个版本开始,MySQL多了一个全局变量default_password_lifetime:

并且在User字段表中增加了两个字段:password_lifetime、password_last_changed:

给大家解释一下,首先无论是全局变量default_password_lifetime还是User表中的字段password_lifetime,它们的单位都是天。

当password_lifetime为null的时候,则代表该用户当前口令的有效期使用的是全局变量default_password_lifetime的值。

当password_lifetime为一个具体的值的时候,则代表该用户当前口令的有效期不使用全局变量default_password_lifetime的值,使用的是字段password_lifetime的值。

对于default_password_lifetime和password_lifetime而言,值为0则代表有效期为永远。

另外,mysql-5.7.4 ~ mysql-5.7.10 这些版本中default_password_lifetime的默认值是360,从mysql-5.7.11开始,default_password_lifetime这个参数的默认值为0。

关于口令过期的具体内容,可以看:mysql-5.7 密码过期详解Mysql5.7.9密码已过有效期的处理过程 ,说得挺清楚的。

*本文原创作者:起于凡而非于凡 ,本文属于FreeBuf原创奖励计划,未经许可禁止转载

# 等保测评2.0 # MySQL身份鉴别
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者