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
使用时记得在Application\Home\Conf\config.php改下配置(我已经全部加了注释,即使不会thinkphp的也可以搭建)
个人代码写的没有多好,思路可能也比较烂。如果您有什么意见欢迎提出来,我会进一步修改的。

上一页     

时间: 2024-11-05 21:42:24

XSS报警机制(前端防火墙:第二篇)的相关文章

Web前端学习第二篇

今天看到了一篇写的不错的文章,是有关对JQuery.js等一些源代码初识的内容,感觉写的还是不错,所以拿过来分享一下. 文章的地址:http://my249645546.iteye.com/blog/1716629 1.对(function(){})(); 几乎所有的开源js代码开篇都是这样(function(……){……})(……); 下面是Jquery的部分源码: (function( window, undefined ) { var jQuery = function( selector

web前端【第二篇】HTML基础二(表单、div)

一.表单 功能:表单用于向服务器传输数据,从而实现用户与Web服务器的交互 表单能够包含input系列标签,比如文本字段.复选框.单选框.提交按钮等等. 表单还可以包含textarea.select.fieldset和 label标签. 表单属性 action: 表单提交到哪.一般指向服务器端一个程序,程序接收到表单提交过来的数据(即表单元素值)作相应处理,比如https://www.sogou.com/web method: 表单的提交方式 post/get默认取值就是get 注意啦!!!!

XSS 前端防火墙 —— 可疑模块拦截

上一篇介绍的系统,虽然能防御简单的内联 XSS 代码,但想绕过还是很容易的. 由于是在前端防护,策略配置都能在源代码里找到,因此很快就能试出破解方案.并且攻击者可以屏蔽日志接口,在自己电脑上永不发出报警信息,保证测试时不会被发现. 昨天提到最简单并且最常见的 XSS 代码,就是加载站外的一个脚本文件.对于这种情况,关键字扫描就无能为力了,因为代码可以混淆的千变万化,我们看不出任何异常,只能将其放行. 因此,我们还需增加一套可疑模块跟踪系统. 被动扫描 和之前说的一样,最简单的办法仍是遍历扫描.我

XSS 前端防火墙 —— 无懈可击的钩子

昨天尝试了一系列的可疑模块拦截试验,尽管最终的方案还存在着一些兼容性问题,但大体思路已经明确了: 静态模块:使用 MutationObserver 扫描. 动态模块:通过 API 钩子来拦截路径属性. 提到钩子程序,大家会联想到传统应用程序里的 API Hook,以及各种外挂木马.当然,未必是系统函数,任何 CPU 指令都能被改写成跳转指令,以实现先运行自己的程序. 无论是在哪个层面,钩子程序的核心理念都是一样的:无需修改已有的程序,即可先执行我们的程序. 这是一种链式调用的模式.调用者无需关心

XSS 前端防火墙 —— 天衣无缝的防护

上一篇讲解了钩子程序的攻防实战,并实现了一套对框架页的监控方案,将防护作用到所有子页面. 到目前为止,我们防护的深度已经差不多,但广度还有所欠缺. 例如,我们的属性钩子只考虑了 setAttribute,却忽视还有类似的 setAttributeNode.尽管从来不用这方法,但并不意味人家不能使用. 例如,创建元素通常都是 createElement,事实上 createElementNS 同样也可以.甚至还可以利用现成的元素 cloneNode,也能达到目的.因此,这些都是边缘方法都是值得考虑

XSS 前端防火墙 —— 内联事件拦截

关于 XSS 怎样形成.如何注入.能做什么.如何防范,前人已有无数的探讨,这里就不再累述了.本文介绍的则是另一种预防思路. 几乎每篇谈论 XSS 的文章,结尾多少都会提到如何防止,然而大多万变不离其宗.要转义什么,要过滤什么,不要忘了什么之类的.尽管都是众所周知的道理,但 XSS 漏洞十几年来几乎从未中断过,不乏一些大网站也时常爆出,小网站更是家常便饭. 预警系统 事实上,至今仍未有一劳永逸的解决方案,要避免它依旧使用最古老的土办法,逐个的过滤.然而人总有疏忽的时候,每当产品迭代更新时,难免会遗

XSS 前端防火墙 —— 整装待发

到目前为止,我们把能用前端脚本防御 XSS 的方案都列举了一遍. 尽管看起来似乎很复杂累赘,不过那些是理论探讨而已,在实际中未必要都实现.我们的目标只是为了预警,能发现问题就行,并非要做到滴水不漏的程度. 事实上,HTML5 早已制定了一套浏览器 XSS 解决方案 -- Content Security Policy,并且大多主流浏览器实现了这个标准. 既然我们使用前端脚本重新实现一遍,因此得在各个方面占有优势. 兼容性 CSP 目前主流浏览器大多已支持,IE10.11 支持部分功能.对于 IE

XSS 前端防火墙(4):天衣无缝的防护

例如,我们的属性钩子只考虑了 setAttribute,却忽视还有类似的 setAttributeNode.尽管从来不用这方法,但并不意味人家不能使用. 例如,创建元素通常都是 createElement,事实上 createElementNS 同样也可以.甚至还可以利用现成的元素 cloneNode,也能达到目的.因此,这些都是边缘方法都是值得考虑的. 下面我们对之前讨论过的监控点,进行逐一审核. 内联事件执行 eval 在第一篇文章结尾谈到,在执行回调的时候,最好能监控 eval,setTi

第二篇 基于微擎的模块开发—PHP

从陌生到如今能勉强完成第一个微网站模块的实现.也算是一个小小的进步,从设计数据库到,返回数据,前端模版渲染 每一点都是有点难度的.所以我想总结一下,我是如何实现一个微擎模块. 第一,首先得分析某个模块的想实现什么需求,根据需求设计合理的数据库结构. 第二,了解微擎的结构,运行流程,设计模块结构. 第三,重点就是site.php , 完成site.php 需要一定的php的编程能力, 第四,site.php 其中 通过 pdo 从数据库的获取我们想得到数据源. 微擎已封装其路由机制, doWeb