16 | 数据库安全:数据库中的数据是如何被黑客拖取的?
下载APP
关闭
渠道合作
推荐作者
16 | 数据库安全:数据库中的数据是如何被黑客拖取的?
2020-01-17 何为舟 来自北京
《安全攻防技能30讲》
课程介绍
讲述:何为舟
时长13:02大小10.46M
你好,我是何为舟。
说到数据库,你肯定会说:“数据库是我最熟悉的工具了。利用它,我能够设计复杂的表结构、写出炫酷的 SQL 语句、优化高并发场景下的读写性能。”当然,我们的日常工作离不开数据库的使用。而且,数据库中储存的大量机密信息,对于公司和用户都至关重要。
那关于数据库的安全你知道多少呢?你知道数据库是如何进行认证的吗?使用数据库交换数据的过程是安全的吗?假如黑客连入了数据库,又会发生什么呢?
今天,我就以两种比较常见的数据库 Redis 和 MySQL 为例,来和你一起探讨数据库的安全。
Redis 安全
我们首先来看 Redis。我们都知道,Redis 是一个高性能的 KV 结构的数据库。Redis 的设计初衷是在可信的环境中,提供高性能的数据库服务。因此,Redis 在设计上没有过多地考虑安全性,甚至可以说它刻意地牺牲了一定的安全性,来获取更高的性能。
那在安全性不高的情况下,黑客连入 Redis 能做什么呢?最直接的,黑客能够任意修改 Redis 中的数据。比如,通过一个简单 FLUSHALL 命令,黑客就能够清空整个 Redis 的数据了。
复杂一些的,黑客还可以发起权限提升,通过 Redis 在服务器上执行命令,从而控制整个服务器。但是,Redis 本身不提供执行命令的功能,那么黑客是如何让 Redis 执行命令的呢?我们一起来看一下具体的代码流程。
针对这个过程,我来详细解释一下,你可以结合代码来看。
黑客连入 Redis。
黑客写入一个任意的 Key,对应的 Value 是想要执行的命令,并按照 Crontab 的格式进行拼接。代码如下:
黑客调用 config_set 方法,就是通过 Redis 的 CONFIG 命令,将 Redis 数据持久化的目录修改成 /var/spool/cron。
黑客调用 save 方法,通过 Redis 的 SAVE 命令,发起 Redis 的数据持久化功能。最终,Redis 将数据写入到 /var/spool/cron 中。写入的文件效果如下:
Crontab 对于无法解析的数据会直接跳过,因此,开头和结尾的乱码不会影响 Crontab 的执行。最终,Crontab 会执行到 Value 中对应的命令。
这样一来,黑客就“聪明”地利用 Redis 保存文件的功能,修改了 Crontab,然后利用 Crontab 执行了命令。
那么,我们该如何对 Redis 进行安全防护呢?这里就需要提到我们前面讲过的“黄金法则”和“最小权限原则”了。
首先,从认证上来说,Redis 提供了最简单的密码认证功能。在 Redis 的配置文件中,只要增加一行 requirepass 123456,我们就能够为 Redis 设置一个密码了。但是,这里有两点需要你注意。
Redis 的性能很高,理论上黑客能够以每秒几十万次的速度来暴力猜测密码。因此,你必须设置一个足够强的密码。我比较推荐随机生成一个 32 位的“数字加字母”的密码。而且 Redis 的密码直接保存在配置文件当中,你并不需要记忆它,需要的时候直接查看就好了。
Redis 是为了高性能而设计的。之所以 Redis 默认不配置密码,就是因为密码会影响性能。按照我之前的测试,加上密码之后,Redis 的整体性能会下降 20% 左右。这也是很多开发和运维,明明知道 Redis 有安全风险,仍然保持无密码状态的原因。所以,是否给 Redis 设置密码,还需要你根据实际的情况进行权衡。
其次是进行授权。尽管 Redis 本身不提供授权机制,但是我们仍然可以通过“重命名”来间接地实现授权功能。我们可以在 Redis 的配置文件中加入 rename-command CONFIG pUVEYEvdaGH2eAHmNFcDh8Qf9vOej4Ho,就可以将 CONFIG 功能的关键词,变成一个随机的字符串,黑客不知道这个字符串,就无法执行 CONFIG 功能了。而且,你仍然可以通过新的命令,来正常地使用 CONFIG 功能,不会对你的正常操作产生任何影响。
现在,你应该已经知道在认证和授权上,我们能使用的防护手段了。那在审计上,因为 Redis 只提供了基本的日志功能(日志等级分为:Debug、Verbose、Notice 和 Warning),实用信息不多,也就没有太多的应用价值。
除了认证和授权,如果你还想要对 Redis 中的数据进行加密,那你只能够在客户端中去集成相应的功能,因为 Redis 本身不提供任何加密的功能和服务。
最后,我们还要避免使用 ROOT 权限去启动 Redis,这就需要用到“最小权限原则”了。在前面命令执行的例子中,黑客是通过 Redis 的保存功能,将命令“写入 Crontab”来实现的命令执行功能。而“写入 Crontab”这个操作,其实是需要 ROOT 权限的。因此,我们以一个低权限的用户(比如 nobody)身份来启动 Redis,就能够降低黑客连入 Redis 带来的影响了。当然,Redis 本身也需要保存日志和持久化数据,所以,它仍然需要写入日志文件的权限(小于 ROOT 权限)来保证正常运行。
总结来说,Redis 是一个极度看重性能的数据库,为了性能舍弃掉了部分的安全功能。我们可以通过“增加密码”“使用最小权限原则”和“授权”的方式,在一定程度上提升 Redis 的安全性。但是,这些防护手段更多的是一种缓解机制,为了保证安全性,我们最好是只在可信的网络中使用 Redis。
MySQL 安全
讲到这里,你现在应该也能总结出,黑客攻击数据库的主要方式,除了执行各种命令对数据库中的数据进行“增删改查”,就是在连入数据库后,通过各种手段实现命令执行,最终控制整个服务器。
那在 MySQL 中,黑客的攻击方式又有什么不同呢?
因为 MySQL 的功能十分强大,自身就提供了和本地文件交互的功能。所以,通过 LOAD DATA INFILE,MySQL 可以读取服务器的本地文件;通过 SELECT … INTO DUMPFILE,MySQL 也能够将数据写入到本地文件中。因此,在黑客连入 MySQL 之后,通过读文件的功能,黑客就能够对服务器的任意文件进行读取,比如敏感的 /etc/passwd 或者应用的源代码等;通过写文件的功能,则可以仿照 Redis 修改 Crontab 的原理,实现命令执行的功能。
相比于 Redis,MySQL 是一个比较成熟的数据库工具,自身的安全性就很高,所以通过正确地配置 MySQL 的安全选项,我们就能够获得较高的安全保障。
那么,MySQL 在黄金法则和加密上,分别提供了哪些功能呢?
MySQL 提供了多用户的认证体系,它将用户的相关信息(认证信息、权限信息)都存储在了 mysql.user 这个系统表中。利用这个系统表,MySQL 可以通过增删改查操作,来定义和管理用户的认证信息、权限列表等。
除此之外,在认证上,MySQL 还提供了比较完善的密码管理功能,它们分别是:
密码过期,强制用户定期修改密码;
密码重用限制,避免用户使用旧的密码;
密码强度评估,强制用户使用强密码;
密码失败保护,当用户出现太多密码错误的尝试后锁定账户。
那么,通过这些密码管理的机制,你就能够拥有一个相对安全的认证体系了。
在多用户的认证体系中,授权是必不可少的。那 MySQL 中的授权机制是怎样的呢?
我们通过修改权限的 GRANT 命令来具体分析一下,MySQL 授权机制中的主体、客体和请求。
主体(user@“127.0.0.1” IDENTIFIED BY “password”):MySQL 的主体是通过用户名、IP 和密码这三个信息组合起来进行标记的。
客体(db.table):MySQL 的客体是数据库和表。
请求(ALL PRIVILEGES):MySQL 将请求的类型定义成了特权(PRIVILEGES)。常见的特权有 INSERT、DELETE 等增删改查操作(如果你想要了解其他更细粒度的特权,可以在官方文档中进行查看)。
除此之外,MySQL 也定义了 ROLE 的概念,你可以基于这个功能,去实现 role-BAC 机制。
虽然和 Redis 一样,MySQL 本身也不提供审计功能。但是,MySQL 可以通过第三方插件,来提供审计的服务。比如 McAfee 提供的mysql-audit以及MariaDB Audit Plugin。这些插件能够自动收集必要的 MySQL 操作信息,并推送到你的 ELK 等日志集群中,方便你进行持续的审计操作。
在加密方面,MySQL 既提供传输过程中 SSL(Security Socket Layer)加密,也提供存储过程中硬盘加密。
我们首先来看 MySQL 的 SSL 加密功能。开启 SSL 功能,需要在配置文件中配置如下命令:
但是,这些配置并不能强制客户端使用 SSL 连接。想要杜绝全部非安全连接的话,我们可以在配置文件中添加 require_secure_transport=ON,来进行强制限制。
接着,我们来看,MySQL 中提供的硬盘加密功能。硬盘加密过程主要涉及两个密钥,一个主密钥和一个表密钥。表密钥由 MySQL 随机生成,通过主密钥进行加密后,存储在表头信息中。因此,每一个表格都拥有不同的密钥。
MySQL 的加密功能是由 keyring_file 这个插件来提供的。需要注意的是,当 keyring_file 第一次启动的时候,它会生成一个主密钥文件在当前的系统中。你一定要备份这个密钥文件,因为它一旦丢失,数据库中的全部数据,都将因为无法解密而丢失。
现在,你应该了解了,MySQL 在黄金法则上都提供了哪些功能。接下来,我们再来看“最小权限原则”。
和 Redis 一样,MySQL 也需要避免以 ROOT 权限启动。不一样的是,MySQL 默认提供了这样的能力,当我们在 Linux 中通过 mysqld 来启动 MySQL 进程的时候,mysqld 会自动创建一个具备最小权限的 mysql 用户,并赋予这个用户对应日志文件的权限,保证 MySQL 拥有必要的最小权限。
总之,MySQL 是一个非常成熟的数据库工具,它提供了完整的安全功能。通过对认证、授权、审计和加密功能的正确配置,你就能够迅速提升 MySQL 的整体安全性。
总结
今天,我们以 Redis 和 MySQL 这两种比较典型的数据库为例,对它们的安全性,以及攻破后能产生的危害进行了分析。在这里,我把安全防护的关键内容总结了一张表格,希望能够帮助你加深理解。
通过对这两种数据库的分析,我们知道,数据库面临的威胁不只存在于数据本身,也会影响到数据库所在的服务器。在数据库本身的安全防护上,我们可以通过对“黄金法则”的运用,在认证、授权、审计和加密方面,为其设置一定的保护能力。同时,为了避免数据库对服务器的衍生影响,我们也应该落实“最小权限原则”, 避免以 ROOT 权限去启动数据库服务。
当然,目前成熟的数据库产品肯定不止这两种。但是,我希望通过对这两种数据库的安全分析,让你掌握数据库安全的主要内容,在实际工作中,能够做到活学活用,自主去分析你用到的数据库。
思考题
最后,让我们来看一道思考题。
在实际工作,除了 Redis 和 MySQL,你还会用到哪些数据库?你可以思考一下,这些数据库有哪些安全事项呢?你可以按照我给出的表格,试着总结出相关的安全防护手段。
欢迎留言和我分享你的思考和疑惑,也欢迎你把文章分享给你的朋友。我们下一讲再见!
分享给需要的人,Ta购买本课程,你将得18元
生成海报并分享
赞 4
提建议
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
上一篇
15 | Docker安全:在虚拟的环境中,就不用考虑安全了吗?
下一篇
17 | 分布式安全:上百个分布式节点,不会出现“内奸”吗?
精选留言(10)
- 小晏子2020-01-17试着分析下当前mongodb的安全性,这个很早之前出了很大的安全性问题,现在早已修复,那么现在它提供了哪些安全保障呢,看了一点资料分析一下。 认证: mongoDB提供了很多认证方法,有SCRAM-SHA-1,即Salted Challenge Authentication Mechanism,是基于文本的用户名密码方式,传输的时候通过TLS加密。MongoDB-CR,在v3.0之后移除了。另外还提供了外部认证协议,包括LDAP,Kerberos, 授权: mongoDB支持RBAC,可以使用授权保证用户只能访问他被允许访问的数据库和资源。 审计: 这个好像只有enterprise版本才提供强大的审计功能。 加密: mongoDB支持网络加密,并可以通过磁盘加密保护数据库和通信,它支持TLS/SSL加密网络通信。 现在看来,mongoDB目前安全性还是很好的,只要正确使用,安全性问题不是主要问题了。展开
作者回复: 其实大部分数据库的安全性都很好,只是很多人不会用或者不关注,而导致安全问题的出现。
9 - 夏陽2020-03-27想问下老师,目前数据中的手机号等敏感信息要做脱敏处理,如何在脱敏后还能查询到数据,目前库中有上亿条数据,这些数据脱敏后的索引重建会不会很崩溃,您有什么好的主流办法处理么
作者回复: 脱敏一般都是在输出的时候做规范。比如数据库存储了手机号,然后由安全部门统一封装一个接口,其他部门通过安全接口,获取脱敏后的手机号,不允许直接访问数据库看原始数据。
6 - leslie2020-01-17mysql的问题和解决方案在关系型数据库都有类似的操作,如:oracle、sql server、sybase,都能找到差不多的方式;今天的梳理其实漏了老师之前讲过的安全方式-存储过程同样可以提高安全性。 redis的问题在no sql数据库方面都有类似的问题。记得老师之前课程有提过redis登陆之后su -s /bin/redis-server nobody。 谢谢老师的分享:虽然今天的课程内容使用的方式做为一个老牌DBA蛮熟悉不过还是有补充;期待后续老师的分享;课程结束时应当常规的风险问题都能较好的防御。建议课程中加一些扩展阅读-满足跟深层次需求。谢谢。展开6
- Michael2022-09-16 来自上海老师讲的redis的这个安全的锅,我这两天就碰到了: 买了个阿里云,上面yum install安装了个redis,没有设置密码,过两天就收到了阿里云的安全告警信息, top了下,看到cpu飙升到了290%,进程kill不掉,最后发现,和老师讲的一样,/var/spool/cron下有个redis文件,跑定时任务,立马将redis停止,按照老师讲的方法折腾了一番。展开
- Finch2021-07-12端口防火墙限制,这就基本过滤大部分攻击了
- Henry Liao2020-07-25那个入侵Redis修改Crontab植入远程连接后门厉害了
- COOK2020-03-29不要用root启动数据库,加上权限验证
- 官2020-03-23主要是mysql和oracle,感觉后者在安全性上比mysql还要强一些。
作者回复: 毕竟是商业产品。
- 追风筝的人2020-03-16只用过mysql和redis这2种数据库
- return2020-03-03老师 有没有 隔离 开发和数据库 连接密码的思路。 就是开发 上线 不需要知道生产的mysql密码。
作者回复: 想要完全不知道比较难,但还是可以做到的。首先开发不能直接接触任何线上环境。这一点做到之后,就可以通过配置中心来隔离线上信息了,也就是开发的时候在配置文件里面填写线下的地址,上线后统一使用线上的配置文件,就可以完成切换了。