• XSS攻击


    XSS攻击思路

    XSS的本质还是一种”HTML“漏洞。用户的数据被当成了HTML的一部分来执行,从而混淆了原有的语义,产生了新的语义。如果未对用户的输入做任何处理,那么会直接产生XSS攻击漏洞。

    通过特定标签实现攻击

    在事件中输出

    onclick

    在URL地址中构造

    将XSS攻击代码通过URLEncode进行编码,然后放在URL中实施攻击。

    在地址输出中:

    <a href="http://www.test.com/?test=$var">test</a>
    

    可能的攻击方法

    <a href="http://www.test.com/?test=" onclick=alert(1)"">test</a>
    

    构造伪协议实施攻击

    <a href="javascript:alert(1);">test</a>
    

    除了javascript作为伪协议可以执行代码外,也有其他的伪协议可能导致脚本运行。

    利用字符编码

    var redirectUrl="";alert(/XSS/);";
    

    "进行了转义,得到一个Unicode字符,因此,实际上得到的结果是这样的

    <script>%c1";alert(/XSS/);</script>
    

    绕过长度限制

    对用户输入的内容进行长度限制,使攻击者连一个完整的函数都无法写完,XSS攻击可能无法成功。但是依然存在风险点,攻击者可以利用事件(Event)来缩短所需要的字节数。

    $var输出为:"onclick=alert(1)//
    
    <input type=text value="" "onclick=alert(1)//"/>
    

    当用户点击文本框,alert将被执行。

    但利用”事件“能够缩短的字节数是有限的,最好的办法是把XSS Payload写到别处,再通过简单的代码加载这段XSS Payload。

    最常用的一个“藏代码”的地方,就是“location.hash”。而且根据HTTP协议,location.hash的内容不会在HTTP包中发送,所以服务端的web日志中并不会记录下location.hash里的内容,从而也更好地隐藏了黑客的真实意图。

    $var输出为: " onclick="eval(location.hash.substr(1))
    

    输出后的HTML是:

    <input type="text" value="" onclick="eval(location.hash.substr(1))" />
    

    因为location.hash的第一个字符是#,所以必须去除第一个字符才行。此时构造出的XSS URL为:

    http://www.a.com/test.html#alert(1)
    

    location.hash本身没有长度限制,但是浏览器的地址栏是有长度限制的,不过这个长度已经足够写很长的XSS Payload了。要是地址栏的长度也不够用, 还可以再使用

    多个输入框使用注释符绕过

    <base>标签

    windows.name

    检查

    代码过滤

    对于用户输入的检查的逻辑,必须放在服务端代码中实现,如果只是在客户端使用JavaScript进行输入检查,是很容易被被攻击者绕过的。目前Web开发的普遍做法,是同时在客户端JavaScript中和服务器端代码中实现相同的输入检查。客户端JavaScript的输入检查,可以阻挡大部分误操作的正常用户,从而节约服务器资源。

    对输入进行特征匹配:关键字,称为XSS Filter。

    javascript script base等
    

    可以在网上找到很多关于XSS Filter的实现。

    但是如果用户提交的是变量$var,就不会被过滤。但是var的内容却携带有XSS攻击脚本的话,一样会被攻击成功。

    在对特殊字符处理的时候,还需要注意不要把正常的业务影响到。比如:

    1+1 < 3
    

    还有下面的情况

    $nickname='hello "world"'
    

    如果在XSS Filter中对双引号进行转义:

    $nickname='hello "world"'
    

    在JavaScript代码中展示时:

    <script>
    var nickname='hello "world"';
    document.write(nickname)
    </script>
    

    这两段代码,得到的结果并不一样。

    hello "world"
    hello "world"
    

    而第一个结果并不是用户想看到的。

    安全的编码函数

    针对HTML代码的编码方式是HtmlEncode,它并非专有名词,只是一种函数实现,它的作用是将字符转换成HTMLEntities,对应的标准是ISO-8859-1。

    针对PHP,有htmllentities,htmlspecialchars,相应的,JavaScript的编码方式可以使用JavaScriptEncode。

    在对抗XSS时,JavaScriptEncode还要求输出的变量必须在引号内部,以避免造成安全问题。

    var x = escapeJavaScript($evil);
    
    var y = '"'+ escapeJavaScript($evil) +'"';
    

    如果escapeJavaScript函数只转义了几个危险字符,比如' " < > & #等,那么上面两行的代码输出后可能会变成:

    var x = 1;alert(2);
    
    var y = "1;alert(2)";
    

    更严格的做法是,除了数字,字母外的所有字符,都使用十六进制'xHH'的方式进行编码。

    var x = 1;alert(2);
    

    变成了

    var x = 1x3balertx282x29;
    

    这样,也可以最大化的保证代码是安全的。

    还有其他很多类似于HtmlEncode、JavaScriptEncode功能的函数。可以在适当的情况下选用适当的函数。

    XSS攻击主要发生在MVC架构中的View层,大部分XSS漏洞可以在模板系统中解决。

    Secure By Default

    XSS是很复杂的问题,需要”在正确的地方使用正确的编码方式“。

    <body>
        <a href=# onclick="alert('$var');">test</a>
    </body>
    

    如果用户输入

    $var = htmlencode("');alert('2");
    

    渲染后的结果是

    <body>
        <a href=# onclick="alert('&#x27;#x29;&#x3b;alert&#x28;&#x27;2');">test</a>
    </body>
    

    对于浏览器来说,htmlparse会优先于JavaScript Parse执行,所以解析过程是,被HtmlEncode的字符先被解码,然后执行JavaScript时间:

    <body>
        <a href=# onclick="alert('');alert('2')">test</a>
    </body>
    

    成功在onclick事件中注入了xss代码。

    防止XSS攻击需要区分情况对待,并不是使用了某一策略就万事大吉。

    处理富文本

    用户发布文章、评论、图片等。

    危险标签

    <iframe>  <script> <base> <form>等
    

    过滤规则应该选用白名单,避免使用黑名单,比如,只允许

    <a> <img> <div>等
    

    白名单原则不仅仅用于标签的选择,同样应该用于属性与事件的选择。

    CSS处理

    如果允许用户自定义CSS、style,则也可能导致XSS攻击。那么需要一个CSS Parser对样式进行分析。

    CSS分析开源工具1

    CSS分析开源工具2

    DOM型

    <script>
        function test(){
        var str = document.getElementById("test").value;
        document.getElementById("t").innerHTML = "<a href='"+str"'">testLink</a>
    } 
    </script>
    
    <div id="t"></div>
    <input type="test" id="test" value=""/>
    <input type="button" id="s" value="write" onclick="test()"/>
    

    在button的onclick事件中,执行了test函数,而该函数中最关键的一句是:

    document.getElementById("t").innerHTML = "<a href='"+str"'">testLink</a>
    

    将HTML代码写入了DOM节点,导致漏洞产生。

    即使通过JavaScriptEscape,也仍然可能产生漏洞。

    <script>
    var x="$var"
    document.write("<a href='"+x+"'">testLink</a>)
    </script>
    
    <script>
    var x="x20x27onclickx3dalertx28x29x3bx2fx27"
    document.write("<a href='"+x+"'">testLink</a>)
    </script>
    

    在第一次执行JavaScriptEscape之后,只保护了变量x,但是当document.write输出数据到HTML页面时,浏览器重新渲染了页面。在<script>标签执行时,已经对变量进行了解码,其后document.write再运行时,参数就变成了

    <a href=' ' onclick=alert(1);//''>testLink</a>
    

    即使改成HtmlEncode依然可能产生漏洞

    <script>
    var x="1&#x22;&#x29;&#x3b;alert&#x28;2&#x29;&#x3b;&#x2f;&#x22"
    document.write("<a href=# onclick='alert(""+x+"")'>testLink</a>)
    </script>
    

    服务器把变量HtmlEncode后再输出到<script>中,然后变量x作为onclick事件的一个函数参数被document.write到了HTML页面里。onclick事件执行了两次alert,第二次是被XSS注入的。

    其他有可能导致XSS攻击的函数

    .after()
    .append()
    .appendTo()
    .before()
    .html()
    .insertAfter()
    .insertBefore()
    .prepend()
    .prependTo()
    .replaceAll()
    .replaceWith()
    .unwrap()
    .wrap()
    .wrapAll()
    .wrapInner()
    .prepend()
    

    其他输入来源

    document.URL *
    document.location.pathname *
    document.location.href *
    document.location.search *
    document.location.hash
    document.referrer *
    window.name
    document.cookie
    window.location(href hash等)
    

    以及所有input框,都是极有可能产生XSS攻击的点。

  • 相关阅读:
    boost lexical_cast 字符串数字间的字面转换(学习笔记)
    Smoke Testing
    深入浅出InfoPath——手工绑定托管代码
    深入浅出InfoPath——操作InfoPath元素
    深入浅出SharePoint2010——附录:常用术语对照
    CAML语法必备
    深入浅出SharePoint ——2010 新特性之搜索
    BVT测试
    Windows 7的71个运行命令列表
    深入浅出InfoPath——如何在项目中引用GAC中的dll文件
  • 原文地址:https://www.cnblogs.com/liuhuan086/p/14741974.html
Copyright © 2020-2023  润新知