破军安全实验室
本文约3000字,阅读约需8分钟。
0x00 环境搭建
Docker地址:
https://github.com/top-think/think/releases/tag/v5.1.29
漏洞影响范围:
5.x < 5.1.31
5.x < 5.0.23
Docker或者phpstudy
Centos7 64位
源码审计工具:VScode
0x01 漏洞详情
-
漏洞描述
ThinkPHP 5.x版本存在远程代码执行漏洞,高危,可被getshell,该框架在今年4月份公开存在反序列化漏洞,但是不知为什么漏洞上线后不久被CNVD官方删除,这里还是简单对ThinkPhP5.x漏洞进行深入分析,因为在之前漏洞挖掘过程中发现有很多网站使用这一框架,当时只是用网上公开的POC进行验证,并未对漏洞产生的根本原因进行了解,就本次针对该漏洞进行学习。
-
漏洞利用
1、环境搭建这里直接采用docker容器搭建环境,这里使用vulhub-master。
2、使用命令docker-compose up -d启动漏洞环境。
3、访问漏洞环境
4、漏洞复现,漏洞复现直接使用目前公开的POC,下面会对漏洞进行详细分析。
POC:POST /index.php?s=captcha HTTP/1.1
Host: 192.168.1.88:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type:application/x-www-form-urlencoded
Content-Length: 72
_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=id
5、直接使用burp拦截数据包验证
6、这里推荐一款比较好用的ThinkPhp 5.x漏洞验证工具TPScan,该工具由雷石安
全研发。
查看当前文件ls
0x02 漏洞分析
-
产生原因
1、路由信息中controller的部分进行了过滤,可知问题出现在路由调度时
2、在未修复之前程序未对控制器进行限制,导致攻击者可以通过引入符号来调用任意类方法。
-
源码分析
1、首先需要先认识ThinkPHP框架的基本目录结构方便进行代码审计。
目录application为应用目录,该目录先存放一些公共模块
接下来就是config目录,里面存放着框架的一些配置文件信息如session、log、cookie、database等等配置信息
然后就是route目录,也是本次漏洞分析的一个关键点,该目录主要提供处理页面时的路径。
接下来就是public目录,该目录主要是对外开放,作为WEB目录
接下来就是thinkphp 框架系统目录,该目录主要存放框架调用的包、类文件
最后就是extend目录,该目录主要是第三方类库依赖包等等
漏洞分析:
ThinkPHP的架构:
http://serverName/index.php/模块/控制器/操作/参数/值
1、首先找到漏洞存在点为index,该文件位于public->index.php,这里一共有两个操作一、加载框架文件base.php;二、调用run方法对客户端传递的参数数据进行处理。
2、跟进run方法,会进行初始化然后绑定控制器,并对路由进行检测。
3、之前分析漏洞成因的时候指明是路由调度的时候出现问题,这里我们直接跟进roteCheck方法。
4、继续跟进path方法,方法中对pathinfo方法进行引用,接下来直接跟进pathinfo方法
5、在pathinfo方法中发现直接引用当前的类中的config方法。
6、跟进config方法,发现对路由检测会返回一个dispatch,返回值调用的是route中的check方法,所以接下来需要跟进的是check方法。
7、在check方法中最后会返回路由解析结果,注意这里是针对url进行检查
8、继续跟进url类,这里可以看到Url这个类是继承的Dispatch类,然后执行init方法,继续看init方法中会使用到Module类执行init方法的返回结果
9、上图中的代码可以得知刚开始路由检查后的的dispatch的值是实例化的module对象,当代码执行到$data这里,这里data的值会被置为null,接下来就是进行条件判断,然后会执行父类中的run方法。
10、跟进父类中的run方法,这里会调用到autoValidate方法进行数据自动验证,最后再调用exec方法
11、接下来继续跟进exec方法,这里调用了当前app的controller方法,到exec方法这里分析的差不多了,接下来我们看一下poc的关键构造。
12、POC如下
?s=index/thinkapp/invokefunction?function=call_user_func&vars[0]=system&vars[1]=whoami
这里个人对poc的构造比较好奇,为什么会有这个玩意,后面在网上找文章发现,这个才是产生RCE的关键所在,首先我们需要了解一下ThinkPHP的执行路由顺序:?s=模块/控制器/操作名,POC中的是指如果控制器的名字中存在或者以开头,就会被当作一个类,就相当于实例化任意类进行执行,导致该问题的点在于parseModuleAndClass方法中。
0x03 总结归纳
在漏洞复现过程中,漏洞复现过程中没有太大的问题,因为都采用默认的控制器,但是在实际渗透测试过程中会遇到一些问题就是,使用POC测试的时候会提示控制器不存在的情况,对于这种情况的解决办法就是没有源码,俺也不知道。
由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,破军安全实验室及文章作者不为此承担任何责任。
破军安全实验室拥有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经破军安全实验室允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。
破军安全实验室
# 长按二维码 关注我们 #
原文始发于微信公众号(破军安全实验室):ThinkPHP5.x RCE 漏洞分析
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论