[譯] 對第三方 SDK 的信任問題

Cup發表於2019-02-19

對第三方 SDK 的信任問題

第三方的 SDK 常常會在你下載他們的時候被輕易地修改!只要使用簡單的中間人攻擊,任何位於同一網路中的人都可以插入病毒程式碼至程式碼庫中,並隨之進入你的應用中,從而在你的使用者的手機中執行。

在最熱門的閉源 iOS SDK 中,31% 的 SDK 和 CocoaPods 中的 623個庫 對於這種攻擊是沒有抵抗力的。作為研究的一部分,我通知了被影響的組織,並向 CocoaPods 提交了補丁,來提醒開發者和 SDK 提供者們。

一個 SDK 被修改潛在後果是什麼?

若某人在你安裝一個 SDK 之前修改了它,那麼情況會變得十分的危險。因為你正在將你的 app 和那些危險的程式碼一起傳送給使用者。它會在幾天內在成千上萬的裝置中執行。同時,它擁有和你的 app 一模一樣的許可權。

這意味著任何你在 app 中引用的 SDK 擁有:

  • 任何你的 app 能接觸到的 keychain
  • 任何你的 app 有許可權接觸到的檔案、資料夾
  • 任何你的 app 所擁有的許可權,例如:定位資訊,相簿許可權等
  • 你的 app 的 iCloud 儲存內容
  • 你的 app 與 web 伺服器交換的所有資料,例如:使用者登入資訊,個人資訊等

Apple 強制要求 iOS app 應用使用沙箱是有很好的理由的,因此不要忘記任何你的 app 所包含的 SDK 在你的 app 的沙箱中執行,並且能夠接觸所有你的 app 有許可權接觸的東西。

一個含病毒的 SDK 最壞會做什麼?

這裡描述的攻擊方法展示了攻擊者是如何利用你的手機 app 來偷取使用者敏感資料的。

網路安全 101

為了使你明白病毒程式碼是如何在未經你的允許或注意的情況下與你的 app 繫結的,我會提供必要的知識背景來讓你明白MITM 攻擊是如何進行的,以及如何避免它。

為了使一個移動端開發者在即使沒有太多的網路通訊知識的情況下,仍然能夠了解這是如何工作的以及它們是如何保護自己的,下面的資訊已經被簡化了。

HTTPs vs HTTP

HTTP: 未加密傳輸,任何位於同一網路(WiFi 或乙太網)的人都可以輕易地監聽網路包。在未加密的 WiFi 網路上這樣監聽的方法非常簡單直觀,而實際上在受保護的 WiFi 或乙太網上依然是同樣簡單的。你的計算機不會去驗證你所請求資料的主機的網路包;其它的計算機可以在你之前接收包裹,開啟並修改它們,之後再將更改過的版本傳送給你。

HTTPs: 在 HTTPs 傳輸中,其它在網路中的主機仍能監聽你的包裹但不能開啟它們。它們仍然能夠獲取一些基本的後設資料,如主機名,但無法得到詳細資料(如資料的 body 部分,完整的 URL 等...)。另外,你的客戶端會驗證你的資料包是否來自原始的主機,且沒有人修改過內容。HTTPs 技術是基於 TLS 的。

瀏覽器是如何從 HTTP 切換至 HTTPs 的

在你的瀏覽器中輸入“google.com” (請輸入 “http”, 而不是 “https”)。你會看見瀏覽器是如何自動的從 “http” 埠切換至 “https” 的。

這個切換並不是在你的瀏覽器中發生,而是來自於遠端的伺服器(google.com),因為你的客戶端(現在即瀏覽器)並不知道主機支援哪一種埠。(除了使用 HSTS 的主機)

[譯] 對第三方 SDK 的信任問題

最初的請求是通過“http”發生的,所以伺服器只能通過“http”明文來告訴客戶端切換至安全的“https”埠,響應的程式碼為“301 Moved Permanently”。

你可能已經看到這裡的問題所在了:由於第一個響應是使用明文,攻擊者可以改變特定的網路包來替換掉重定向的 URL 並保持不加密的 “http”。這叫做 SSL 剝離,我們會在之後更多地談及它。

網路請求是如何工作的

簡單來講,網路請求工作在多層模型上。不同的層上有不同的資訊,告訴網路包如何路由:

  • 最底層(資料鏈路層)使用 MAC 地址來定位主機在網路中的地址
  • 上面的一層(網路層)使用 IP 地址來定位主機在網路中的地址
  • 再上面的層會新增埠資訊和實際要傳遞的訊息內容

如果你對此感興趣,你可以學習 OSI 模型是如何工作的,特別是在實現 TCP/IP 協議時 (例如 microchipdeveloper.com/tcpip:tcp-i…)。

所以,如果你的計算機將一個網路包傳輸給路由器,它是如何基於第一層(MAC address)知道怎麼去將網路包路由的呢?為了解決這個問題,路由器採用了一種埠叫做 ARP (Address Resolution Protocol)。

ARP 的工作原理以及是如何被濫用的

簡單來講,網路中的裝置利用 ARP 對映來記住去將含有特定 MAC 地址的網路包送到哪裡。ARP 的工作原理很簡單:如果一個裝置知道該一個網路包所應送入的 IP 地址,它就會詢問網路中的所有人:“這個 MAC 地址應該與哪個 IP 地址對應?”擁有那個 IP 地址的裝置就會回覆該資訊 ✋

[譯] 對第三方 SDK 的信任問題

不幸的是,裝置無法驗證 ARP 訊息傳送者的身份。因此攻擊者可以快速地響應另一臺裝置的 ARP 宣告:“請將所有 IP 為 X 的網路包傳送至這個 MAC 地址。”路由器就會記住並在以後對所有相關的請求應用該資訊。這被稱為“ARP 欺騙”。

[譯] 對第三方 SDK 的信任問題

明白所有的網路包是如何經過攻擊者而不是直接從主機路由至你的計算機上的了嗎?

只要網路包經過攻擊者的機器,就會有一些風險。與你使用你信任的 ISP 或 VPN 服務的風險一樣:如果你使用的服務進行了合適的加密,他們就不能得知你正在做的事情或在你的客戶端(比如瀏覽器)注意不到的情況下修改你的網路包。如之前所說,仍然有一些資訊如特定的元資訊是可見的(例如主機名)。

如果存在未加密的網路包(例如 HTTP),那麼攻擊者不僅可以查閱裡面的內容,同時還可以隨意改寫任何資訊而不被發現。

注意: 上面所述的技術與你可能讀過的公共 WiFi 安全問題是不同的。公共 WiFi 的問題在於任何人都可以讀取在其中所傳送的網路包,如果這些網路包是沒有加密的 HTTP,那麼很容易就解讀出正在發生的事情。ARP 汙染作用於所有的網路,無論是公共與否,WiFi 還是乙太網。

讓我們看看它在實踐中如何作用

讓我們看看一些 SDK,它們是如何釋出它們的檔案的,然後我們看看能不能找到什麼。

CocoaPods

開源 Pods: CocoaPods 在底層使用 git 來從如 GitHub 等服務下載程式碼。 git://埠使用ssh://,與 HTTPs 的加密相似。總體上,如果你使用 CocoaPods 從 GitHub 上安裝開源 SDK,你還是很安全的。

閉源 Pods: 在準備這篇文章時,我注意到 Pods 可以定義一個 HTTP URL 來指向二進位制 SDK,所以我提交了一個 pull request(12),合併後釋出為CocoaPods 1.4.0 來在一個 Pod 使用未加密的 http 時產生警告。

Crashlytics SDK

Crashlytics 使用 CocoaPods 作為預設的釋出,但還有 2 種可選的安裝方式:Fabric Mac app 或手動安裝,這兩種都是 https 加密的,所以我們在這沒有太多可做的。

Localytics

讓我們看一下一個 SDK 樣例,文件頁面是通過未加密的 http 傳輸的(見位址列)

[譯] 對第三方 SDK 的信任問題

所以你可能會想:“啊,我只是在這裡查閱文件而已,我又不在乎它沒有被加密。”但問題在於,這裡的下載連結(藍色的)也是網站的一部分,意味著一個攻擊者可以輕易地將 https:// 連結替換為 http://,使得實際的檔案下載並不安全。

或者,攻擊者也可以選擇只是將 https:// 連結換為看起來相似的攻擊者的連結。

同時,使用者沒有好的方法來驗證特定主機的身份,URL 或者 SDK 作者的 S3 bucket。

為了驗證這點,我設定了我的樹莓派 來劫持流量並實現多種 SSL 欺騙(將 HTTPs 連結降級為 HTTP),從 JavaScript 檔案,圖片檔案,到下載連結。

[譯] 對第三方 SDK 的信任問題

一旦下載連結被降級為 HTTP,就很容易將 zip 檔案的內容替換掉:

[譯] 對第三方 SDK 的信任問題

在傳輸中替換 HTML 文字很容易,但一個攻擊者如何替換一個 zip 檔案或者二進位制檔案呢?

  1. 攻擊者下載原來的 SDK
  2. 攻擊者將病毒程式碼插入 SDK
  3. 攻擊者壓縮更改後的 SDK
  4. 攻擊者等待來往的網路包,並將所有擁有特定特徵的檔案替換為攻擊者準備好的 zip 檔案

(這與圖片替換技巧中使用的方法一樣:每個通過 HTTP 傳輸的圖片都被一個表情替換)

結果是,所下載的 SDK 可能包含被修改過的額外的檔案或程式碼:

[譯] 對第三方 SDK 的信任問題

要讓這個攻擊生效,所需的是:

  • 攻擊者與你位於同一網路
  • 文件網頁是未加密的並且所有的連結都能夠使用 SSL 欺騙

[譯] 對第三方 SDK 的信任問題

Localytics 在問題被披露後解決了它,所以文件頁面和下載現在都是 HTTPs 加密的了。

AskingPoint

看下下一個 SDK,它的文件頁面是 HTTPs 加密的,從截圖來看,似乎是安全的:

[譯] 對第三方 SDK 的信任問題

然而,這個基於 HTTPs 的網站連結指向了一個未加密的 HTTP 檔案,而瀏覽器在這種情況下是不會警告使用者的(一些瀏覽器已經會在 JS/CSS 檔案通過 HTTP 下載時發出警告)。對於使用者來說,很難發現這裡發生著什麼,除非他們會手動比較所提供的雜湊值。作為這個專案的一部分,我撰寫了一份安全報告,針對 Google Chrome (794830) 和 Safari (rdar://36039748)來警告那些從 HTTPs 網站下載未加密檔案的使用者們。

AWS SDK

[譯] 對第三方 SDK 的信任問題

在我進行這項研究的時候,AWS iOS SDK 的下載頁面使用了 HTTPs 加密,但連結至了一個未經加密的 zip 下載檔案,與之前所提到的 SDK 相似。這個問題在被披露後,亞馬遜解決了它。

總而言之

回想起之前提到過的 iOS 隱私漏洞(iCloud 釣魚,通過圖片獲得定位,在後臺使用攝像頭),如果我們談論的不是那些針對使用者的惡意開發者,而是那些針對你,一個 iOS 開發人員的攻擊者,為了在短時間內接觸到上百萬使用者呢?

攻擊開發者

如果一個 SDK 在你下載的時候被使用中間人攻擊修改了內容,並插入了病毒程式碼,導致使用者對你的信任破裂,你會怎麼辦呢?讓我們以 iCloud 釣魚彈窗為例,要想使用其它開發者的 app 來偷取使用者的密碼,併傳送至你的遠端伺服器上,到底有多難?

在下面的視訊中,你可以看到一個 iOS 樣例 app,有地圖展示功能。在下載並將 AWS SDK 加入這個專案後,你可以看到病毒程式碼是如何被執行的,在這個案例中 iCloud 彈窗釣魚顯示了出來,然後 iCloud 的明文密碼被讀取並傳送到一個遠端伺服器上。

YouTube 視訊請見:https://youtu.be/Mx2oFCyWg2A

這個攻擊唯一的發動前提就是攻擊者需要與你在你一個網路上(例如在同一個會議酒店中)。或者攻擊也可以通過你使用的 ISP 或 VPN 服務來完成。我的 Mac 使用的是預設的 macOS 配置,意味著是沒有代理,自定義 DNS 或者 VPN 設定的。

設定這樣的攻擊簡單地令人驚訝,因為可以使用專為 SSL 欺騙,ARP 汙染和替換多種請求內容而設計的工具來自動完成攻擊。如果你之前實現過攻擊,在其他任意的計算機上僅需不到一個小時就能完成設定,包括像我用於這次研究的樹莓派上。因此整個攻擊的花費不到 $50 美元。

[譯] 對第三方 SDK 的信任問題

我決定不公開我所使用的工具名稱,以及我寫的程式碼。你可以看看一些有名的工具如 sslstripmitmproxyWireshark

在開發者的機器上執行任意的程式碼

在之前的例子中,攻擊者通過劫持 SDK 來向 iOS app 中插入病毒程式碼。另一個攻擊方向是開發者的 Mac。一旦攻擊者可以在你的機器上執行程式碼,甚至擁有遠端 SSH 許可權,那麼損害將會變的巨大:

  • 啟用管理員賬戶的遠端 SSH 許可權
  • 安裝鍵盤記錄器來獲取管理員密碼
  • 使用密碼來解密 keychain,並將所有登入憑據傳送至遠端伺服器
  • 獲取本地機密,如 AWS 憑據,CocoaPods 和 RubyGems 的上傳令牌還有:    *   如果開發者擁有著一個受歡迎的 CocoaPod,你可以將病毒程式碼散播到更多的 SDK 中
  • 接觸你的 Mac 上幾乎所有的檔案及資料庫,包括 iMessage 的對話,郵件和原始碼
  • 在使用者不知情的情況下錄屏
  • 安裝一個新的 root 下的 SSL 證照,使得攻擊者能夠監聽你大部分加密的網路請求

為了證明這是可以發生的,我查詢了如何在開發者本地執行的 shell 文字中插入病毒程式碼,在 BuddyBuild 案例中:

  • 與之前的前提相同,攻擊者需要在同一個網路中
  • BuddyBuild 文件告訴使用者去 curl 一個未加密的 URL 來通過 sh 進行操作,意味著任何 curl 命令返回的程式碼都會被執行
  • 修改過的 UpdateSDK 由攻擊者(樹莓派)提供,並且詢問管理員密碼(通常 BuddyBuild 的更新指令碼不會詢問這個)
  • 在一秒鐘之內,病毒指令碼可以做到:
    • 為當前賬戶啟動遠端 SSH 許可權
    • 安裝並配置鍵盤記錄器,用於自動記錄你的登入操作

一旦攻擊者獲得了 root 密碼和 SSH 許可權,他們可以去做任何上述的事情。

YouTube 視訊請見:https://youtu.be/N1Wj6ipc-HU

BuddyBuild 在問題反饋後解決了這一問題。

這樣的攻擊有多現實?

**非常現實!**開啟你的 Mac 的網路設定,並檢視你的 Mac 連線過的 WiFi 列表。對我來說,我的 MacBook 曾連線過超過 200 個熱點。而其中有多少你可以完全相信呢?即使在相信的網路中,其它的機器也可能在之前被侵入,而實現遠端控制攻擊(見上部分)。

SDK 和 開發者工具成為了越來越多的攻擊者的目標。這裡有一些過去幾年的例子:

  • Xcode Ghost 影響了近 4000 個 iOS app,包括微信:
    • 攻擊者對任何使用這些 app 的機器擁有遠端登入許可權
    • 展示釣魚彈窗
    • 擁有閱讀並更改貼上板的許可權(當使用密碼管理器的時候這會變得很危險)
  • NSA 致力於尋找 iOS 漏洞
  • Pegasus:針對非越獄 iPhone 的惡意軟體, 被政府利用
  • KeyRaider:僅影響越獄 iPhone,但仍然偷取了超過 200,000 終端使用者的使用者憑證
  • 在僅僅幾周之前,有很多關於這是如何影響網站專案的博文被髮出 (例如1, 2

以及更多類似的事件。另一個方法是獲取下載伺服器的許可權(例如 S3 bucket 使用許可權金鑰)並替換掉二進位制檔案。這在過去幾年中常常發生,例如 Mac app 傳輸事件。這開啟了攻擊領域的另一個層級,是我在這篇博文中沒有講到的。

會議中心,酒店,咖啡廳

每當你在會議中心,酒店或者咖啡廳連結 WiFi 時,你會成為一個易於攻擊的目標。攻擊者知道這裡有大量的開發者在會議中,並可以輕易地利用這點。

SDK 提供者如何保護他們的使用者呢?

這會超出這篇博文的討論範圍。Mozilla 提供了一份安全指導 是一個不錯的主意。 Mozilla 還提供了一個工具叫做observatory ,能夠自動檢查伺服器的配置和證照。

有多少熱門的 SDK 被這一弱點影響了?

[譯] 對第三方 SDK 的信任問題

[譯] 對第三方 SDK 的信任問題

[譯] 對第三方 SDK 的信任問題

我從 2017 年 11 月 23 日開始研究,根據 AppSight(將所有 Facebook 和 Google 的 SDK 算作一個,因為他們都採用了同一種安裝方法——略過所有在 GitHub 上開源的 SDK),調查了 41 個最受歡迎的移動端 SDK。

  • 41 個檢查的 SDK 中
    • 23 個是閉源的且你只能下載二進位制檔案
    • 18 個是開源的(它們都在 GitHub 上)
  • 13 是容易成為中間人攻擊而使用者無法得知任何情況的目標
    • 10 個為閉源 SDK
    • 3 個是開源的 SDK,意味著使用者們既可以從未加密的官網 HTTP 渠道下載,也可以安全地從 GitHub 上下載原始碼
  • 5 個 SDK沒有任何安全的下載方法,意味著他們或者對應的服務(如 GitHub)完全不支援 HTTPs
  • 31% 的 SDK 是極易被這類攻擊攻陷的目標
  • 5 個另外的 SDK 需要賬戶來下載(難道他們有什麼要隱藏的東西麼?)

我在 2017 年的 11 和 12 月通知了所有可能被攻擊影響的目標,在公開談論這件事之前給予他們兩個月的時間來解決這個問題。在這 13 個被影響的 SDK 中:

  • 1 個在三個工作日內解決了問題
  • 5 個在一個月內解決了問題
  • 7 個 SDK 在這篇博文被髮出時仍然保留著弱點

仍被該漏洞影響的 SDK 提供者們尚未對我的郵件做出迴應,或者僅僅回覆了“我們會去看一下它的”——它們都在使用量最高的前 50 個 SDK 中。

從 CocoaPods 中來看,有總計 4,800 個釋出版本被影響,來自 623 個 CocoaPods。我在本地對 Specs 目錄通過 grep -l -r '"http": "http://' * 得到的這些資料。

開源 vs 閉源

從上文的數字來看,如果你使用閉源的 SDK,那麼你很可能被攻擊波及到。更重要的是,當 SDK 是閉源的時候,你很難驗證依賴庫的完整性。如你所知,你應該總是利用版本控制檢查 Pods 目錄,來檢測其中的變化,審計你的依賴庫的更新。我所調查的開源 SDK 中,100% 都可以從 GitHub 中直接使用,意味著如果你使用 GitHub 的版本而不是提供者網站的版本,即使使用上文中那三個被影響的 SDK,你也不會受到影響。

基於上面的數字,可以很清楚的知道,你除了不能深入閉源 SDK 的原始碼之外,還會有比較高的被攻擊的風險。不僅僅是中間人攻擊,還包括:

  • 攻擊者獲取了 SDK 下載伺服器的許可權
  • 提供 SDK 的公司被滲透
  • 當地政府強制公司包含後門
  • 提供 SDK 的公司本身有不良意圖,幷包含了你不想要的追蹤以及程式碼

你應該對你傳送的程式碼負責! 你應該保證你沒有辜負使用者對你的信任,違背歐盟的資料保護法(GDPR),或通過病毒 SDK 偷取使用者的憑據。

總結

作為開發者,我們有責任僅將我們信任的程式碼傳送給客戶。現在最簡單的一種攻擊就是通過 SDK 病毒實現的。如果一個 SDK 是在 GitHub 上開源的,並通過 CocoaPods 安裝,那麼你還是很安全的。要特別注意繫結的二進位制閉原始碼或你不完全信任的 SDK。

由於這種攻擊的留下的痕跡很小,你很難發現你的程式碼被改變了。而使用開原始碼,我們作為開發者可以最好地保護自己,和我們的客戶。

參考我的 其它與隱私和安全相關的文獻.

鳴謝

特別感謝 Manu Wallner 為視訊提供的錄音。

特別感謝我的朋友們對於這篇文章的反饋: Jasdev Singh, Dave Schukin, Manu Wallner, Dominik Weber, Gilad, Nicolas Haunold 以及 Neel Rao.

除非在文章中特別提到,否則這些專案皆為我利用週末及晚上的時間來完成的業餘專案,與我所做的工作和僱主無關。


掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章