利用 CVE-2020-1938 读取webapp 下任意文件复现 以及源码调试分析【已通过】

0x00 前言

之前挖src 的时候,想着用幽灵猫来挖,但是由于没有理解原理,导致测试的时候直接用脚本扫描出错了也一脸懵逼,所以想好好分析分析这个漏洞,全面了解原理,也学习学习tomcat

0x01 漏洞介绍

image

0x02 环境搭建:

1. 下载t omcat :

**tomcat源码压缩包(https://archive.apache.org/dist/tomcat/tomcat-7/v7.0.99/src/apache-tomcat-7.0.99-src.zip ),另一个是tomcat可执行的压缩包。( https://mail.qq.com/cgi-bin/mail_spam?action=check_link&spam=0&spam_src=1&mailid=ZL1201-fIhPFlrtPhTAnCF_p7MIGa6&url=https%3A%2F%2Farchive.apache.org%2Fdist%2Ftomcat%2Ftomcat-7%2Fv7.0.99%2Fbin%2Fapache-tomcat-7.0.99-windows-x64.zip) )

参考配置: https://blog.csdn.net/u013268035/article/details/81349341

2.没有自动导入maven

https://blog.csdn.net/qq_31017737/article/details/81010462?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase

3.坑:

image

image

一定亲自为项目配置低版本的jdk ,jdk 11 过不了

启动成功:

image

默认8089端口是开启的:

image

0x03 ajp协议介绍:

参考 https://www.cnblogs.com/guanghuiqq/p/11204719.html

0x04 审计前言:

开源项目爆出漏洞的时候可以去github查看commit 或者在提高了版本的时候可以使用compare 来对比

先去查看commit :

compare:

image

0x04 复现:

准备读取manager/WEB-INF/1.txt

image

image

【使用 的脚本地址 : https://github.com/hypn0s/AJPy

image

image

(为了按照后文的步骤调试文件读取 , 把/xxxxx.jsp 修改为/xxxxx, 也就是修改requesturi不然和后文调试的过程不太一样)

wireshark 抓包:

对话流:

image

一次会话,回复了三次

设置的参数

0x05 调试前的准备知识:

(1) tomcat 的架构 https://www.guildhab.top/?p=2406 热气球工会 epicccal 师傅

https://blog.csdn.net/xlgen157387/article/details/79006434 徐刘根师傅 四张图读懂tomcat 架构

可以看下面这张图:

image

简单的总结就是:

server 是tomcat 中最顶层的容器,一个tomcat 只有一个容器

service 对外提供服务连接,可以提供不同的协议连接,比如http , https ,ajp ,这取决于connectors 的设置,一个service 包含一个container 和 多个connectors

connectors 就是来处理不同连接的,把socket 请求封装成Request 请求,交给container 处理

container 用于封装和管理servlet ,并且处理来自connetors 的Requests 请求,返回Response 响应,返回给connectors 组件

对于container :

【引自热气球公会 https://www.guildhab.top/?p=2406

(3)理解requestsHeaderMessage (prepareRequests的时候经常遇到)

requestsHeaderMessage 是AJPMessage类的一个实例

AJPMessage 类中的getBytes() 和 getByte() ,里面有个pos 记录当前读或者写的buf位置,每次getBytes 和 getByte 都会改变这个pos 。

image

getByte() 函数:

getBytes函数后面会讲到

(4) tomcat 对静态资源的处理: 参考光辉飞翔师傅:https://www.cnblogs.com/chuonye/p/10816345.html

image

cacheEntry:

image

image

image

0x06 调试:

ðparepareReques

Tomcat在接收ajp请求的时候调用org.apache.coyote.ajp.AjpProcessor来处理ajp消息,prepareRequest()方法将ajp里的内容取出,并设置成request对象的属性。既然如此,我们先在调用prepareRequest()方法的地方下一个断点。

image

具体文件路径:

image

跟进这个函数: (其实就是在一步步处理requestsHeaderMessage , 把 requestsHeaderMessage的值写到requests里面)

image

发现很多getBytes() ,于是跟进getBytes() 函数,

image

image

image

image

set 之后,可以看到requests,remoteAddr() 的值如下:

然后就是解析headers :

image

解析完成后

image

接下来就是解析额外的标记:

image

image

可以看到对比7.0.100 和 7.0.99 版本;

然后读了三次之后: requests.attributes 就读入了我们添加的属性

image

接着检查如果需要secret 的话是否提交了secret ,没有的话就返回403

image

所以防御的时候可以设置secret:

image

检查是否是完整的uri

image

image

然后设置requests中的host :

到此解析完成

然后process the request in the adapter:

image

跟进adapter:

image

然后调用容器:

跟进invoke:

再跟进invoke:

跟进getNext:

image

一步步跟进,到context :

image

然后一直跟进回到wrapper:

image

(这里如果开始脚本没有修改为/xxxxx的话,会是jsp)

一路跟进,会看到分配servlet:

image

接着下面会有doFilter:

image

跟进doFilter ,看到servlet.service (到servlet 了,正式处理request 和 response 了)

image

一步步跟进service ,会到一个getRelativePath 函数:

image

image

接着下面关键点,会到一个lookupCache()函数:

跟进到cacheLookup函数中:

一直跟进cacheLoad: (第一次访问,自然不会找到缓存条目,后面测试,即使进入了else分支 ,else 里面也会进入后面的new File 的)

image

跟进:

跟进:

跟进,可以看到会new 一个File 对象,【也就是漏洞的触发点】

其中validate 函数限制了file 的合格性:

image

后面就是把读取的资源输出来

调用栈:

参考:

https://www.guildhab.top/?p=2406 热气球工会 epicccal 师傅 cve-2020-1938 复现

https://www.cnblogs.com/r00tuser/ 水泡泡师傅 cve-2020-1938 复现

https://blog.csdn.net/xlgen157387/article/details/79006434 徐刘根师傅 tomcat 系统架构

https://www.cnblogs.com/chuonye/p/10816345.html wskwbog 师傅 tomcat 静态文件处理

https://blog.csdn.net/u013268035/article/details/81349341 包华杰师傅 配置idea 调试tomcat源码

https://github.com/hypn0s/AJPy hypn0s 大佬的工具

后记

第一次调试java 源代码来漏洞复现,学到了tomcat 整个容器的架构 , 怎么处理请求,以及tomcat如何处理静态文件.

收益颇多,继续学习

  • 通过
  • 未通过

0 投票者

1 Like