apache struts2漏洞 但是系统没有用_tomcat ajp漏洞

apache struts2漏洞 但是系统没有用_tomcat ajp漏洞0x00前言ApacheStruts是美国阿帕奇(Apache)软件基金会负责维护的一个开源项目,是一套用于创建企业级JavaWeb应用的开源MVC框架,主要提供两个版本框架产品:Struts1和Struts2。Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Contro

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

0x00 前言

       Apache Struts是美国阿帕奇(Apache)软件基金会负责维护的一个开源项目,是一套用于创建企业级Java Web 应用的开源MVC框架,主要提供两个版本框架产品:    Struts 1和Struts 2。 Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架。

0x01 漏洞原理

1、基于Jakarta Multipart解析器执行文件上传时存在远程代码执行漏洞2、恶意攻击者精心构造Content-Type的值
3、通过版本比对定位漏洞原因
①Content-Length 的长度值超长
②Content-Disposition的filename存在空字节
Content-Length 的长度值超长
这个漏洞需要在strust.xml中加入 <constant name=”struts.multipart.parser” value=”jakarta-stream” />才能触发。
触发漏洞的代码在 JakartaStreamMultiPartRequest类中,processUpload函数处理了content-length长度超长的异常,导致问题触发。
private void processUpload(HttpServletRequest request, String saveDir)
        throws Exception {

    // Sanity check that the request is a multi-part/form-data request.
    if (ServletFileUpload.isMultipartContent(request)) {

        // Sanity check on request size.
        boolean requestSizePermitted = isRequestSizePermitted(request);
        // Interface with Commons FileUpload API
        // Using the Streaming API
        ServletFileUpload servletFileUpload = new ServletFileUpload();
        FileItemIterator i = servletFileUpload.getItemIterator(request);
        // Iterate the file items
        while (i.hasNext()) {

            try {

                FileItemStream itemStream = i.next();
                // If the file item stream is a form field, delegate to the
                // field item stream handler
                if (itemStream.isFormField()) {

                    processFileItemStreamAsFormField(itemStream);
                }
                // Delegate the file item stream for a file field to the
                // file item stream handler, but delegation is skipped
                // if the requestSizePermitted check failed based on the
                // complete content-size of the request.
                else {

                    // prevent processing file field item if request size not allowed.
                    // also warn user in the logs.
                    if (!requestSizePermitted) {

                        addFileSkippedError(itemStream.getName(), request);
                        LOG.warn(“Skipped stream ‘#0’, request maximum size (#1) exceeded.”, itemStream.getName(), maxSize);
                        continue;
                    }
                    processFileItemStreamAsFileField(itemStream, saveDir);
                }
            } catch (IOException e) {

                e.printStackTrace();
            }
        }
    }
}
触发点在LOG.warn(“Skipped stream ‘#0’, request maximum size (#1) exceeded.”, itemStream.getName(), maxSize);
之后进入了函数addFileSkippedError,我们又见到了熟悉的buildErrorMessage,而这次带入的参数为fileName
private void addFileSkippedError(String fileName, HttpServletRequest request) {

    String exceptionMessage = “Skipped file ” + fileName + “; request size limit exceeded.”;
    FileSizeLimitExceededException exception = new FileUploadBase.FileSizeLimitExceededException(exceptionMessage, getRequestSize(request), maxSize);
    String message = buildErrorMessage(exception, new Object[]{fileName, getRequestSize(request), maxSize});
    if (!errors.contains(message))
        errors.add(message);
}
Content-Disposition的filename存在空字节
第二种触发漏洞的方式,属于直接触发,在streams.class中,会对filename进行检查,如果检查出错,也会记录log。
public static String checkFileName(String fileName) {

    if (fileName != null  &&  fileName.indexOf(‘\u0000’) != -1) {

        // pFileName.replace(“\u0000”, “\\0”)
        final StringBuilder sb = new StringBuilder();
        for (int i = 0;  i < fileName.length();  i++) {

            char c = fileName.charAt(i);
            switch (c) {

                case 0:
                    sb.append(“\\0”);
                    break;
                default:
                    sb.append(c);
                    break;
            }
        }
        throw new InvalidFileNameException(fileName,
                “Invalid file name: ” + sb);
    }
    return fileName;
}
最终进入的是JakartaStreamMultiPartRequest类的,我们又见到了buildErrorMessage
public void parse(HttpServletRequest request, String saveDir)
        throws IOException {

    try {

        setLocale(request);
        processUpload(request, saveDir);
    } catch (Exception e) {

        e.printStackTrace();
        String errorMessage = buildErrorMessage(e, new Object[]{});
        if (!errors.contains(errorMessage))
            errors.add(errorMessage);
    }
}

0x02漏洞危害

   通过Jakarta 文件上传插件可执行具有恶意Content-Disposition 值或具有不正确Content-Length 报头的RCE攻击,直接获取应用系统所在服务器的控制权限,进而控制网站服务器

0x03 修复建议

1、升级版本: 请升级至Struts2安全版本
Struts 2.3.32:https://cwiki.apache.org/confluence/display/WW/Version+Notes+2.3.32 
Struts 2.5.10.1:https://cwiki.apache.org/confluence/display/WW/Version+Notes+2.5.10.1 

欢迎大家分享更好的思路,热切期待^^_^^ !

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/194054.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 用websocket实现实时聊天功能

    用websocket实现实时聊天功能最近想实现网页版的仿QQ聊天工具,本来想用ajax实现的,但是一想到要一直轮询,就感觉有点蠢。后来在网上找到了websocket相关的资料,就拿来跟大家分享下(不是很熟练,现在只实现了群聊,单聊的前端不会写了。但可以跟大家说说思路)。服务器端代码:首先要创建类WebSocketConfig实现ServerApplicationConfig接口,ServerApplicationConfig项目…

    2022年10月21日
  • uint16_t转换成char_16bit转8bit

    uint16_t转换成char_16bit转8bit简单来说,uint8_t/uint16_t/uint32_t/uint64_t这些数据类型都只是别名而来,具体如下:一、C语言数据基本类型在C语言中有6种基本数据类型:short、int、long、float、double、char1)整型:shortint、int、longint2)浮点型:float、double3)字符类型:char二、分析uint8_…

  • 百度面试题

    百度面试题1.一个int数组,里面数据无任何限制,要求求出所有这样的数a[i],其左边的数都小于等于它,右边的数都大于等于它。能否只用一个额外数组和少量其它空间实现。这道题的解答请看下一篇日志2.一个文件,内含一千万行字符串,每个字符串在1K以内,要求找出所有相反的串对,如abc和

  • 线程池详解(通俗易懂超级好)「建议收藏」

    线程池详解(通俗易懂超级好)「建议收藏」目标【理解】线程池基本概念【理解】线程池工作原理【掌握】自定义线程池【应用】java内置线程池【应用】使用java内置线程池完成综合案例线程池线程池基础线程池使用线程池综合案例4.学员练习5.线程池总结概念介绍1:什么是线程池2:为什么使用线程池3:线程池有哪些优势什么是池什么是线程池线程池其实就是一种多线程处理形式,处理过程中可以将任务添加到队列中,然后在创建线程后自动启动这些任务。这里的线程就是我们前面学过的线程,这里的任务就是我们前面学过的实现了Runna.

    2022年10月24日
  • HTTP详解(1)-工作原理「建议收藏」

    HTTP详解(1)-工作原理「建议收藏」1.HTTP简介HTTP协议(HyperTextTransferProtocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传送协议。它可以使浏览器更加高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示(如文本先于图形)等。在了解HTTP如何工作之前,我…

  • c语言 自己编程解析 xml,C语言解析.XML文件

    c语言 自己编程解析 xml,C语言解析.XML文件最近手头上有个活在忙,中间很重要的一部分就是用C语言将.XML文件中想要的key和value读出来,与之前已有的值进行比较。核心的.XML文件的格式如下:zzzxxxyyy而我的思路是这样的:1.将整个文件读到一个buf中;2.去掉不需要的头部分;(xml?>)3.采用下降递归的方法,获取到每一个人tag和content;其中用到的结构体有:typedefstructXM…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号