0x00 相關背景介紹
Clickjacking(點擊劫持)是由互聯網安全專家羅伯特·漢森和耶利米·格勞斯曼在2008年首創的。
是一種視覺欺騙手段,在web端就是iframe嵌套一個透明不可見的頁面,讓用戶在不知情的情況下,點擊攻擊者想要欺騙用戶點擊的位置。
由於點擊劫持的出現,便出現了反frame嵌套的方式,因為點擊劫持需要iframe嵌套頁面來攻擊。
下面代碼是最常見的防止frame嵌套的例子:
if(top.location!=location) top.location=self.location;
事實上,這種代碼很容易被繞過,在后文中討論。
0x01 防御的幾種方式
防止frame嵌套的js使用代碼由高到低比例:
1
2
3
4
5
6
7
8
9
10
|
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.length!=0))
|
檢測到后的處理方案:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
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
top.location.href = self.location
top.location = window.location
top.location.replace(window.location.pathname)
window.top.location = window.self.location
setTimeout(
function
(){document.body.innerHTML=
''
;},1);
window.self.onload =
function
(evt){document.body.innerHTML=
''
;}
var
url = window.location.href; top.location.replace(url)
|
0x02 繞過的幾種方式
對於使用parent.location來防御的可以使用多層嵌套的方式繞過。
一、例如防御代碼為:
if(top.location!=self.location){ parent.location = self.location; }
建立兩個頁面:
1.html代碼為:
<iframe src="2.html">
2.html代碼為:
<iframe src="http://www.victim.com">
訪問1.html之后可以看到頁面並無跳轉等動作。
二、onBeforeUnload函數的利用:
onBeforeUnload的介紹以及各種瀏覽器的支持情況請見:
http://w3help.org/zh-cn/causes/BX2047
如下的防御代碼:
if(top != self) top.location.replace(location);
新建立頁面,代碼如下:
<script> var framekiller = true; window.onbeforeunload = function() { if(framekiller) { return "Write something here to keep people stay!";} }; </script> <iframe src="http://www.victim.com/">
打開頁面顯示如下:
欺騙用戶點擊留在此頁后顯示:
三、XSS filter的利用
IE8以上以及Chrome瀏覽器都有XSS篩選器,這些可以用來對付防御frame嵌套的代碼。
防御代碼如下:
if(top!=self){ top.location=self.location; }
新建立頁面,代碼如下:
<iframe src="http://www.victim.com/?<script>">
訪問后頁面顯示:
IE的xss篩選器自動攔截了跳轉。
斯坦福的文章里寫了Chrome也會出現這種情況,並給出了攻擊代碼:
<iframe src=http://www.victim.com/?v=if(top+!%3D+self)+%7B+top.location%3Dself.location%3B+%7D">
但是測試發現,新版的Chrome並不會攔截了,會直接跳轉過去。
如果跟的參數中有變量在頁面中顯示的,會把變量過濾一遍再輸出,但不會阻止跳轉。
四、Referer檢查的問題
有一些站點允許自己的域名嵌套自己,禁止外站對自己的嵌套。
通常是用document.referer來檢測來源是否為自己的域名。
1
2
3
4
5
6
|
if
(top.location!=location){
if
(document.referrer && document.referrer.indexOf(
"aaa.com"
)==1)
{
top.location.replace(document.location.href);
}
}
|
判斷字符串中是否含有本域名是常見的錯誤用法,利用二級域名的方式便可繞過,如:
http://aaa.com.bbb.com
注:從https域下post數據到http域的時候,瀏覽器不帶Referer。
IE有個屬性可以設置security為restricted可以禁止iframe里執行js腳本,但是要達到點擊劫持的效果,必須要能夠執行js所以很雞肋。
代碼如下:
<iframe src="http://www.victim.com/iframe.html" security="restricted"></iframe>
重點是手機站點,很多主站做的很不錯,但是手機站點沒有做任何防護,很容易造成點擊劫持。
五、location劫持
在IE瀏覽器中,如果能夠在防御代碼的前面可以插入form表單的話,可以利用form表單對location進行劫持。
<form name=self location="javascript:alert(1)"></form> <script> if(top!=self){ top.location=self.location } </script>
用iframe嵌套此代碼,可以看到沒有跳轉,執行了alert(1)。
相關案例: 騰訊微博clickhijacking(不要被你的雙眼欺騙)
0x03 推薦防御的方法:
一、X-FRAME-OPTIONS
X-FRAME-OPTIONS是微軟提出的一個http頭,專門用來防御利用iframe嵌套的點擊劫持攻擊。
並且在IE8、Firefox3.6、Chrome4以上的版本均能很好的支持。
這個頭有三個值:
DENY // 拒絕任何域加載 SAMEORIGIN // 允許同源域下加載 ALLOW-FROM // 可以定義允許frame加載的頁面地址
php中設置示例:
header ( "X-FRAME-OPTIONS:DENY");
二、目前最好的js的防御方案為:
1
2
3
4
5
6
7
8
9
10
11
12
|
<head>
<style> body { display : none;} </style>
</head>
<body>
<script>
if
(self == top) {
var
theBody = document.getElementsByTagName(
'body'
)[0];
theBody.style.display =
"block"
;
}
else
{
top.location = self.location;
}
</script>
|