0x00 開始
最近看到一篇文章叫做《Pretty-Bad-Proxy:An Overlooked Adversary in Browsers’ HTTPS Deployments》隘世,雖然是好幾年前的文章岗憋,有些漏洞也早已修復(fù)熙尉,不過現(xiàn)在看來一汽,很多想法思路都非常棒,畢竟是國際頂級信息安全會(huì)議出品涂屁,值得與大家分享渴杆,我大概對其總結(jié)了一下墓陈,挑出了其中的關(guān)鍵部分。
我們都知道埋嵌,HTTPS是為了加密通信傳輸而專門設(shè)計(jì)的一個(gè)協(xié)議破加,防的就是中間人嗅探和攻擊,目的是保證兩邊接收與發(fā)送的數(shù)據(jù)都是沒有經(jīng)過篡改和偽造的雹嗦,協(xié)議設(shè)計(jì)的初衷是好的范舀,但瀏覽器在處理的時(shí)候留下了太多的缺陷,下面的5種方式就能看出瀏覽器是怎么拖HTTPS的后腿了罪。
以下默認(rèn)情況都是存在代理锭环,或者說用戶已經(jīng)被中間人攻擊,我們可以隨意攔截修改用戶的數(shù)據(jù)包泊藕,只是因?yàn)榧用軅鬏敻ū纾瑹o法獲知內(nèi)容而已,就像下面這樣。
第一種方法:利用瀏覽器對錯(cuò)誤信息頁面(4XX/5XX)中腳本的信任執(zhí)行(已被修復(fù))
我們都知道服務(wù)器錯(cuò)誤信息都是自定義的玫锋,不同服務(wù)器的信息都不一樣蛾茉,類似于下面這樣:
問題就出在這里,如果里面有惡意腳本那怎么辦撩鹿?
像下面的情景:
(1) 用戶訪問https://secret.com/
(2) 中間人攔截請求谦炬,并發(fā)送回一個(gè)狀態(tài)碼為502的響應(yīng),響應(yīng)內(nèi)容包括以下:
handle = ifr.document//do anything
1
2
1
2
(3) 瀏覽器渲染頁面节沦,重新發(fā)送對https://secret.com/的請求键思,此時(shí)中間人不再攔截。
(4) 頁面正常加載散劫,腳本執(zhí)行稚机,加密傳輸?shù)捻撁姹恍崽胶痛鄹摹?/p>
注意腳本執(zhí)行,因?yàn)榉祷氐?02狀態(tài)碼获搏,地址欄依舊是https://secret.com/
讓我們看看實(shí)際的結(jié)果赖条,用版本為54.0的chrome做下實(shí)驗(yàn),并用fiddler在響應(yīng)回瀏覽器前抓包修改內(nèi)容和狀態(tài)碼:
結(jié)果如下:
iframe 成功加載常熙,地址欄也是https://www.baidu.com/纬乍,但是腳本被凈化了。
第二種方法裸卫,利用HTTPS站點(diǎn)引用第三方腳本仿贬,偽造重定向到惡意腳本站點(diǎn)(已復(fù)現(xiàn))
很多的HTTPS站點(diǎn)也會(huì)引用一些第三方的js腳本文件,為了安全墓贿,他們一般也會(huì)確保這個(gè)第三方腳本所在網(wǎng)站是HTTPS茧泪,但是,這樣就安全了嗎聋袋?
試想队伟,當(dāng)你的頁面在請求第三方腳本時(shí),請求被攔截幽勒,然后中間人給你返回一個(gè)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的頁面中硝逢。
我們實(shí)際測試一下姨拥,攔截某HTTPS網(wǎng)站的腳本請求绅喉,修改響應(yīng)數(shù)據(jù)包:
這里我們返回的地址是fiddler的測試地址,然后叫乌,瀏覽器成功的發(fā)起了對https://www.fiddler2.com/sandbox/FormAndCookie.asp的請求:
這里之所以顯示301的請求結(jié)果是因?yàn)閒iddler的那個(gè)測試頁面不存在導(dǎo)致的柴罐,至此,我們發(fā)現(xiàn)憨奸,這種方法可以完美突破HTTPS革屠。
0x04 第三種方法,利用HPIHSL(HTTP-Intended-but-HTTPS-Loadable) (已復(fù)現(xiàn))
為了提高訪問速度或者是降低成本的著想排宰,一個(gè)站點(diǎn)往往并不是所有的頁面都是HTTPS的似芝,對于那些不那么重要的頁面,我們常常會(huì)用HTTP板甘,因?yàn)榉凑话舾行畔⒌澄停孤读艘矝]關(guān)系。但恰恰就是這種頁面有一個(gè)特性盐类,那就是大多數(shù)這樣的頁面通衬椋可以用HTTPS來連接,稱這樣的頁面為HPIHSL在跳。
單純這樣一個(gè)頁面肯定是無害的枪萄,但如果這個(gè)頁面引用的是HTTP的資源(js,img猫妙,css等)瓷翻,那當(dāng)它采用HTTPS的方式發(fā)起連接,所引用的資源卻是HTTP的割坠,雖然地址欄左邊會(huì)失去帶鎖的圖標(biāo)齐帚。
試想當(dāng)我們替換掉HTTP資源內(nèi)容為惡意代碼,那我們便成功攻入了HTTPS的頁面彼哼,打破了SOP童谒。或許會(huì)有疑問沪羔,那也只是個(gè)不包含敏感信息的頁面,根本沒有價(jià)值象浑。
但配合上點(diǎn)擊劫持呢蔫饰?(其實(shí)只要注入了惡意JS代碼,那就可以做任何事了愉豺,沒有SOP的限制篓吁,一切都是那么輕松)
當(dāng)我們把一個(gè)包含惡意代碼的js腳本混入HTTPS頁面時(shí),新建一個(gè)指向正常HTTPS頁面的透明iframe覆蓋在某個(gè)按鈕上(像結(jié)算蚪拦,登陸等需要跳轉(zhuǎn)的地方)杖剪,并且綁定一個(gè)點(diǎn)擊事件冻押,點(diǎn)擊后在新標(biāo)簽頁打開HTTPS頁面,那么盛嘿,我們是不是成功拿到了對真正HTTPS頁面的控制權(quán)洛巢?
實(shí)際測試中發(fā)現(xiàn),這個(gè)問題依舊存在次兆,但是這種方式要求比較多:
(1)HTTP和HTTPS共同存在的站點(diǎn)
(2)域名相同(為了之后獲得對真正HTTPS頁面的控制權(quán))
(3)HTTP站點(diǎn)有第三方腳本的請求
我們再回顧一下整個(gè)攻擊過程:
(1)用戶訪問HTTP頁面稿茉,中間人在響應(yīng)中加入iframe,該iframe指向一個(gè)HPIHSL頁面芥炭。
(2)之后該HPIHSL請求第三方HTTP資源漓库,中間人攔截后返回惡意js代碼。
(3)該惡意代碼添加一些點(diǎn)擊事件园蝠,點(diǎn)擊以后會(huì)打開一個(gè)正常HTTPS頁面渺蒿。
(4)用戶隨意點(diǎn)擊頁面,在新標(biāo)簽中打開正常HTTPS頁面彪薛,因?yàn)榇藭r(shí)符合SOP茂装,HTTPS頁面被獲取和控制。
這種方法適合有針對性的攻擊陪汽,也可以配合魚叉式釣魚训唱,可以說很難發(fā)現(xiàn)破綻。
0x05 第四種方法挚冤,利用 certificate cache况增,偽造HTTPS頁面
前面提到利用瀏覽器對錯(cuò)誤信息頁面(4XX/5XX)中腳本的信任執(zhí)行可以攻破HTTPS,但是這個(gè)缺陷現(xiàn)在已經(jīng)被修復(fù)了训挡,所以這里有另外一種方法可以在不使用任何腳本的情況下依舊攻破HTTPS澳骤。
講這個(gè)之前不得不提一下HTTPS的原理,我們都知道HTTPS發(fā)送的內(nèi)容是經(jīng)過加密的澜薄,但具體是怎么做的呢为肮?
或許我們最熟悉的就是RSA公鑰加密算法了,雖然高長度密鑰的對稱加密算法也非常安全肤京,但是對Web應(yīng)用這種多用戶訪問一個(gè)服務(wù)器的方式颊艳,服務(wù)器需要保存數(shù)量巨大的對稱密鑰,簡直原地爆炸忘分。公鑰加密就很適合目前的場景棋枕,所有用戶共用一個(gè)公鑰,服務(wù)器保存私鑰妒峦,安全簡便重斑,但是RSA慢啊?虾А?恕祖很!對稱加密快啊Q假颇!怎么辦?所以就有了公鑰加密和對稱加密混合使用的方式符相,也就是如今SSL(TSL)協(xié)議的實(shí)現(xiàn)方式拆融。
簡單點(diǎn)說,就是在建立起一個(gè)安全的傳輸層之前啊终,需要進(jìn)行兩次SSL握手镜豹,期間商定好加密的方法和各種信息(如驗(yàn)證服務(wù)器的證書,生成一些隨機(jī)數(shù)等)蓝牲,用公鑰加密算法加密一個(gè)隨機(jī)數(shù)發(fā)送給服務(wù)器 趟脂,之后兩邊再用這些隨機(jī)數(shù)和商定的加密方法生成對稱加密密鑰,也就是之后的“會(huì)話密鑰”例衍。
很麻煩昔期?我也覺得,這么說吧佛玄,意思就是客戶端與服務(wù)器兩次握手建立安全通道硼一,之后的通信不必再進(jìn)行公鑰加密和身份認(rèn)證,就像正常的HTTP會(huì)話一樣梦抢,只不過內(nèi)容被對稱加密了般贼,密鑰我們無法獲知。
我們可以干嘛奥吩?不去破壞身份認(rèn)證環(huán)節(jié)哼蛆,在會(huì)話中返回一個(gè)偽造頁面。
具體流程如下:
(1)用戶訪問https://secret.com/霞赫, 中間人攔截請求返回502頁面腮介,包含一個(gè)meta標(biāo)簽和一個(gè)img標(biāo)簽。
(2)meta標(biāo)簽將在一秒后重定向到https://secret.com/端衰,img標(biāo)簽請求https://secret.com/上的一張圖片(可以不存在叠洗,我們的目的是完成SSL的兩次握手)
(3)瀏覽器為了能夠成功請求圖片,與服務(wù)器成功完成SSL握手建立連接旅东,生成了會(huì)話密鑰惕味,之后的會(huì)話不需要身份驗(yàn)證,瀏覽器已經(jīng)信任這個(gè)鏈接玉锌。
(4)一秒之后,瀏覽器重定向到https://secret.com/疟羹,中間人攔截請求主守,返回502響應(yīng)禀倔,其中為純HTML的一個(gè)偽造頁面(如登陸頁面,只不過表單中的action地址是我們的服務(wù)器)
(5)瀏覽器渲染頁面参淫,此時(shí)地址欄依舊為綠綠的HTTPS>群!涎才!
我們依舊來實(shí)際操作一下:
首先攔截前往https://www.baidu.com/的請求:
然后等待它完成SSL握手之后鞋既,再次攔截前往https://www.baidu.com/的請求,返回一個(gè)502狀態(tài)碼耍铜,內(nèi)容為:
看一下效果:
成功了邑闺,問題就是途中的重定向之前會(huì)被發(fā)現(xiàn),你可以把時(shí)間調(diào)短一點(diǎn)棕兼,也可以把返回的頁面做一些社會(huì)工程陡舅,比如加一段話“正在前往中,請稍后伴挚“醒埽”之類的。
0x06 第五種方法茎芋,利用Cookie的同源策略不區(qū)分HTTP和HTTPS來盜取Cookies
前面介紹的兩種方法都要求了較高的社會(huì)工程技術(shù)和門檻颅眶,或許不容易成功,但現(xiàn)在這個(gè)方法卻相當(dāng)容易施展田弥。
因?yàn)镃ookie同源策略的原因涛酗,如果不對其設(shè)置secure標(biāo)志,那么Cookie將被發(fā)送到HTTP頁面皱蹦,就算一個(gè)站點(diǎn)沒有HTTP頁面煤杀,但我們可以通過篡改任意HTTP響應(yīng)添加一個(gè)iframe來要求瀏覽器發(fā)送對HTTPS站點(diǎn)的HTTP請求,而該請求會(huì)附帶明文Cookie沪哺,之后就可以利用這個(gè)Cookie登陸HTTPS站點(diǎn)了沈自。
我們看一下具體流程:
(1)用戶完成一個(gè)HTTPS站點(diǎn)(如https://secret.com/)的登陸操作,獲得會(huì)話辜妓,會(huì)話信息存儲(chǔ)在Cookie中枯途。
(2)用戶此時(shí)又請求另一個(gè)不相干的HTTP站點(diǎn),我們發(fā)現(xiàn)之后在響應(yīng)中添加一個(gè)指向http://secret.com/的HTTP請求籍滴。
(3)瀏覽器渲染頁面酪夷,發(fā)起對http://secret.com/請求,并附帶HTTPS頁面的Cookie孽惰,我們攔截并獲取到了Cookie晚岭。
(4)利用該Cookie成功獲得會(huì)話。
這個(gè)應(yīng)該不用我演示勋功,肯定會(huì)成功的坦报。
如果真的存心想嗅探你的數(shù)據(jù)库说,方法總比困難多。
最后再次致敬微軟研究院的大神前輩們片择。