当前位置: 首页 > news >正文

【BurpSuite】插件开发学习之J2EEScan(上)-被动扫描

【BurpSuite】插件学习之J2EEScan(上)-被动扫描

前言

插件开发学习第5套。前置文章:

【BurpSuite】插件学习之Log4shell
【BurpSuite】插件学习之Software Vulnerability Scanner
【BurpSuite】插件学习之dotnet-Beautifier
【BurpSuite】插件学习之active-scan-plus-plus

J2EEScan

https://github.com/PortSwigger/j2ee-scan.git
逻辑代码在

|____src
| |____main
| | |____java
| | | |____burp
| | | | |____HTTPMatcher.java
| | | | |____J2EELFIRetriever.java
| | | | |____SoftwareVersions.java
| | | | |____WeakPasswordBruteforcer.java
| | | | |____j2ee
| | | | | |____PassiveScanner.java
| | | | | |____Confidence.java
| | | | | |____annotation
| | | | | | |____RunOnlyOnce.java
| | | | | | |____RunOnlyOnceForApplicationContext.java
| | | | | |____Risk.java
| | | | | |____passive
| | | | | | |____SessionFixation.java
| | | | | | |____ApacheStrutsS2023Rule.java
| | | | | | |____JettyRule.java
| | | | | | |____HttpServerHeaderRule.java
| | | | | | |____SqlQueryRule.java
| | | | | | |____PassiveRule.java
| | | | | | |____strutstoken
| | | | | | | |____StrutsTokenCracker.java
| | | | | | | |____ReplayRandom.java
| | | | | | |____ApacheTomcatRule.java
| | | | | | |____SessionIDInURL.java
| | | | | | |____JSPostMessage.java
| | | | | | |____ExceptionRule.java
| | | | | |____IssuesHandler.java
| | | | | |____lib
| | | | | | |____TesterAjpMessage.java
| | | | | | |____SimpleAjpClient.java
| | | | | |____issues
| | | | | | |____impl
| | | | | | | |____OracleEBSSSRF.java
| | | | | | | |____OracleEBSSSRFLCMServiceController.java
| | | | | | | |____ApacheStrutsS2032.java
| | | | | | | |____NodeJSRedirect.java
| | | | | | | |____ApacheRollerOGNLInjection.java
| | | | | | | |____ApacheStrutsDebugMode.java
| | | | | | | |____ApacheAxis.java
| | | | | | | |____HTTPWeakPassword.java
| | | | | | | |____HTTPProxy.java
| | | | | | | |____PrimeFacesELInjection.java
| | | | | | | |____WeblogicUDDIExplorer.java
| | | | | | | |____ApacheStrutsS2052.java
| | | | | | | |____JBossWebConsole.java
| | | | | | | |____EL3Injection.java
| | | | | | | |____XXEParameterModule.java
| | | | | | | |____UndertowTraversal.java
| | | | | | | |____LFIModule.java
| | | | | | | |____ApacheStrutsS2043.java
| | | | | | | |____FastJsonRCE.java
| | | | | | | |____OracleReportService.java
| | | | | | | |____SnoopResource.java
| | | | | | | |____JBossJMXReadOnly.java
| | | | | | | |____WebInfInformationDisclosure.java
| | | | | | | |____XInclude.java
| | | | | | | |____JavaServerFacesTraversal.java
| | | | | | | |____Seam2RCE.java
| | | | | | | |____WeblogicConsole.java
| | | | | | | |____RESTAPISwagger.java
| | | | | | | |____JettyRemoteLeakage.java
| | | | | | | |____JBossJMXInvoker.java
| | | | | | | |____OASConfigFilesDisclosure.java
| | | | | | | |____JacksonDataBindCVE20177525.java
| | | | | | | |____XXEModule.java
| | | | | | | |____WeblogicCVE20192725.java
| | | | | | | |____WeblogicWebServiceTestPageCVE20182894.java
| | | | | | | |____JKStatus.java
| | | | | | | |____WeblogicCVE201710271.java
| | | | | | | |____LFIAbsoluteModule.java
| | | | | | | |____ApacheStrutsS2016.java
| | | | | | | |____ApacheStrutsShowcase.java
| | | | | | | |____ApacheStrutsWebConsole.java
| | | | | | | |____ApacheStrutsS2020.java
| | | | | | | |____StatusServlet.java
| | | | | | | |____UTF8ResponseSplitting.java
| | | | | | | |____TomcatHostManager.java
| | | | | | | |____SpringBootRestRCE.java
| | | | | | | |____PivotalSpringTraversalCVE20143625.java
| | | | | | | |____Htaccess.java
| | | | | | | |____JBossjBPMAdminConsole.java
| | | | | | | |____ELInjection.java
| | | | | | | |____NodeJSPathTraversal.java
| | | | | | | |____ApacheStrutsS2017.java
| | | | | | | |____ApacheSolrXXE.java
| | | | | | | |____OASSqlnetLogDisclosure.java
| | | | | | | |____NodeJSResponseSplitting.java
| | | | | | | |____URINormalizationTomcat.java
| | | | | | | |____JBossWS.java
| | | | | | | |____SpringCloudConfigPathTraversal.java
| | | | | | | |____InfrastructurePathTraversal.java
| | | | | | | |____AJPDetector.java
| | | | | | | |____JBossAdminConsole.java
| | | | | | | |____SSRFScanner.java
| | | | | | | |____SpringDataCommonRCE.java
| | | | | | | |____JavascriptSSRF.java
| | | | | | | |____ApacheWicketArbitraryResourceAccess.java
| | | | | | | |____SpringBootActuator.java
| | | | | | | |____IDocInjection.java
| | | | | | | |____TomcatManager.java
| | | | | | | |____NextFrameworkPathTraversal.java
| | | | | | | |____OracleCGIPrintEnv.java
| | | | | | | |____JBossJuddi.java
| | | | | | | |____AJP_Tomcat_GhostCat.java
| | | | | | | |____SpringWebFlowDataBindExpressionCVE20174971.java
| | | | | | |____IModule.java
| | | | | |____CustomScanIssue.java
| | | | |____J2EELocalAssessment.java
| | | | |____WeakPassword.java
| | | | |____HTTPParser.java
| | | | |____CustomHttpRequestResponse.java
| | | | |____BurpExtender.java

这个代码是基于java写的

BurpExtender

老样子,继承BurpExtender

class BurpExtender(IBurpExtender):

基本信息也和java差不多

public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks) {
        // keep a reference to our callbacks object
        this.callbacks = callbacks;
        this.callbacks.registerExtensionStateListener(this);
        // obtain an extension helpers object
        helpers = callbacks.getHelpers();
        // obtain our output stream
        stdout = new PrintWriter(callbacks.getStdout(), true);
        stderr = new PrintWriter(callbacks.getStderr(), true);

        // set our extension name
        callbacks.setExtensionName("J2EE Advanced Tests");

然后创建了一个临时数据库文件并连接了

j2eeDBState = File.createTempFile("burpsuite-j2eescan-state", ".db");
            stdout.println("Using temporary db state file: " + j2eeDBState.getAbsolutePath());
            stdout.println("This internal state is used to avoid duplicate infrastructure security "
                    + "checks on the same host, improving the scan performance");

            connectToDatabase(j2eeDBState.getAbsolutePath());

初始化的数据库表executed_plugins

String fields = "plugin, host, port";

        conn.createStatement().executeUpdate("CREATE TABLE IF NOT EXISTS executed_plugins ("
                + " plugin TEXT PRIMARY KEY,"
                + " host TEXT,"
                + " port INTEGER,"
                + " UNIQUE(" + fields + "))");

doPassiveScan

重写了被动扫描,在PassiveScanner这个类里。

PassiveScanner.scanVulnerabilities(baseRequestResponse, callbacks);

遍历如下规则进行扫描

static PassiveRule[] PASSIVE_RULES = {
            new ApacheTomcatRule(),
            new ExceptionRule(),
            new HttpServerHeaderRule(),
            new SqlQueryRule(),
            new ApacheStrutsS2023Rule(),
            new JettyRule(),
            new SessionIDInURL(),
            new JSPostMessage(),
            new SessionFixation()
    };

一个一个看,

ApacheTomcatRule

【1】tomcat版本发现

Risk.Low

Pattern.compile("Apache Tomcat/([\\d\\.]+)"

【2】tomcat远程jvm虚拟机

Risk.Information

Pattern.compile("\"><small>(1\\.\\d\\.[\\w\\-\\_\\.]+)<"

ExceptionRule

【3】Apache Struts 测试页面

判断struts是开发环境还是dev环境
Risk.Low

"<title>Struts Problem Report</title>".getBytes();

【4】Apache Tapestry 异常错误展示

Risk.Low

            byte[] tapestryException = "<h1 class=\"t-exception-report\">An unexpected application exception has occurred.</h1>".getBytes();

【5】Grails 异常错误展示

Risk.Low

            byte[] grailsException = "<h1>Grails Runtime Exception</h1>".getBytes();

【6】GWT 异常错误展示

Risk.Low

            byte[] gwtException = "com.google.gwt.http.client.RequestException".getBytes();

【7】java 常见的应用异常错误展示

Risk.Low

List<byte[]> javaxServletExceptions = Arrays.asList(
                    "javax.servlet.ServletException".getBytes(),
                    "οnclick=\"toggle('full exception chain stacktrace".getBytes(),
                    "at org.apache.catalina".getBytes(),
                    "at org.apache.coyote.".getBytes(),
                    "at org.jboss.seam.".getBytes(),
                    "at org.apache.tomcat.".getBytes(),
                    "<title>JSP Processing Error</title>".getBytes(),  // WAS
                    "The full stack trace of the root cause is available in".getBytes());
                    "<pre><code>com.sun.facelets.FaceletException".getBytes(),
                    "Generated by MyFaces - for information on disabling".getBytes(),
                    "<title>Error - org.apache.myfaces".getBytes(),
                    "org.primefaces.webapp".getBytes());

HttpServerHeaderRule

http 头泄露应用版本号

【8】Java&Jetty &GlassFish&Weblogic

Pattern.compile("java\\/([\\d\\.\\_]+)"
Pattern.compile("Jetty.([\\d\\.]+)"
Pattern.compile("GlassFish Server Open Source Edition ([\\d\\.]+)"
Pattern.compile("WebLogic (:?Server )?([\\d\\.]+)"

【10】 oracle

ORACLE_APPLICATION_SERVER_RE.add(Pattern.compile("Oracle Application Server Containers for J2EE 10g \\(([\\d\\.]+)\\)", Pattern.DOTALL));
ORACLE_APPLICATION_SERVER_RE.add(Pattern.compile("Oracle.Application.Server.10g\\/([\\d\\.]+)", Pattern.DOTALL));
ORACLE_APPLICATION_SERVER_RE.add(Pattern.compile("Oracle Application Server\\/([\\d\\.]+)", Pattern.DOTALL));
ORACLE_APPLICATION_SERVER_RE.add(Pattern.compile("Oracle9iAS\\/([\\d\\.]+)", Pattern.DOTALL));

【11】nodejs

if (xPoweredByHeader.trim().equals("Express")) {

SqlQueryRule

【12】SQL exception

SQL_QUERIES_RE.add(Pattern.compile("select ", Pattern.CASE_INSENSITIVE | Pattern.DOTALL | Pattern.MULTILINE));
SQL_QUERIES_RE.add(Pattern.compile("IS NOT NULL", Pattern.CASE_INSENSITIVE | Pattern.DOTALL | Pattern.MULTILINE));

ApacheStrutsS2023Rule

【13】StrutsTokenCracker

提取token

    private final Pattern TOKEN_FIELD_PATTERN = Pattern.compile("<input type=\"hidden\" name=\"token\" value=\"([^\"]+)\"");

转int,按固定长度切割

 int[] tokenInts = bytesToInt(bigIntToByte(token));

根据int找到seed

        long seed = findSeed(reverseByteOrder(tokenInts[1]), reverseByteOrder(tokenInts[2]));

根据种子预测随机数,和就token匹配,如果能匹配上,说明种子是对的,也就是说明token可预测。

int[] nextInts = new int[4];
        for(int i=0;i<nextInts.length;i++) {
            nextInts[i] = reverseByteOrder(random.nextInt());
        }

        boolean match1 = tokenInts[2] == nextInts[0];
        boolean match2 = tokenInts[3] == nextInts[1];
        boolean match3 = tokenInts[4] == nextInts[2];

JettyRule

【14】Jetty发现

    private static final Pattern JETTY_PATTERN = Pattern.compile("><small>Powered by Jetty", Pattern.DOTALL | Pattern.MULTILINE);

SessionIDInURL

【15】Session Token in URL

    private static final List<String> SESSIONIDs = new ArrayList<>(Arrays.asList(";jsessionid"));

JSPostMessage

【16】JSPostMessage函数

js的跨域信息通信的函数。

POSTMESSAGE_PATTERNS.add(Pattern.compile(".addEventListener\\(\"message", Pattern.CASE_INSENSITIVE | Pattern.DOTALL | Pattern.MULTILINE));
POSTMESSAGE_PATTERNS.add(Pattern.compile("window\\).on\\(\"message", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE));
POSTMESSAGE_PATTERNS.add(Pattern.compile(".postMessage\\(", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE));

SessionFixation

【17】session fixation attack(固定会话攻击)

先检查url,这个检查很粗糙,直接判断后缀,还是黑名单,没有后缀就默认通过

isJavaApplicationByURL(curURL)

在这里插入图片描述

然后条件是请求包有JSESSIONID且返回包含有账号等信息

if (requestCookie != null && requestCookie.contains("JSESSIONID")) {
            String reqBodyLowercase = reqBody.toLowerCase();

if (reqBodyLowercase != null
                    && (reqBodyLowercase.contains("password") || reqBodyLowercase.contains("pwd") || reqBodyLowercase.contains("passw"))
                    && (reqBodyLowercase.contains("user") || reqBodyLowercase.contains("uid") || reqBodyLowercase.contains("mail"))) {

并且返回包没有setcookie(说明固定了会话),或者setcookie字段里包含JSESSIONID
这种校验比较粗糙,注释也说了

Due to the nature of the vulnerability, this check is prone to False Positives and must be manually confirmed
在这里插入图片描述

后话

主动扫描有点多,放在一个文章显得有点重,拆成两个。

相关文章:

  • java计算机毕业设计企业公开招聘系统源码+数据库+系统+lw文档+mybatis+运行部署
  • 赛事开源Baseline参考目录格式
  • C++设计模式之Bridge桥模式
  • Kibana-8.4.0-Linux安装
  • @hook扩展分析
  • 利用 zabbix 监控服务端口
  • FastAPI 学习之路(二十九)使用(哈希)密码和 JWT Bearer 令牌的 OAuth2
  • 【愚公系列】2022年08月 微信小程序-纵向和横向选项卡功能实现
  • 猿创征文|Java实现自定义注解
  • 全网唯一OpenCyphal/UAVCAN教程(8)libcanard介绍
  • Redis的主从复制搭建
  • java毕业设计物资租赁管理系统mybatis+源码+调试部署+系统+数据库+lw
  • java计算机毕业设计评标专家管理信息系统源码+数据库+系统+lw文档+mybatis+运行部署
  • java毕业设计希望酒店信息管理系统mybatis+源码+调试部署+系统+数据库+lw
  • 数仓项目拉链表
  • 【跃迁之路】【699天】程序员高效学习方法论探索系列(实验阶段456-2019.1.19)...
  • Akka系列(七):Actor持久化之Akka persistence
  • Apache Spark Streaming 使用实例
  • co.js - 让异步代码同步化
  • js面向对象
  • JS正则表达式精简教程(JavaScript RegExp 对象)
  • Leetcode 27 Remove Element
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • node 版本过低
  • Object.assign方法不能实现深复制
  • open-falcon 开发笔记(一):从零开始搭建虚拟服务器和监测环境
  • Traffic-Sign Detection and Classification in the Wild 论文笔记
  • 飞驰在Mesos的涡轮引擎上
  • 解决jsp引用其他项目时出现的 cannot be resolved to a type错误
  • 浅谈Golang中select的用法
  • 设计模式走一遍---观察者模式
  • 使用Envoy 作Sidecar Proxy的微服务模式-4.Prometheus的指标收集
  • 小程序开发之路(一)
  • 字符串匹配基础上
  • 国内唯一,阿里云入选全球区块链云服务报告,领先AWS、Google ...
  • ​​​​​​​​​​​​​​Γ函数
  • ​虚拟化系列介绍(十)
  • (10)Linux冯诺依曼结构操作系统的再次理解
  • (16)UiBot:智能化软件机器人(以头歌抓取课程数据为例)
  • (2)关于RabbitMq 的 Topic Exchange 主题交换机
  • (52)只出现一次的数字III
  • (8)Linux使用C语言读取proc/stat等cpu使用数据
  • (Forward) Music Player: From UI Proposal to Code
  • (Repost) Getting Genode with TrustZone on the i.MX
  • (九)c52学习之旅-定时器
  • (欧拉)openEuler系统添加网卡文件配置流程、(欧拉)openEuler系统手动配置ipv6地址流程、(欧拉)openEuler系统网络管理说明
  • (十六)一篇文章学会Java的常用API
  • (一)SpringBoot3---尚硅谷总结
  • (转)菜鸟学数据库(三)——存储过程
  • (转)重识new
  • ./configure、make、make install 命令
  • .NET Core6.0 MVC+layui+SqlSugar 简单增删改查
  • .NET 材料检测系统崩溃分析
  • .NET 简介:跨平台、开源、高性能的开发平台
  • .Net(C#)常用转换byte转uint32、byte转float等