0
曾幾何時,人們對于蘋果產品的信任程度就好像他們經(jīng)常使用的冰箱、空調、洗衣機一樣,但隨著“蘋果絕對安全”謠言的破滅,更多安全人員開始投身到蘋果產品的漏洞挖掘研究之中。
今年年初,蘋果手機軟件FaceTime的一項重大漏洞被曝光,更是讓人們深知世上并無絕對的安全可言。
據(jù)The Verge報道,該漏洞可以讓用戶通過 FaceTime 群聊功能(Group FaceTime)打電話給任何人,在對方接受或拒絕來電之前,就能聽到他們手機里的聲音,該漏洞的曝光把蘋果推上了輿論的風口浪尖。
那么,這樣的漏洞是如何被發(fā)現(xiàn)的呢?除了上述漏洞之外,F(xiàn)aceTime是否還存在著其他安全風險呢?
在此次ISC上,盤古團隊聯(lián)合創(chuàng)始人王鐵磊、盤古實驗室研究員黃濤就“蘋果FaceTime零接觸遠程漏洞首次被還原”這一議題詳細解密了FaceTime的逆向全程并分享了幾個典型的漏洞案例。
內繁外簡的FaceTime
但凡用過FaceTime的用戶,一定對下面這張圖不會陌生。它看起來要比微信、QQ的主界面更加清晰、簡潔,這十分符合蘋果的一貫風格。
然而,對FaceTime進行過逆向漏洞挖掘研究的黃濤卻深知它的“內在”遠沒有我們看到的這么簡單,其內部結構甚至可以使用“錯綜復雜”來形容。
通過逆向分析黃濤發(fā)現(xiàn),F(xiàn)aceTime UI界面其實分成了通訊框和視頻區(qū)兩個部分??此坪唵蔚腢I區(qū)域實則是由多個進程在合作完成整個UI的運作,它們分別是callservicesd、avconferenced(macOS)和mediaserverd(iOS)三個部分組成。
其中,callservicesd進程主要負責渲染通訊框部分,以及撥打或者掛電話的功能。callservicesd進程主要管理了三個功能——第一個是FaceTime接聽、撥打的音視頻狀態(tài);第二個是反饋、響應一些FaceTime產生的UI上的數(shù)據(jù);其次會為avconferenced(macOS)和mediaserverd(iOS)兩個進程去提供信息傳遞的橋梁。
avconferenced和mediaserverd主要負責右邊的視頻區(qū),它們負責處理通訊時的圖像內容,其主要的功能就是將自身的音視頻發(fā)給遠端或者處理遠端傳遞過來的音視頻信息。
現(xiàn)在試想,當一個用戶撥打FaceTime請求的時候,首先會點擊左邊的通訊框內容選擇通話對象,這時UI會發(fā)送UINotification-Call通信,以此告知系統(tǒng)“我要打一個電話出去”。
這個時候callservicesd就會接受到系統(tǒng)發(fā)出的UINotification,它會通過一個函數(shù)開啟通話模式的請求。然后,callservicesd就會調用【CSDFaceTimeProviderDelegateprovider:performStartCallAction】函數(shù)與avconferenced做交互,獲取到lnviteData請求并以此建立通話渠道。
在通話渠道創(chuàng)建之后,其通訊數(shù)據(jù)會被返回給callservicesd。這時callservicesd會將其內部的通訊數(shù)據(jù)封裝起來并傳送給identityservicesd,這就是callservicesd的第三個動作,也是和avconferenced(macOS)以及mediaserverd(iOS)建立通信橋梁的過程(identityservicesd是一個系統(tǒng)進程,主要用來管理用戶和iCould和MAC的連接)。
隨后,identityservicesd會將通訊信息機型封裝,并且同時把它傳輸給一個叫apsd(用于和蘋果發(fā)射推送數(shù)據(jù))的進程,后者和蘋果保持了可行的安全連接,它們在持有交互證書的情況下運作以確保進程的安全性。
在apsd收到來自identityservicesd的封裝信息之后,前者會再度將一層一層的數(shù)據(jù)打包成一個對象,同時將其推送給AppleServer。當然,蘋果服務器不會簡單地把消息推送過去,而是會對消息做一個簡單的過濾。
“老實說,我們發(fā)現(xiàn)這種過濾機制并非真的能確保FaceTime整個運作進程的安全可靠,在尚未被過濾的信息中,我們仍可找到可能被攻擊者遠端控制的數(shù)據(jù)。”
原來,研究人員會人為發(fā)送一組數(shù)據(jù)進入到上述的進程流程當中,在經(jīng)過蘋果服務器過濾后,再通過對比這些數(shù)據(jù)和遠端發(fā)送的數(shù)據(jù),以此得知哪些數(shù)據(jù)是可控的。在這個流程完成后,蘋果服務器就會把apsiMessage傳遞給遠端的apsd,也就是被呼叫那個用戶的設備上了。
在接聽方設備收到數(shù)據(jù)后,便能夠看到來自撥打方的音視頻信息,為了實現(xiàn)雙向交流,與此同時apsd收到的數(shù)據(jù)會采用與上述完全一致的封裝結構來反序列化apsiMessage。為了方便觀察apsiMessage中具體包含了哪些數(shù)據(jù)信息,通常會在其反序列的函數(shù)里面設置一個斷點。
通過設置斷點,可以看到其中幾個比較重要的參數(shù),它們標示了apsd數(shù)據(jù)包究竟會被傳輸?shù)侥抢镞M行處理。apsd會通過兩個參數(shù)把消息傳遞給mediaserverd,之后進一步進行反序列化。
“最終,我們在mediaserverd函數(shù)里面看到數(shù)據(jù)變了,其中有一個字段叫做C的值是232,其代表遠端發(fā)來的是一個Notification。通過不同的C值,比如說232、233、234、235來調用不同的函數(shù)去處理Notification,所以即便不改變漏洞內容,只改變與之對應的處理函數(shù)會不一樣。”
緊接著,mediaserverd會繼續(xù)把數(shù)據(jù)解開然后發(fā)給callservicesd,其同樣也會把數(shù)據(jù)進行反序列化,將其推送給遠端的mediaserverd。如此以來,遠程呼叫端的設備就獲取到了呼叫端的媒體配置信息和加密信息。在這些數(shù)據(jù)處理完之后,呼叫端遠端就會跳出一個UI上面顯示——有一個人正在通過Facetime與你通話的音視頻信息。
這樣一來,一次FaceTime的通話連接便被建立起來了。
為了實現(xiàn)實時的通話需求,遠端用戶接通的時候同樣會產生一個與上述FaceTime UI數(shù)據(jù)傳遞路徑完全一致的反交換過程,這一過程同樣會被遠端的callservicesd去處理,接下來流程和之前幾乎是一樣。
“值得注意的是,在反向通訊的過程中之前的C值不是232而是233了,這時遠端已經(jīng)接受了對方設備視頻的請求,這時會調用相應函數(shù)值來處理返回過來的數(shù)據(jù)。這種情況下,兩端都會打開各自的avconferenced(macOS)和mediaserverd(iOS)端口,并且在穿墻協(xié)議的幫助下實現(xiàn)雙方找到IP建立端對端鏈接?!?/p>
通過端對端的鏈接,identityservicesd負責處理和接收網(wǎng)絡包,另一個函數(shù)會調用apsiMessage從udp端口拿到網(wǎng)絡包傳遞給IDSGlobaLink,后者會判斷該網(wǎng)絡報是否符合seiten協(xié)議,如果是就會將其傳送給對應的執(zhí)行函數(shù),進一步解析網(wǎng)絡包,再次將其發(fā)送給更細分的執(zhí)行函數(shù)。與此同時,identityservicesd還會響應一些其他的協(xié)議。
這張圖是真正的在建立FaceTime之后其數(shù)據(jù)的音視頻究竟是怎樣的,到這里逆向的分析也就告一段落了。
可見,看似簡潔的FaceTime其進行數(shù)據(jù)處理、執(zhí)行及反饋的渠道多到令人咋舌的地步,這也注定FaceTime更容易存在攻擊面。而對于如此龐雜的數(shù)據(jù)流通線路,其中需要用戶進行操控的地方少之又少,這就意味著一旦攻擊開始,其整個過程具有極強隱蔽性。
FaceTime的4個漏洞案例分享
從上面FaceTime逆向的過程可以看出,實際上從呼出到最終的雙方看到音視頻信息是一個非常長的處理流程。也就是說,一旦逆向分析有所疏漏,漏洞挖掘的過程只是在某一層進行,這就難免會使得研究數(shù)據(jù)完整性欠缺,甚至會損壞其格式。
那么,在搞清楚FaceTime的工作原理之后,關于其漏洞挖掘的過程才算真正開始。在這里,王鐵磊分享了4個FaceTime的漏洞分析案例。
案例1
第一個案例介紹的是一個疑似的信息泄露,這個漏洞發(fā)生在從apsd到avconferenced之間,也就是在最初的信息數(shù)據(jù)包處理上。
通過查看數(shù)據(jù)流,發(fā)現(xiàn)攻擊者的數(shù)據(jù)包中包含了一些U字段的報文數(shù)據(jù)。這個U字段數(shù)據(jù)實際上是一個UUID,其本身只是一些嵌入符號,并沒有什么特別的含義。
“但是,我們發(fā)現(xiàn)通過在其前后插入額外的字段,可以讓這些原本毫無意義的字段來強制執(zhí)行一些命令。”
首先在Notification插入一些額外的字段,當遠端收到之后U字段和人工植入的數(shù)據(jù)都在其中,于是強制返回包中會包含UUID——到目前為止整個流程上還沒有什么問題,只是一方面是數(shù)據(jù)的發(fā)送另一方面是信息的返回。但是,因為這里有同樣的字段,這也正是漏洞的所在。
首先,來看看這段代碼的具體意思——收到一個Notification以后,遠端會把整個字典數(shù)據(jù)做一個分析,它先試圖去看有沒有所謂的U字段,有的話就把U字段所對應的數(shù)據(jù)包給取出來,并假定其是一個AI Sdatae,然后將其作為參數(shù)傳入一個以GWUUID開頭的函數(shù)中,其本意是為了把AI Sdatae轉換成一個CFStun,但是這個假定數(shù)據(jù)的長度是16字節(jié),而因為其調用的一個函數(shù)的LOKCBfer是沒有初始化的,這就意味這如果發(fā)出去的UUID的長度不到16字節(jié),那么就有可能得到一個未初始化的棧溢出數(shù)據(jù)。
為了證明上述猜測,研究人員首先發(fā)送了一個遠端的UUID。研究人員的最初想法,是想看到的輸出一些值得關注的地址,但卻發(fā)現(xiàn)改造后的Notification發(fā)過去后在遠端收到的UUID不見了,這就意味著蘋果服務器那端把短的UUID剝離掉了,從代碼角度來看這是一個100%未初始化內存泄露的問題,但是真實POC構造過程中蘋果服務器扮演了一個未知的角色,因此不確定是何時開始過濾的。
案例2
當FaceTime的連接建立之后,一個非常重要的一個角色就是mediaserverd,因為mediaserverd進程負責第一層網(wǎng)絡報文的處理,F(xiàn)aceTime的所有數(shù)據(jù)或者其它控制的發(fā)送,這些報文在最初的未處理狀態(tài)都被mediaserverd服務運行。
mediaserverd會根據(jù)包的內容來去選擇是哪些其它的進程或者是其它的函數(shù)來處理,其中typeMessage攻擊者就可以通過udp把攻擊文件發(fā)送到遠端的mediaserverd,遠端的mediaserverd會識別typeMessage。
根據(jù)它的協(xié)議,typeMessage在偏移為“4”的地方會有執(zhí)行。因此,從代碼執(zhí)行上可以看到mediaserverd就是做了一個比較,如果包里存在為“4”的值那就是typeMessage,然后將其一個函數(shù)除去,之后發(fā)送的報文會被反序列化成為一個叫IDSStunMessage的對象,而IDSStunMessage在這個反序列化構成中沒有發(fā)現(xiàn)什么特別的漏洞,然后當typeMessage被反序列化成這個對象以后,會進一步處理函數(shù)。
實際上,期間過程中一共包含了20個屬性,他們全部是從udp報文中拷貝過去的,也就是說它們在現(xiàn)在這一階段是完全可以被攻擊者控制的。如果typeMessage中的type數(shù)值為“0x17”,這時會阻斷一個特殊函數(shù),其功能是將類型為19的屬性取出來,這一過程都屬于安全流程,但是在隨后的反序列化過程中就會暴露出很多問題。
反序列化的時候數(shù)據(jù)格式非常簡單,它就是兩字節(jié)的type兩字節(jié)的長度。但實際上,這里面如果看到一個屬性的type是0xF或者很多種類型的屬性都會得到一個叫readIDSGLAttrBinaryData的函數(shù),其過程會調用到memcpy。而這個memcpy的case參數(shù)完全可控,其執(zhí)行難度不大,稍加長度布局的改動即可讓其顯示141414...的錯誤顯示,這是一個典型的堆出漏洞。
案例3
callservicesd會把數(shù)據(jù)再轉給avconferenced(macOS)或者mediaserverd(iOS),這其實進入到了音視頻流的處理流程,而這里的這個漏洞是一個棧溢出。
該漏洞的原理是——當去做視頻剪輯的時候,一幀數(shù)據(jù)可能會很大,這個時候一個處理單元就可能被分割成多個RTP包被進行傳送,然后接受方接收了這些包之后再重組成完整數(shù)據(jù)包做處理。由于RTP包是通過UDP包來的,所以有前有后,為了維持如此布局就要將這些RTP都進行串聯(lián),在傳送到之后才重組起來。
在每收到一個RTP包的時候會嚴格檢查包的格式,但是有時候會出現(xiàn)丟包的情況,在蘋果的處理方案中,其引入了一種容錯機制——它可以通過已經(jīng)收到的包去重構出一些已丟包的基本信息,這就是為什么在發(fā)生網(wǎng)絡抖動的時候,F(xiàn)aceTime聊天的畫面會糊一點,但還是能夠保持能看到基本的內容的原因。
但是問題在于,在做包修復的時候,RTP里面會含一個叫做FEC的東西會重構出RTP包,重構出來的長度則是在FEC Header里面制定的。但是FEC Header是沒有經(jīng)過任何檢查的,所以最后導致的后果就是容錯機制被調度起來的時候,執(zhí)行函數(shù)中的size是完全可控的,這是最經(jīng)典的棧溢出。
那么,在2019年iOS上面,棧溢出還能不能利用?
實際上,像這種傳統(tǒng)的經(jīng)典棧溢出的最有效防范就是啟用cookie。它的基本原理就是當函數(shù)值被調用的時候,在返回地址和局部變量之間插入一個cookie,在函數(shù)返回的時候從棧上把剛才的cookie拿出來作比較,如果二者不一致的話那么意味著整個cookie都被破壞掉了,很可能返回地址也已經(jīng)被破壞掉了,所以這時該程序就可以主動地退出,避免整個返回地址被控制住。
這種連續(xù)溢出會破壞stack_cookie,這些指令在函數(shù)執(zhí)行進來的時候,函數(shù)參數(shù)(地址)已經(jīng)在棧上了,有些指令可以把一些寄存器暫時壓在棧上,這幾條指令在分配局部變量,其實也是在放置棧的cookie。
其中的問題是,棧cookie被放在了局部變量后面,這就意味著當局部變量發(fā)生棧溢出的時候它會直接覆蓋到crashed而無需破壞stack_cookie。這個問題十分嚴重,stack_cookie根本沒有放在一個合適的位置,自然也起不了正常的作用。
通過crash log的截圖可以看出,在iOS上可以看到serverd34號線程已經(jīng)發(fā)生了崩潰,整個PC已經(jīng)完全被控制,變成了808080,與此同時其他的寄存器也都被控制了。在將該漏洞報告蘋果后,后者在12.4版本中做了修復,但事情并沒有就此告一段落:
在意識到stack_cookie出問題的時候,研究人員又去檢查了其他的模塊及函數(shù),他們發(fā)現(xiàn)很多函數(shù)都有這個問題,因此他們意識到這里還有一個編譯器的漏洞。因此,結論是這是一個在FaceTime棧溢出背后還有一個編譯器漏洞問題。
實際上,蘋果是LLVM編譯器的一個最大推手,如果蘋果編譯器有問題那么多半意味著LLVM編譯器有問題,最終這個問題蘋果的安全團隊在進行更詳細的分析后發(fā)現(xiàn)確實如此,其影響的是整個品牌的編譯器產品,這也是為什么之后該廠商為這樣一個威脅程度為0的漏洞發(fā)布了公開聲明的原因。
案例4
identityservicesd會根據(jù)收到的Notification里的一個函數(shù)決定是將消息發(fā)給callservicesd還是其它的服務。這是一個叫做Phone countinuity的漏洞,它原本是可以實現(xiàn)在MAC筆記本和iPhone在登陸統(tǒng)一Apple ID的情況啟用通話功能的一項附加功能。雷鋒網(wǎng)雷鋒網(wǎng)雷鋒網(wǎng)
實際上,這就意味著手機和電腦之間存在著一個數(shù)據(jù)通道。他們也做了一些逆向分析,最終發(fā)現(xiàn)這個還是在identityservicesd做的處理。
其實會存在這樣的執(zhí)行路徑,IDSLinkManager最后會走到一個叫做IDSSockAddrWrapper initWithSockAddr:的函數(shù)。這個函數(shù)實際是根據(jù)UTP包中的內容去反序列化一些地址,這里也是最終出問題的地方。如果大家對去年的imptcp模塊安全漏洞熟悉的話,iOS內核嘗試著去把一個用戶的數(shù)據(jù)反序列化成一個soft地址,問題是對于一個有效地址其長度是0X80,但一個soft結構體它的長度域可表達的范圍是0XFF,這就與意味著當把一個地址進行拷貝時,要根據(jù)其第一字節(jié)的長度來進行調節(jié),因此一定要做嚴格的長度檢查。但是,這個函數(shù)里只對地址域進行了檢查,沒有檢查長度,這意味著可以把第一個字節(jié)填稱0XFF最多可以溢出0XFF-[字節(jié)長度]這么長,那這個函數(shù)和前面說到了漏洞利用十分接近。
總結
在整個分析中,F(xiàn)aceTime的大量攻擊漏洞被逐一挖掘出來。
在對FaceTime進行分析時王鐵磊稱,首先,F(xiàn)aceTime的代碼質量非常差,這個出乎他們的預期,整個FaceTime需要一個極大的提高,否則隨著安全研究人員的不斷挖掘會有更多漏洞被曝出來;其次,整個Message的接口有非常大的畸變,其本質都是通過identityservicesd做的一個轉化,這么多功能糅雜在一起也就意味這復雜性很高,那么攻擊面是非常大的;最后對于進行安全研究的人員來說,很多老的漏洞并沒有過時,比如上面講的棧溢出就是十分經(jīng)典的例子。
雷峰網(wǎng)原創(chuàng)文章,未經(jīng)授權禁止轉載。詳情見轉載須知。