日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
SSLStrip的未來——HTTPS前端劫持

0x00 前言

成都做網(wǎng)站、網(wǎng)站建設(shè),成都做網(wǎng)站公司-創(chuàng)新互聯(lián)已向超過千家企業(yè)提供了,網(wǎng)站設(shè)計,網(wǎng)站制作,網(wǎng)絡(luò)營銷等服務(wù)!設(shè)計與技術(shù)結(jié)合,多年網(wǎng)站推廣經(jīng)驗,合理的價格為您打造企業(yè)品質(zhì)網(wǎng)站。

在之前介紹的流量劫持文章里,曾提到一種『HTTPS 向下降級』的方案 —— 將頁面中的 HTTPS 超鏈接全都替換成 HTTP 版本,讓用戶始終以明文的形式進(jìn)行通信。

看到這,也許大家都會想到一個經(jīng)典的中間人攻擊工具 —— SSLStrip,通過它確實能實現(xiàn)這個效果。

不過今天講解的,則是完全不同的思路,一種更有效、更先進(jìn)的解決方案 —— HTTPS 前端劫持。

0x01 后端的缺陷

在過去,流量劫持基本通過后端來實現(xiàn),SSLStrip就是個典型的例子。

類似其他中間人工具,純后端的實現(xiàn)只能操控最原始的流量數(shù)據(jù),這嚴(yán)重阻礙了向更高層次的發(fā)展,面臨眾多難以解決的問題。

動態(tài)元素怎么辦?

如何處理數(shù)據(jù)包分片?

性能消耗能否降低?

......

動態(tài)元素

在 Web 剛出現(xiàn)的年代里,SSLStrip 這樣的工具還是大有用武之地的。那時的網(wǎng)頁都以靜態(tài)為主,結(jié)構(gòu)簡單層次清晰。在流量上進(jìn)行替換,完全能夠勝任。

然而,如今的網(wǎng)頁日益復(fù)雜,腳本所占比重越來越多。如果僅僅從流量上著手,顯然力不從心。

var protocol = 'https';  document.write('Login');

即使非常簡單的動態(tài)元素,后端也毫無招架之力。

分片處理

分塊傳輸?shù)牡览泶蠹叶济靼住τ谳^大的數(shù)據(jù),一口氣是無法傳完的??蛻舳艘来问盏礁鱾€數(shù)據(jù)塊,最終才能合并成一個完整的網(wǎng)頁。

??

??

由于每次收到的都是殘缺的碎片,這給鏈接替換帶來很大的麻煩。加上不少頁面并非標(biāo)準(zhǔn)的 UTF-8 編碼,因此更是難上加難。

為了能順利進(jìn)行,中間人通常先收集數(shù)據(jù),等到頁面接收完整,才開始替換。

??

??

如果把數(shù)據(jù)比作水流,這個代理就像大壩一樣,攔截了源源不斷往下流的水,直到蓄滿了才開始釋放。因此,下游的人們需忍受很久的干旱,才能等到水源。

性能消耗

由于 HTML 兼容眾多歷史遺留規(guī)范,因此替換工作并非是件輕松事。

各種復(fù)雜的正則表達(dá)式,消耗著不少的 CPU 資源。盡管用戶最終點擊的只是其中一兩個鏈接,但中間人并不知道將會是哪個,因此仍需分析整個頁面。這不得不說是個悲哀。#p#

0x02 前端的優(yōu)勢

如果我們的中間人能打入到頁面的前端,那么情況會不會有所改善呢?

分片處理

首先,要派一名間諜到頁面里。這是非常容易辦到的:

??

??

不像超鏈接遍布在頁面各處,腳本插入到頭部即可運(yùn)行了。所以我們根本不用整個頁面的數(shù)據(jù),只需改造下第一個 chunk 就可以,后續(xù)的數(shù)據(jù)仍然交給系統(tǒng)轉(zhuǎn)發(fā)。

因此,整個代理的時間幾乎不變!

動態(tài)元素

很好,我們輕易滲透到頁面里。但接著又如何發(fā)起進(jìn)攻?

既然到了前端里,方法就相當(dāng)多了。最簡單的,就是遍歷超鏈接元素,將 https 的都替換成 http 版本。

這個想法確實不錯,但仍停留在 SSLStrip 思維模式上。還是『替換』這條路,只是從后端搬到前端而已。

盡管這個方法能勝任大多場合,但仍然不是最完美的。我們并不知道動態(tài)元素何時會添加進(jìn)來,因此需要開啟定時器不斷的掃描。這顯然是個很挫的辦法。

性能優(yōu)化

事實上,超鏈接無論是誰產(chǎn)生的、何時添加進(jìn)來的,只要不點擊,都是不起作用的。所以,我們只需關(guān)心何時去點擊就可以 —— 如果我們的程序,能在點擊產(chǎn)生的第一時間里控制住現(xiàn)場,那么之后的流程就可由我們決定了。

聽起來似乎很玄乎,不過在前端,這只是小菜一碟的事。點擊,不過個事件而已。既然是事件,我們用最基礎(chǔ)的事件捕獲機(jī)制,即可將其輕松拿下:

document.addEventListener('click', function(e) {      // ...  }, true);

DOM-3-Event 是個非常有意義的事件模型。之前用它來實現(xiàn)『內(nèi)聯(lián) XSS 攔截』,如今同樣也可以用來劫持鏈接。

我們捕獲全局的點擊事件,如果發(fā)現(xiàn)有落在 https 超鏈接上,果斷將其......攔截?

如果真把它攔截了,那新頁面就不會出現(xiàn)了。當(dāng)然你會說,可以自己 window.open 彈一個,反正點擊事件里是可以彈窗的。

不過,請別忘了,并非所有的超鏈接都是彈窗,也有不少是直接跳轉(zhuǎn)的。你也會說可以修改 location 來實現(xiàn)。

但要識別是『彈窗』還是『跳轉(zhuǎn)』,并不簡單。除了超鏈接的 target 屬性,頁面里的 元素也會有影響。當(dāng)然,這些相信你都能處理好。

然而,現(xiàn)實未必都是那么簡單的。有些超鏈接本身就綁定了 onclick 事件,甚至在其中 return false 或 preventDefault,屏蔽了默認(rèn)行為。如果我們不顧及這些,仍然模擬跳轉(zhuǎn)或彈窗,那就違背頁面的意愿了。

事實上,有一個非常簡單的辦法:當(dāng)我們的捕獲程序運(yùn)行時,新頁面還遠(yuǎn)沒出現(xiàn),這時仍有機(jī)會修改超鏈接的 href。待事件冒泡完成、執(zhí)行默認(rèn)行為時,瀏覽器才讀取 href 屬性,作為最終的結(jié)果。

因此,我們只需捕獲點擊事件,修改超鏈接地址就可以了。至于是跳轉(zhuǎn)、彈窗、還是被屏蔽,根本不用我們關(guān)心。

??

??

就那么簡單。因為我們是在用戶點下去之后才修改,所以瀏覽器狀態(tài)欄里,顯示的仍是原先 https !

當(dāng)然,點過一次之后,再把鼠標(biāo)放到超鏈接上,狀態(tài)欄里顯示的就是修改后的了。

為了能繼續(xù)忽悠,我們在修改 href 之后的下個線程周期里,把它改回來。因為有了一定延時,新頁面并不受影響。

var url = link.href;                                // 保存原始地址  link.href = url.replace('https://', 'http://');     // 暫時換成 http 的  setTimeout(function() {      link.href = url;                                // 新頁面打開后,還原回來  }, 0);

 

這樣,頁面里的超鏈接始終都是正常的 —— 只有用戶點下的瞬間,才臨時偽裝一下。#p#

0x03 更多攔截

除了通過超鏈接,還有其他方式訪問頁面,我們應(yīng)盡可能多的進(jìn)行監(jiān)控。例如:

表單提交

window.open 彈窗

框架頁面

.....

表單提交

表單提交和超鏈接非常類似,都具有事件,只是將 click 換成 submit,href 換成 action 而已。

腳本彈窗

函數(shù)調(diào)用的最簡單了,只需一個小鉤子即可搞定:

var raw_open = window.open;  window.open = function(url) {      // FIX: null, case insensitive      arguments[0] = url.replace('https://', 'http://');      raw_open.apply(this, arguments);  }

 

框架頁面

因為我們把主頁面降級成 http 了,但里面的框架地址仍是原先的。由于協(xié)議不同,這會產(chǎn)生跨域問題,導(dǎo)致頁面無法正常工作。

所以我們還要把頁面里的框架,也都轉(zhuǎn)型成 http 版本,確保能和主頁面融為一致。

但框架和之前的那些不同,因為它是自動加載的,而且也沒有一個即將加載的事件。如果等到框架加載完了再去處理,說不定已經(jīng)開始報跨域錯誤了。而且還會白白的浪費(fèi)一次加載流量。

因此,我們必須讓框架一出現(xiàn),就立即替換掉地址。

這在過去是個很棘手的問題,然而 HTML5 時代給我們帶來了新希望 —— MutationEvent。用它即可實時監(jiān)控頁面元素,之前也嘗試過一些試驗。

當(dāng)然,即使 MutationEvent,偶爾也會有延時遺漏。為了能徹底避免出現(xiàn) https 框架頁,我們繼續(xù)使用 HTML5 帶來的一項新技術(shù) —— Content Security Policy,由于它是瀏覽器原生支持的,因此實施的非常徹底。

在我們的代理返回頭中,加上如下 HTTP 頭部,即可完美攔截 https 框架頁了:

Content-Security-Policy: default-src * data 'unsafe-inline' 'unsafe-eval'; frame-src http://*

解決了框架頁的問題,我們就能成功劫持支付寶登錄頁的賬號框 IFrame 了!

??

??

#p#

0x04 后端配合

通過前端的 XSS 腳本,我們輕易解決了過去各種棘手的問題。但挑戰(zhàn)并未就此結(jié)束,我們?nèi)悦媾R著眾多難題。

如何告訴代理

盡管在前端上面,我們已經(jīng)避開了各種進(jìn)入 https 的途徑,讓請求以明文的形式交給代理。但代理又如何決定,這個請求用 https 還是 http 轉(zhuǎn)發(fā)呢?

傳統(tǒng)的后端劫持之所以能正確轉(zhuǎn)發(fā),那是在替換超鏈接的時候,已經(jīng)做下記錄。當(dāng)出現(xiàn)記錄中的請求,就走 https 的轉(zhuǎn)發(fā)。

而我們的劫持在前端,并且只發(fā)生在點擊的一瞬間。即使馬上去告訴中間人,某個 URL 是 https 的,這時也來不及了。

告訴中間人是必須的。但我們可以用一個巧妙的方法,不必單獨發(fā)送消息 —— 我們只需在轉(zhuǎn)型后的 URL 里,做個小記號就可以了。

當(dāng)代理發(fā)現(xiàn)請求的 URL 里有這個記號,它自然就懂了,直接走 https!

??

??

由于把頁面從 https 降級到了 http,因此相關(guān)請求的referer也變成 http 版了。所以,中間人應(yīng)盡量把 referer 也修正回來,避免被服務(wù)器察覺。

隱藏偽裝

不過,在 URL 里加標(biāo)記的方法,也有很大的缺陷。

因為頁面的 URL 會在地址欄里顯示出來,所以用戶會看見我們的記號。當(dāng)然,我們可以使用一些迷惑性的字符,例如 ?zh_cn、?utf_8,?from_baidu 等等,更好的欺騙用戶。

當(dāng)然,如果你覺得還是不滿意,也有辦法讓這些礙眼標(biāo)記盡快消失:

if url has symbol

history.replaceState(..., clear_symbol(url) )

HTML5 為我們提供了修改地址欄的能力,并且無需刷新。這些強(qiáng)悍的功能,如今都可以在前端利用起來了。

重定向劫持

當(dāng)然,光靠前端的劫持,還是遠(yuǎn)遠(yuǎn)不夠的。現(xiàn)實中,還有另一種很常見的方式,那就是重定向到安全頁面。

仔細(xì)回想下,平時我們是怎樣進(jìn)入想上的網(wǎng)站的。例如支付寶,除非你有收藏,否則就得自己敲入 www.alipay.com 或 www.zhifubao.com,當(dāng)你回車進(jìn)入時,瀏覽器又如何知道這是個 HTTPS 的網(wǎng)站呢?

顯然,第一個請求仍是普通的 HTTP 協(xié)議。當(dāng)然,這個 HTTP 版的支付寶的確存在,它的唯一功能就將用戶重定向到 HTTPS 版本。

當(dāng)我們的中間人一旦發(fā)現(xiàn)有重定向到 HTTPS 網(wǎng)站的,當(dāng)然不希望用戶走這條不受自己控制的路。于是攔下這個重定向,然后以 HTTPS 的方式,獲取重定向后的內(nèi)容,最后再以 HTTP 明文的方式,回復(fù)給用戶。

??

??

因此在用戶看來,始終處于 HTTP 網(wǎng)站上。

不過,如今的 Web 里增加一個新的安全標(biāo)準(zhǔn):HTTP Strict Transport Security。如果客戶端收到這個頭部,之后一段時間內(nèi)訪問該站點,就始終通過 HTTPS 的方式。

所以我們的中間人一旦發(fā)現(xiàn)有這個字段,就得果斷將其刪除。

當(dāng)然,用戶直接敲網(wǎng)址的并不常見。大多都是搜索引擎,然后直接從第一個結(jié)果里進(jìn)來了。

比較悲劇的是,國內(nèi)的搜索引擎幾乎都是 HTTP 的。在用戶訪問搜索頁面的時候,我們的 XSS 早已潛伏在其中了,因此從中點出來的任何一條結(jié)果,都是進(jìn)不到官方的 HTTPS 里的:)

除了搜索頁面,不少類似 hao123 之類的網(wǎng)址大全,大多也未開啟 HTTPS。因此從中導(dǎo)流的網(wǎng)站,都面臨著被中間人劫持的風(fēng)險。#p#

0x05 防范措施

介紹了攻擊方法,接著講解防御措施。

腳本跳轉(zhuǎn)

事實上,無論是前端劫持還是后端過濾,仍有不少的網(wǎng)站無法成功。例如京東的登錄:

??

??

它是通過腳本跳轉(zhuǎn)到 HTTPS 地址的。而瀏覽器的 location 是個及其特殊的屬性,它可以被屏蔽,但無法被重寫。因此我們難以控制頁面的跳轉(zhuǎn)情況。

如果非要劫持京東頁面,我們只能使用白名單的方式,特殊對待該站點。但這樣就大幅增加了攻擊成本。

混淆明文

當(dāng)然,不難發(fā)現(xiàn)京東的登錄腳本里,URL 是以最直白的明文出現(xiàn)的。所以我們利用 SSLStrip 的方式,對腳本里的 https:// 的文本進(jìn)行替換,也能起到一定的作用,畢竟大多腳本都對此毫無防備。

但對于稍微復(fù)雜一點的腳本,例如通過字符串拼接而成的 URL,那么就難以實施了。

所以在安全需要較高的場合,不妨把一些重要的地址進(jìn)行簡單的處理,中間人就無法使用通用的方式來攻擊。而必須針對站點進(jìn)行特殊對待,從而提高攻擊成本。

盡可能多的 HSTS

之前提到 HSTS 頭。只要這個字段出現(xiàn)過一次,瀏覽器在很長時間里都會只用 HTTPS 訪問站點。因此,我們盡可能多的開啟 HSTS。

現(xiàn)實中的劫持并非都是 100% 成功的,上述提到,使用腳本跳轉(zhuǎn)很容易出現(xiàn)遺漏。所以,只要逮住用戶一次遺漏,HSTS 就可以讓之后的頁面降級徹底失效了。#p#

0x06 攻擊演示

因為是前端劫持,所以 Demo 有兩個文件:一個前端代碼,另一個后端腳本(NodeJS)。

相關(guān)源碼:https://github.com/EtherDream/https_hijack_demo

相比之前寫的流量劫持演示,這里功能更為專一,不再提供額外的劫持途徑(例如 DNS 等)。

想測試其實非常簡單,只需配置瀏覽器代理,即可模擬 HTTP 的劫持:

??

??

不嫌麻煩的話,也可以在 Linux 內(nèi)核的系統(tǒng)上測試,轉(zhuǎn)發(fā) 80 到本機(jī)即可。原理都是一樣的。

我們隨便找一個 HTTP -> HTTPS 網(wǎng)站做測試。

得益于前端腳本的優(yōu)勢,我們把鼠標(biāo)放到登錄超鏈接上,狀態(tài)欄顯示的仍是原始 URL:

??

??

在我們點擊的瞬間,暗藏頁面中的 XSS 鉤子觸發(fā)了,成功把我們帶到中間人虛擬的 HTTP 登錄頁面里。

當(dāng)然,由于 URL 參數(shù)很多,地址欄里的那個記號看不到了。

??

??

慶幸的是,淘寶的登錄頁面未進(jìn)行地址判斷,被降級后的頁面仍然能登錄成功!

當(dāng)然之前也說了,并非所有的頁面都能劫持成功。

如今越來越多的網(wǎng)站都已重視,因此前端的安全性檢測也隨之而生。僅僅通過一個工具,實現(xiàn)大規(guī)模通用化的劫持,未來會更加困難。

但先比傳統(tǒng)的純后端實現(xiàn),前后結(jié)合的方案能夠帶來更大的發(fā)揮空間。


分享文章:SSLStrip的未來——HTTPS前端劫持
分享鏈接:http://www.dlmjj.cn/article/djcepoi.html