版本: v5.0.22 问题: 命令执行
分析
1. 倒着看
首先,找到”万恶之源”:
在Request类下的 filterValue:
我们来打印一下$value:
果然是他。我们看到这里其实运行了system('whoami')
.
其中$filter = ‘system’, $value = ‘whoami’;
这玩意儿被掉了四次,只在第四次炸了。
回到App, 看这货的入口, 我把它分成列两段,第一段new Request已经把恶意命令注入了,第二部分$req->param()触发。
我们倒着看: 假设我们成功的污染了Request对象的get和filter,他怎么执行的。
上头我们看到了,要执行,关键是要污染:array_walk_recursive($data, [$this, ‘filterValue’], $filter);
其中,$data应为$get, $filter就为filter。
Request->filter = “System”
Request->get = “Whoami”
好了,filter知道了, 那么$data是怎么拿到$get的呢?
看到没,正是第四次,$data是一个数组中包含”whoami”时,搞的事情。
2.正着看
首先,我们再来看看payload:
url: http://127.0.0.1:8088/public/index.php?s=captcha
post data: _method=__construct&filter[]=system&method=get&get[]=whoami
奇奇怪怪的东西有s和_method,
看配置文件:
那么他们是肿么用的呢?
收看我们来看s:
啥是兼容模式呢?来看tp5的url设计:
https://www.kancloud.cn/manual/thinkphp5/118012
所谓普通模式就是: m=module&c=controller&action=action 来获得dispatch
path_info模式:module/controller/action
而所谓的兼容模式不过是给tp一个var_pathinfo来。
我们来看这个怎么用:
/**
* 获取当前请求URL的pathinfo信息(含URL后缀)
* @access public
* @return string
*/
public function pathinfo()
{
if (is_null($this->pathinfo)) {
if (isset($_GET[Config::get('var_pathinfo')])) {
// 判断URL里面是否有兼容模式参数
$_SERVER['PATH_INFO'] = $_GET[Config::get('var_pathinfo')]; //s
unset($_GET[Config::get('var_pathinfo')]);
} elseif (IS_CLI) {
// CLI模式下 index.php module/controller/action/params/...
$_SERVER['PATH_INFO'] = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : '';
}
// 分析PATHINFO信息
if (!isset($_SERVER['PATH_INFO'])) {
foreach (Config::get('pathinfo_fetch') as $type) {
if (!empty($_SERVER[$type])) {
$_SERVER['PATH_INFO'] = (0 === strpos($_SERVER[$type], $_SERVER['SCRIPT_NAME'])) ?
substr($_SERVER[$type], strlen($_SERVER['SCRIPT_NAME'])) : $_SERVER[$type];
break;
}
}
}
$this->pathinfo = empty($_SERVER['PATH_INFO']) ? '/' : ltrim($_SERVER['PATH_INFO'], '/');
}
return $this->pathinfo;
}
现在我们的url中没有pathinfo信息且有Config::get(‘var_pathinfo’), 即s。那么我们的$_SERVER[‘PATH_INFO’]就会被赋值为s参数的内容。($_SERVER[‘PATH_INFO’] = $_GET[Config::_get(‘varpathinfo’)];
即所谓的兼容模式(其实就是不写pathinfo时,看看参数里有没有var_pathinfo, 有的话把他的值当作pathinfo)
现在我们的pathinfo就是一个captcha了。那么为啥时captcha不是娃哈哈呢?接着往下看。