Apache Tomcat 任意文件读取漏洞复现与分析

漏洞原因:

由于Tomcatajp传递过来的数据的处理存在问题,导致我们可以控制“javax.servlet.include.request_uri”“javax.servlet.include.path_info”“javax.servlet.include.servlet_path”,这三个参数,从而读取任意文件

漏洞环境:

Tomcat 8.0.50版本搭建,

http://archive.apache.org/dist/tomcat/tomcat-8/v8.0.50/

下载对应的Tomcat源码文件,和可执行文件。

注意:版本需一致,如下图所示:

Apache Tomcat 任意文件读取漏洞复现与分析

访问http://localhost:8080/出现下图即搭建成功。

Apache Tomcat 任意文件读取漏洞复现与分析

漏洞复现:

成功执行exp非授权访问到指定文件

Apache Tomcat 任意文件读取漏洞复现与分析

Apache Tomcat 任意文件读取漏洞复现与分析

漏洞分析:

tomcat默认的conf/server.xml中配置了2个Connector,一个为8080的对外提供的HTTP协议端口,另外一个就是默认的8009 AJP协议端口,AJP 协议可以理解为 HTTP 协议的二进制性能优化版本,它能降低 HTTP 请求的处理成本,因此主要在需要集群、反向代理的场景被使用。如下图所示:

Apache Tomcat 任意文件读取漏洞复现与分析

tomcat服务启动后,查看端口可以发现8009端口已经处于监听状态:

Apache Tomcat 任意文件读取漏洞复现与分析

在接收ajp请求的时候会调用org.apache.coyote.ajp.AjpProcessor来处理ajp消息,由于环境是tomcat 8.0.50版本搭建的,产生漏洞的点并不在AjpProcessor.prepareRequest()方法,tomcat8.0.50版本的漏洞点存在于AjpProcessor的父类,AbstractAjpProcessor这个抽象类的prepareRequest()。我们在此处下断点

Apache Tomcat 任意文件读取漏洞复现与分析

Debug模式启动tomacat-8.0.50版本,然后对指定ip、指定端口运行exp

Apache Tomcat 任意文件读取漏洞复现与分析

此时的调用链如下:

Apache Tomcat 任意文件读取漏洞复现与分析

走的是8009端口,经过几次调用交由AbstractAjpProcessor.prepareRequest(),该方法就是漏洞产生的第一个点。

Apache Tomcat 任意文件读取漏洞复现与分析

跟进去request.setAttribute()方法看一下,发现是HashMap,意思是将我们通过AJP协议传递过来的三个参数循环遍历存入这个HashMap

 

接着看request.setAttribute()发现运行了三次

Apache Tomcat 任意文件读取漏洞复现与分析

While循环的结果是将三个参数存到Request对象的attributes属性下:

Apache Tomcat 任意文件读取漏洞复现与分析

通过AJP协议传来的数据最终还是要交由Servlet来进行处理的,查看了ajp协议的介绍,配置Apache以提供静态Web应用程序文件。所以由DefaultServlet来处理,DefaultServlet主要用于处理静态资源,如HTML、图片、CSSJS文件等,而且为了提升服务器性能,Tomcat对访问文件进行缓存。按照默认配置,客户端请求路径与资源的物理路径是一致的。

Apache Tomcat 任意文件读取漏洞复现与分析

定位到DefaultServletdoGet方法doGet方法里面又调用了serveResource()

Apache Tomcat 任意文件读取漏洞复现与分析

跟进去serveResource(),发现调用了getRelativePath()方法来进行路径拼接,

Apache Tomcat 任意文件读取漏洞复现与分析

跟进去发现如果跟进去的数据有request_uri,就对path_info servlet_path进行赋值,如果发送的数据包中没有request_uri,就会走else后面的两行代码进行赋值。

Apache Tomcat 任意文件读取漏洞复现与分析

接下来就是对路径的拼接了,这里可以看到如果传递数据时不传递servlet_path,则result在进行路径拼接时就不会讲“/”拼接在“WEB-INF/web.xml”的头部,最后拼接的结果仍然是“WEB-INF/web.xml”

 Apache Tomcat 任意文件读取漏洞复现与分析

接下来返回到DefaultServle.serveResource(),紧接着判断path变量长度是否为0,为0则调用目录重定向方法

Apache Tomcat 任意文件读取漏洞复现与分析

往下走,开始读取指定的资源文件了

Apache Tomcat 任意文件读取漏洞复现与分析

跟进去发现getResource()方法中又调用了一个很重要的方法validate()方法并将path作为变量传递进去进行处理

Apache Tomcat 任意文件读取漏洞复现与分析

继续跟入

Apache Tomcat 任意文件读取漏洞复现与分析

我们可以看到正常请求最后return的result的路径就是我们文件所在的相对路径。

当我们尝试使用WEB-INF/../../Test.txt来读取webapps以外的目录中的文件时。可以看到此时返回的result就是null了,而且会抛出异常。

因为RequestUtil.normalize()这个函数对我们传递进来的路径处理上做了判断

Apache Tomcat 任意文件读取漏洞复现与分析

我们传入的路径是“/WEB-INF/../../Test.txt”,首先程序会判断我们的路径中是否存在“/../”,自然是存在的且索引是8大于0,所以第一个if 判断不会成功,也就不会跳出while循环,此时处理我们的路径,截取“/WEB-INF/..”以后的内容,然后在用String,indexOf()函数判断路径里是否有“/../”,显然还是有的,且索引为零,符合第二个if判断的条件,return null。

Apache Tomcat 任意文件读取漏洞复现与分析

此处的目的就是 不允许传递以“/../”为开头的路径,且不允许同时出现两个连在一起的“/../” 所以我们最多只能读取到webapps目录,无法读取webapps以外的目录中的文件。

程序最终拼接出我们所指定文件的绝对路径,并作为返回值进行返回

Apache Tomcat 任意文件读取漏洞复现与分析

接下来就是回到getResource()函数进行文件读取了

Apache Tomcat 任意文件读取漏洞复现与分析

跟进去

Apache Tomcat 任意文件读取漏洞复现与分析

任意文件读取的调用链

Apache Tomcat 任意文件读取漏洞复现与分析

 

漏洞利用方式:

由以上漏洞分析可知:

  1. 利用DefaultServlet实现任意文件下载。

当url请求未在映射的url列表里面,会通过tomcat默认的DefaultServlet,根据上面的三个属性来读取文件,通过serveResource方法来获取资源文件:

通过getRelativePath来获取资源文件路径:

  1. 通过jspservlet实现任意后缀文件包含

网站应用提供文件上传的功能,攻击者可以先向服务端上传一个内容含有恶意 JSP 脚本代码的文件(上传的文件本身可以是任意类型的文件,比如图片、纯文本文件等),然后利用 Ghostcat 漏洞进行文件包含,从而达到代码执行的危害。

当url(比如http://xxx/xxx/xxx.jsp)请求映射在org.apache.jasper.servlet.JspServlet这个servlet的时候,也可以通过上述三个属性来控制访问的jsp文件,如下图所示:

控制路径之后就能以jsp解析该文件,所以只需要一个内容可控的文件即可实现rce。

漏洞修复:

1.临时禁用AJP协议端口,在conf/server.xml配置文件中注释掉

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

2.配置ajp配置中的secretRequired跟secret属性来限制认证

3.官方下载最新版下载地址:

https://tomcat.apache.org/download-70.cgi

https://tomcat.apache.org/download-80.cgi

https://tomcat.apache.org/download-90.cgi

https://github.com/apache/tomcat/releases

相关链接:

AJP协议规范:https://tomcat.apache.org/connectors-doc/ajp/ajpv13a.html

参考链接:

Tomcat AJP协议漏洞分析与利用:https://www.freebuf.com/column/227973.html

Ghostcat 是存在于 Tomcat 中的高危文件读取/包含漏洞:https://www.chaitin.cn/zh/ghostcat