Apache Tomcat AJP协议文件包含漏洞分析

2020-02-27 19:08 AJP Tomcat 漏洞分析

背景

Tomcat是由Apache软件基金会属下Jakarta项目开发的Servlet容器,按照Sun Microsystems提供的技术规范,实现了对Servlet和JavaServer Page(JSP)的支持。由于Tomcat本身也内含了HTTP服务器,因此也可以视作单独的Web服务器。2020年1月6日,国家信息安全漏洞共享平台(CNVD)收录了Apache Tomcat文件包含漏洞(CNVD-2020-10487,对应CVE-2020-1938)。攻击者可利用该漏洞读取或包含 Tomcat 上所有 webapp 目录下的任意文件,如:webapp 配置文件或源代码等,若服务器端同时存在文件上传功能,攻击者可进一步实现远程代码的执行。

AJP简介

AJP 的全称是 Apache JServ Protocol,支持AJP协议的Web容器包括Apache Tomcat,JBoss AS / WildFly和GlassFish
AJP是一个二进制协议,通常在存在负载平衡的部署中使用AJP,一般位于Web服务器的后面,使用路由机制将会话重定向到正确的应用服务器,其中每个应用服务器实例都获得一个名称。在这种情况下,Web服务器充当应用程序服务器的反向代理。最后,AJP支持请求属性,当在反向代理中使用特定于环境的设置填充请求属性时,该属性可提供反向代理与应用程序服务器之间的安全通信。

漏洞分析

运行Tomcat

打开下面的URL下载Tomcat运行程序
https://archive.apache.org/dist/tomcat/tomcat-7/v7.0.96/bin/apache-tomcat-7.0.96.zip
并进入bin目录执行 catalina.bat jpda start 采用调试模式启动 Tomcat 服务器

漏洞PoC

下载 https://github.com/hypn0s/AJPy ,并导入Tomcat类

t = Tomcat("127.0.0.1", 8009)
attributes = [
{'name':'req_attribute','value':['javax.servlet.include.request_uri','/']},
    {'name':'req_attribute','value':['javax.servlet.include.path_info','/index.jsp']},
    {'name':'req_attribute','value':['javax.servlet.include.servlet_path','/']},
]

r = t.perform_request("/fdsdf", attributes=attributes)
for x in r[1]:
   print(x.data)

可以看到读取到了index.jsp的源码

如果要执行webapp下的一个非jsp文件,将perform_request改成下面即可

r = t.perform_request("/fdsdf.jsp", attributes=attributes)

调试分析

在下面的位置打断点,此时request才刚开始处理
tomcat-coyote.jar!/org/apache/coyote/ajp/AjpProcessor.class:40

在tomcat-coyote.jar!/org/apache/coyote/ajp/AbstractAjpProcessor.class:532 中可以看到设置了当前request的属性,其中字段名为在PoC传入的 javax.servlet.include.*字段

通过CoyoteAdapter的postParseRequest函数进入到Servlet的处理流程
catalina.jar!/org/apache/catalina/connector/CoyoteAdapter.class:328

任意文件读取

根据Tomcat默认路由规则,/fdsdf 将会匹配到DefaultServlet
org.apache.catalina.servlets.DefaultServlet#serveResource

catalina.jar!/org/apache/catalina/servlets/DefaultServlet.class:171
进入到serveResource,将会调用getRelativePath从属性中获取真正的路径

通过自定义下面三个属性可以达到WEB目录下任意文件读取的作用。

javax.servlet.include.request_uri
javax.servlet.include.path_info
javax.servlet.include.servlet_path

任意文件后缀代码执行

根据Tomcat默认路由规则,/fdsdf.jsp 将会匹配到JspServlet

将目标1.txt当成jsp执行

为什么不能读取WEB目录外的文件

以进入到DefaultServlet为例,进入到函数serveResource函数,最终会调用
catalina.jar!/org/apache/naming/resources/FileDirContext.class:302 中的Validate函数,这里面包含多次验证,无法绕过WEB目录

影响版本

Apache Tomcat 6
Apache Tomcat 7 < 7.0.100
Apache Tomcat 8 < 8.5.51
Apache Tomcat 9 < 9.0.31

修复建议

1.更新到安全版本

Apache Tomcat 7.0.100
Apache Tomcat 8.5.51
Apache Tomcat 9.0.31

2.关闭AJP服务

(1)编辑 Tomcat 配置文件 conf/server.xml,找到如下行

<Connector port="8009"protocol="AJP/1.3" redirectPort="8443" />

(2)将此行进行注释掉

<!--<Connectorport="8009" protocol="AJP/1.3"redirectPort="8443" />-->

(3)保存配置文件,重新启动Tomcat

参考

https://www.cnvd.org.cn/flaw/show/CNVD-2020-10487
http://tomcat.apache.org/

评论(3)

2spontaneity

2023/01/27 06:53
2emblematic

3consecrate

2022/09/02 20:36
2preclude

crawlergo@gmail.com

2021/08/25 00:13
Crawlergo

发表评论

captcha