b1cat`s

Ajp任意文件读取和包含漏洞调试

Word count: 891Reading time: 3 min
2020/02/26

Ajp任意文件读取和包含漏洞调试

漏洞简述

Apache Tomcat AJP协议(默认8009端口)由于存在实现缺陷导致相关参数可控,攻击者利用该漏洞可通过构造特定参数,读取服务器webapp目录下的任意文件。若服务器端同时存在文件上传功能,攻击 者可进一步结合文件包含实现远程代码的执行。

影响范围

1
2
3
4
Tomcat 6.*
Tomcat 7.* < 7.0.100
Tomcat 8.* < 8.5.51
Tomcat 9.* < 9.0.31

遇到几个问题

  1. Ajp如何到HTTP

  2. 漏洞触发原理及利用

  3. 调试过程中的问题

1. Ajp如何到HTTP

AJP协议是定向包(面向包)协议,采用二进制形式代替文本形式,以提高性能。

image-20200226195010805

tomcat web路由 conf/web.xml

  • 第一条:url 为/开头default路由,对应servlet,org.apache.catalina.servlets.DefaultServlet
  • 第二条:url为*.jsp,*.jspx的路由,对应servle,org.apache.jasper.servlet.JspServlet

image-20200226195405072

image-20200226195739793

image-20200226195746201

2. 漏洞触发原理及利用过程

漏洞原理:

在Ajp接受到数据后, 先进行prepareRequest()获取request属性,然后getAdapter().service(request, response)根据web路由发送servlet对象处理。

其中以*.jsp, *.jspx结尾的URI会经JspServlet处理,而其他请求资源使用DefaultServlet处理。

在处理过程中使用了用户可控的request 属性,然后造成文件读取,及文件包含漏洞(需能上传文件)。

触发过程:

tomcat开启调试:

image-20200226201030164

任意文件读取

执行poc:

image-20200227120353857

Ajp处理数据:

image-20200226201112957

  • AjpProcessor->prepareRequest()取出request属性

image-20200226201139795

  • getAdapter().service(request, response); 发送给HTTP servlet处理

image-20200226201309298

image-20200226201314804

  • 获取get资源

image-20200226201326747

  • 通过getRelativePath获取资源路径
image-20200226201507868
  • getAttribute需要三个属性

    • request_uri = RequestDispathcher.INCLUDE_REQUEST_URL

    • path_info = RequestDispathcher.INCLUDE_PATH_INFO

    • servlet_path = RequestDispathcher.INCLUDE_SERVLET_PATH

      可控路径path = servletPath + pathinfo/WEB-INF/web.xml

      • url目录来源resource对象根据url进行了一个路径匹配 然后在设置context的值
      image-20200227211511003

      最终路径 = url目录+ path/manager/WEB-INF/web.xml

    image-20200226201555534

    image-20200227122416708

  • 获取资源

image-20200226202044896

  • 输出

image-20200226202110197

文件包含RCE

运行poc , 这个1.jsp并不要实际存在,目的只是为了走JspServlet路由

test.xml是提前上传的文件

1
2
//test.xml
<%Runtime.getRuntime().exec("open -a Calculator");%>

image-20200227121607194

可控路径 = jspUri = servlet_path + path_info

最终路径 = url目录+jspUri ,即/manager/test.xml

image-20200226202318630

由我们控制的 jspuri 被封装成了一个 JspServletWrapper 添加到了Jsp运行上下文 JspRuntimeContext 中.最后 wrapper.service() 会编译 test.xml ,并执行它的 _jspService() 方法来处理当前请求,我们的代码被执行。

image-20200227121527529

在其他目录也是如此:

image-20200226202335867

3. 调试过程中的问题

1. 为何不能跳出wabapps目录读取/etc/passwd

测试传递 ../../../../etc/passwd

image-20200226203215183

  • 存在validate对路径做验证

image-20200226203236772

image-20200226203245388

image-20200226203255359

  • RequestUtil.normalize(String, boolean) line: 100 因为匹配到/../返回0,然后报错

image-20200226203304763

image-20200226203359137

2. 有的目录下文件读取或包含不成功

原因:如访问/docs会先重定向/docs/

image-20200226203932737

3. 调试时出现sourece not found无法看到源码

image-20200226203721480

解决方法:

debug配置中导入项目源码包

  • 先导出,项目右键export->jar

image-20200226203807083

  • 配置导入,Debug config -> Add -> External Archive -> tomcat.jar

image-20200226203859853

修复方法

1
2
3
4
5
//tomcat修复
1. 默认不开启AJP
2. 默认只监听本地ip
3. 强制设置认证secret
4. 代码层面主要在 AjpProcessor 类的 prepareRequest 方法封装 requst 对象时采用了白名单,只添加已知属性。这样 三个include属性 不再被客户端控制,漏洞修复。

####参考链接

ajp-bug

eclipse调试tomcat

Eclipse的Debug调试技巧大全
AJP协议总结与分析

CVE-2020-1938:Tomcat AJP文件包含漏洞分析

脚本来源https://github.com/b1cat/CVE_2020_1938_ajp_poc

CATALOG
  1. 1. Ajp任意文件读取和包含漏洞调试
    1. 1.0.1. 漏洞简述
    2. 1.0.2. 影响范围
    3. 1.0.3. 遇到几个问题
    4. 1.0.4. 1. Ajp如何到HTTP
    5. 1.0.5. 2. 漏洞触发原理及利用过程
      1. 1.0.5.1. 漏洞原理:
      2. 1.0.5.2. 触发过程:
        1. 1.0.5.2.1. 任意文件读取
        2. 1.0.5.2.2. 文件包含RCE
    6. 1.0.6. 3. 调试过程中的问题
      1. 1.0.6.1. 1. 为何不能跳出wabapps目录读取/etc/passwd
      2. 1.0.6.2. 2. 有的目录下文件读取或包含不成功
      3. 1.0.6.3. 3. 调试时出现sourece not found无法看到源码
    7. 1.0.7. 修复方法