無(wú)視HTTPS發(fā)起中間人攻擊
大約十年前,F(xiàn)iresheep制造了一個(gè)大新聞。多年來(lái),安全人員已經(jīng)了解了公共WiFi網(wǎng)絡(luò)的危害,但直到有人創(chuàng)建了這個(gè)用戶友好的Firefox擴(kuò)展插件之后,這個(gè)安全問(wèn)題才得到了人們的關(guān)注。從那時(shí)起,網(wǎng)絡(luò)上發(fā)生了很多事情,那么這樣的事情還有可能再發(fā)生嗎?
TL; DR; 由于HTTPS的存在,MITM攻擊目前不再是一個(gè)問(wèn)題。但是,使用CORS,postMessage和其他一些很酷的東西,有時(shí)也可以繞過(guò)HTTPS。雖然這是網(wǎng)站所有者的錯(cuò),但受害的卻是用戶。
幾年前Firesheep是人們腦海中最重要的東西。在那個(gè)年代的網(wǎng)站,比如說(shuō)Facebook,默認(rèn)情況下還沒(méi)有開(kāi)始使用HTTPS。移動(dòng)設(shè)備(包括筆記本電腦和手機(jī))的急劇增加使得連接到不受信任的WiFi網(wǎng)絡(luò)變得越來(lái)越普遍。
八年后的今天,這實(shí)際上不再是一個(gè)問(wèn)題。這是由于HTTPS的廣泛采用,讓大量的網(wǎng)絡(luò)流量能夠被加密傳輸。就在上周,WIRED發(fā)表了一篇名為“ 關(guān)于使用酒店的Wi-Fi 你知道些什么?。來(lái)自你的設(shè)備的流量現(xiàn)在已被加密,即使有人發(fā)起MITM攻擊,你也不會(huì)受到什么太多的影響。這絕對(duì)是真的,當(dāng)談?wù)摰桨踩詴r(shí),你在酒店或咖啡店所提到的第一件事情就是MITM,但它已經(jīng)發(fā)生了很大的變化。
當(dāng)你在假期旅行時(shí),從機(jī)場(chǎng)到上飛機(jī)再到入住酒店,你可能會(huì)發(fā)現(xiàn)自己面臨著一個(gè)熟悉的困境:我真的要選擇信任這些隨機(jī)的公共Wi-Fi網(wǎng)絡(luò)嗎?就在幾年前,答案幾乎肯定是選擇不信任。但是在2018年,你的回答可能會(huì)有不同。
然而,即使網(wǎng)絡(luò)流量被加密了,但如果有人發(fā)起了MITM攻擊,仍然會(huì)發(fā)生很多不好的事情??梢詮膸讉€(gè)角度出發(fā)討論這個(gè)話題。本文將重點(diǎn)介紹如何利用現(xiàn)代Web技術(shù)繼續(xù)發(fā)起MITM攻擊,以及網(wǎng)站所有者該如何阻止這種攻擊。
(WIRED發(fā)布的文章仍然有一個(gè)有效的觀點(diǎn),但也有很大技術(shù)討論空間。)
攻擊場(chǎng)景的其余部分將基于下面的一些條件
你正在酒店過(guò)夜,并將你的設(shè)備連接到酒店的WiFi。由于你處于不受信任的網(wǎng)絡(luò)中,因此你可能不會(huì)去瀏覽任何敏感的信息。
但是,你正在使用與往常相同的瀏覽器會(huì)話。出于方便,人們永遠(yuǎn)不會(huì)退出Facebook或他們的工作電子郵件。
HSTS和cookie標(biāo)志
我們需要從一些有關(guān)HSTS的基本信息開(kāi)始。
HSTS是一個(gè)HTTP標(biāo)頭,它指示瀏覽器后續(xù)只應(yīng)嘗試通過(guò)HTTPS的方式加載該頁(yè)面。從瀏覽器第一次訪問(wèn)具有此標(biāo)頭的網(wǎng)站時(shí),它會(huì)將域名添加到列表中,并在標(biāo)頭中指定的時(shí)間內(nèi)記住它。即使我明確的寫(xiě)了http://網(wǎng)頁(yè)瀏覽器也會(huì)直接通過(guò)HTTPS發(fā)送請(qǐng)求。
也可以添加一個(gè)標(biāo)志來(lái)預(yù)先加載標(biāo)頭。當(dāng)Web瀏覽器獲取更新或下載時(shí),會(huì)包含預(yù)加載的域名列表。Web瀏覽器將拒絕向這些域名發(fā)送HTTP流量,即使用戶第一次訪問(wèn)這些站點(diǎn)也是如此。
HSTS的另一個(gè)重要特性是名為includeSubDomains的標(biāo)志。如果https://example.com包含此標(biāo)頭,則Web瀏覽器將拒絕發(fā)送任何未加密的流量到http://foo.example.com。
HSTS標(biāo)頭只能在HTTPS請(qǐng)求中設(shè)置。根據(jù)規(guī)范,這個(gè)標(biāo)頭在HTTP請(qǐng)求上應(yīng)該是不起作用的(實(shí)際上沒(méi)有經(jīng)過(guò)足夠多的瀏覽器測(cè)試來(lái)確定這一點(diǎn))。當(dāng)人們按以下順序進(jìn)行重定向時(shí),這會(huì)導(dǎo)致一個(gè)常見(jiàn)問(wèn)題:
http://example.com>
http://www.example.com>
https://www.example.com
由于第一個(gè)HTTPS請(qǐng)求將轉(zhuǎn)到www. 因此includeSubDomains-flag并不起作用的,因?yàn)楸仨氃赼pex域名上設(shè)置。
最后,還需要提到的一個(gè)東西是安全標(biāo)志(secure)。這是在創(chuàng)建cookie時(shí)在cookie上設(shè)置的標(biāo)志。設(shè)置此標(biāo)志后,將永遠(yuǎn)不會(huì)通過(guò)HTTP發(fā)送cookie。如果向http://example.com發(fā)出請(qǐng)求則響應(yīng)看起來(lái)像是用戶沒(méi)有保存的cookie一樣。
CORS
我們之前在這里已經(jīng)提到過(guò)一些關(guān)于CORS常見(jiàn)的錯(cuò)誤配置。如果你還沒(méi)有正確配置,那么我建議你先閱讀那篇文章。
最簡(jiǎn)單的攻擊方式是壓根兒不使用HSTS。假設(shè)CORS已經(jīng)啟用,那么http://example.com可以請(qǐng)求https://example.com并讀取數(shù)據(jù)。這在MITM場(chǎng)景中是可能發(fā)生的,因?yàn)榘l(fā)出請(qǐng)求的那個(gè)請(qǐng)求是通過(guò)HTTP托管的。由于實(shí)際的請(qǐng)求將通過(guò)HTTPS發(fā)送,因此即使帶有secure標(biāo)志的cookie也會(huì)隨之發(fā)送。
另一個(gè)非常常見(jiàn)的問(wèn)題是CORS允許訪問(wèn)任何子域名,但HSTS沒(méi)有設(shè)置includeSubDomains-標(biāo)志。這意味著攻擊者能夠在http://foobar.example.com上托管惡意的javascript然后向https://example.com發(fā)出請(qǐng)求。在MITM攻擊場(chǎng)景中,攻擊者可以隨意構(gòu)造他們想攻擊的任何子域名。在討論HSTS時(shí),我們?cè)谇懊嬉呀?jīng)解釋過(guò),它存在一個(gè)重定向問(wèn)題,因此當(dāng)主應(yīng)用程序托管在www上時(shí),這種攻擊手法就很常見(jiàn)的。
一個(gè)有趣的攻擊向量是在使用HSTS時(shí),CORS可以支持多個(gè)域名。我們用一個(gè)真實(shí)的案例來(lái)說(shuō)明一下,在periscope.tv上的CORS可以通過(guò)HTTP和HTTPS接受*.periscope.tv,*.pscp.tv和*.twitter.com。只要有人登錄到periscope.tv,HSTS就會(huì)確保后續(xù)的請(qǐng)求不會(huì)通過(guò)HTTP發(fā)送到該域名。但是,受害者之前從未訪問(wèn)過(guò)*.pscp.tv的可能性很大,而且在MITM攻擊場(chǎng)景中,攻擊者可以在那里偽造一個(gè)HTTP的頁(yè)面并發(fā)送請(qǐng)求到periscope.tv。在這種情況下,這種攻擊將被阻止,因?yàn)樗羞@些域名的所有HSTS策略都是預(yù)加載的。
postMessage
正如我們之前所述,在使用postMessage時(shí)檢查消息的來(lái)源非常重要。但是,這些檢查僅檢查來(lái)源是否以特定內(nèi)容作為結(jié)尾并因此導(dǎo)致攻擊者可以匹配任何子域名,這是個(gè)很常見(jiàn)的問(wèn)題。這意味著完全沒(méi)有檢查協(xié)議。任何子域名上的HTTP頁(yè)面都能夠?qū)⑾l(fā)送到主應(yīng)用程序。
還有一些基于正則表達(dá)式的來(lái)源檢查,有意允許了HTTP和HTTPS,即使Web應(yīng)用程序應(yīng)該只能通過(guò)HTTPS使用也會(huì)允許匹配HTTP。還應(yīng)該注意的是,有幾種網(wǎng)絡(luò)協(xié)議實(shí)際上也可以托管Web內(nèi)容,例如FTP。因此,務(wù)必確保將HTTPS列入了白名單,而不是將HTTP列入黑名單。相關(guān)案例請(qǐng)查看:https://hackerone.com/reports/210654
至于與HSTS的組合使用,實(shí)際上與CORS的問(wèn)題遵循的是相同的原則。
WebSocket
WebSocket實(shí)際上在握手請(qǐng)求中共享了cookie,因此需要用與CORS請(qǐng)求相似的方式進(jìn)行源的檢查。這僅在應(yīng)用程序需要關(guān)注cookie數(shù)據(jù)時(shí)才很重要,因此并不總是適用于很多情況。
https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers
可能已經(jīng)有一些類似的方式或技術(shù)以上述類似的方式被濫用。如果今天沒(méi)有,那很快就會(huì)有。如果MITM在你的威脅模型中,那么這些都是不應(yīng)忽視的問(wèn)題。
修復(fù)建議
網(wǎng)站所有者
HSTS
第一步是在網(wǎng)站上開(kāi)始使用HSTS,因?yàn)榻裉煸S多人都沒(méi)有這樣做。在已經(jīng)通過(guò)HTTPS提供服務(wù)的網(wǎng)站上,這樣做沒(méi)有任何問(wèn)題。當(dāng)你實(shí)現(xiàn)了HSTS并確保它正常工作時(shí),記得添加關(guān)于預(yù)加載它的標(biāo)志。
如果可能,請(qǐng)?jiān)贖TTP頭中包含includeSubDomains-header。但是,這將要求所有子域名也要通過(guò)HTTPS提供所有流量,不過(guò)這取決于具體情況并且可能有點(diǎn)困難。
CORS
確保CORS僅接受HTTPS請(qǐng)求。因?yàn)樽畛R?jiàn)的解決方案是反射源,即使源與模式匹配成功,也需要檢查它是否https://開(kāi)頭。
postMessage和WebSocket
與CORS非常相似:確保檢查了源并檢查了協(xié)議而不僅僅是主機(jī)名。
普通用戶
在寫(xiě)這篇文章之前,我曾與幾個(gè)有這些安全問(wèn)題的大網(wǎng)站的安全人員聯(lián)系過(guò)。雖然許多人都比較關(guān)心這個(gè)問(wèn)題,但也有幾個(gè)人認(rèn)為這是可以接受的風(fēng)險(xiǎn)。他們認(rèn)為受害者不太可能受到這樣的MITM攻擊或類似的理由。因此,盡管應(yīng)該由網(wǎng)站所有者負(fù)責(zé)修復(fù),但用戶也必須關(guān)心這個(gè)問(wèn)題。
· 第一步是安裝HTTPS Everywhere。它是一個(gè)瀏覽器插件,類似于HSTS,但是在客戶端上。
· 第二個(gè)建議是不要使用公共WiFi。自Firesheep時(shí)代以來(lái)的最大變化也是移動(dòng)數(shù)據(jù)的價(jià)值的變化。許多經(jīng)常連接到開(kāi)放網(wǎng)絡(luò)的人也會(huì)用手機(jī)連接這些開(kāi)放式網(wǎng)絡(luò)。
· 如果上面一條不適用于你,那第二個(gè)最好的建議是使用VPN。但是,應(yīng)該明白的是,這也不是一種防御策略。由于許多公共熱點(diǎn)在你連接時(shí)都有某種登錄頁(yè)面,因此你實(shí)際上必須連接到網(wǎng)絡(luò)一段時(shí)間,而不會(huì)有流量通過(guò)VPN。在此期間,熱點(diǎn)會(huì)強(qiáng)制你的設(shè)備發(fā)出前文所描述的技術(shù)的網(wǎng)絡(luò)請(qǐng)求。
...
讓我再次引用WIRED文章作為本文所有內(nèi)容的結(jié)束。請(qǐng)記住,要對(duì)自己的情況進(jìn)行風(fēng)險(xiǎn)分析,然后采取行動(dòng)。