iOS安全系列之二:HTTPS進(jìn)階上一篇《iOS安全系列之一:HTTPS》被CocoaChina轉(zhuǎn)載,還順便上了下頭條: 打造安全的App!iOS安全系列之 HTTPS,但那篇文章只是介紹了比較偏應(yīng)用的初級(jí)知識(shí),對(duì)于想要深入了解HTTPS的同學(xué)來(lái)說(shuō)是遠(yuǎn)遠(yuǎn)不夠的,剛好本人最近工作上也遇到并解決了一些HTTPS相關(guān)的問(wèn)題,以此為契機(jī),決定寫這篇更深入介紹HTTPS的文章。 本文分為以下五節(jié):
其中第1節(jié)“中間人”是比較常見基礎(chǔ)的知識(shí),網(wǎng)上也可以找到相關(guān)的資料,如果對(duì)中間人攻擊已經(jīng)有了足夠的了解,可以跳過(guò)。后面幾節(jié)則是個(gè)人在iOS方面的實(shí)踐總結(jié),除了一些與系統(tǒng)相關(guān)的特性外,大部分都是系統(tǒng)無(wú)關(guān)的通用知識(shí),并且每一章節(jié)都比較獨(dú)立,所以可以直接跳到感興趣的地方閱讀。 1. 中間人攻擊關(guān)于HTTPS,我經(jīng)常會(huì)提到的就是中間人攻擊,那究竟什么是中間人攻擊呢?中間人攻擊,即所謂的Main-in-the-middle attack(MITM),顧名思義,就是攻擊者插入到原本直接通信的雙方,讓雙方以為還在直接跟對(duì)方通訊,但實(shí)際上雙方的通信對(duì)方已變成了中間人,信息已經(jīng)是被中間人獲取或篡改。 當(dāng)然,本文并不是科普性文章,本節(jié)就針對(duì)HTTPS攻擊,特別是HTTPS在App這一應(yīng)用場(chǎng)景下的常見的攻擊手段進(jìn)行分析討論。 由前文我們知道,HTTPS在建立了TCP連接之后,會(huì)進(jìn)行SSL握手(SSL Handshake)來(lái)校驗(yàn)證書,協(xié)商加密協(xié)議和對(duì)稱加密的密鑰,之后就會(huì)使用協(xié)商好的密鑰來(lái)進(jìn)行傳輸。所以HTTPS攻擊一般分為SSL連接建立前的攻擊,以及HTTPS傳輸過(guò)程中的攻擊; 常見的HTTPS中間人攻擊,首先需要結(jié)合ARP、DNS欺騙等技術(shù),來(lái)對(duì)會(huì)話進(jìn)行攔截, 1.1 SSL證書欺騙攻擊此類攻擊較為簡(jiǎn)單常見。首先通過(guò)ARP欺騙、DNS劫持甚至網(wǎng)關(guān)劫持等等,將客戶端的訪問(wèn)重定向到攻擊者的機(jī)器,讓客戶端機(jī)器與攻擊者機(jī)器建立HTTPS連接(使用偽造證書),而攻擊者機(jī)器再跟服務(wù)端連接。這樣用戶在客戶端看到的是相同域名的網(wǎng)站,但瀏覽器會(huì)提示證書不可信,用戶不點(diǎn)擊繼續(xù)瀏覽就能避免被劫持的。所以這是最簡(jiǎn)單的攻擊方式,也是最容易識(shí)別的攻擊方式。 此類攻擊有個(gè)經(jīng)典的工具:SSLSniff。SSLSniff是大神Moxie Marlinspike開發(fā)的工具,該工具一開始是設(shè)計(jì)用于上一篇文章中提到的Basic Constaints 漏洞的,這類系統(tǒng)級(jí)別的漏洞,基本上可以讓你不知不覺(jué);現(xiàn)在的操作系統(tǒng)和瀏覽器基本修復(fù)了這一漏洞。但也可以使用SSLSniff來(lái)偽造證書實(shí)現(xiàn)釣魚攻擊。 防范措施:釣魚類攻擊,App直接調(diào)用系統(tǒng)API創(chuàng)建的HTTPS連接( 1.2 SSL剝離攻擊(SSLStrip)SSL剝離,即將HTTPS連接降級(jí)到HTTP連接。假如客戶端直接訪問(wèn)HTTPS的URL,攻擊者是沒(méi)辦法直接進(jìn)行降級(jí)的,因?yàn)镠TTPS與HTTP雖然都是TCP連接,但HTTPS在傳輸HTTP數(shù)據(jù)之前,需要在進(jìn)行了SSL握手,并協(xié)商傳輸密鑰用來(lái)后續(xù)的加密傳輸;假如客戶端與攻擊者進(jìn)行SSL握手,而攻擊者無(wú)法提供可信任的證書來(lái)讓客戶端驗(yàn)證通過(guò)進(jìn)行連接,所以客戶端的系統(tǒng)會(huì)判斷為SSL握手失敗,斷開連接。 該攻擊方式主要是利用用戶并不會(huì)每次都直接在瀏覽器上輸入https://xxx.來(lái)訪問(wèn)網(wǎng)站,或者有些網(wǎng)站并非全網(wǎng)HTTPS,而是只在需要進(jìn)行敏感數(shù)據(jù)傳輸時(shí)才使用HTTPS的漏洞。中間人攻擊者在劫持了客戶端與服務(wù)端的HTTP會(huì)話后,將HTTP頁(yè)面里面所有的 這種攻擊手段更讓人難以提防,因?yàn)樗褂肏TTP,不會(huì)讓瀏覽器出現(xiàn)HTTPS證書不可信的警告,而且用戶很少會(huì)去看瀏覽器上的URL是 防范措施:該種攻擊方式同樣無(wú)法劫持App內(nèi)的HTTPS連接會(huì)話,因?yàn)锳pp中傳入請(qǐng)求的URL參數(shù)是固定帶有 1.3 針對(duì)SSL算法進(jìn)行攻擊上述兩種方式,技術(shù)含量較低,而且一般只能影響 WebApp,而很難攻擊到 Native App , 所以高階的 Hacker,會(huì)直接針對(duì)SSL算法相關(guān)漏洞進(jìn)行攻擊,期間會(huì)使用很多的密碼學(xué)相關(guān)手段。由于本人非專業(yè)安全相關(guān)人員,沒(méi)有多少相關(guān)實(shí)踐經(jīng)驗(yàn),所以本節(jié)不會(huì)深入講解相關(guān)的攻擊原理和手段,有興趣的同學(xué)可以查看以下拓展閱讀: 防范措施:這類攻擊手段是利用SSL算法的相關(guān)漏洞,所以最好的防范措施就是對(duì)服務(wù)端 SSL/TLS 的配置進(jìn)行升級(jí):
1.4 模擬最簡(jiǎn)單的攻擊經(jīng)過(guò)上述幾種攻擊方式的說(shuō)明之后,我們來(lái)模擬下最簡(jiǎn)單的中間人攻擊。 中間人攻擊步驟方式的上文已經(jīng)說(shuō)過(guò)了,流量劫持相關(guān)操作不是本文重點(diǎn),可以參考流量劫持是如何產(chǎn)生的?, 本例直接使用Charles來(lái)做代理,對(duì)流量進(jìn)行劫持。并使用SSL代理來(lái)模擬下對(duì)iPhone設(shè)備HTTPS請(qǐng)求的中間人攻擊,讓大家在思考理解中間人攻擊方式的同時(shí),了解在開發(fā)中如何防范類似的攻擊。 1) Charles設(shè)置代理在Charles中開啟并設(shè)置HTTP代理和SSL代理,Menu -> Proxy -> Proxy Setting,設(shè)置如圖: HTTP代理設(shè)置,注意記住端口號(hào)為:8888 SSL代理設(shè)置,在Locations上可以設(shè)置想要進(jìn)行SSL代理的域名,這里以百度的百付寶 2) 在iPhone端設(shè)置HTTP代理在Mac上獲取當(dāng)前機(jī)器的IP地址:
還有一個(gè)簡(jiǎn)單的方法,按住option+點(diǎn)擊頂部菜單欄的WiFi網(wǎng)絡(luò)圖標(biāo): 可以看到當(dāng)前電腦的IP地址為: 將iPhone連接到與電腦相同的WiFi,在iPhone設(shè)置中:無(wú)線局域網(wǎng) -> 已連接WiFi右邊的Info詳情圖標(biāo) -> HTTP代理 -> 手動(dòng) -> 設(shè)置HTTP代理: 設(shè)置完成之后,打開Safari隨便訪問(wèn)一個(gè)網(wǎng)頁(yè),初次設(shè)置代理的話,Charles會(huì)彈出一個(gè)iPhone請(qǐng)求代理的確認(rèn)框,點(diǎn)擊Allow即可。然后在Charles上就可以看到iPhone上的HTTP請(qǐng)求了。為了避免Mac上的請(qǐng)求過(guò)多影響對(duì)被代理iPhone上HTTP請(qǐng)求的查看和調(diào)試,可以在Charles取消Mac的代理:Menu -> Proxy -> 取消勾選Mac OS X Proxy 即可。 假如你訪問(wèn)的是被代理的目標(biāo) URL http://www. 則打不開網(wǎng)頁(yè)。因?yàn)閕Phone的HTTPS請(qǐng)求已經(jīng)被Charles攔截,但iPhone無(wú)法信任Charles的證書,所以SSL Handshake失敗,無(wú)法建立HTTPS連接。 3) 偽造證書欺騙在被代理的iPhone上打開Safari,訪問(wèn)http://www./getssl,會(huì)彈出安裝描述符文件的界面,該描述文件包含了Charles根證書: 注意:這個(gè)Charles證書是內(nèi)置在Charles中的,可以在菜單Help -> SSL Proxying可以直接保存和安裝證書。安裝后的描述文件可以在iPhone設(shè)備的設(shè)置 -> 通用 -> 描述文件進(jìn)行查看和管理。 “安裝”完成之后,就會(huì)將Charles根證書加入系統(tǒng)可信任證書列表中,使用該證書簽發(fā)的子證書也會(huì)被系統(tǒng)信任。Charles會(huì)為之前SSL代理設(shè)置中配置的域名生成對(duì)應(yīng)的SSL證書,這樣偽造證書的證書就實(shí)現(xiàn)了欺騙??梢允褂肕ac SSL代理查看下: 4) 結(jié)果驗(yàn)證下載百度App,然后登錄賬號(hào),在我 -> 我的錢包,就會(huì)訪問(wèn)百付寶: 看到已成功獲取到HTTPS請(qǐng)求包的內(nèi)容。從這里,我們可以猜測(cè)出該App是使用系統(tǒng)默認(rèn)的校驗(yàn)方式:系統(tǒng)信任了這個(gè)中間人服務(wù)器返回的SSL證書,App就信任了這一校驗(yàn),SSL握手成功;而沒(méi)有對(duì)服務(wù)器證書進(jìn)行本地對(duì)比校驗(yàn)。這是當(dāng)下非常多App存在的安全隱患。 這個(gè)簡(jiǎn)單的SSL代理模擬了簡(jiǎn)單釣魚式的中間人攻擊,大家應(yīng)該都基本明白了這種攻擊方式的所針對(duì)的漏洞,以及防范這種攻擊方法的措施:
2. 校驗(yàn)證書的正確姿勢(shì)上一節(jié)對(duì)中間人攻擊進(jìn)行了簡(jiǎn)單介紹,本節(jié)就上一節(jié)我們遇到的安全隱患問(wèn)題,來(lái)討論下在App中,應(yīng)該怎么校驗(yàn)服務(wù)器返回的SSL證書,來(lái)保證HTTPS通信的安全。上一篇文章《iOS安全系列之一:HTTPS》有對(duì)基本校驗(yàn)過(guò)程相關(guān)代碼進(jìn)行講解,本文不會(huì)贅述這些細(xì)節(jié),而是主要討論校驗(yàn)證書中幾個(gè)重要的點(diǎn): 2.1 域名驗(yàn)證前不久,iOS上最知名的網(wǎng)絡(luò)開源庫(kù)AFNetworking爆出HTTPS校驗(yàn)漏洞,該漏洞是因?yàn)槠湫r?yàn)策略模塊 這個(gè)漏洞以及AFNetworking的相關(guān)源碼會(huì)讓很多人以為系統(tǒng)的默認(rèn)校驗(yàn)是不校驗(yàn)證書對(duì)應(yīng)域名的,實(shí)際上并非如此。這里AFNetworking確有畫蛇添足之嫌。首先我們查看下系統(tǒng)的默認(rèn)校驗(yàn)策略:
打印默認(rèn)校驗(yàn)策略信息:
從打印信息來(lái)看,系統(tǒng)的默認(rèn)校驗(yàn)策略中已包含了域名校驗(yàn)。然后再看
這其實(shí)也是很多開發(fā)者在處理異常與默認(rèn)邏輯分支時(shí)會(huì)犯的錯(cuò)誤,這段邏輯推薦實(shí)現(xiàn)方式是:
從代碼上看,邏輯是否變得更清晰了?而且也表明系統(tǒng)默認(rèn)的校驗(yàn)方式是會(huì)驗(yàn)證域名的。實(shí)際上調(diào)用 2.2 校驗(yàn)證書鏈?上一篇文章介紹系統(tǒng)驗(yàn)證SSL證書的方法和流程時(shí),不是已經(jīng)說(shuō)明了會(huì)對(duì)證書鏈進(jìn)行層層校驗(yàn),以保證證書的可信么?為什么還需要討論這一問(wèn)題?其實(shí)本節(jié)要討論的是 先說(shuō)明下結(jié)果:在
開啟 2.3打包證書校驗(yàn)那是否就不需要在App中打包證書進(jìn)行驗(yàn)證了呢? 這時(shí)需要想想為什么偽造證書是可以實(shí)現(xiàn)中間人攻擊的?答案就在于用戶讓系統(tǒng)信任了不應(yīng)該信任的證書。用戶設(shè)置系統(tǒng)信任的證書,會(huì)作為錨點(diǎn)證書(Anchor Certificate)來(lái)驗(yàn)證其他證書,當(dāng)返回的服務(wù)器證書是錨點(diǎn)證書或者是基于該證書簽發(fā)的證書(可以是多個(gè)層級(jí))都會(huì)被信任。這就是基于信任鏈校驗(yàn)方式的最大弱點(diǎn)。我們不能完全相信系統(tǒng)的校驗(yàn),因?yàn)橄到y(tǒng)的校驗(yàn)依賴的證書的源很可能被污染了。這就需要選取一個(gè)節(jié)點(diǎn)證書,打包到App中,作為Anchor Certificate來(lái)保證證書鏈的唯一性和可信性。 所以還是需要App本地打包證書,使用
也就是說(shuō),單純調(diào)用
只相信傳入的錨點(diǎn)證書,也就只會(huì)驗(yàn)證通過(guò)由這些錨點(diǎn)證書簽發(fā)的證書。這樣就算被驗(yàn)證的證書是由系統(tǒng)其他信任的錨點(diǎn)證書簽發(fā)的,也無(wú)法驗(yàn)證通過(guò)。 最后一個(gè)問(wèn)題:選擇證書鏈的哪一節(jié)點(diǎn)作為錨點(diǎn)證書打包到App中?很多開發(fā)者會(huì)直接選擇葉子證書。其實(shí)對(duì)于自建證書來(lái)說(shuō),選擇哪一節(jié)點(diǎn)都是可行的。而對(duì)于由CA頒發(fā)的證書,則建議導(dǎo)入頒發(fā)該證書的CA機(jī)構(gòu)證書或者是更上一級(jí)CA機(jī)構(gòu)的證書,甚至可以是根證書。這是因?yàn)椋?/p> 1) 一般葉子證書的有效期都比較短,Google和Baidu官網(wǎng)證書的有效期也就幾個(gè)月;而App由于是客戶端,需要一定的向后兼容,稍疏于檢查,今天發(fā)布,過(guò)兩天證書就過(guò)期了。 2) 越往證書鏈的末端,證書越有可能變動(dòng);比如葉子證書由特定域名(aaa.bbb.com)改為通配域名(*.bbb.com)等等。短期內(nèi)的變動(dòng),重新部署后,有可能舊版本App更新不及時(shí)而出現(xiàn)無(wú)法訪問(wèn)的問(wèn)題。 因此使用CA機(jī)構(gòu)證書是比較合適的,至于哪一級(jí)CA機(jī)構(gòu)證書,并沒(méi)有完全的定論,你可以自己評(píng)估選擇。 3. ATS在本文發(fā)表的時(shí)間(2015-09-03),大部分的iOS開發(fā)同學(xué)應(yīng)該升級(jí)到iOS9了,在iOS9下進(jìn)行HTTP/HTTPS請(qǐng)求時(shí)會(huì)遇到如下錯(cuò)誤:
這是iOS9中一個(gè)重大的更新:App Transport Security,簡(jiǎn)稱ATS。ATS對(duì)使用NSURLConnection, CFURL, 或NSURLSession 等 APIs 進(jìn)行網(wǎng)絡(luò)請(qǐng)求的行為作了一系列的強(qiáng)制要求,反逼服務(wù)器配置,以提高網(wǎng)絡(luò)數(shù)據(jù)傳輸?shù)陌踩裕?/p>
ATS要求運(yùn)行在iOS9的App,需將HTTP連接升級(jí)到HTTPS,并且TLS版本不得低于v1.2;而且規(guī)定了支持的加密套件(Cipher Suite)和證書簽名的哈希算法;如果想要向前兼容的話,可以通過(guò)設(shè)置Info.plist來(lái)降低校驗(yàn)強(qiáng)度,具體可以看這篇文章:Configuring App Transport Security Exceptions in iOS 9 and OSX 10.11。 本人升級(jí)到iOS9 GM版,從App Store上下載了一些并沒(méi)有完全支持ATS的應(yīng)用,使用起來(lái)也完全沒(méi)有問(wèn)題,估計(jì)iOS系統(tǒng)對(duì)使用低于SDK9編譯的App做了兼容,這方面也是符合預(yù)期的,畢竟ATS的影響實(shí)在太大,基本上沒(méi)有任何的App能夠幸免,比如圖片下載一般使用HTTP,而不會(huì)使用HTTPS。所以建議可以暫時(shí)使用 日益復(fù)雜脆弱的網(wǎng)絡(luò)難以保證用戶的數(shù)據(jù)安全,因此Apple才在iOS9上強(qiáng)推ATS,反向逼迫服務(wù)端升級(jí),以提供更安全的網(wǎng)絡(luò)環(huán)境。建議開發(fā)者不要簡(jiǎn)單地將ATS禁用,而應(yīng)該升級(jí)服務(wù)器的配置支持ATS,為用戶提供更安全的服務(wù)。 4. 調(diào)試SSL/TLS開發(fā)一個(gè)新的App,通常終端和后端先協(xié)商好了具體業(yè)務(wù)邏輯的通信協(xié)議,后端和終端按照協(xié)議實(shí)現(xiàn)邏輯之后,就進(jìn)入聯(lián)調(diào)階段,第一次聯(lián)調(diào)往往會(huì)回到很多問(wèn)題,包括數(shù)據(jù)格式不對(duì),缺少基礎(chǔ)字段等;假如是基于HTTPS的網(wǎng)絡(luò)請(qǐng)求,則很可能由于后臺(tái)配置問(wèn)題,導(dǎo)致遇到如 4.1 錯(cuò)誤碼這會(huì)不會(huì)太簡(jiǎn)單了?其實(shí)最簡(jiǎn)單的往往是最有效的。SSL相關(guān)錯(cuò)誤碼可以在
但靠錯(cuò)誤碼只能判斷大概的情況,很多時(shí)候并不能明確知道到底是什么原因?qū)е碌?,所以最直觀的,還是需要抓包分析。 4.2 抓包分析在這一階段,使用Charles來(lái)抓包是沒(méi)有用的,因?yàn)镃harles是作為HTTP代理工作的,它會(huì)抓取代理的網(wǎng)絡(luò)報(bào)文,然后將報(bào)文組合成HTTP/HTTPS協(xié)議包,對(duì)于HTTP調(diào)試非常方便,但由于細(xì)節(jié)的缺失,沒(méi)辦法使用它來(lái)分析SSL相關(guān)錯(cuò)誤。所以我們需要使用上古神器Wireshark。 關(guān)于Wireshark就不再多介紹了,網(wǎng)上已經(jīng)有很多相關(guān)介紹和抓包教程,如《Mac OS X上使用Wireshark抓包》等,基本上可以很快上手。下面我們就以適配iOS9的ATS為例,來(lái)說(shuō)下如何進(jìn)行抓包分析,找出因?yàn)椴恢С諥TS導(dǎo)致SSL握手失敗問(wèn)題。 還記得SSL握手過(guò)程么?不記得可以重溫下這篇文章:圖解SSL/TLS協(xié)議。我們也來(lái)看看Wireshark上抓取到的包來(lái)直觀學(xué)習(xí)正常的SSL握手流程: 上圖是一個(gè)標(biāo)準(zhǔn)的HTTPS請(qǐng)求抓取的包: 1) 在TCP三次握手成功之后,客戶端發(fā)起SSL的 2) 服務(wù)器從 3) 服務(wù)器同時(shí)會(huì)將證書發(fā)給客戶端(No.73幀);有時(shí)候抓取的包只有 拓展閱讀:
4) 客戶端確認(rèn)證書有效,則會(huì)生產(chǎn)最后一個(gè)隨機(jī)數(shù)(Premaster secret),并使用證書的公鑰RSA加密這個(gè)隨機(jī)數(shù),發(fā)回給服務(wù)端。為了更高的安全性,會(huì)改為Diffie-Hellman算法(簡(jiǎn)稱DH算法);采用DH算法,最后一個(gè)隨機(jī)數(shù)(Premaster secret)是不需要傳遞的,客戶端和服務(wù)端交換參數(shù)之后就可以算出。 5) 接下來(lái)雙方都會(huì)發(fā)送 6) 最后是雙方的 掌握了SSL/TLS握手流程之后,調(diào)試SSL/TLS就會(huì)變得非常簡(jiǎn)單,只需要看在哪個(gè)環(huán)節(jié)報(bào)錯(cuò)(Alert),就可以基本推斷出相關(guān)的錯(cuò)誤。 相關(guān)SSL/TLS接口信息,請(qǐng)查看:RFC5246以及SSL/TLS in Detail 下面就列舉下調(diào)試適配ATS過(guò)程中遇到的主要問(wèn)題: 1) 加密套件(Cipher Suite)等參數(shù)無(wú)法匹配:加密套件不匹配是最常見的握手失敗的例子。 在ATS中,可接受的加密套件有包括:
但往往很多服務(wù)器的HTTPS配置很久沒(méi)有升級(jí),沒(méi)辦法支持這些Cipher Suite;客戶端發(fā)送 一般在接受到客戶端發(fā)送的 2) SSL/TLS版本過(guò)低,這個(gè)也非常常見,但一般會(huì)被上一個(gè)參數(shù)不匹配的錯(cuò)誤所掩蓋。因?yàn)榇蠖鄶?shù)SSL/TLS版本低的服務(wù)器HTTPS配置支持的加密套件等參數(shù)版本也比較低,而SSL/TLS版本是客戶端收到 3) 證書鏈配置錯(cuò)誤:在開發(fā)過(guò)程中,本人遇到過(guò)證書鏈沒(méi)有按照順序進(jìn)行配置的問(wèn)題,也遇到過(guò)只配置了葉子證書的問(wèn)題。對(duì)于這些問(wèn)題,可以直接查看SSL握手過(guò)程中,服務(wù)端返回的 上圖可以看到證書鏈 PS:使用Wireshark進(jìn)行抓包的時(shí)候,有時(shí)候由于一些HTTPS請(qǐng)求的SSL/TLS版本號(hào)太低,Wireshark沒(méi)辦法辨認(rèn)其是SSL包,而是顯示為TCP;此時(shí)可以手動(dòng)來(lái)Decode:選擇對(duì)應(yīng)的TCP數(shù)據(jù)幀,右鍵 -》Decode As -》Transport 選擇SSL -》Apply既可。 5. 后記這個(gè)時(shí)代,安全重要么?這是我曾常疑惑的。90%以上的大眾對(duì)安全沒(méi)有切實(shí)的概念,即使安全上了春晚,過(guò)了熱潮一切又重歸原樣。特別最近換工作到保險(xiǎn)金融類公司,安全問(wèn)題更是觸目驚心。一直相信,人如同一個(gè)圓,你知道的越多,學(xué)的越深,接觸的越廣,圓就越大,越知道自己的渺小,越懂得敬畏。 這世界永遠(yuǎn)不會(huì)缺少矛和盾,沒(méi)有“Mission Impossible”,不是么? |
|