1. 程式人生 > >5種打破HTTPS的方式 —《Pretty-Bad-Proxy》

5種打破HTTPS的方式 —《Pretty-Bad-Proxy》

0x00 開始

最近看到一篇文章叫做《Pretty-Bad-Proxy:An Overlooked Adversary in Browsers’ HTTPS Deployments》,雖然是好幾年前的文章,有些漏洞也早已修復,不過現在看來,很多想法思路都非常棒,畢竟是國際頂級資訊保安會議出品,值得與大家分享,我大概對其總結了一下,挑出了其中的關鍵部分。

0x01 都是瀏覽器的鍋

我們都知道,HTTPS是為了加密通訊傳輸而專門設計的一個協議,防的就是中間人嗅探和攻擊,目的是保證兩邊接收與傳送的資料都是沒有經過篡改和偽造的,協議設計的初衷是好的,但瀏覽器在處理的時候留下了太多的缺陷,下面的5種方式就能看出瀏覽器是怎麼拖HTTPS的後腿。

0x02 環境

以下預設情況都是存在代理,或者說使用者已經被中間人攻擊,我們可以隨意攔截修改使用者的資料包,只是因為加密傳輸,無法獲知內容而已,就像下面這樣。
這裡寫圖片描述

0x03 對錯誤資訊頁面的處理不當

第一種方法:利用瀏覽器對錯誤資訊頁面(4XX/5XX)中指令碼的信任執行(已被修復)

我們都知道伺服器錯誤資訊都是自定義的,不同伺服器的資訊都不一樣,類似於下面這樣:

這裡寫圖片描述

問題就出在這裡,如果裡面有惡意指令碼那怎麼辦?
像下面的情景:
(1) 使用者訪問 https://secret.com/
(2) 中間人攔截請求,併發送回一個狀態碼為502的響應,響應內容包括以下:

<iframe
src="https://secret.com/" id=ifr>
<iframe> <script>handle = ifr.document //do anything</script>

(3) 瀏覽器渲染頁面,重新發送對https://secret.com/的請求,此時中間人不再攔截。
(4) 頁面正常載入,指令碼執行,加密傳輸的頁面被嗅探和篡改。

注意指令碼執行,因為返回的502狀態碼,位址列依舊是https://secret.com/

讓我們看看實際的結果,用版本為54.0的chrome做下實驗,並用fiddler在響應回瀏覽器前抓包修改內容和狀態碼:

這裡寫圖片描述

結果如下:

這裡寫圖片描述

iframe 成功載入,位址列也是https://www.baidu.com/,但是指令碼被淨化了。

第二種方法,利用HTTPS站點引用第三方指令碼,偽造重定向到惡意指令碼站點(已復現)

很多的HTTPS站點也會引用一些第三方的js指令碼檔案,為了安全,他們一般也會確保這個第三方指令碼所在網站是HTTPS,但是,這樣就安全了嗎?

試想,當你的頁面在請求第三方指令碼時,請求被攔截,然後中間人給你返回一個302重定向,瀏覽器能分辨響應的真偽嗎?答案是肯定不能的。

大概的流程如下:
(1) 使用者請求 https://secret.com/ ,中間人不攔截
(2) 頁面請求第三方指令碼 https://js.secret.com/example.js ,中間人攔截
(3) 中間人返回302資料包,location的值為第三方惡意指令碼網站 https://evil.com/evil.js/
(4) 頁面重新請求指令碼,地址為 https://evil.com/evil.js/,中間人放行,然後惡意指令碼被插入HTTPS的頁面中。

我們實際測試一下,攔截某HTTPS網站的指令碼請求,修改響應資料包:

這裡寫圖片描述

這裡我們返回的地址是fiddler的測試地址,然後,瀏覽器成功的發起了對 https://www.fiddler2.com/sandbox/FormAndCookie.asp 的請求

這裡寫圖片描述
這裡寫圖片描述

這裡之所以顯示301的請求結果是因為fiddler的那個測試頁面不存在導致的,至此,我們發現,這種方法可以完美突破HTTPS

0x04 第三種方法,利用HPIHSL(HTTP-Intended-but-HTTPS-Loadable) (已復現)

為了提高訪問速度或者是降低成本的著想,一個站點往往並不是所有的頁面都是HTTPS的,對於那些不那麼重要的頁面,我們常常會用HTTP,因為反正不包含敏感資訊,洩露了也沒關係。但恰恰就是這種頁面有一個特性,那就是大多數這樣的頁面通常可以用HTTPS來連線,稱這樣的頁面為HPIHSL。

單純這樣一個頁面肯定是無害的,但如果這個頁面引用的是HTTP的資源(js,img,css等),那當它採用HTTPS的方式發起連線,所引用的資源卻是HTTP的,雖然位址列左邊會失去帶鎖的圖示。

試想當我們替換掉HTTP資源內容為惡意程式碼,那我們便成功攻入了HTTPS的頁面,打破了SOP。或許會有疑問,那也只是個不包含敏感資訊的頁面,根本沒有價值。

但配合上點選劫持呢?(其實只要注入了惡意JS程式碼,那就可以做任何事了,沒有SOP的限制,一切都是那麼輕鬆)

當我們把一個包含惡意程式碼的js指令碼混入HTTPS頁面時,新建一個指向正常HTTPS頁面的透明iframe覆蓋在某個按鈕上(像結算,登陸等需要跳轉的地方),並且繫結一個點選事件,點選後在新標籤頁開啟HTTPS頁面,那麼,我們是不是成功拿到了對真正HTTPS頁面的控制權?

實際測試中發現,這個問題依舊存在,但是這種方式要求比較多:
(1)HTTP和HTTPS共同存在的站點
(2)域名相同(為了之後獲得對真正HTTPS頁面的控制權)
(3)HTTP站點有第三方指令碼的請求

我們再回顧一下整個攻擊過程:
(1)使用者訪問HTTP頁面,中間人在響應中加入iframe,該iframe指向一個HPIHSL頁面。
(2)之後該HPIHSL請求第三方HTTP資源,中間人攔截後返回惡意js程式碼。
(3)該惡意程式碼新增一些點選事件,點選以後會開啟一個正常HTTPS頁面。
(4)使用者隨意點選頁面,在新標籤中開啟正常HTTPS頁面,因為此時符合SOP,HTTPS頁面被獲取和控制。

這種方法適合有針對性的攻擊,也可以配合魚叉式釣魚,可以說很難發現破綻。

0x05 第四種方法,利用 certificate cache,偽造HTTPS頁面

前面提到利用瀏覽器對錯誤資訊頁面(4XX/5XX)中指令碼的信任執行可以攻破HTTPS,但是這個缺陷現在已經被修復了,所以這裡有另外一種方法可以在不使用任何指令碼的情況下依舊攻破HTTPS。

講這個之前不得不提一下HTTPS的原理,我們都知道HTTPS傳送的內容是經過加密的,但具體是怎麼做的呢?

或許我們最熟悉的就是RSA公鑰加密演算法了,雖然高長度金鑰的對稱加密演算法也非常安全,但是對Web應用這種多使用者訪問一個伺服器的方式,伺服器需要儲存數量巨大的對稱金鑰,簡直原地爆炸。公鑰加密就很適合目前的場景,所有使用者共用一個公鑰,伺服器儲存私鑰,安全簡便,但是RSA慢啊!!!對稱加密快啊!!怎麼辦? 所以就有了公鑰加密和對稱加密混合使用的方式,也就是如今SSL(TSL)協議的實現方式。

簡單點說,就是在建立起一個安全的傳輸層之前,需要進行兩次SSL握手,期間商定好加密的方法和各種資訊(如驗證伺服器的證書,生成一些隨機數等),用公鑰加密演算法加密一個隨機數傳送給伺服器 ,之後兩邊再用這些隨機數和商定的加密方法生成對稱加密金鑰,也就是之後的“會話金鑰”。

很麻煩?我也覺得,這麼說吧,意思就是客戶端與伺服器兩次握手建立安全通道,之後的通訊不必再進行公鑰加密和身份認證,就像正常的HTTP會話一樣,只不過內容被對稱加密了,金鑰我們無法獲知。

我們可以幹嘛?不去破壞身份認證環節,在會話中返回一個偽造頁面。
具體流程如下:
(1)使用者訪問https://secret.com/, 中間人攔截請求返回502頁面,包含一個meta標籤和一個img標籤。
(2)meta標籤將在一秒後重定向到https://secret.com/ ,img標籤請求https://secret.com/ 上的一張圖片(可以不存在,我們的目的是完成SSL的兩次握手)
(3)瀏覽器為了能夠成功請求圖片,與伺服器成功完成SSL握手建立連線,生成了會話金鑰,之後的會話不需要身份驗證,瀏覽器已經信任這個連結。
(4)一秒之後,瀏覽器重定向到https://secret.com/ ,中間人攔截請求,返回502響應,其中為純HTML的一個偽造頁面(如登陸頁面,只不過表單中的action地址是我們的伺服器)
(5)瀏覽器渲染頁面,此時位址列依舊為綠綠的HTTPS!!!

我們依舊來實際操作一下:
首先攔截前往https://www.baidu.com/的請求:

這裡寫圖片描述

然後等待它完成SSL握手之後,再次攔截前往https://www.baidu.com/的請求,返回一個502狀態碼,內容為:

這裡寫圖片描述

看一下效果:

這裡寫圖片描述

成功了,問題就是途中的重定向之前會被發現,你可以把時間調短一點,也可以把返回的頁面做一些社會工程,比如加一段話“正在前往中,請稍後。”之類的。

0x06 第五種方法,利用Cookie的同源策略不區分HTTP和HTTPS來盜取Cookies

前面介紹的兩種方法都要求了較高的社會工程技術和門檻,或許不容易成功,但現在這個方法卻相當容易施展。

因為Cookie同源策略的原因,如果不對其設定 secure 標誌,那麼Cookie將被髮送到HTTP頁面,就算一個站點沒有HTTP頁面,但我們可以通過篡改任意HTTP響應新增一個iframe來要求瀏覽器傳送對HTTPS站點的HTTP請求,而該請求會附帶明文Cookie,之後就可以利用這個Cookie登陸HTTPS站點了。

我們看一下具體流程:
(1)使用者完成一個HTTPS站點(如https://secret.com/)的登陸操作,獲得會話,會話資訊儲存在Cookie中。
(2)使用者此時又請求另一個不相干的HTTP站點,我們發現之後在響應中新增一個指向http://secret.com/ 的HTTP請求。
(3)瀏覽器渲染頁面,發起對http://secret.com/ 請求,並附帶HTTPS頁面的Cookie,我們攔截並獲取到了Cookie。
(4)利用該Cookie成功獲得會話。

這個應該不用我演示,肯定會成功的。

0x07 小結

如果真的存心想嗅探你的資料,方法總比困難多。

相關推薦

5打破HTTPS方式 —《Pretty-Bad-Proxy

0x00 開始 最近看到一篇文章叫做《Pretty-Bad-Proxy:An Overlooked Adversary in Browsers’ HTTPS Deployments》,雖然是好幾年前的文章,有些漏洞也早已修復,不過現在看來,很多想法思路都非常棒

Nginx upstream的5權重分配方式分享

weight 一個 當前 共享 結果 壓力 宕機 clas 機器 Nginx負載均衡的分發方式有4種: 1.輪詢,默認采取此方式,Nginx會按照請求時間的先後順序進行輪詢分發,若某臺Web Server宕機,Nginx自動將其摘掉。 2.

map的5遍歷方式

entry keyset clas emp com spa post pmap next() Map<String, Integer> tempMap = new HashMap<String, Integer>(); tempMap.pu

linux下Nginx反向代理多個tomcat(單獨訪問或叢集配置) Nginx upstream的5權重分配方式

第一步需要在你的伺服器上安裝Nginx,請檢視此文章:https://blog.csdn.net/u013641234/article/details/73838472 安裝完成以後,啟動Nginx,看看是否能夠正常訪問, 然後開始配置Nginx反向代理 : 同一臺伺服器或多臺伺服

Windows系統下Oracle配置服務的5Host書寫方式

通過Oracle 工具 Net Manager 可以建立Oracle服務用來連線各項資料庫例項。 這種服務配置最終修改的是tnsnames.ora 檔案,這個檔案路徑一般位於 %ORACLE_HOME%/NETWORK\ADMIN 目錄下,%ORACLE_HOME% 為安裝的Oracl

springboot的5讀取配置方式5):通過applicationContext.xml讀取

2.通過config讀取指定檔案:可以把同一類的bean進行統一管理,然後通過config指定讀取配置檔案/** * 學生實體類 * Created by ASUS on 2018/5/4 */ public class

Java 5字串拼接方式效能比較。

最近寫一個東東,可能會考慮到字串拼接,想了幾種方法,但對效能未知,於是用Junit寫了個單元測試。 程式碼如下: import java.util.ArrayList; import java.util.List; import org.apache.commons.la

springboot的5讀取配置方式(1):直接讀取bean

1.直接讀取bean:/** * 學生實體類 * Created by ASUS on 2018/5/4 */ public class Student { private String

springboot的5讀取配置方式(2):通過config讀取指定檔案

2.通過config讀取指定檔案:可以把同一類的bean進行統一管理,然後通過config指定讀取配置檔案/** * 學生實體類 * Created by ASUS on 2018/5/4 */

Java 5字串拼接方式效能比較

總結:字串優化 由於String物件時不可變物件,因此在需要對字串進行修改操作時(如字串連線和替換),String物件總是會生成新的物件,所以其效能相對較差。 String常量的累加操作:對於靜態字串的連線操作,Java在編譯時會進行徹底的優化,將多個連線操作的字串

springboot的5讀取配置方式(3):通過application.properties讀取

3.通過application.properties讀取:/** * 學生實體類 * Created by ASUS on 2018/5/4 */ @Component("Student") pu

JavaScript陣列的5迭代方式

ECMAScript 5 為陣列定義了5個迭代方法。每個方法都接收兩個引數: 要在每一項上執行的函式和(可選的)執行該函式的作用域物件–影響this的值。 傳入的這些方法中的函式會接收三個引數: 陣列

Android中的5資料儲存方式之——SharedPreferences

SharedPreferences 簡介 SharedPreferences是Android平臺上一個輕量級資料儲存方式,用來儲存應用的一些常用配置,比如Activity狀態,Activity暫停時,將此activity的狀態保到SharedPer

Nginx upstream的5權重分配方式分享1、輪詢(預設) 每個請求按時間順序逐一分配到不同的後端伺服器,如果後端伺服器down掉,能自動剔除。 2、weight 指定輪詢機率,we

轉載:http://www.jb51.net/article/31273.htm 1、輪詢(預設) 每個請求按時間順序逐一分配到不同的後端伺服器,如果後端伺服器down掉,能自動剔除。 2、weight指定輪詢機率,weight和訪問比率成正比,用於後端伺服器效能不均的情況

單例模式的5實現方式

ber none jvm hid dem abs spl null uic 1.餓漢模式(線程安全,調用效率高,但是不能延時加載): package com.yanwu.www.demo; /* * 測試單例模式 * * 餓漢模式 * * @author

QProcess::startDetached(5.10有了一新的方式

add rep set rpath pos ppr sed int rtai From Qt 5.10 on, there is a new way how to start detached processes with QProcess. Of course you

Java中創建對象的5方式

java開發 instance img 創建 ots args true per src 作為Java開發者,我們每天創建很多對象,但我們通常使用依賴管理系統,比如Spring去創建對象。然而這裏有很多創建對象的方法,我們會在這篇文章中學到。 Java中有5種創建對象的方式

線程的幾個主要概念----線程間通信;線程死鎖;線程控制:掛起、停止和恢復(線程同步的5方式)

推薦 處理 本地變量 之間 管理 zed 空間 get ted (一)線程同步(5種同步方式) 1.同步方法--->有synchronized關鍵字修飾的方法。(Java的每個內置對象都有一個內置鎖,當用synchronized修飾方法--->內置鎖保護整個方法

[原創]java導出word的5方式

插入表格 server 聲明 eof 分享圖片 之間 ima 創建 word導出 在網上找了好多天將數據庫中信息導出到word中的解決方案,現在將這幾天的總結分享一下。總的來說,java導出word大致有5種解決方案: 1:Jacob是Java-COM Bridge的縮寫,

css點滴3—5方式實現圓環

比較 顏色 置頂 寬度 頁面效果 身高 ima 內部 水平 使用css實現圓環,最簡單的方式就是使用嵌套標簽,設置border-radius就可以實現,但是這個是最簡單的方式,這篇文章我們介紹5種方式實現圓環。 1.兩個標簽嵌套 html代碼: <di