0x00 開始
最近看到一篇文章叫做《Pretty-Bad-Proxy:An Overlooked Adversary in Browsers’ HTTPS Deployments》,雖然是好幾年前的文章,有些漏洞也早已修復(fù),不過現(xiàn)在看來,很多想法思路都非常棒,畢竟是國際頂級信息安全會議出品,值得與大家分享,我大概對其總結(jié)了一下,挑出了其中的關(guān)鍵部分。
我們都知道,HTTPS是為了加密通信傳輸而專門設(shè)計的一個協(xié)議,防的就是中間人嗅探和攻擊,目的是保證兩邊接收與發(fā)送的數(shù)據(jù)都是沒有經(jīng)過篡改和偽造的,協(xié)議設(shè)計的初衷是好的,但瀏覽器在處理的時候留下了太多的缺陷,下面的5種方式就能看出瀏覽器是怎么拖HTTPS的后腿。
以下默認(rèn)情況都是存在代理,或者說用戶已經(jīng)被中間人攻擊,我們可以隨意攔截修改用戶的數(shù)據(jù)包,只是因為加密傳輸,無法獲知內(nèi)容而已,就像下面這樣。
第一種方法:利用瀏覽器對錯誤信息頁面(4XX/5XX)中腳本的信任執(zhí)行(已被修復(fù))
我們都知道服務(wù)器錯誤信息都是自定義的,不同服務(wù)器的信息都不一樣,類似于下面這樣:
問題就出在這里,如果里面有惡意腳本那怎么辦?
像下面的情景:
(1) 用戶訪問https://secret.com/
(2) 中間人攔截請求,并發(fā)送回一個狀態(tài)碼為502的響應(yīng),響應(yīng)內(nèi)容包括以下:
handle = ifr.document//do anything
1
2
1
2
(3) 瀏覽器渲染頁面,重新發(fā)送對https://secret.com/的請求,此時中間人不再攔截。
(4) 頁面正常加載,腳本執(zhí)行,加密傳輸?shù)捻撁姹恍崽胶痛鄹摹?/p>
注意腳本執(zhí)行,因為返回的502狀態(tài)碼,地址欄依舊是https://secret.com/
讓我們看看實際的結(jié)果,用版本為54.0的chrome做下實驗,并用fiddler在響應(yīng)回瀏覽器前抓包修改內(nèi)容和狀態(tài)碼:
結(jié)果如下:
iframe 成功加載,地址欄也是https://www.baidu.com/,但是腳本被凈化了。
第二種方法,利用HTTPS站點引用第三方腳本,偽造重定向到惡意腳本站點(已復(fù)現(xiàn))
很多的HTTPS站點也會引用一些第三方的js腳本文件,為了安全,他們一般也會確保這個第三方腳本所在網(wǎng)站是HTTPS,但是,這樣就安全了嗎?
試想,當(dāng)你的頁面在請求第三方腳本時,請求被攔截,然后中間人給你返回一個302重定向,瀏覽器能分辨響應(yīng)的真?zhèn)螁??答案是肯定不能的?/p>
大概的流程如下:
(1) 用戶請求https://secret.com/,中間人不攔截
(2) 頁面請求第三方腳本https://js.secret.com/example.js,中間人攔截
(3) 中間人返回302數(shù)據(jù)包,location的值為第三方惡意腳本網(wǎng)站https://evil.com/evil.js/
(4) 頁面重新請求腳本,地址為https://evil.com/evil.js/,中間人放行,然后惡意腳本被插入HTTPS的頁面中。
我們實際測試一下,攔截某HTTPS網(wǎng)站的腳本請求,修改響應(yīng)數(shù)據(jù)包:
這里我們返回的地址是fiddler的測試地址,然后,瀏覽器成功的發(fā)起了對https://www.fiddler2.com/sandbox/FormAndCookie.asp的請求:
這里之所以顯示301的請求結(jié)果是因為fiddler的那個測試頁面不存在導(dǎo)致的,至此,我們發(fā)現(xiàn),這種方法可以完美突破HTTPS。
0x04 第三種方法,利用HPIHSL(HTTP-Intended-but-HTTPS-Loadable) (已復(fù)現(xiàn))
為了提高訪問速度或者是降低成本的著想,一個站點往往并不是所有的頁面都是HTTPS的,對于那些不那么重要的頁面,我們常常會用HTTP,因為反正不包含敏感信息,泄露了也沒關(guān)系。但恰恰就是這種頁面有一個特性,那就是大多數(shù)這樣的頁面通常可以用HTTPS來連接,稱這樣的頁面為HPIHSL。
單純這樣一個頁面肯定是無害的,但如果這個頁面引用的是HTTP的資源(js,img,css等),那當(dāng)它采用HTTPS的方式發(fā)起連接,所引用的資源卻是HTTP的,雖然地址欄左邊會失去帶鎖的圖標(biāo)。
試想當(dāng)我們替換掉HTTP資源內(nèi)容為惡意代碼,那我們便成功攻入了HTTPS的頁面,打破了SOP?;蛟S會有疑問,那也只是個不包含敏感信息的頁面,根本沒有價值。
但配合上點擊劫持呢?(其實只要注入了惡意JS代碼,那就可以做任何事了,沒有SOP的限制,一切都是那么輕松)
當(dāng)我們把一個包含惡意代碼的js腳本混入HTTPS頁面時,新建一個指向正常HTTPS頁面的透明iframe覆蓋在某個按鈕上(像結(jié)算,登陸等需要跳轉(zhuǎn)的地方),并且綁定一個點擊事件,點擊后在新標(biāo)簽頁打開HTTPS頁面,那么,我們是不是成功拿到了對真正HTTPS頁面的控制權(quán)?
實際測試中發(fā)現(xiàn),這個問題依舊存在,但是這種方式要求比較多:
(1)HTTP和HTTPS共同存在的站點
(2)域名相同(為了之后獲得對真正HTTPS頁面的控制權(quán))
(3)HTTP站點有第三方腳本的請求
我們再回顧一下整個攻擊過程:
(1)用戶訪問HTTP頁面,中間人在響應(yīng)中加入iframe,該iframe指向一個HPIHSL頁面。
(2)之后該HPIHSL請求第三方HTTP資源,中間人攔截后返回惡意js代碼。
(3)該惡意代碼添加一些點擊事件,點擊以后會打開一個正常HTTPS頁面。
(4)用戶隨意點擊頁面,在新標(biāo)簽中打開正常HTTPS頁面,因為此時符合SOP,HTTPS頁面被獲取和控制。
這種方法適合有針對性的攻擊,也可以配合魚叉式釣魚,可以說很難發(fā)現(xiàn)破綻。
0x05 第四種方法,利用 certificate cache,偽造HTTPS頁面
前面提到利用瀏覽器對錯誤信息頁面(4XX/5XX)中腳本的信任執(zhí)行可以攻破HTTPS,但是這個缺陷現(xiàn)在已經(jīng)被修復(fù)了,所以這里有另外一種方法可以在不使用任何腳本的情況下依舊攻破HTTPS。
講這個之前不得不提一下HTTPS的原理,我們都知道HTTPS發(fā)送的內(nèi)容是經(jīng)過加密的,但具體是怎么做的呢?
或許我們最熟悉的就是RSA公鑰加密算法了,雖然高長度密鑰的對稱加密算法也非常安全,但是對Web應(yīng)用這種多用戶訪問一個服務(wù)器的方式,服務(wù)器需要保存數(shù)量巨大的對稱密鑰,簡直原地爆炸。公鑰加密就很適合目前的場景,所有用戶共用一個公鑰,服務(wù)器保存私鑰,安全簡便,但是RSA慢?。。?!對稱加密快?。?!怎么辦?所以就有了公鑰加密和對稱加密混合使用的方式,也就是如今SSL(TSL)協(xié)議的實現(xiàn)方式。
簡單點說,就是在建立起一個安全的傳輸層之前,需要進(jìn)行兩次SSL握手,期間商定好加密的方法和各種信息(如驗證服務(wù)器的證書,生成一些隨機(jī)數(shù)等),用公鑰加密算法加密一個隨機(jī)數(shù)發(fā)送給服務(wù)器 ,之后兩邊再用這些隨機(jī)數(shù)和商定的加密方法生成對稱加密密鑰,也就是之后的“會話密鑰”。
很麻煩?我也覺得,這么說吧,意思就是客戶端與服務(wù)器兩次握手建立安全通道,之后的通信不必再進(jìn)行公鑰加密和身份認(rèn)證,就像正常的HTTP會話一樣,只不過內(nèi)容被對稱加密了,密鑰我們無法獲知。
我們可以干嘛?不去破壞身份認(rèn)證環(huán)節(jié),在會話中返回一個偽造頁面。
具體流程如下:
(1)用戶訪問https://secret.com/, 中間人攔截請求返回502頁面,包含一個meta標(biāo)簽和一個img標(biāo)簽。
(2)meta標(biāo)簽將在一秒后重定向到https://secret.com/,img標(biāo)簽請求https://secret.com/上的一張圖片(可以不存在,我們的目的是完成SSL的兩次握手)
(3)瀏覽器為了能夠成功請求圖片,與服務(wù)器成功完成SSL握手建立連接,生成了會話密鑰,之后的會話不需要身份驗證,瀏覽器已經(jīng)信任這個鏈接。
(4)一秒之后,瀏覽器重定向到https://secret.com/,中間人攔截請求,返回502響應(yīng),其中為純HTML的一個偽造頁面(如登陸頁面,只不過表單中的action地址是我們的服務(wù)器)
(5)瀏覽器渲染頁面,此時地址欄依舊為綠綠的HTTPS!??!
我們依舊來實際操作一下:
首先攔截前往https://www.baidu.com/的請求:
然后等待它完成SSL握手之后,再次攔截前往https://www.baidu.com/的請求,返回一個502狀態(tài)碼,內(nèi)容為:
看一下效果:
成功了,問題就是途中的重定向之前會被發(fā)現(xiàn),你可以把時間調(diào)短一點,也可以把返回的頁面做一些社會工程,比如加一段話“正在前往中,請稍后?!敝惖摹?/p>
0x06 第五種方法,利用Cookie的同源策略不區(qū)分HTTP和HTTPS來盜取Cookies
前面介紹的兩種方法都要求了較高的社會工程技術(shù)和門檻,或許不容易成功,但現(xiàn)在這個方法卻相當(dāng)容易施展。
因為Cookie同源策略的原因,如果不對其設(shè)置secure標(biāo)志,那么Cookie將被發(fā)送到HTTP頁面,就算一個站點沒有HTTP頁面,但我們可以通過篡改任意HTTP響應(yīng)添加一個iframe來要求瀏覽器發(fā)送對HTTPS站點的HTTP請求,而該請求會附帶明文Cookie,之后就可以利用這個Cookie登陸HTTPS站點了。
我們看一下具體流程:
(1)用戶完成一個HTTPS站點(如https://secret.com/)的登陸操作,獲得會話,會話信息存儲在Cookie中。
(2)用戶此時又請求另一個不相干的HTTP站點,我們發(fā)現(xiàn)之后在響應(yīng)中添加一個指向http://secret.com/的HTTP請求。
(3)瀏覽器渲染頁面,發(fā)起對http://secret.com/請求,并附帶HTTPS頁面的Cookie,我們攔截并獲取到了Cookie。
(4)利用該Cookie成功獲得會話。
這個應(yīng)該不用我演示,肯定會成功的。
如果真的存心想嗅探你的數(shù)據(jù),方法總比困難多。
最后再次致敬微軟研究院的大神前輩們。