导语:Redis是一种开源的,内存中的数据结构存储系统,可用作数据库,消息代理或缓存。由于它是在在受信任的环境中访问,因此不应在Internet上公开。但是,一些Redis服务绑定到公共接口,甚至没有密码身份验证保护。
Redis是一种开源的,内存中的数据结构存储系统,可用作数据库,消息代理或缓存。由于它是在在受信任的环境中访问,因此不应在Internet上公开。但是,一些Redis服务绑定到公共接口,甚至没有密码身份验证保护。
在某些情况下,如果Redis使用root帐户运行,攻击者可以将SSH公钥文件写入root帐户,直接通过SSH登录到受害服务器。这会允许黑客获得服务器权限,删除或窃取数据,甚至导致加密勒索,严重危及正常的业务服务。
漏洞利用的简化流程
· 登录不受保护的Redis
· 将其备份位置更改为.ssh目录 – 将SSH密钥写入新的备份位置
· 使用SSH密钥远程连接并登录目标服务器
我们应该已经熟悉如何使用私钥+公钥进行SSH自动登录了。
漏洞复现
现在我们来开始实战,设置一台目标机器。我们需要两台机器,可以是物理机,虚拟机,也可以是远程VPS。
只要攻击端能够ping通目标就行。
本次示例的环境配置:
目标机器:Ubuntu上的Redis-3.2.11
攻击机:kali
配置目标机器
首先,在目标机器上安装Redis。通过下面这个命令来下载源码:
wget http://download.redis.io/releases/redis-3.2.11.tar.gz
解压和编译,命令如下:
tar xzf redis-3.2.11.tar.gz cd redis-3.2.11 make
make之后,我们使用nano来打开redis-3.2.11目录下的redis.conf配置文件。为了能够进行远程访问,我们需要注释掉 bind 127.0.0.1这一行,并禁用protected-mode,如图所示:
现在使用我们刚才编辑的配置文件启动Redis服务。注意:redis-server在redis-3.2.11/src目录下,启动命令如下:
src/redis-server redis.conf
现在,我们已经完成了目标服务器的设置。此外,我们还应检查是否有 .ssh文件夹。如果没有,我们应该创建一个,一会儿攻击时会用到。
攻击机配置
首先,确定我们可以ping通目标。然后,我们将生成一个私钥和公钥,以便稍后SSH到目标机器中。运行以下命令以生成SSH密钥并将密码保留为空:
ssh-keygen -t rsa
然后,进入.ssh目录,如果你是root用户,请输入/.ssh,不是root用户,输入~/.ssh,然后将私钥复制到temp.txt中:
(echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > temp.txt
有人可能会奇怪,为什么我们在公钥前后放两个空行?如果你不知道的话,我们这里先卖一个关子,下面自会解答。
很好,现在我们已经生成了一对密钥对,现在我们需要找到一个方法将公钥上传到Redis服务器中(目标机器)。
我们将使用redis-cli向Redis服务器发送命令,并且直接在终端中读取服务器的响应。
在redis-3.2.11/sct目录下执行以下命令:
cat /.ssh/temp.txt | redis-cli -h 203.137.255.255 -x set s-key
这里,我们来看看命令。我们使用-h参数来指定远程Redis服务器IP,这样redis-cli就可以进行连接并发送命令。-x参数后的语句意思是,设置redis中s-key密钥的值为temp.txt。
这里,我们有了一个隐藏着ssh秘钥的密钥!现在我们再来连接到Redis并查看它的配置文件。使用redis-cli再次连接到Redis服务器,如图所示:
查看上面的截图,我们首先使用get s-key命令来验证s-key密钥的值,这个值正是我们想要的 – 前后有两个空行的公钥。我们这里真正要做的就是获取存储在.ssh文件夹中的“s-key”(SSH公钥)的值, 这样我们就可以不用输入密码而远程SSH登录到目标机器了。
我们需要执行如下操作:
备注:SSH中的authorized_keys文件指定可用于登录的用户帐户,配置文件已经修改。参考文章:ssh.com
攻击时刻
在攻击机上,使用下列命令ssh连接到目标机器上:
# command: private key [email protected] IP ssh -i id_rsa [email protected]
太赞了,可以看到,我们使用SSH密钥已经成功自动登录到服务器上!到此,我们已经完成了漏洞复现。
最后,我想展示Redis的备份文件是什么样的,如图:
注意不可读的字符?在关键内容之前和之后添加“\ n \ n”只是为了安全起见并将其与其他内容分开,以便可以正确解析。上面卖的关子,其实就是这个意思,很简单。
使用搜索引擎查找易受攻击的Redis服务器
我们将使用Shodan来搜索具有Redis特征的服务器。
我们通过Redis的默认端口进行简单搜索。
共计75,665条搜索结果。而且你知道吗,这些结果中,有大量的主机都没有密码保护(截图中没有显示,但是我们向下滚动的话,能够看到)!!
这个漏洞是在几年前发现的,仍有无数机器没有设置密码,还暴露在公网中,这对攻击者来说,拿下服务器简直是探囊取物,不费吹灰之力。不得不说,这些人心真是大啊。
根据shadon显示,2015年有大约56,000个未受保护的 Redis服务器。
根据ZoomEye显示,分布的范围如图所示:
据ZoomEye称,漏洞主机数量排名最高的国家是:中国,美国,德国……
OK,言归正传。我们如何使用Python脚本验证服务器是否受到保护呢?其实,非常简单。
1.使用socket连接到目标IP
2.执行GET请求
3.如果服务器不受保护,GET请求会成功; 否则会失败
缓解措施
· 不要绑定到0.0.0.0
· 如果需要绑定,请更改默认端口(6379)
· 设置密码