徐少培,來自于騰訊玄武實驗室的研究員,主要是從事Web安全研究以及瀏覽器安全研究(前端)。曾經和余弦合寫了《Web前端黑客技術揭秘》。
本文通過徐少培三個Chrome地址欄漏洞,來總結一下地址欄上漏洞挖掘的思路和技巧,徐少培并提出如何深刻的理解地址欄之困,才能更好的挖掘地址欄上的漏洞的理論。
地址欄到底有多重要?
在現代瀏覽器當中,地址欄是唯一可靠的指示器。就是通俗的說,如果地址欄上出現了問題,后續我們所見到的Web頁面,可信任的這些體系將全部崩塌。對于瀏覽器廠商,他們的主要任務是消除軟件當中的緩沖區溢出漏洞。其次,如何幫助人們在上網的時候做出安全的決策。這個安全指示符(地址欄)就是他們在這上面所做的工作之一。
安全指示符
安全指示符,它的目的就在于如何表示當前網站的安全狀態,比如說一個盾牌,一個小鎖或者說一個其他的圖標。常見的瀏覽器廠商是怎么設計它們的標識符的?Chrome就是一個綠色的小圖標,這是一個灰色的大圖標,Firefox也是綠色的,但是它的綠色的顏色跟Chrome還不太一樣,Safari是一個小圖標,還有一個盾牌,國內的瀏覽器可能是一個運行的地球。
這么多對同一個技術狀態的描述,用了不同的指示符。谷歌2015年的時候做了一個調查,大家對地址欄上的指示符到底是不是真正的了解,在谷歌匿名調查的1329人當中,其中提出了兩個問題。一,你對HTTPS網址,對左邊的這個符號是否了解,如果是HTTP的話,你對HTTP左邊的白色符號是否了解。最后的結果其實很尷尬,在訪問的1329人當中,大部分人對于HTTPS這個指示符還知道。對于HTTP這個標識符,大部分人不知道答案。
URL
1994年的時候發布了第一個標準URL,在1998年的時候發布了擴充版RRI。2005年的時候發布了IRI,就是國際統一指示符。
網址到底是什么呢?是URL?是URI?是IRI?公認網址就是URL,而且URL目前維護的這一套標準,而且這個標準還提出,URL的解析,應該像HTML的解析一樣堅固,不要有太多的歧義。
漏洞挖掘過程當中對URL有什么意義?
地址欄漏洞的關鍵因素就是URL。又分為協議、主機、端口、參數、目錄幾部分
協議分為本地協議,網絡協議,注冊的協議,比如說HTTP、HTPPS,這些協議容易出現安全問題。
主機,當瀏覽器地址很小,可以把主機的覆蓋掉而顯示前面偽裝的多級域名主機。
對于端口,目前默認的端口是空,或者是無符號16位的一個整形。端口過多可以出現問題。
地址欄漏洞
什么是地址欄上的漏洞,這里所說的地址欄上的偽裝漏洞就是URL Spoof,本質是Web最基本的安全邊界。
Web當中最扎實,最有根基的就是同源策略,如果這個源被偽造,后續所有的安全體系將會全部崩塌。這個起源指的是什么呢?起源指的是協議加上主機,加上端口。
對于瀏覽器廠商,普通用戶報貨開發者都不關注源是什么,而傾向于主機是什么,所以在地址欄當中,只要偽造主機就可以了。你只要偽造了主機這一個字符串,你就可以說這是一個URL Spoof漏洞。
地址欄漏洞如何挖掘
此處用三個Chrome地址欄漏洞來分析地址欄上的漏洞應該如何挖掘
第一個漏洞。當用戶點擊了一個跳轉到Gmail,由于Gmail的頁面是攻擊者偽裝的。當你登錄Gmail,輸入用戶名和密碼,你的信息就被攻擊者獲取。
這個漏洞是如何實現的。
當用戶點擊這個按鈕的時候,打開了一個頁面,寫下了一堆關鍵代碼。這個代碼是在當前頁面用A標簽自身又打開了一個窗口,導航到了一個地址這是一個畸形的URL,最后有兩個冒號,就是瀏覽器基本上默認是無法去解析的,于是漏洞就觸發了。這個畸形的URL會使瀏覽器發生了什么呢?
當Chrome瀏覽器運行到畸形的URL時,它允許去加載,這就是錯誤的開始。當加載了這個畸形的URL的時候,因為加載的是無效的地址,根本沒有辦法去訪問。地址欄處于掛載的狀態。加載反饋數據,就是瀏覽器加載的流程開始返回。因為你加載的是一個無效地址,只能返回一個空的頁面,也就是說返回了一個空域。此時Chrome還處于掛起狀態,于是會冒號完全隱藏掉并顯示最后的地址。
第二個漏洞。這個協議是發生在Blog協議上,我簡單說一下,Blog協議其實是一個二進制文件的容器,Blog URL允許外部應用程序安全的訪問內存中二進制的文件,也就是說,對于內存中二進制文件的一個Blog引用。按理說安全同源策略來說,你不可能直接打開一個你不能控制域的Blog的URL,通過這個頁面,從視覺感官上是成功打開了谷歌域的Blog的URL,其實是偽造的。
如何做到的?當你點擊了這個按鈕之后,其實首先打開了一個攻擊者可控制域的Blog的URL,就是下面這個黃色的關鍵核心的。過了500毫秒之后,在這個頁面上寫入偽造內容。大家可以看到黃色的關鍵代碼,@后面的域才是攻擊者的域,就是我可控制的,而前面的那些都是偽造的。首先偽造了一個谷歌的字符串,后面進了大量的空白字符。瀏覽器遇到這樣的字符串,這樣的URL。10前來說這個是正常的URL,但是現在已經不允許了,我一會兒會說一下為什么。Chrome會怎么處理呢?Chrome其實犯了一個邏輯上非常嚴重的錯誤,他一直在對HTTP、HTTP做了很多限制,可能邊緣化的協議沒有太注意。其實它渲染了用戶名和密碼的部分,就是@符號前面的部分,按理說應該不會去渲染。就是你可以去解析,但是你在UI上顯示的時候不能顯示出來。因為一個URL的用戶名和密碼一旦被渲染,極有可能被用戶認為是這個URL的主機。比如下面我列舉的這個鏈接,如果直接全被渲染的話,@前面的字符串就有可能被認為是這個主機,也就是偽造了這個域名。
第三個漏洞。這個漏洞其實觸發起來核心代碼就是右鍵點擊,出來了一個UI,當中會有一個你是不是從新窗口打開,。
抓包以后可以看到,其實在左邊抓的,兩個鏈接,其實都已經訪問了,但是最終Chrome瀏覽器是停留在谷歌的網址上,但是頁面內容是我的頁面內容,可控制的,就造成了一個URL欺騙。這個Payload發生了什么?我們通過URL加載的過程來說一下,當你通過右鍵在新窗口打開,Chrome又允許加載一個無效的地址。當時在53版本的時候其實Chrome已經補了,當時不允許加載無效的網址,而且專門把這兩個冒號標識出來了。但是沒有補的時候,說通過不同的網站,不同的方式打開,通過右鍵去打開,可能導航又是另一套程序,這一塊就沒有考慮,還是可以加載google.com:的這樣一個無效網址。加載以后,剛才我說的那一套流程又返回頁面,把google.com:作為一個提交地址。其實到這里應該結束了,如果你在當前重定向到另外一個網上,不會更新當前的URL,URL還會停留在谷歌,其實你的內容已經重定向到了另一個網站的內容,于是又產生了一個URL的欺騙。
用戶在一個網站頁面,你不管是點擊、拖放還是右鍵,去導航到另一個網站的時候。在這個過程當中,攻擊者偽造了你的目的地的URL,其實相當于你就沒有到達目的網站,你是困在了你在哪兒和你要去哪兒的這個中間。
瀏覽器地址欄其實是一個挺矛盾的個體,它提供兩個相互競爭的角色,這兩個角色就是你在哪兒和你要去哪兒,但是只能顯示出其中的一個。而地址欄恰恰就困在這兩個角色的轉換之中,其實你沒有真正的轉換到你要去哪兒,就已經被攻擊者偽造了你要去哪兒的那個網站了,就停留在那兒了。從視覺感官上來說,你也被困在里面了
對于地址欄上的指示符還需要進一步的優化,盡快的幫助人們上網的時候做出安全的決策。地址欄在處理常網址、多網址、畸形網址的時候,不是程序的問題,是自身的地址欄顯示的邏輯問題。比如說只顯示最左邊或者是只顯示最右邊,少一些邏輯上明顯的漏洞?,F在瀏覽器屏幕會越來越小,大家用到的手機,地址欄上的UI可以說是寸像素必爭了。又要提供安全性,又要顯示你是HTTPS是加密的,還要顯示出來正確的源是什么等等,估計空間也不夠。所以在如何處理安全性和用戶體驗上,我覺得可能會是一個非常重要的挑戰。最關鍵的就是大家能記住我這一頁,如果挖漏洞的話,記住如何深刻的理解地址欄之困,在地址欄上能夠如何有效的開展漏洞挖掘工作,也是我們進一步思考的問題。