初学审计的我很菜,跪求各位大牛指点;
认真分析这个漏洞,版本是HongCMS3.0.0;

直接访问/index.php是不行的,还必须手动安装;
访问/intall/index.php进行图形化安装完成之后,按照指引对install目录进行删除;
使用刚才安装时候的账户和密码登录后台之后,在:系统->模板管理->模板文件列表功能中观察,有修改模板的功能;

我首先使用正常功能对其进行修改并进行操作并抓包分析:

新加了一行,然后保存更新,查看这个包:

根据这个功能分析是这样的:
1.页面是在/admin/index.php,然后调用的方法是template控制器里面的save()方法进行保存;
2.参数分析:file=文件名&dir=目录(这个目录好像只能指向Default目录)&fileconten=修改之后的文件内容;

直接跟到代码层去分析这个方法:
/admin/controllers/tmplate.php

public function save(){  //保存模板文件
        $file = ForceStringFrom('file');
        $filepath = $this->temp_path . $this->current_dir . $file;

        if (is_writable($filepath)) {
            $filecontent = trim($_POST['filecontent']);
            if (get_magic_quotes_gpc()) {
                $filecontent = stripslashes($filecontent);
            }

            $fd = fopen($filepath, 'wb');
            fputs($fd,$filecontent);

            Success('template'. Iif($this->current_dir, '?dir=' . $this->current_dir));
        }else{
            $errors = '模板文件('.$file.')不可写! 请将其属性设置为: 777';
            Error($errors, '编辑模板错误');
        }
    }

这个save()方法直接通过 /admin/index.php/template/save进行调用。
代码中的$file是通过ForceStringFrom函数进行收取。

而ForceStringFrom()和ForceString()直接收取$_POST[]中的参数与值,调用函数EscapeSql进行转义和过滤;
但是这也就证明了$file是我们可以控制的;
而通过控制$file,我们可以间接的控制$filepath:

$filepath = $this->temp_path . $this->current_dir . $file;
    //public function __construct($path){
    //      parent::__construct($path);
    //
    //      $this->temp_path = ROOT.'public/templates/';
    //
    //      $this->current_dir = ForceStringFrom('dir');
    //
    //      if(!$this->ajax) SubMenu('模板管理'); //根据父对象SAdmin的ajax成员变量, 判断是否为ajax动作
    //  }
    //
    //这个类名叫c_template,继承自SAdmin,构造函数如上,如刚才我们那样传参:
    //$this->temp_path = /public/templates/
    //$this->current_dir = Default/
    //$filepath = /public/templates/Default/[文件名]
    //如果将$file构造成这样:../../../../shell.php应该就可以直接对其他目录的其他文件进行操作了。

这里我总结一下:
可以控制$file和$filepath两个变量了;

if (is_writable($filepath)) {
            $filecontent = trim($_POST['filecontent']);    //这里直接通过POST接受内容,去掉前面的空白内容。
            if (get_magic_quotes_gpc()) {
                $filecontent = stripslashes($filecontent);
            }

而在其后的if()语句中,$filecontent直接接受$_POST['filecontent']作为变量内容,这里我们又可以控制写入文件的内容了;
但是在上面的if()中有个is_writable()去验证我们上面的$filepath是否存在并且为可写的。

那么这里我们只能找一个已经在web程序目录中存在的php文件去覆写并获取shell了;

/models/user.php看上去没有什么实质性的用处,我试试去覆写他;
那么$filepath我们需要控制为:/public/templates/Default/../../../models/user.php;

然后:

源链接

Hacking more

...