IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    PHPCMS V9 版本后台设计缺陷导致任意代码执行漏洞

    小残发表于 2016-11-06 09:52:44
    love 0

    0x01 背景

    由于默认安装后需要超级管理员权限,故该漏洞很鸡肋,但感觉应该会在其它cms中也存在,所以主要分享下挖掘思路~ PS:使用的测试环境是php5.6(已经移除gpc选项)

    pshell

    0x02 漏洞分析

    漏洞起源: yoursite\phpsso_server\phpcms\modules\admin\system.php下的uc函数:

    <?php
    public function uc() {
        if (isset($_POST['dosubmit'])) {
            $data = isset($_POST['data']) ? $_POST['data'] : '';
            $data['ucuse'] = isset($_POST['ucuse']) && intval($_POST['ucuse']) ? intval($_POST['ucuse']) : 0;
            $filepath = CACHE_PATH.'configs'.DIRECTORY_SEPARATOR.'system.php';
            $config = include $filepath;
            $uc_config = '<?php '."\ndefine('UC_CONNECT', 'mysql');\n";
            foreach ($data as $k => $v) {
                $old[] = "'$k'=>'".(isset($config[$k]) ? $config[$k] : $v)."',";
                $new[] = "'$k'=>'$v',";
                $uc_config .= "define('".strtoupper($k)."', '$v');\n";
            }
            $html = file_get_contents($filepath);
            $html = str_replace($old, $new, $html);
            $uc_config_filepath = CACHE_PATH.'configs'.DIRECTORY_SEPARATOR.'uc_config.php';
            @file_put_contents($uc_config_filepath, $uc_config);
            @file_put_contents($filepath, $html);
            $this->db->insert(array('name'=>'ucenter', 'data'=>array2string($data)), 1,1);
            showmessage(L('operation_success'), HTTP_REFERER);
        }
        $data = array();
        $r = $this->db->get_one(array('name'=>'ucenter'));
        if ($r) {
            $data = string2array($r['data']);
        }
        include $this->admin_tpl('system_uc');
    }
    ...

    将表单中的数据$data按照键值对遍历并以如下形式存储到$uc_config变量里:

    $uc_config .= "define('".strtoupper($k)."', '$v');\n";

    上面只是对$k变量进行了字母转大写处理,然后就写到yoursite\phpsso_server\caches\configs\uc_config.php中了,所以这里应该可以构造一句话木马写入到uc_config.php中,从而拿到webshell。

    转载请注明:小残博客

    0x03 漏洞证明

    通过观察uc_config.php,我们构造一句话木马的方法如下(审查元素或者代理改包均可)

    pshell

    获取shell

    pshell1

    解决方案

    临时解决方案我这里引入了特殊字符的数组$array_key_safe = array(“,”, “;”, “‘“, “(“, “)”, “\“); 然后在foreach循环时对$k进行过滤如下:
    public function uc() {
    //引入$array_key_safe
    $array_key_safe = array(",", ";", "'", "(", ")", "\\");
    if (isset($_POST['dosubmit'])) {
    $data = isset($_POST['data']) ? $_POST['data'] : '';
    $data['ucuse'] = isset($_POST['ucuse']) && intval($_POST['ucuse']) ? intval($_POST['ucuse']) : 0;
    $filepath = CACHE_PATH.'configs'.DIRECTORY_SEPARATOR.'system.php';
    $config = include $filepath;
    $uc_config = '<?php '."\ndefine('UC_CONNECT', 'mysql');\n";
    foreach ($data as $k => $v) {
    //对$k中敏感字符替换为空
    $k = str_replace($array_key_safe, "", $k);
    $old[] = "'$k'=>'".(isset($config[$k]) ? $config[$k] : $v)."',";
    $new[] = "'$k'=>'$v',";
    $uc_config .= "define('".strtoupper($k)."', '$v');\n";
    }
    $html = file_get_contents($filepath);
    $html = str_replace($old, $new, $html);
    $uc_config_filepath = CACHE_PATH.'configs'.DIRECTORY_SEPARATOR.'uc_config.php';
    @file_put_contents($uc_config_filepath, $uc_config);
    @file_put_contents($filepath, $html);
    $this->db->insert(array('name'=>'ucenter', 'data'=>array2string($data)), 1,1);
    showmessage(L('operation_success'), HTTP_REFERER);
    }

    当然这个修补方法很暴力~

    博客头像
    作者: 小残 绳命不息 |折腾不止 |我一天不折腾心里难受
    转载请以链接形式注明本文地址:https://www.exehack.net/4154.html
    版权所有© 小残博客 | 关注网络安全 | 本网站内容采用 BY-NC-SA 进行授权。


沪ICP备19023445号-2号
友情链接