zoukankan      html  css  js  c++  java
  • XSS报警机制(前端防火墙:第二篇)

    XSS报警机制(前端防火墙:第二篇)

    在第一章结尾的时候我就已经说了,这一章将会更详细的介绍前端防火墙的报警机制及代码。在一章出来后,有人会问为什么不直接防御,而是不防御报警呢。很简单,因为防御的话,攻击者会定位到那一段的JavaScript代码,从而下次攻击的时候绕过代码。如果不防御而报警的话,攻击者会降低警觉,不会在看JavaScript代码(至少我是这样)。回到正题,下面说的代码,是基于thinkphp框架和bootstrap3.3.5框架。如果你的网站没有使用thinkphp3.2.3框架的话,可以参照我的思路重新写一个。这里我强调一下“前端防御XSS是建立在后端忘记做过滤,没有做过滤,疏忽做过滤的基础上的...
    0x01 前端要做的事
    其实标题应该改成“XSS报警机制”的,因为在这一章里使用了大量的后端代码。但是第一章的标题都出来了,也没法改了。
    前端要做的事情在第一章的时候就已经说了,代码如下:

    现在我们就是针对第38行进行修改,改成我们后台接受的API URL。就像这样:

    对,就这一行。没有其他代码。在实际的线上环境中,也只需要上面5行。可以直接copy到您的线上环境中,记得把倒数第二行的url改成自己的地址就行了。难道就那么简单?不,0x05节还有一部分前端代码。0x01~0x04主要是针对于平台。
    0x02 数据库要做的事
    一共两个表。fecm_user和fecm_bugdata。
    fecm_user的字段信息如下:

    name:管理员账户名
    md5name:3次name值的md5
    password:3次密码的md5
    email:管理员邮箱
    create_date:管理员创建时间
    为了安全起见(其实就是懒)没有写添加管理员的,自行在数据库里添加
    fecm_bugdata的字段信息如下:

    url:漏洞的url地址
    category:漏洞类型
    cookies:攻击者的cookies
    ua:攻击者的User-Agent
    hxff_ip:攻击者的HTTP_X_FORWARDED_FOR
    hci_ip:攻击者的HTTP_CLIENT_IP
    ra_ip:攻击者的REMOTE_ADDR
    time:攻击者攻击的时间
    fixes:漏洞是否修复(0为未修复,1为已修复)
    0x03 后端要做的事
    因为后端代码太多,所以我就说一些核心的后端处理代码。
    在0x01节里,有个核心的代码是new Image().src = 'http://fecm.cn/Api/addVul/';
    接下来我们来说说这个Api的处理方式(ThinkPHP代码)
    public function addVul(){
        if(I('get.category','','int') == ""){
            $this->ajaxReturn(array(
                "typeMsg" =>  "error",
                "msgText" =>  "漏洞类型错误",
            ));
        }
        switch (I('get.category','','int')) {
            case '1':
                $vul['category'] = "触发alret函数";
                break;
            case '2':
                $vul['category'] = "发现不在白名单里的第三方JavaScript资源";
                break;
            default:
                $this->ajaxReturn(array(
                    "typeMsg" =>  "error",
                    "msgText" =>  "漏洞类型错误",
                ));
                break;
        }
        if($_SERVER['HTTP_X_FORWARDED_FOR'] === null){
            $vul['hxff_ip'] = "攻击者没有通过代理服务器访问";
        }else{
            $vul['hxff_ip'] = I('server.HTTP_X_FORWARDED_FOR'); //获取攻击者的HTTP_X_FORWARDED_FOR
        }
        if($_SERVER['HTTP_CLIENT_IP'] === null){
            $vul['hci_ip'] = "攻击者数据包头部没有HTTP_CLIENT_IP";

        

        }else{
            $vul['hci_ip'] = I('server.HTTP_CLIENT_IP');//获取攻击者的HTTP_CLIENT_IP
        }
        $vul['ra_ip'] = I('server.REMOTE_ADDR');    //获取攻击者的REMOTE_ADDR
        $vulcookie    = I('cookie.');   //获取攻击者的cookies
        for($i = 0;$icount($vulcookie);$i++){
            $vul['cookies'] .= array_keys($vulcookie)[$i].'='.$vulcookie[array_keys($vulcookie)[$i]].'; ';  //拼接成方便查看的cookies格式
        }
        $vul['url']   = I('server.HTTP_REFERER');   //获取攻击者攻击成功的url
        $vul['ua']    = I('server.HTTP_USER_AGENT');    //获取攻击者的User-Agent
        $vul['time']  = date("Y-m-d");  //获取攻击者攻击的时间
        $vul['fixes'] = 0;  //默认为漏洞未修复
        $bugData = M('bugdata');    //连接fecm_bugdata数据库
        $bugData->data($vul)->add();    //添加到数据库中
    }
    因为这里是接受攻击信息,不能有管理员验证。
    后台有一个数据库可视化的表格,这里我使用的Chart.js,下面是后端代码:
    public function index(){
        $reportForm = M('bugdata'); //连接fecm_bugdata数据库
        $dateTimeLabels = [];
        $dateTimeTotal = [];
        for($i = 0;$i $i++){    //获取近7天的数据
            $time = date("Y-m-d",strtotime(-$i." day"));
            array_unshift($dateTimeLabels,$time);
            $data['time'] = array('like','%'.$time.'%');
            array_unshift($dateTimeTotal,$reportForm->where($data)->count());
        }
        $reportForm = json_encode(["Labels" => $dateTimeLabels,"Total" => $dateTimeTotal]); //转化成json格式
        $this->assign('reportForm',$reportForm)->assign('total',total());   //交给前端模块
        $this->display();   //前端页面生成
    }
    前端代码:
    var lineChartData = {
        labels :eval({$reportForm})['Labels'],
        datasets : [
            {
                fillColor : "rgba(151,187,205,0.5)",
                strokeColor : "rgba(151,187,205,1)",
                pointColor : "rgba(151,187,205,1)",
                pointStrokeColor : "#fff",
                data : eval({$reportForm})['Total']
            }
        ]
    }
    var myLine = new Chart(document.getElementById("Statistics").getContext("2d")).Line(lineChartData);
    实际的效果图:



    0x04 让我们实际测试一下
    代码就用0x01节的代码。我们输入alert(1)。看一下:

    我们再去平台看一下:


    成功显示了。
    0x05 检测第三方js资源是否为xss脚本
    这一节需要用到之前长短短分享的代码:
    for(var i=0,tags=document.querySelectorAll('iframe[src],frame[src],script[src],link[rel=stylesheet],object[data],embed[src]'),tag;tag=tags[i];i++){
        var a = document.createElement('a');
        a.href = tag.src||tag.href||tag.data;

    上一页      

        if(a.hostname!=location.hostname){
            console.warn(location.hostname+' 发现第三方资源['+tag.localName+']:'+a.href);
        }
    }
    但是他这里只是在console里显示,没有进一步的操作,而且他这里同时检测了iframe、frame、script、link、object、embed标签,对我们来说只需要script标签就行了,于是我重写了这段代码,首先我们需要一个白名单列表,用于放置网站允许第三方加载的url地址:
    var scriptList = [
        location.hostname,
    ]
    这里只是默认的只允许当前域名加载,打击爱可以根据自己的需要添加。
    然后就是获取当前网页的所有script标签:

    var webScript = document.querySelectorAll('script[src]');
    在把当前的地址赋值var webHost = location.hostname;至于为什么不放在for循环里,因为根据js优化规则,for循环里避免多次一样的赋值。
    接下来就是for循环里的代码了:
    for(var i = 0;i
        var a = document.createElement('a');    //建立一个新的a标签,方便取值
        a.href = webScript[i].src;  //把script里的src赋值给a标签里的href属性
        if(a.hostname != webHost){  //对比,是否为第三方资源
            for(var j = 0;j
                if(a.hostname != scriptList[i]){    //判断当前的第三方资源是否在白名单里
                    new Image().src = 'http://fecm.cn/Api/addVul/category/2';   //发送给FECM
                }
            }
        }
    }
    这里我做了一个测试,加载hi.baidu.com的资源:

    刷新后,打开FECM平台,看一下:


    0x06 结语
    因为穷,没有服务器和域名,也没法添加邮件自动提醒功能了。感兴趣的可以自己添加,如果后来我有钱了,我买个服务器,会添加邮件自动提醒的,第一时间会在乌云社区里发布。本来打算采用ED的on事件拦截代码的,但是发现on事件在程序里也会大量使用,索性就没有添加,如果你有思路
    下载地址:http://pan.baidu.com/s/1jGVP7Ps
    使用时记得在ApplicationHomeConfconfig.php改下配置(我已经全部加了注释,即使不会thinkphp的也可以搭建)
    个人代码写的没有多好,思路可能也比较烂。如果您有什么意见欢迎提出来,我会进一步修改的。
     

    上一页     

  • 相关阅读:
    C. Shaass and Lights 解析(思維、組合)
    D. Binary String To Subsequences(队列)(贪心)
    CodeForces 1384B2. Koa and the Beach (Hard Version)(贪心)
    CodeForces 1384B1. Koa and the Beach (Easy Version)(搜索)
    CodeForces 1384C. String Transformation 1(贪心)(并查集)
    CodeForces 1384A. Common Prefixes
    POJ-2516 Minimum Cost(最小费用最大流)
    POJ3261-Milk Patterns(后缀数组)
    HDU-1300 Pearls(斜率DP)
    HDU-4528 小明系列故事-捉迷藏(BFS)
  • 原文地址:https://www.cnblogs.com/xdans/p/5412655.html
Copyright © 2011-2022 走看看