Web信息安全实践_5. 点击劫持(click hijacking)

  • 如果在iframe中引用了其他来源的页面,当前网站的JS不能控制iframe中的元素。
<iframe id='myIFrame' src = 'x1.html' onload="fun1()"></iframe>
<p id='2'>I am 2.html.</p>
<p id='p'>hello world.</p>
<script>
function fun1(){
    var myframe = document.getElementById('myIFrame');
    (window.document.getElementById("myIFrame").contentWindow.document.getElementById('p').style.display="none");
}
</script>
 

点击劫持原理 

  • 攻击者覆盖多个透明或不透明层,以诱使用户点击另一页上的按钮或链接
  • 在原始界面上的点击被劫持并路由到了另一个界面
    • 使用iframe在攻击页面嵌入攻击目标网页
    • 透明化攻击目标页面
    • 在攻击页面、攻击目标页面切换

点击劫持实现技术

(1)任何网站都可以在内容页嵌入其他网站 —— iframe

(2)HTML 的属性

a)在不同页面进行层次切换 —— z-index 属性

  • 设置元素的层次顺序
  • 具有较大 z-index 的元素位于具有较低值的元素前面
<!DOCTYPE html>
<html>
    <head>        
        <style type="text/css">
        #img1
        {   position:absolute; left:0px; top:0px; z-index:-1 }
        </style>

        <script>
        function changeStackOrder()
        { document.getElementById("img1").style.zIndex=1; }
        </script>
    </head>

    <body>
    <h1>This is a Heading</h1>
    <img id="img1" src="bulbon.gif" width="100" height="180">
    <input type="button" onclick="changeStackOrder()" value="Change stack order">
    <p>Default z-index is 0. Z-index -1 has lower priority.</p>
    </body>
    
</html>

b)定义了 iframe 的可见百分比 —— Opacity

Opacity
  • 1:完全可见
  • 0:完全不可见
 
CSS的三种不同方式的透明化
  • opacity:0  
  • visibility:hidden
  • display:none
 
理解opacity:0、visibility:hidden、display:none
我们想象一下,一个人Bob存在于宇宙中,他坐在一把椅子上,如果你拍一下他,他会有反应。那我们网页上的正常的内容,就类似于Bob。在正常的网页流中,一个元素是在 DOM 中的,它是 可见 的,它 占据文档流 中的一定的位置,然后如果点击它(有onclick的动作属性),则会做出 反应
  • 如果我们使用opacity:0使得Bob隐形,那么Bob像穿了隐身衣,依然存在于宇宙中,他还坐在椅子上,如果你拍一下他,他自然也还是有反应的。(DOM+文档流+反应
  • 如果我们使用visibility:hidden使得Bob隐形,那么Bob依然存在于宇宙中,他不坐在椅子上,但是如果你拍一下他,他没有反应。(DOM+文档流
  • 如果我们使用display:none使得Bob隐形,那么Bob依然存在于宇宙中,但是他和他的椅子已经不在原地了,当然,也没办法去拍他了。(DOM
!DOCTYPE>
<html> 
    <head>
        <style type="text/css">
            #message { 
                color: #ffffff;
                background-color: #ff0000;
                border-width: 10px;
                border-color: black;
                border-style: solid;
                width: 100px;
                height: 50px;
                padding: 50px;
            }
        </style>
        <script type="text/javascript">
            window.onload = function(event) {
                document.getElementById('toggle').onclick = function() {
                    var message = document.getElementById('message');
                    if(message.style.display === 'none') {   
                        message.style.display = 'block';           
                    }
                    else {
                        message.style.display = 'none';  
                    }
                };
            };
        </script>        
    </head>
    <body>
        <button id='toggle'>Toggle the visible status</button>
        <hr>
        This is a text! This is a text! This is a text! This is a text! This is a text!
        <div id="message">Message 1</div>
        This is other text!This is other text!This is other text!This is other text!This is other text!
    </body>
  </html>                      
 
 
 
<script type="text/javascript">
    window.onload = function(event) {
    document.getElementById('toggle').onclick = function() {
            var message = document.getElementById('message');
            if(message.style.visibility === 'hidden') {            
             message.style.visibility = 'visible';              
            }
            else {
            message.style.visibility = 'hidden';  
            }
    };
    };
</script>   
<script type="text/javascript">
    window.onload = function(event) {
    document.getElementById('toggle').onclick = function() {
            var message = document.getElementById('message');
            if(message.style.opacity == 0)                 {            
             message.style.opacity = 1;         
            }
            else {
            message.style.opacity = 0;  
            }
    };
    };
</script>      

点击劫持防御

frame busting(网页提供代码,旨在防止网页被加载到 iframe 中)

  • 同域网页仍被允许嵌入

(1)防止页面被加载到 iframe 中 的方法

if(top.location != self.location) // 查看最上层是否是自己
    parent.location = self.location; // 不是,把上层换成自己

(2)攻击者破解策略

  • Javascript 的 onUnload 事件
<body onUnload="javascript: cause_an_abort;)"> // 发现要被替换,攻击者通过代码停止替换
  • 攻击者通过代码,诱使用户帮助攻击者实现iframe

    • 用户可能手动取消 Frame Busting 代码的功能
<script>    
    window.onbeforeunload = function() { 
        confirm("Do you want to leave? ");
        return "hi there";
    }
</script>

<body>
<iframe id='myIFrame' src = 'p2.html'></iframe>
p2 is framed.
</body>

(3)不可靠的frame busting示例

Walmart 不可靠的 frame busting 代码

if (top.location != location) {
    if(document.referrer && document.referrer.indexOf("walmart.com") == -1) {        
        top.location.replace(document.location.href);
    }
} 
 

 纽约时报 不可靠的 frame busting 代码

if (window.self != window.top && !document.referrer.match(/https?:\/\/[^?\/]+\.nytimes\.com\//)) {
    self.location = top.location;
}

(4)frame busting 推荐代码

  • 效率低
<style>body {display:none;}</style> <!--不显示页面内容-->

<body>
I'm not be framed! 
<script>
    if(self==top) { // 确认在最上层
        document.getElementsByTagName("body")[0].style.display='block' // 设置显示
    }
    else{ // 如果不能挣脱iframe,那么就不显示
        top.location = self.location;
    }
</script>

X-Frames-Options

  • X-Frames-Options首先在 IE8(浏览器) 中提出,用于控制页面能否被 iframe。
  • 如果开发者在某个页面或整个网站都设置了X-Frames-Options,那么HTTP头部会出现X-Frames-Options
 
HTTP 头部 ——  X-Frames-Options( DENY 和 SAMEORIGIN )
  • DENY :不会嵌入到 iframe 中
  • SAMEORIGIN :同源可嵌入
header("X-Frame-Options:DENY");

猜你喜欢

转载自www.cnblogs.com/tianjiazhen/p/12235919.html