• AJP 文件包含漏洞分析


    0x01. 前言

    时隔应该快一年了吧,具体ghost这个漏洞出来我也忘记了,由于我最近无聊,然后想起我使用的tomcat有没有漏洞,于是我就来试了试,顺便分析一下这段已经时隔许久的漏洞,依稀记得上次的文章是简单的复现~~ 反正是闲的无聊

    0x02. 环境部署

    idea2020.2 + tomcat7.0.99+jdk1.8

    具体参考这篇文章,idea导入Tomcat源码:

    https://blog.csdn.net/u013268035/article/details/81349341

    https://www.cnblogs.com/r00tuser/p/12343153.html

    0x03.漏洞的基础

    Tomcat部署的时候会有两个重要的文件

    而Tomcat在 server.xml中配置了两种连接器。其中包含的是AJP Connector和HTTP Connector

    AJP Connector说明启用了8080和8009端口,这时候我们可以看一下


    而相对于,8080我们是可以访问的

    也就是说,8080是负责Http协议,8009负责接收ajp协议;

    提问1:AJP协议和HTTP协议有什么区别吗?

    HTTP协议:负责接收建立HTTP数据包,成为一个web服务器,处理HTTP协议的同时还额外可处理Servlet和jsp

    AJP协议: 负责和其他的HTTP服务器建立连接, 通过AJP协议和另一个web容器进行交互

    Web用户访问Tomcat服务器的两种方式

    而一个Tomcat就是一个server,其中包含多个service;而每个service由ConnectorContainer、Jsp引擎、日志等组件构成,造成漏洞的关键地方是ConnectorContainer

    Connector上面已经说过分别是AJP ConnectorHTTP Connector ,是用来接受客户端的请求,请求中的数据包在被Connector解析后就会由Container处理。这个过程大致如下图:

    一次请求的处理可以划分为ConnectorContainer进行处理,经历的过程大致如下:

    • 一个TCP/IP数据包发送到目标服务器,被监听此端口的Tomcat获取到。
    • 处理这个Socket网络连接,使用Processor解析及包装成request和response对象,并传递给下一步处理。
    • Engine来处理接下来的动作,匹配虚拟主机Host、上下文Context、Mapping Table中的servlet。
    • Servlet调用相应的方法(service/doGet/doPost...)进行处理,并将结果逐级返回。

    小结

    对于使用HTTP协议或AJP协议进行访问的请求来讲,在解析包装成为request和response对象之后的流程都是一样的,主要的区别就是对 socket流量的处理以及使用Processor进行解析的过程的不同

    也就是第二步的地方出现问题

    0x04.源码分析

    通过第三步中,我们知道是Processor的解析过程不同,而提供这部分功能的接口,在 org.apache.coyote.Processor,主要负责请求的预处理。

    而此处AjpProcessor则是处理ajp协议的请求,并通过它将请求转发给Adapter,针对不用的协议则具有不同的实现类。

    我们从上面wirshark抓包可以看出

    可以看出这边是设置了三个莫名其妙的东西

    通过exp源码可以看到这边是设置了三个域对象的值


    可以看出,我们这边是执行成功了,由于wirshark抓包没有去截图,又关闭了,所以就不截图了

    这边可以假设:请求参数时是写死,也就是xxx.jsp文件,而jsp后缀等等原因,然后成功进行了文件包含

    那么我们的test.txt是怎么识别的?

    我们继续往下看,来解决种种疑惑

    知道是这个prepareRequest()问题,我们f7跟进去看看


    进入了该方法的内部,我们继续跟进查看,这边进行判断,获取到了请求参数为GET

    首先是一些解析数据包读取字节的操作

    while循环获取,switch判断

    attributeCode=10时,则进入第一条分支,继续f8进去




    是不是有了有种眼熟的感觉~~~ 其实就是往域对象中存值

    由于if都不满足,直接进入了最后这个比进的else分支


    最后进入第二个步骤的最后一小步,f8继续下一步走,在预处理完了request headers之后,在adapter里面处理request,然后调用Adapter将请求交给Container处理


    进入service方法,然后f8一直跟进

    直到跟进此处,请求会发送到对应的servlet,我们请求的是一个jsp文件,根据tomcat的默认web.xml文件

    通过上面假设,tomcat默认将jsp/jspx结尾的请求交给org.apache.jasper.servlet.JspServlet处理,它的service()方法如下:


    而jspUri等于null,满足条件,则进入该if条件分支

    由于javax.servlet.include.servlet_path可控制,通过getAttribute去域对象中获取属性名为javax.servlet.include.servlet_path的值,得到值为 test.txt


    此时,jspUri的值为/test.txt

    pathInfo的值此时为空


    最后一直到下面,传入serviceJspFile方法中

    继续跟进,会先判断文件是否存在,如果存在,随后才会初始化wrapper,最后调用JspServletWrapperservice方法来解析,从而导致本地文件包含

    参考

    [https://gitee.com/wdragondragon/javasec/blob/master/tomcat ajp任意文件包含漏洞分析.md](https://gitee.com/wdragondragon/javasec/blob/master/tomcat ajp任意文件包含漏洞分析.md)

    https://www.cnblogs.com/r00tuser/p/12343153.html

    https://xz.aliyun.com/t/7325#toc-6

    https://zhishihezi.net/b/5d644b6f81cbc9e40460fe7eea3c7925#

  • 相关阅读:
    .netcore利用DI实现级联删除
    识别手写数字增强版100%
    嗨!请查收这道有趣的面试题
    理解TCP/IP协议栈之HTTP2.0
    基于Redis的分布式锁和Redlock算法
    从生日悖论谈哈希碰撞
    Redis面试热点工程架构篇之数据同步
    Redis面试热点之底层实现篇(续)
    saltstack安装+基本命令
    25个iptables常用示例
  • 原文地址:https://www.cnblogs.com/0x7e/p/14290888.html
Copyright © 2020-2023  润新知