提交 14f57b37 编写于 作者: N natsunoyoru97

#182 translated: common_knowledge/redis入侵.md

上级 73b5bc86
**Translator: [natsunoyoru97](https://github.com/natsunoyoru97)**
**Author: [labuladong](https://github.com/labuladong)**
All right, now my article also becomes a clickbait. How can I have my server attackd since I'm always being cautious?
I talked to my friend yesterday. He said one day he found **ALL** of his data **IS LOST** with only the key pair left on one of his cloud servers which ran the Redis database, in which the value looks like a string of the RSA public key. He thought he has deleted the database, but fortunately, there is nothing important in his server so he doesn't pay attention to this.
I also know that he ran an open-source program which is too old to maintain. His Redis is in the old version and he is not familiar with the Linux operation. I am sure that his server has been under an attack. It also makes me think about someone who doesn't pay attention to system permissions, firewall and data protection, so here I will explain the reason behind and how to prevent such things happen.
P.S. Such an attack doesn't work anymore because the updated version of Redis adds the protect mode, which is safer. We can only simulate the attack on the local.
### How Did It Go?
This attack was in 2015, in which Redis was poor in security. The security of the database only depended on SREs. There are thousands of nodes was attacked and the weird things happened like mentioned above. All data was emptied with only one key called `crackit` left, and the value looks like the string of the RSA public key.
It came out that the hackers applied dynamic configuration and persistence, and write their RSA public keys into `/root/.ssh/authored_keys` in the victims' computers, so they can use the private key to log in the root of the servers then invade the systems.
The servers have been attacked are poor in security:
1. The port of Redis is in default and can be visited via the public internet.
2. No password in Redis.
3. The Redis process is started by the user.
ANY of these points make the server vulnerable, and it is lethal when added on. Despite your system contains the public key of others, it is a big loss if your database were emptied by the malicious operation. So what are the steps to do such an attack? I'll show you on my local loopback address.
### Performing on Local
The default port of Redis is 6379, and we set it receives the connection from NIC 127.0.0.1, so I can connect to Redis on local to simulate the scenario that Redis can be visited from the public internet.
Now I am the ordinary user named fdl, and I want to log in the root user via ssh. I need the password but I don't know so I can't log in.
I can also use the RSA key pair to log in despite password, but I have to store the public key to the home directory in root `/root/.ssh/authored_keys`. We know the permission of the `/root` directory doesn't allow any other user to access, read or write:
![](../pictures/redis_attack/1.png)
But I find I can access Redis:
![](../pictures/redis_attack/2.png)
If Redis is running by root, I can operate Redis to write my public key into the home directory of the root file. There is one way to do persistence in Redis is to generate the RDB file which contains source data.
Now I have an evil wicked grin. First, I empty the data in Redis, and then I write my RSA public key into the database. I also add line breaks in the start and the end to avoid the RDB file to damage the string of the public key:
![](../pictures/redis_attack/3.png)
And make Redis to store the generated data to the file `authored_keys` in the directory `/root/.ssh/`:
![](../pictures/redis_attack/4.png)
Now the home directory of root contains our RSA public key, and we can log in the root by the key pair:
![](../pictures/redis_attack/5.png)
Take a look at the public key written into the root home directory:
![](../pictures/redis_attack/6.png)
Maybe the messy code is encoded in the GDB file, but the public key is completely stored and oddly the ssh login program should verify the public key surrounded by the messy code!
Now I own the root privilege and can do anything I would like to do …
### Lessons Learnt
It is nearly impossible to be the victim of such kind of attack (the updated version of Redis is not available when there is no password in default), but everyone is supposed to be vigilant about the system security.
We buy a cloud server with a simple configuration. We often omit to configure the firewall and to set a strong password of the database. These are definitely not good behaviors.
Now the computer system is more and more completed and every mature program is maintained by the elites. It is supposed to be technically flawless, so the only possible problem is in the users.
If there is someone's QQ (A popular social media platform in China) account is hacked, I believe the hackers won't hack in the database of Tencent (The company which owns QQ), it must be the owner is careless and put the account name and the password into a fraud website. I rarely see someone's Wechat (Also a popular social media platform in China) account is hacked, maybe it is because Wechat uses the QRcode to login instead of the password. Probably it is a consideration of security, Wechat supplies online payment after all.
It is easy for geeks to identify the fraud mentioned above by looking at the url and analyzing the network packets by browsers. But believe it or not, normies have no idea about identifying the fraud website. Out of my expectation, we are in the year 2020 but there is still someone trying to find this leak and someone still be the victim …
Turn back to the usage of Redis, its official site has listed the advice to protect your system. Let me do the brief summary:
1. Run an unprivileged Redis user that is only used for this purpose. Strong passwords must be set to prevent the crack by brute force.
2. The Redis port should be firewalled to prevent access from the outside. So does the config file, it also should be properly configured.
3. Disable commands in Redis or to rename them into an unguessable name, so that normal clients are limited to a specified set of commands.
### See Also
[Redis Security](https://redis.io/topics/security)
RedisWannaMine attack in 2018:
[RedisWannaMine Unveiled: New Cryptojacking Attack Powered by Redis and NSA Exploits](https://www.imperva.com/blog/rediswannamine-new-redis-nsa-powered-cryptojacking-attack/)
[New research shows 75% of ‘open’ Redis servers infected](https://www.imperva.com/blog/new-research-shows-75-of-open-redis-servers-infected/)
好吧,我也做了回标题党,像我这么细心的同学,怎么可能让服务器被入侵呢?
其实是这样的,昨天我和一个朋友聊天,他说他自己有一台云服务器运行了 Redis 数据库,有一天突然发现数据库里的**数据全没了**,只剩下一个奇奇怪怪的键值对,其中值看起来像一个 RSA 公钥的字符串,他以为是误操作删库了,幸好自己的服务器里没啥重要的数据,也就没在意。
经过一番攀谈交心了解到,他跑了一个比较古老已经停止维护的开源项目,安装的旧版本的 Redis,而且他对 Linux 的使用不是很熟练。我就知道,他的服务器已经被攻陷了,想到也许还会有不少像我这位朋友的人,不重视操作系统的权限、防火墙的设置和数据库的保护,我就写一篇文章简单看看这种情况出现的原因,以及如何防范。
PS:这种手法现在已经行不通了,因为新版本 Redis 都增加了 protect mode,增加了安全性,我们只能在本地简单模拟一下,就别乱试了。
### 事件经过
其实这种攻击手法都是 2015 年的事了,那时候 Redis 的安全保护机制比较差,只能靠运维人员来合理配置以保证数据库的安全。有段时间,全球几万个 Redis 节点遭到了攻击,出现了上述奇怪的现象,所有数据被清空,只剩一个键叫 `crackit`,它的值形似 RSA 公钥的字符串。
后来查证,攻击者利用 Redis 动态设置配置和数据持久化的功能,把自己的 RSA 公钥写入到了被攻击服务器的 `/root/.ssh/authored_keys` 这个文件,从而可以用私钥直接登录对方的 root 用户,侵入对方系统。
沦陷的服务器安全防护做的很不好,具体如下:
1、Redis 的端口是默认端口,而且可以从公网访问。
2、Redis 还没设密码。
3、Redis 进程是由 root 用户启动的。
以上每个点都是比较危险的,合在一起,那真是很致命了。且不说别人把公钥写到你的系统里,就说连上你的数据库然后删库,那损失都够大了。那么具体的流程是什么呢,下面我在本地回环地址上简单演示一下。
### 本地演示
Redis 监听的默认端口是 6379,我们设置它接收网卡 127.0.0.1 的连接,这样我从本地肯定可以连接 Redis,以此模拟「从公网可以访问 Redis」这一条件。
现在我是名叫 fdl 的普通用户,我想用 ssh 登录我系统上的 root 用户,要输入 root 的密码,我不知道,所以没办法登录。
除了密码登录之外,还可以使用 RSA 密钥对登录,但是必须要把我的公钥存到 root 的家目录中 `/root/.ssh/authored_keys`。我们知道 `/root` 目录的权限设置是不允许任何其他用户闯入读写的:
![](../pictures/redis入侵/1.png)
但是,我发现自己竟然可以直接访问 Redis:
![](../pictures/redis入侵/2.png)
如果 Redis 是以 root 的身份运行的,那么我就可以通过操作 Redis,让它把我的公钥写到 root 的家目录中。Redis 有一种持久化方式是生成 RDB 文件,其中会包含原始数据。
我露出了邪恶的微笑,先把 Redis 中的数据全部清空,然后把我的 RSA 公钥写到数据库里,这里在开头和结尾加换行符目的是避免 RDB 文件生成过程中损坏到公钥字符串:
![](../pictures/redis入侵/3.png)
命令 Redis 把生成的数据文件保存到 `/root/.ssh/` 中的 `authored_keys` 文件中:
![](../pictures/redis入侵/4.png)
现在,root 的家目录中已经包含了我们的 RSA 公钥,我们现在可以通过密钥对登录进 root 了:
![](../pictures/redis入侵/5.png)
看一下刚才写入 root 家的公钥:
![](../pictures/redis入侵/6.png)
乱码是 GDB 文件的某种编码吧,但是中间的公钥被完整保存了,而且 ssh 登录程序竟然也识别了这段被乱码包围的公钥!
至此,拥有了 root 权限,就可以为所欲为了。。。
### 吸取教训
虽然现在基本不会受到这种攻击(新版本的 Redis 没有密码时默认不对外网开放),但是对于系统的安全性是每个人都应该重视的。
我们自己折腾东西,用个低配云服务器,为了省事儿一般也不认真配置防火墙,数据库不设密码或者设成 admin、root 这样简单的密码,反正也没啥数据。这样肯定不是个好习惯。
现在我们的计算机系统越来越完善,每个成熟的项目都由最优秀的一帮人维护,从技术上说应该算是无懈可击了,那么唯一可能出问题的地方就在于使用它们的人。
就像经常看到有人的 QQ 被盗,我相信盗号的人肯定不是跑到腾讯的数据库里盗号,肯定是 QQ 号主安全防范意识差,在哪个钓鱼网站输入了自己的账号密码,导致被盗。我基本没见过微信被盗的,可能是微信弱化密码登录,改用二维码扫描登录的原因。这应该也算是一种安全方面的考量吧,毕竟微信是有支付功能的。
上面这种骗局对于技术人来说,看看 url,浏览器分析一下网络包就很容易识别出来,但是你还别不信,一般人真的搞不明白怎么识别钓鱼网站和官方网站。就像我真没想到都 2020 年了,还有人在找 Redis 的这个漏洞,而且还有人中招。。。
那么说回 Redis 数据库的使用,在官网上明确写出了安全防护的建议,我简单总结一下吧:
1、不要用 root 用户启动 Redis Server,而且一定要设置密码,而且密码不要太短,否则容易被暴力破解。
2、配置服务器防火墙和 Redis 的 config 文件,尽量不要让 Redis 与外界接触。
3、利用 rename 功能伪装 flushall 这种危险命令,以防被删库,丢失数据。
坚持原创高质量文章,致力于把算法问题讲清楚,欢迎关注我的公众号 labuladong 获取最新文章:
![labuladong](../pictures/labuladong.jpg)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册