ThinkPHP5.0核心Request类新payload分析
简介
又看了下宝塔waf
对ThinkPHP
的RCE
的过滤
基本上是对已知的payload
的一种拦截
除了,寻找宝塔waf
自身的漏洞之外,还可以从漏洞本身出发,寻找不同的payload
这里是检测的_method
的组合,以及_method
不允许是初始化方法
测试
分析版本
- ThinkPHP 5.0.23
代码分析
首先要明白通过_method
调用初始话方法的目的
就是覆盖filter
成员变量
基于此,我们可以寻找到另外一个方法filter
方法
基本流程
在App的run方法中,先对过滤器进行初始化
进入routeCheck后,调用Route的check方法进行路由检测
在check方法中调用了Request的method方法,通过payload进行变量覆盖
当开启debug的时候在App的Run方法中调用了Request的param方法导致的RCE
不开启路由的时候,需要存在一个完整的路由,一会提,先看这个
进入param方法后,再一次调用method方法
这个时候会进入上面的if分支
并且$this->server
为POST
进入过滤器
其实这并不影响最简单的payload
这个时候我们可以通过post
传参
1 | a=system&_method=filter |
这个时候的filter
就是system
和filter
在进行get
传参
1 | b=dir |
即可触发RCE
,可以看到这种payload
简单的多
但是在宝塔中不仅仅只有这一种拦截
还有对参数的过滤,以及disable_functions
在某些低版本中可以尝试构造代码执行,但是这里是不行的
至于文件包含,还得先有文件
所以,我们去找一个文件写入的地方,并且这个方法是静态的,不存在$this
的调用
找到一处build类中的buildHello方法
跟进
由于宝塔中还特意过滤了base64_decode函数
由于第一个参数是POST,并不可控,需要需要一个方法,返回一个可控的变量
这里找到pathinfo方法和header方法
并且将第一个过滤方法设置为error_reporting,传入POST
相当于关闭了报错
调用的build类的传入参数为
最终
1 | http://127.0.0.1:82/?s=6161613b230a406576616c28245f524551554553545b27696d67275d293b2f2f2e2e2f2e2e2f7075626c69632f |
header方法
1 | POST /index.php |
最后会在public
目录下生成/controller/Index.php
,密码img
限制
5.0.0<= ThinkPHP<=5.0.7
无法利用,对method存在验证,原payload中是_method=__construct&method=POST
5.0.8<= ThinkPHP<=5.0.12
无限制
5.0.13<=ThinkPHP<=5.0.23
需要开启debug