admin

某cms前台储存型XSS
首发于先知:https://xz.aliyun.com/t/54510x1 漏洞分析位置:/4.1.190209/...
扫描右侧二维码阅读全文
03
2019/07

某cms前台储存型XSS

首发于先知:https://xz.aliyun.com/t/5451

0x1 漏洞分析

位置:/4.1.190209/Lib/Lib/Action/Home/ForumAction.class.php
line 71~107

public function update(){
        $post = $_POST;
        $post['forum_cookie'] = md5('forum_'.intval($post['forum_sid']).'_'.intval($post['forum_pid']).intval($post['forum_uid']).'_'.intval($post['forum_cid']));
        //报错取消验证
        if($post['forum_sid'] == 24){
            D("Forum") -> setProperty("_validate", '');
        }
        //写入数据库
        $info = D("Forum")->ff_update($post);
        if($info){
            $email_type = '';
            if( $info['forum_sid'] == 5 ){
                if( C('user_email_guestbook') ){
                    $email_type = '留言';
                }
            }elseif( $info['forum_sid'] == 24 ){
                if( C('user_email_error') ){
                    $email_type = '报错';
                }
            }else{
                if( C('user_email_forum') ){
                    $email_type = '评论';
                }
            }
            if( $email_type ){
                D("Email")->send(C('site_email'), '站长您好', '收到用户('.$info['forum_uid'].')的'.$email_type, $info['forum_content']);
            }
            //返回状态
            if (C('user_check')) {
                $this->ajaxReturn($info, "谢谢,我们会尽快审核你的发言!", 201);
            }else{
                $this->ajaxReturn($info, "感谢你的参与!", 200);
            }
        }else{
            $this->ajaxReturn('', D("Forum")->getError(), 0);
        }
  }

先来看下流程:

  • 先获取了post传输过来的数据
  • forum_cookie是获取传入过来的forum的各种id参数并且是强制int和md5加密的
  • 接下来进行了写入到数据库操作跟进D("Forum")->ff_update()方法
  • 获取返回值根据返回值的确定进行了什么操作
  • 最后返回状态

跟进Lib/Lib/Model/ForumModel.class.php中的ff_update()方法
carbon.png

这里只是进行了数据的添加具体数据库,ForumModel继承了RelationModel,会先验证传入的数据是否满足要求
carbon (1).png

问题出现在了
array('forum_ip','get_client_ip',1,'function'),这里 没有对
继续跟进 get_client_ip

位置/Lib/Common/common.php
Line 2703~2715

function get_client_ip(){
   if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown"))
       $ip = getenv("HTTP_CLIENT_IP");
   else if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown"))
       $ip = getenv("HTTP_X_FORWARDED_FOR");
   else if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown"))
       $ip = getenv("REMOTE_ADDR");
   else if (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown"))
       $ip = $_SERVER['REMOTE_ADDR'];
   else
       $ip = "unknown";
   return($ip);
}

这里我们那可以控制HTTP_X_FORWARDED_FOR而且没有对数据进行过滤或者验证处理

0x02 漏洞利用

首先注册一个用户,跳转到留言页面添加留言
拦截数据包 增加payload到X-Forwarded-For
1560867451350.jpg

屏幕快照 2019-06-18 22.28.36.png

可以看到可以控制的是两个地方但是只能输入20个字符 所以尝试使用分段突破字符限制
因为这个评论内容是顺序排列的所以payload分为三次提交:

  • */</script><!--
  • */alert(1);/*
  • <script>/*

QQ20190618-0.png
18BEC4087A1BE9677B6E80F1007AF7BA.jpg

这时打开后台管理跳转到评论页面就会自动弹出
屏幕快照 2019-06-18 22.32.50.png

至于怎么偷取cookie 自行使用js的各种拼接创建元素就可以了

Last modification:July 3rd, 2019 at 03:59 pm
If you think my article is useful to you, please feel free to appreciate

Leave a Comment