tomcat ajp 漏洞分析

什么是ajp

简单理解成http的二进制优化版。
image.png

tomcat结构

在Container部分,一个Host代表一个虚拟主机,一个Context代码一套web程序,一个Wrapper代表一个serlvlet。一个tomcat可以有多个Host,一个Host可以有多个Context,一个Context往往有多个Wrapper。
image.png

在Conector部分Endpoint的Acceptor监听连接,Handler用于处理接收到的Socket,在内部调用Processor进行处理。processor把信息读取出来并设置进request中对象最后交给Adaptor,Adapter将请求适配到Servlet容器进行具体的处理。
image.png

环境说明

tomcat 7.0.96

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0"
metadata-complete="true">

<display-name>Welcome to Tomcat</display-name>
<description>
Welcome to Tomcat
</description>

</web-app>

代码流程跟踪

代码跟踪从handler调用processor的process开始。
image.png
process里面有两部很重要一个是prepareRequest,另一个是this.adapter.service。image.png

prepareRequest

先来看prepareRequest。顾名思义,这个函数的作用是把ajp的二进制版的http数据读取(请求方法,请求路径,http头等信息,不每处都截图了)并设置进request对象,然后设置一些对header和cookies长度或数量做一些限制。
image.png
接下来会读取一个叫attributeCode的东西,payload有意把它设置成了10。这样他会把我们在payload中构造的attributes设置进request对象的attribute,后面任意读文件或者包含祸起就是从这里开始的。

1
2
3
4
5
6
7
file_path = "/WEB-INF/web.xml"

attributes = [
{"name": "req_attribute", "value": ("javax.servlet.include.request_uri", "/",)},
{"name": "req_attribute", "value": ("javax.servlet.include.path_info", file_path,)},
{"name": "req_attribute", "value": ("javax.servlet.include.servlet_path", "/",)},
]

image.png

adapter.service

在adapter.service中会在postParseRequest中对url进行处理及合法性检查(这里面可能涉及到对url权限校验的问题以后有机会再聊)。如果合法的会进入下面的invoke。
image.png

跟进invoke后会发现是一连串疯狂的invoke,这里取几个有代表性的截图
StandardEngineValve invoke
image.png
StandardHostValve invoke
image.png
StandardContextValve invoke
image.png
最后进入StandardWrapperValve的invoke
wrapper.allocate会返回这次请求对应的servlet,因为我们访问路径是/,所以默认对应index.jsp,所以由jspServlet来处理。
image.png
接下来进入过滤器链
image.png
doFilter内部调用internalDoFilter
image.png
在internalDoFilter中会遍历所有注册过的filter然后进行过滤。遍历完成后会调用对应servlet的services方法。
image.png
image.png
这里会把payload中的 javax.servlet.include.request_uri javax.servlet.include.path_info提取并拼接到一起形成jspUri。
image.png
这里jspUri会被传入,正常情况下这里传入的是jsp,tomcat会把jsp转为servlet,但是因为我们传入的路径是是非jsp文件不符合语法所以这部分原样输出。因此另一种使用方法也呼之欲出,如果有一个上传洞可以把文件上传到webapp目录下(不管什么后缀)那么我们可以包含这个文件达到rce效果(和php很像)。
image.png
image.png
image.png

补充,只能包含webapp下面的东西。在读取之前会对传入的路径进行格式化,并在格式化后强制加/,无法../跳出。
image.png

代码流程跟踪图

image.png

受影响版本

  • Apache Tomcat 9.x < 9.0.31
  • Apache Tomcat 8.x < 8.5.51
  • Apache Tomcat 7.x < 7.0.100
  • Apache Tomcat 6.x

其他

文中分析的是最理想的情况实际利用会受到过滤器或是框架的影响关于这部分内容可以看如何更加精确的检测Tomcat AJP文件包含漏洞(CVE-2020-1938)

参考

Tomcat Ajp协议文件包含漏洞分析
tomcat幽灵猫分析

Author

李三(cl0und)

Posted on

2020-04-26

Updated on

2024-08-11

Licensed under