首页
社区
课程
招聘
web前端安全基础与攻防(续篇)
发表于: 2015-4-21 10:02 7848

web前端安全基础与攻防(续篇)

2015-4-21 10:02
7848
<script>function XSS(){
        a = new ActiveXObject('Microsoft.XMLHTTP');
        a.open('get', 'http://www.baidu.com', false);
        a.send();
        b = a.responseText;
        document.write(b);
        }
        XSS();
</script>
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta http-equiv="Content-type" content="text/html;charset=utf-8" />
        <title>XssPayloadTest</title>
        <script type = "text/javascript">
        var xmlhttp;
        function LoadXMLDoc(url)
        {
            xmlhttp = null;
            if (window.XMLHttpRequest)
            {
                xmlhttp = new XMLHttpRequest();
            }
            else if (window.ActiveXObject)
            {
                xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
            }
            if (xmlhttp != null)
            {
                xmlhttp.onreadystatechange = state_Change();
                xmlhttp.open("GET", url, true);
                xmlhttp.send(null);
                 
            }
            else
            {
                alert("your browser does not support XMLHTTP");
            }
        }
 
        function state_Change()
        {
            if (xmlhttp.readyState == 4)
            {
                if (xmlhttp.status == 200)
                {
                    document.getElementById('T1').innerHTML = xmlhttp.responseText;
                }
                else
                {
                    alert("problem retrieving data:" + xmlhttp.statusText);
                }
     
            }
        }        
        </script>
     
    </head>
    <body onload = "LoadXMLDoc('http://bbs.pediy.com/index.php')">
    <div id = "T1" style = "border:1px solid black;height:40;width:300;padding:5"></div><br />
    <button onclick = "LoadXMLDoc('http://shayi1983.blog.51cto.com')">Click</button>
    </body>
</html>
var xhr = new XMLHttpRequest();
xhr.open("PUT", "http://www.friendlySite.com/index.html", true);
xhr.send();
OPTIONS http://www.friendlySite.com/index.html HTTP/1.1
Host: www.friendlySite.com 
User-Agent: Mozilla/5.0(Macintosh; Intel Mac OS X 10.7; rv:11.0) Gecko/20150101 Firefox/37.0
Accept: text/html,application/xhtml+xml,applicatiin/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.5
Origin: http://www.webSite.com 
Accept-Control-Request-Method: PUT
HTTP/1.1 200 OK
Date: Wed, 13 Apr 2015 06:51:53 GMT
Server: Tengine
Access-Control-Allow-Origin: http://www.webSite.com
Access-Control-Allow-Methods: PUT
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 10
Content-Length: 0
<!DOCTYPE html>
<htMl lang="en">
    <head>
        <meta http-equiv="Content-type" content="text/html;charset=utf-8" />
        <title>XssPayloadTest</title>
    </head>
     
    <body>
    ' " `
    <a href = http://www.baidu.com>百度首页。。。
    </oops>
    <IMG src = #>
</hTml>

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (14)
雪    币: 7
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
写的不错,有没有兴趣把这个教程作成实验啊,我们的实验平台是征集实验的,帮助更多人嘛。
2015-4-21 12:14
0
雪    币: 6
活跃值: (1161)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
非常不错,支持楼主
2015-4-21 12:35
0
雪    币: 1604
活跃值: (640)
能力值: ( LV13,RANK:460 )
在线值:
发帖
回帖
粉丝
4
什么样的实验?你们是互联网公司还是安全公司
2015-4-21 13:19
0
雪    币: 7
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
我们是做网络安全人才培训的互联网公司
我们的实验形式请参考http://erange.heetian.com/  里面有很多类型的实验了。
希望能有合作。
2015-4-22 08:19
0
雪    币: 1604
活跃值: (640)
能力值: ( LV13,RANK:460 )
在线值:
发帖
回帖
粉丝
6
补充内容

《页面使用 UTF-7 字符编码导致的 XSS 漏洞详解》

很多安全类书籍都介绍到 UTF-7 字符编码会导致 XSS 漏洞,但是部分内容各执一词,且描述不清楚,这里总结如下:

UTF-7 编码是 unicode 编码的一类子集,后者包含的其它编码类型有 UTF-8,UTF-16LE(小端法,将代表编码字符的最低有效字节放在前面),UTF-16BE(大端法,将代表编码字符的最高有效字节放在前面),UTF-32LE,UTF-32BE 等等。在 UTF-7 编码方案中,左尖括号被编码成“+ADW-”;右尖括号被编码成“+AD4-”,其中的加号与减号分别标识着 UTF-7 编码序列的开始与结束;如果服务器端的 XSS 过滤器没有过滤这两个UTF-7 编码格式的左右尖括号,(或没有将其编码成其它无害形式的字符),并且客户端浏览器的版本过于老旧(例如 IE 7),那么当被注入攻击载荷的页面返回至客户端时,浏览器将解码 script 标签前后的 +ADW- +AD4- 字符,还原成明文的左右尖括号,从而执行 script 标签内部的恶意代码:

<!DOCTYPE html>
<html>
    <head>
    <meta http-equiv="Content-type" content="text/html;charset=UTF-7" />
        <title>XssPayloadTest</title>
    </head>
    <body>
        +ADW-script+AD4-alert("xss")+ADW-/script+AD4-
    </body>
</html>


以上文档中,web 服务器(愚蠢到)在 meta 元素中显式指定字符集为 UTF-7,如果浏览器同样愚蠢(例如 IE 7以下版本,美其名曰是为了保持向后兼容)遵循这个设置字符集的指令,就会解码任何 UTF-7 字符,最终导致弹出提示框。需要补充说明的是,多数现代浏览器均已经不支持 UTF-7 了,因而上述文档在最新版本的三大浏览器中测试,都不会弹出提示框;另外,实际的触发环境和条件更为复杂,考虑如下场景中,假设用户的浏览器是 IE 6/7 :

1。如果 web 服务器在返回的 HTTP Content-Type 响应头中,没有明确设置字符集编码,并且响应体中的 HTML 文档中的 meta 元素内,也没有设置字符集编码,那么浏览器在碰到任何 UTF-7 字符时,都会尝试确定其编码方案,并且解码还原成明文字符,以上述文档为例,就会弹出提示框;

2。如果 web 服务器在返回的 HTTP Content-Type 响应头中,明确设置字符集编码为 UTF-8,并且响应体中的 HTML 文档中的 meta 元素内设置的字符编码为 UTF-7,那么浏览器最终将按照响应头中的设置(响应头的优先级比响应体中 meta 标签的优先级高 ),以上述文档为例,会弹出提示框(因为采用 UTF-8 字符编码时,浏览器无法识别,解码 +ADW-+AD4- 字符);

3。如果 web 服务器在返回的 HTTP Content-Type 响应头中,设置字符集编码为 UTF-7,并且响应体中的 HTML 文档中的 meta 元素内设置的字符编码为 UTF-8,

根据浏览器的采用优先级原则,上述文档将会弹出提示框;

总结,应对 UTF-7 XSS攻击,从最终用户防御的角度来看,应该确保浏览器总是处在当前的最新版本状态;从 web 站点防御的角度来看,应该明确在响应头与响应体的 HTML 文档中,设置字符编码为 UTF-8 或者其它安全的编码方案;

对于每个包含HTML内容的响应,web应用需要在其中包含 Content-type 头部,并且用“charset=”指令设置一个标准的,(浏览器)可辨识的字符集,
例如:

Content-Type: text/html; charset=utf-8

或者:
Content-Type: text/html; charset=ISO-8859-1
(如前所述,还要确保响应中的所有可能位置指定了相同的字符集)

并且过滤掉任何 UTF-7 危险字符,如果没有把握通过编程屏蔽所有危害字符,则可以模仿浏览器的 HTML 解析引擎将用户输入的内容在内存中保留一份副本,将其渲染成 HTML 页面,在渲染结果中查找任何明文的危害字符,对其进行编码过滤,然后再次渲染,再过滤,直到完全清除干净后,才可以把最终的文档返回给客户端。

(这也是许多优秀的服务器端 XSS 过滤器,WAF 采用的工作模式)


2015-4-24 09:33
0
雪    币: 268
活跃值: (114)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
Mark
2015-4-25 22:20
0
雪    币: 1604
活跃值: (640)
能力值: ( LV13,RANK:460 )
在线值:
发帖
回帖
粉丝
8
补充内容

HTML 文档的跨平台支持:根据不同的浏览器类型,执行不同的代码块

由于各种浏览器对于新的 HTML5 规范,以及 DOM 的支持,实现程度不一致,为了保证自己所编写的文档,以及其中的脚本代码能够在所有主流浏览器中正确运行,一种解决办法是:先判断浏览器类型,然后执行相应浏览器支持的代码块。实现这个功能的关键,在于浏览器的用户代理字串值,即 navigator.userAgent

实现逻辑如下:


<!DOCTYPE html>
<html>
    <head>
    <meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
        <title>XssPayloadTest</title>
    </head>
    <body>
        <script>
            document.write(navigator.userAgent);
            document.write("<br><br>");
            var isIE = navigator.userAgent.indexOf('Trident') > 0;
            var isChrome = navigator.userAgent.indexOf('Chrome') > 0;
            var isFirefox = navigator.userAgent.indexOf('Firefox') > 0;
            var isOpera = navigator.userAgent.indexOf('OPR') > 0;
            if (isIE){
                document.write('<b>您使用的是IE浏览器</b>');
            }else if (isChrome){
                if (isOpera){
                    document.write('<b>您使用的是Opera浏览器</b>');
                }else{
                    document.write('<b>您使用的是Chrome浏览器</b>');
                }
            }else if (isFirefox){
                document.write('<b>您使用的是Firefox浏览器</b>');
            }else{
                document.write('<b>您使用的是其它浏览器</b>');
            }
        </script>
 
    </body>
</html>


这是一个非常简单的先判断然后输出用户使用的浏览器类型的页面。

第8行直接在当前页面输出打开该页面的浏览器的用户代理字串;第11~14行分别查找各种浏览器的用户代理字串中,能够唯一识别浏览器类型的关键词,这是由于,在早期的“浏览器世界大战”中,许多 web 页面的特定内容仅支持 Netscape Navigator 浏览器(网景公司的产品,其 “Mozilla” 字串就是它首创的,含义为“Mosaic Killer”,即浏览器鼻祖 Mosaic 的杀手),而其它品牌浏览器为了提高自身市场份额与竞争力,也在其用户代理中添加了“Mozilla”字串,用于告诉目标站点:“我是与 Mozilla 兼容的浏览器”,如此一来,站点就会返回原本仅响应给 Mozilla 浏览器的页面内容,而这个内容通常是比较丰富的;

最终效果就是, IE 浏览器的用户访问某站点获得的内容与 Netscape Navigator 浏览器的用户获得的内容一致,因为 IE 在它的用户代理字串中,添加了“Mozilla”字串。

其它浏览器相继模仿这个做法,导致通过“Mozilla”字串根本无法实际识别浏览器类型,所以,必须找到用户代理字串中,每个浏览器都不一样的关键词,这就是第11~14行代码的工作,例如第11行查找用户代理字串中的“Trident”,后者是 IE 浏览器的 HTML 渲染引擎内核代号,然后保存在一个变量中,第15~16行代码通过判断这个变量的值来输出用户使用的是 IE 浏览器(在实际开发时,应该把这里的内容替换成仅 IE 浏览器支持的页面代码,其它类型浏览器以此类推)。

另一方面,当前的 chrome 与 Opera 浏览器的用户代理字串中,都包含了“Chrome”关键词,所以仅凭它无法区分这2个浏览器,需要检查在包含“Chrome”关键词的用户代理字串中,是否含有“OPR”字串,如果有,则能识别出 Opera 浏览器,反之,则为 chrome 浏览器;而这就是第17~22行的嵌套 if-else 语句的工作。顺便提一下,这2个浏览器的 HTML 解析引擎内核都源于苹果公司开发 Safari 浏览器时的内核 WebKit;google 公司在 WebKit 的基础上开发出新的内核称为 Blink;这2个浏览器厂商“饮水思源”的做法导致你在使用这2个浏览器打开上述文档时,看到了各自的用户代理字串都包含“AppleWebKit”:











我在第25~27行就停止了判断浏览器类型,你也可以继续添加判断其它浏览器的 else if 语句块,例如 Safari,以及国产的 360 浏览器,这需要预先找出能唯一标识它们的用户代理字串片断,就如第11~14行代码所做的一样,各位可以自行测试。
2015-4-26 12:18
0
雪    币: 3480
活跃值: (246)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
楼主的注释很详尽   赞一个
2015-4-27 15:52
0
雪    币: 1604
活跃值: (640)
能力值: ( LV13,RANK:460 )
在线值:
发帖
回帖
粉丝
10
补充内容

《存储型 XSS 示例》

一些社交网站如 twitter 提供的站内短信功能,在其中会通过 a 标签的 href 属性值进行短信链接的导航,这个属性值是用户能够控制的输入数据,所以 twitter 对其进行了严格输入检查,编码,过滤等操作,主要是过滤尖括号以及 script,embed,object 等危害性元素。

假设用于生成短信链接的输入框的初始 HTML 代码如下:


<a href="></a>


在上面场景中,攻击者想方设法要绕过 twitter 服务器的 XSS 过滤器,最终目的是让输入的攻击载荷存储在由服务器的 web 应用维护的,某个能够公开访问的“页面”(类似新浪微博的“广场”功能),其它用户访问这个页面时,XSS 漏洞在用户浏览器中触发,执行恶意脚本代码。由于上面提到的过滤规则,插入尖括号的方法已经不再适用,必须寻找新的方法来绕过,例如下面这个攻击载荷使用了众多web 前端黑客技术:

1。双引号元素属性闭合;

2。 onmouseover 事件结合 eval 函数执行任意代码;

3。对 URL 进行 UTF-16 编码绕过 XSS 防火墙;

4。利用社会工程学攻击来引诱用户点击链接;


http://t.co@" style="font-size:99px;" onmouseover="eval(location.href='http:\u002f\u002fwww.baidu.com\u002f')" class/


其中,邮件符号 @ 后面的第一个双引号用于闭合原始 HTML 代码中, 等号后面的第一个双引号,于是攻击者可以在后面插入自定义内容;style属性将字体增大到 99 像素,保证受害者能够“准确地”点击到具诱惑性的恶意链接; onmouseover 属性代表的事件在用户将鼠标指针移动到该元素(a 元素)范围内时触发,事件触发后,执行自定义代码,将当前文档的 URL 重定向到百度首页(这里经过我净化,实际的攻击载荷中,其 URL 肯定是由攻击者控制的站点上的恶意 .js 文件);需要注意,考虑到 twitter 的 XSS 防火墙可能会过滤以“http://”起始的字符串,因此使用 UTF-16 编码(\u002f)对恶意 URL 中的正斜杠(/)进行转义,这样就能绕过服务器的 XSS 防火墙(只要不是精确匹配,输入字串就能通过检查),关键在于,转义后的字符序列在作为 HTTP 的响应体内容返回至客户端后,浏览器会解码,还原成正斜杠,导致最终访问该 URL ;另外, onmouseover 属性的值必须是能够执行的函数或者代码快,这就是调用 eval 函数的目的;最后,使用 class 后面的正斜杠来注释掉原始 HTML 代码中的第二个双引号,避免浏览器因为语法错误而无法执行脚本。

为了增强链接的视觉诱惑性,我在 a 元素的 innerHTML 中,添加了名为“邀请码发放页面”的文本节点(请勿在论坛中尝试!),最终的注入效果(即存储到服务器上的漏洞页面)如下所示:


<!DOCTYPE html>
<html>
    <head>
    <meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
        <title>XssPayloadTest</title>
    </head>
    <body >
        <a href="http://t.co@" style="font-size:99px;" onmouseover="eval(location.href='http:\u002f\u002fwww.baidu.com\u002f')" class/">邀请码发放页面</a>
    </body>
</html>


使用当前任意类型的最新版浏览器打开上面 HTML 文件,就会重定向到百度首页,这就完整的模拟出攻击载荷成功绕过,存储到服务器上,并且返回给客户端后,用户浏览器成功执行代码的场景,截图如下:

2015-4-28 11:10
0
雪    币: 44
活跃值: (35)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
讲得很细,可以看出楼主对浏览器、脚本语言以及XSS的了解很专业。顶一个!
2015-4-29 07:33
0
雪    币: 1604
活跃值: (640)
能力值: ( LV13,RANK:460 )
在线值:
发帖
回帖
粉丝
12
补充内容

关于浏览器支持 unicode 字符转义序列引发的 xss

以 “\u”开始的6个 ASCII 字符,是 javascript 语言核心中,用于
unicode 字符的转义序列,“\u”后面的4个 ASCII 字符(或2个16进制数),可以采用 UTF-8/16/32 等编码形式;这里使用的是 UTF-16 编码(三种编码都是 unicode 编码的子集),使用这些编码是为了支持一些不能正常显示 unicode 字符的计算机系统。实际上,unicode 字符转义使用与 ASCII 字符的16进制编码相同的
映射;例如,对于字符串“alert”,其 ASCII 16进制编码形为“\61\6c\65\72\74”;其 unicode UTF-16 编码转义形式为“\u0061\u006c\u0065\u0072\u0074” ,第2个16进制数与 ASCII 字符的16进制编码相同,第1个16进制数在编码 ASCII 字符时为 00;在编码其它 unicode 字符时不为 00。
javascript 语言核心(以及实现它的浏览器内部的 javascript 解释引擎)直接支持
unicode 字符转义序列,这意味着,只有这些转义字符出现在页面中与 javascript 执行上下文相关的环境中时,才能被浏览器正确解码,这些环境包括但不限于(其它上下文各位可以自行挖掘):
1。 script 元素内部;
2。 支持绑定事件处理程序的元素内部;
3。支持在属性值中使用 javascrip 伪协议的元素;
如果直接在 HTML 文档中(例如普通的元素内)使用 unicode 字符转义序列 ,浏览器可能无法识别并解码成相应的 unicode 字符,下面通过例子演示:


<!DOCTYPE html>
<html>
    <head>
                <meta http-equiv="Content-type" content="text/html;charset=utf-8" />
                <title>XssPayloadTest</title>
        </head>
        <body>
        \u0061\u006c\u0065\u0072\u0074
        <div>
            <a href = "javascript:\u0061\u006c\u0065\u0072\u0074('xss!')">百度首页</a>
            <input type = "text" name ="search" id ="search" value = ""onfocus = \u0061\u006c\u0065\u0072\u0074('利用事件处理程序的xss!')//" class = "text_area"/>
            <script>
                document.write("\u0061\u006c\u0065\u0072\u0074");
            </script>
             
    </body>
</html>


第8行直接在 body 元素(页面文档体)中写入ASCII 字符串“alert”的 unicode UTF-16 编码转义形式 “\u0061\u006c\u0065\u0072\u0074”,浏览器将不会解码并还原成“alert”,而是直接在页面输出“\u0061\u006c\u0065\u0072\u0074”;
第10行在 a 元素的 href 属性值中使用 javascript 伪协议,其中的“alert”保留字使用 unicode UTF-16 编码转义形式,浏览器会解码并还原成 “alert”,导致在点击名为“百度首页”的超链接时,弹出显示“xss!”的信息框;
第11行给 input 元素的 onfocus (鼠标点击聚焦输入框)事件绑定的回调函数正是采用 unicode UTF-16 编码转义形式的 “alert”,浏览器会解码并还原,导致用户点击输入框时触发事件处理程序,弹出提示框;
第13行在 script 元素内调用 document.write(),作为其参数传递的正是 unicode UTF-16 编码转义形式的 “alert”,浏览器会解码并还原,最终在页面输出 alert 字符串。
下面的截图验证了浏览器的 javascript 解析引擎在上述三种 javascript 执行上下文中,遇到 unicode  字符转义序列时,所表现出的行为:




这个小实验再次说明了基于黑名单过滤的 XSS 防火墙是不安全的:你也许想到要在元素属性值中过滤 alert ,script,javascript 等字符串,但是你能考虑周全地过滤掉所有相应字符串的 unicode 字符转义序列吗?黑名单匹配曝露的受攻击面是如此之广,以至于任何漏网之鱼都可能被攻击者用于发起 XSS !
2015-5-25 15:59
0
雪    币: 268
活跃值: (114)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
多谢楼主的分享。
2015-6-12 16:32
0
雪    币: 5
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
学习了!真乃精细高手也!
2015-7-5 21:13
0
雪    币: 96
活跃值: (175)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
收获匪浅
2017-9-3 09:29
0
游客
登录 | 注册 方可回帖
返回
//