Apache Tomcat - 远程代码执行漏洞 - CVE-2024-50379

0x01:漏洞简介

部分版本 Apache Tomcat 由于在验证文件路径时存在缺陷,如果 readonly 参数被设置为 false(这是一个非标准配置),并且服务器允许通过 PUT 方法上传文件,那么攻击者就可以上传含有恶意 JSP 代码的文件。通过不断的发送请求,攻击者可以利用条件竞争漏洞,使得 Tomcat 解析并执行这些恶意文件,从而实现远程代码执行。

该漏洞的利用具有以下两个前提:

  • Tomcat 启用 PUT 方法(在 Tomcat 的 default servlet 配置中将 readonly 设置为 false)。

  • Tomcat 运行在大小写不敏感的操作系统上,比如 Windows。

0x02:影响范围

  • 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

0x03:环境搭建

环境准备

  • 靶机环境:Windows 7 - IP 172.16.0.102

  • 攻击机环境:Kali Linux - IP 172.16.0.103

0x0301:靶机环境搭建

靶机:Windows 7 服务器配置概览

笔者上面提供了一个 Java JDK 的二进制安装包,解压后添加到环境变量中即可,对应的 Java 版本截图如下:

笔者还提供了一个 9.0.63 的 Apache Tomcat 安装包,也是下载后解压添加到环境变量中即可使用,其版本信息如下(安装方式参考:环境配置 - Java - Apache Tomcat 安装与配置):

除了安装上面这两个环境外,我们还需要修改一下 Apache Tomcat 的配置,将 default servlet 的 readonly 配置修改为 false,开启 Tomcat 的 PUT 功能。(漏洞的前置条件之一)

Tomcat 的配置路径在其安装路径的 /conf/web.xml

以记事本的方式打开它,然后搜索下面的内容:

 <servlet-name>default</servlet-name>

然后在这里添加下面的配置,将 DefaultServlet 的 readonly 参数设置为 false:

 <init-param>
     <param-name>readonly</param-name>
     <param-value>false</param-value>
 </init-param>

0x0302:攻击机环境搭建

攻击机:Kali Linux 服务器配置概览

攻击机中没有什么需要配置的东西,从上面那两个地址中挑一个,将漏洞对应的 POC 上传到靶机中即可,POC 用法如下(下面复现时候会演示):

 ./CVE-2024-50379 -u http://192.168.2.245:8080 -f shell.jsp -p ggsl.jsp
 # -f shell.jsp => 本地要上传的文件
 # -p ggsl.jsp => 保存到目标服务器上的名称(路径)
 # -u => Tomcat 服务器的 url

0x04:漏洞复现

0x0401:开启靶机的 Tomcat 服务

首先来到靶机中,在命令行中输入下面的命令,运行 Tomcat 服务:

 startup

然后我们在攻击机中访问靶机的 8080 端口,看看能不能看到靶机的 Tomcat 服务:

 http://172.16.0.102:8080

0x0402:CVE-2024-50379 漏洞复现

此漏洞的复现十分简单,本质上是一个条件竞争漏洞。我们需要开启两个线程,一个线程不断尝试向 Tomcat 提交包含恶意代码的 JSP 脚本文件,另外一个线程不断的向 Tomcat 请求我们上传的 jsp 文件,如果请求成功的话,jsp 中的恶意代码就会被执行,攻击也就成功了。

上面这个流程很繁琐,但好在,已经有大佬帮忙写好了 POC 了(笔者上面提供的那个),至于恶意脚本,就看个人编程能力了。不过笔者在刚刚提供的那个 POC 中包含了一个测试用的恶意脚本,内容如下:

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

该代码在执行后会让 Windows 电脑弹出一个计算机。

然后我们输入下面的命令,使用 CVE-2024-50379 的 POC,尝试将我们的 test.jsp 上传到目标的 Tomcat 服务器上(运行后需要等待一会):

 chmod +x CVE-2024-50379_linux_amd64 # 为 POC 赋予执行权限
 ./CVE-2024-50379_linux_amd64 -u http://172.16.0.102:8080 -f test.jsp -p test.jsp
 ​
 # -u http://172.16.0.102:8080 => 这个是我们靶机 Tomcat 的地址
 # -f test.jsp => 这个是我们想要上传的文件名
 # -p test.jsp => 这个是期望服务端保存的文件名,随意都行

如上,运行 POC 后等待一会显示 利用成功:http://172.16.0.102:8080/test.jsp,就证明攻击成功了。

现在,只要我们只要一使用浏览器访问上面这个地址,靶机中就会执行 test.jsp 文件,就会弹出一个计算器(笔者这里就通过 Linux 的 curl 命令来模拟浏览器访问啦):

0x05:漏洞分析

下面我们来分析一下这个漏洞产生的原因(不涉及 Tomcat 源码,小白也可轻松看懂)。我们先来了解一下 Tomcat 上传文件的流程:

在 Tomcat 中,当用户刚上传一个 test.JSP(注意,后缀是大写的),然后在一个很短的时间对这个文件发起访问,Tomcat 会调用 getCanonicalPath 方法来获取这个文件的名称,此时返回的名称是 test.jsp。当过一小会后,再次请求该文件时,getCanonicalPath 方法就会返回 test.JSP。

以上其实就是本次漏洞产生的原因(是不是有点蒙),我知道你的疑问:

  • test.JSP 与 test.jsp 有啥差别?

Tomcat 是禁止直接上传 .jsp 文件的,因为后缀为小写的 .jsp 文件,当用户访问时,Tomcat 会交给 jspServlet 处理,它会直接执行文件中的代码。而当用户访问后缀为大写的 .JSP 文件时,Tomcat 会交给 defaultServlet 处理,defaultServlet 在处理文件时,会直接把文件内容返回给浏览器,并不会直接执行它。

然后我们再来了解一下 Tomcat defaultServlet 的 readonly 参数:该参数是用来控制 default servlet 是否允许读写的,默认情况下,readonly 值为 true,表示 default servlet 仅支持读取文件,不允许通过 HTTP 请求(如 PUT 或 DELETE)修改或删除文件。当该参数设置为 false 时,就代表允许 default servlet 进行读写操作,这意味着客户端可以通过 HTTP 请求(如 PUT 或 DELETE)上传,修改或者删除服务器上的文件。

知道了以上信息后,我们再来梳理一下这个漏洞的利用过程:

  1. 因为服务端配置问题,导致用户可以通过 HTTP 请求上传文件。

  2. 攻击者开启一个线程,不断的向服务端上传 test.JSP 文件。(上传的是大写的 JSP 哈)

  3. 攻击者又开启一个线程,不断的尝试请求服务端的 test.jsp 文件。

  4. 服务端收到请求后尝试找 test.jsp 文件,但是由于 Windows 系统大小写不敏感的特性,它找到了 test.JSP 文件(对于 Windows 系统,abc.txtABC.txt 其实是一个文件),然后它就把 test.JSP 文件内容当成 test.jsp 文件,直接给执行了,就造成了 RCE 漏洞。

明确了上面这些后,我们再来看看这个 CVE-2024-50379 POC 的逻辑,首先来到靶机 Tomcat 的根目录看看,路径就是你 Tomcat 安装目录下的 webapps/ROOT

上面框出来的那两个文件就是 POC 一开始上传的文件,这里我们通过 Tomcat 访问看看:

和我们之前介绍的一样,你访问 .Jsp 这种包含大写字母的文件扩展名,经过 Tomcat 处理后会直接显示文件内容,而不会执行。上面那个就是 POC 创建的文件,其实逻辑很简单,content 变量里就是我们本地写的恶意程序经过 base64 编码后的内容,我们可以解码看看:

如上,我们可以推测,这个 POC 先将我们的恶意程序进行 Base64 编码后,保存到 content 字符串中,然后利用 CVE-2024-50379 漏洞,上传一个 .Jsp 文件,并不断访问它,终于有一次,访问成功了,它上传的这个 .Jsp 文件执行,在目标服务器中创建了一个 test.jsp,内容就是 Base64 解码后的恶意程序。

这就是为啥,我们后面即使很慢的访问 test.jsp 也能让目标执行代码的原因。从这里也可以看出来,Tomcat 处理 .Jsp 文件与 .jsp 文件还是有差别的。

0x06:修复方案

安全更新:更新 Apache Tomcat 到最新版本即可解决该漏洞。

修复缓解措施

  1. 在不影响业务的前提下将 conf/web.xml 文件中的 readOnly 参数设置为 true 或直接注释该参数。

  2. 禁用 PUT 方法并重启 Tomcat 服务以启用新的配置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Blue17 :: Hack3rX

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值