zoukankan      html  css  js  c++  java
  • 无需登录-悟空CRM 存储型XSS

    无需登录-悟空CRM 存储型XSS

    审计悟空的缘由是看见某云爆出CRM的getshell,于是就想着去挖出来瞅瞅!但可能自己把自己给局限了,就想着去挖那些无限制访问的文件。

    故事的发生点
    漏洞文件:/App/Lib/Action/LogAction.class.php
    public function wxadd(){
            if($_POST['subject']){
                $log = M('Log');
                $log->create();
                $log->create_date = time();
                $log->update_date = time();
                
                $log->role_id = $_GET['id'];
                if($log->add()){
                    $this->success(L('ADD SUCCESS', array(L('LOG'))));
                }else{
                    $this->error(L('ADD_LOG_FAILED'));
                }
            }else{
                $this->display();
            }
        }
    判断是否为post请求,如果条件为真则进入添加(这里要说一下,网站是开启了GPC的,但是存储入数据库时是进行了还原的)
    public function index(){
            $m_log = M('Log');
            $m_comment = M('Comment');
            $where = array();
            $params = array();
            
            $order = "create_date desc";
            if($_GET['desc_order']){
                $order = trim($_GET['desc_order']).' desc';
            }elseif($_GET['asc_order']){
                $order = trim($_GET['asc_order']).' asc';
            }
            
            $below_ids = getSubRoleId(false);
            $all_ids = getSubRoleId();
            $module = isset($_GET['module']) ? trim($_GET['module']) : '';
            $by = isset($_GET['by']) ? trim($_GET['by']) : '';
            switch ($by) {
                case 'today' : $where['create_date'] =  array('gt',strtotime(date('Y-m-d', time()))); break;
                case 'week' : $where['create_date'] =  array('gt',(strtotime(date('Y-m-d', time())) - (date('N', time()) - 1) * 86400)); break;
                case 'month' : $where['create_date'] = array('gt',strtotime(date('Y-m-01', time()))); break;
                case 'add' : $order = 'create_date desc';  break;
                case 'update' : $order = 'update_date desc';  break;
                case 'sub' : $where['role_id'] = array('in',implode(',', $below_ids)); break;
                case 'me' : $where['role_id'] = session('role_id'); break;
                default :  $where['role_id'] = array('in',implode(',', $all_ids)); break;
            }
        
            if ($_GET['r'] && $_GET['module']){
                $m_r = M($_GET['r']);
                $log_ids = $m_r->getField('log_id', true);
                $where['log_id'] = array('in', implode(',', $log_ids));
            }

        

            if (!isset($where['role_id'])) {
                $where['role_id'] = array('in',implode(',', getSubRoleId()));
            }
            if(intval($_GET['type'])){
                $where['category_id'] = intval($_GET['type']);
            }else{
                $where['category_id'] = array('neq',1);
            }
            if ($_REQUEST["field"]) {
                $field = trim($_REQUEST['field']);
                $search = empty($_REQUEST['search']) ? '' : trim($_REQUEST['search']);
                $condition = empty($_REQUEST['condition']) ? 'eq' : trim($_REQUEST['condition']);
                if  ('create_date' == $field || 'update_date' == $field) {
                    $search = strtotime($search);
                } elseif ('role_id' == $field) {
                    $condtion = "is";
                }
                $params = array('field='.$_REQUEST['field'], 'condition='.$condition, 'search='.trim($_REQUEST["search"]));
                $field = trim($_REQUEST['field']) == 'all' ? 'subject|content' : $_REQUEST['field'];
                switch ($_REQUEST['condition']) {
                    case "is" : $where[$field] = array('eq',$search);break;
                    case "isnot" :  $where[$field] = array('neq',$search);break;
                    case "contains" :  $where[$field] = array('like','%'.$search.'%');break;
                    case "not_contain" :  $where[$field] = array('notlike','%'.$search.'%');break;
                    case "start_with" :  $where[$field] = array('like',$search.'%');break;
                    case "end_with" :  $where[$field] = array('like','%'.$search);break;
                    case "is_empty" :  $where[$field] = array('eq','');break;
                    case "is_not_empty" :  $where[$field] = array('neq','');break;
                    case "gt" :  $where[$field] = array('gt',$search);break;
                    case "egt" :  $where[$field] = array('egt',$search);break;
                    case "lt" :  $where[$field] = array('lt',$search);break;
                    case "elt" :  $where[$field] = array('elt',$search);break;
                    case "eq" : $where[$field] = array('eq',$search);break;
                    case "neq" : $where[$field] = array('neq',$search);break;
                    case "between" : $where[$field] = array('between',array($search-1,$search+86400));break;
                    case "nbetween" : $where[$field] = array('not between',array($search,$search+86399));break;
                    case "tgt" :  $where[$field] = array('gt',$search+86400);break;

    上一页      

                    default : $where[$field] = array('eq',$search);
                }
            }
            $p = isset($_GET['p']) ? intval($_GET['p']) : 1 ;
            $list = $m_log->where($where)->page($p.',10')->order($order)->select();
            $count = $m_log->where($where)->count();
            import("@.ORG.Page");
            $Page = new Page($count,10);
            if (!empty($_REQUEST['by'])){
                $params['by'] = 'by=' . trim($_REQUEST['by']);
                
            }
            if (!empty($_REQUEST['r']) && !empty($_REQUEST['module'])) {
                $params['r'] = 'r=' . trim($_REQUEST['r']);
                $params['module'] = 'module=' . trim($_REQUEST['module']);
            }
            if (!empty($_REQUEST['type'])) {
                $params['type'] = 'type=' . trim($_REQUEST['type']);
            }
            
            $this->parameter = implode('&', $params);
            if ($_GET['desc_order']) {
                $params[] = "desc_order=" . trim($_GET['desc_order']);
            } elseif($_GET['asc_order']){
                $params[] = "asc_order=" . trim($_GET['asc_order']);
            }
            
            $Page->parameter = implode('&', $params);
            $show = $Page->show();     
            $this->assign('page',$show);
            foreach($list as $key=>$value){
                $list[$key]['creator'] = getUserByRoleId($value['role_id']);
                if($m_comment->where("module='log' and module_id=%d", $value['log_id'])->select()){
                    $list[$key]['is_comment'] = 1;
                }
            }
            
            $this->category_list = M('LogCategory')->order('order_id')->select();
            //获取下级和自己的岗位列表,搜索用
            $d_role_view = D('RoleView');
            $this->role_list = $d_role_view->where('role.role_id in (%s)', implode(',', $below_ids))->select();
            
            $this->assign('list',$list);
            $this->alert = parseAlert();
            $this->display();
        }
    首先要说下此为需要登录后的权限才能访问的页面,然后则是查询咱们log表中的内容,以正序的方式查询。最后用assign直接输出到了当前模板中0.0  我这里就简单的说明了。函数内容太多!!!一个个的说挺费劲的。说的不对希望指出
    验证漏洞:
    这里还感谢90群里面的roisatm表哥提供了一种绕过悟空CRM的webscan方法

    未登录下可访问的页面
    填入咱们的测试XSS
    object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgiSm9zZXBoIik7PC9zY3JpcHQ+=">
    /object>

    没有拦截,只有顺畅的感觉就是棒棒哒
    现在登录去后台看下

     

    上一页     

    觉得文章不错的点赞多多支持!
  • 相关阅读:
    阶梯式测试
    websocket协议
    性能指标
    环境变量
    解密断言+参数写入文本
    将参数进行URL编码
    日志级别
    对返回结果进行断言
    python小题目:循环/函数
    如果使用JSON提取器 和正则提取器
  • 原文地址:https://www.cnblogs.com/xdans/p/5412461.html
Copyright © 2011-2022 走看看