freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

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

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

FreeBuf+小程序

FreeBuf+小程序

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

等保测评2.0:MySQL身份鉴别(上)
起于凡而非于凡 2020-02-27 08:00:17 1079247

一、 说明

本篇文章主要说一下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 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
等级保护2.0
起于凡而非于凡 LV.6
VX群聊:qiuri_1 | QQ群:950055640
  • 42 文章数
  • 970 关注者
等保测评2.0:Windows访问控制结果记录描述
2021-03-05
等保测评2.0:Windows身份鉴别结果记录描述(下)
2021-02-21
先导篇之等级保护系列文章介绍
2020-10-12
文章目录