【XSS】延长 XSS 生命期
XSS 的本質(zhì)仍是一段腳本。和其他文檔元素一樣,頁(yè)面關(guān)了一切都銷(xiāo)毀。除非能將腳本蔓延到頁(yè)面以外的地方,那樣才能獲得更長(zhǎng)的生命力。
慶幸的是,從 DOM 誕生的那一天起,就已為我們準(zhǔn)備了這個(gè)特殊的功能,讓腳本擁有突破當(dāng)前頁(yè)面的能力。
下面開(kāi)始我們的續(xù)命黑魔法。
反向注入
一個(gè)不合理的標(biāo)準(zhǔn),往往會(huì)埋下各種隱患。
瀏覽器提供了一個(gè) opener 屬性,供彈出的窗口訪問(wèn)來(lái)源頁(yè)。但該規(guī)范設(shè)計(jì)的并不合理,導(dǎo)致通過(guò)超鏈接彈出的頁(yè)面,也能使用 opener。
但按理來(lái)說(shuō),只有通過(guò)腳本彈出的子頁(yè)面,才能擁有 opener 屬性,這樣可以相互訪問(wèn)和操作。
然而事實(shí)上,通過(guò)超鏈接點(diǎn)開(kāi)的頁(yè)面居然也有!這為 XSS 打開(kāi)了一扇大門(mén) —— XSS 不僅可以操控當(dāng)前頁(yè)面,甚至還能傳染給同源的父頁(yè)面。
XSS 一旦感染到父頁(yè)面里,戰(zhàn)斗力就大幅提升了。
可以想象,只要看了一個(gè)帶有 XSS 的帖子,即使立即關(guān)了,那么帖子列表頁(yè)也會(huì)遭到感染。
更有趣的是,opener 這個(gè)屬性不受同源策略限制。即使父頁(yè)面不同源,但父頁(yè)面的 opener 仍然可以訪問(wèn)。
我們可以順著 opener.opener.opener... 一直往上試探,只要是和當(dāng)前頁(yè)面同源的,仍然能夠進(jìn)行操控 —— 盡管中間隔著其他不同源的頁(yè)面。
網(wǎng)站的主頁(yè)面顯然比詳細(xì)頁(yè)更受用戶的信任,停留的時(shí)間也會(huì)更長(zhǎng),因此攻擊力可成倍的增加。
正向注入
如果說(shuō)反向注入是茍且偷生的話,那么正向注入就是當(dāng)家做主翻身的機(jī)會(huì)了。
盡管我們能夠控制父頁(yè)面,但從父頁(yè)面點(diǎn)開(kāi)的網(wǎng)頁(yè)仍然不受操控。如果具有控制子頁(yè)面的能力,那就更完美了。
不幸的是,我們無(wú)法控制超鏈接打開(kāi)的新頁(yè)面。唯一能夠操控的新頁(yè)面,那就是 window.open 的彈框頁(yè)。幸運(yùn)的是,在絕大多數(shù)瀏覽器上,它們看起來(lái)的效果是一樣的。
因此,我們可以在用戶的點(diǎn)擊瞬間,屏蔽掉默認(rèn)的超鏈接行為,用彈框頁(yè)取而代之,即可把 XSS 注入到 window.open 返回的新頁(yè)面里了。
類似的,通過(guò)子頁(yè)面遞歸打開(kāi)的新頁(yè)面,同樣也無(wú)法逃脫。于是子子孫孫盡在我們的掌控之中。
反向注入,讓我們占據(jù)已有的地盤(pán);正向注入,把我們的勢(shì)力擴(kuò)大蔓延出去。兩者結(jié)合,即可占據(jù)半壁江山了。
值得注意的是,正向注入中有個(gè)細(xì)節(jié)問(wèn)題。并非所有的超鏈接都是彈出型的(_blank),也有不少是在當(dāng)前頁(yè)面跳轉(zhuǎn)的。若是想劫持的狠點(diǎn),可以忽略這個(gè)問(wèn)題;如果不想被細(xì)心的用戶發(fā)現(xiàn),那么可以判斷下當(dāng)前超鏈接以及<base>的 target 屬性,決定是否劫持。
頁(yè)面監(jiān)督
上面提到,如果是在當(dāng)前頁(yè)面里跳轉(zhuǎn),那么還能繼續(xù)感染嗎?或者說(shuō),某個(gè)頁(yè)面刷新之后,是否就丟失了?
答案是肯定的。如果我們不采取一些措施,任憑占據(jù)的地盤(pán)不斷丟失,那么我們的勢(shì)力范圍就會(huì)越來(lái)越小,直到消亡。
相比進(jìn)攻,防守則更為困難。我們不知何時(shí)會(huì)失去,因此必須定時(shí)去檢查。
一旦發(fā)現(xiàn)對(duì)方已擺脫我們的控制,那么必須立即重新注入,以恢復(fù)我們的勢(shì)力。
對(duì)于新頁(yè)面的 XSS 來(lái)說(shuō),當(dāng)然是注入的越早越好。越前面擁有越高的優(yōu)先級(jí),甚至可以攔截頁(yè)面的正常業(yè)務(wù)功能。
為了能盡快獲知頁(yè)面刷新、跳轉(zhuǎn)等行為,我們還可跟蹤 unload 事件,在頁(yè)面即將丟失的瞬間,將消息通知出去,讓對(duì)方盡快來(lái)拯救自己。
這樣,就不必等待定時(shí)器了,可以最快的速度恢復(fù)。甚至能趕在頁(yè)面的第一個(gè)腳本之前,運(yùn)行我們的 XSS。
當(dāng)然,并非任何情況都能收回的。如果跳轉(zhuǎn)到了不同源的頁(yè)面,那顯然是無(wú)能為力了 —— 不過(guò),就此而放棄它嗎?回答是:決不妥協(xié)!
盡管頁(yè)面已經(jīng)和我們分道揚(yáng)鑣了,但所在的窗體仍然被我們掌控。我們可以跳轉(zhuǎn)、關(guān)閉它,甚至還有可能出現(xiàn)奇跡:只要頁(yè)面跳轉(zhuǎn)回我們的站點(diǎn),又可被我們所收復(fù)!
互相聯(lián)結(jié)
不難發(fā)現(xiàn),只要還有一個(gè)頁(yè)面存在,就有可能收回曾經(jīng)被占領(lǐng)的地盤(pán)。因此,我們要將可控的頁(yè)面都聯(lián)結(jié)起來(lái),讓每個(gè)頁(yè)面都知曉并監(jiān)督所有成員。
當(dāng)有新成員加入時(shí),通知給大家,記錄在各自的頁(yè)面里。
這樣即使其中一個(gè)頁(yè)面意外關(guān)閉了,也不會(huì)丟失重要的信息 —— 信息已被分布儲(chǔ)存在各個(gè)頁(yè)面里了。
因此,頁(yè)面開(kāi)的越多,相互聯(lián)結(jié)就越牢固。
所以,把超鏈接都變成新頁(yè)面中打開(kāi),還是有很大的優(yōu)勢(shì)的。
如果只剩最后一個(gè)頁(yè)面,那么一旦刷新之后就沒(méi)人來(lái)拯救了,于是就會(huì)消亡。
降域嘗試
一些網(wǎng)站為了方便通信,將 document.domain 降到根域。例如支付寶網(wǎng)站的絕大部分頁(yè)面,都是 alipay.com。這樣原本不同源的子站,這時(shí)也能夠相互操控了。
因此,遇到不同源的頁(yè)面,可以嘗試降低自身的域,再次發(fā)起操作,或許就能成功注入了。
表單劫持
之前說(shuō)到正向注入,是通過(guò)劫持超鏈接點(diǎn)擊實(shí)現(xiàn)的。事實(shí)上,除了超鏈接外,還有個(gè)進(jìn)入新頁(yè)面的方式,那就是表單提交。
相比超鏈接,表單顯得棘手一些。我們不僅得打開(kāi)一個(gè)新頁(yè)面,還要把表單里的數(shù)據(jù)也提交上去。如果把整個(gè)表單的元素克隆到新頁(yè)面提交,一些數(shù)據(jù)又會(huì)丟失。
不過(guò),仔細(xì)研究一下表單元素,會(huì)發(fā)現(xiàn)有一個(gè)非常簡(jiǎn)單的方法:原來(lái) window.open 第二個(gè)參數(shù)可以賦予新窗口一個(gè) name,然后將 name 賦予表單的 target 屬性,即可在我們創(chuàng)建的新窗口里提交。這樣就可以把 XSS 注入進(jìn)去了。
框架注入
不同頁(yè)面之間可以正反注入。同個(gè)頁(yè)面中,可能存在多個(gè)框架頁(yè),因此還可以嘗試框架頁(yè)之間的上下注入。
也許,XSS 位于頁(yè)面中某個(gè)小框架。如果只局限于自身頁(yè)面,那么是毫無(wú)發(fā)展空間的。因此得跳出圈子,向更廣闊的 parent 頁(yè)面注入。
類似的,如果主頁(yè)面僅僅是個(gè)外殼,實(shí)際內(nèi)容運(yùn)行在某個(gè)框架里,那么得注入到子框架中,才能獲取更有意義的信息。
同樣,我們還可以將上下注入結(jié)合,即可讓 XSS 從某個(gè)框架頁(yè)里破殼而出,感染到所有的框架頁(yè)里。
后記
盡管這些特征從 DOM 誕生起就已存在了,不過(guò)要寫(xiě)出一個(gè)完善的腳本并不容易。直到如今的 IE 11,不同窗體間的操作,仍有各種奇怪問(wèn)題,更不用說(shuō)那些非主流 IE 了。
不過(guò)好在除 IE 外的其他主流瀏覽器,都能很好的運(yùn)行。下面分享一個(gè) Demo,其中實(shí)現(xiàn)了上述部分功能:
https://www.etherdream.com/FunnyScript/XSSGhost/
當(dāng)我們順著超鏈接往前點(diǎn),一旦進(jìn)入有 XSS 的頁(yè)面,先前的父頁(yè)面都遭到感染。更嚴(yán)重的是,被感染的頁(yè)面打開(kāi)的子頁(yè)面,也都無(wú)一幸免。即使刷新,也會(huì)被其他頁(yè)面監(jiān)控到,從而立即恢復(fù)。
正如幽靈鬼魂一般揮之不去。
總結(jié)
以上是生活随笔為你收集整理的【XSS】延长 XSS 生命期的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ios开发中,User Defined
- 下一篇: TypeError: decoding