重要發現
- 微信有超過十億每月活躍使用者,我們分析了微信使用的主要網路協定 MMTLS 的安全和隱私特性,並發佈了首篇公開的研究報告。
- 我們發現 MMTLS 其實是修改自 TLS 1.3 協定,微信開發者修改了當中的密碼學機制,在部分修改當中引入了弱點。
- 進一步分析發現,早期的微信版本使用一個不同的、更不安全的自製協定,稱作「業務層加密」。業務層加密包含多個安全漏洞,在我們測試的新版微信當中,業務層加密與 MMTLS 同時被使用。
- 雖然我們並未發展出方法完全破解微信的網路加密,但其網路加密仍存在部分弱點,例如當中使用了決定性的初始向量 (Initialization Vector) ,以及欠缺向前保密特性 (forward secrecy) 。以一款擁有十億以上使用者的應用程式來說,其安全程度仍有待加強。
- 近期已有一些其他研究指出,中國市場中的應用程式經常不遵循密碼學界公認的最佳做法 (best practices),而選擇發展它們自行設計的加密系統,背離最佳做法的後果是,這些加密系統經常含有大小不一的漏洞。本研究為上述現象提出了更強烈的佐證。
- 我們在研究中開發使用的工具程式和技術方法文件,釋出於我們的 Github 儲存庫。這些工具程式和技術文件將會協助其他研究人員進一步探索微信程式系統內部的運作方式。
註:本摘要未翻譯所有研究發現,請閱讀我們的英文報告以得知研究發現的細節。本摘要僅翻譯了完整報告中的「探討」及「建議」章節。
探討
「業務層加密」為何重要?
既然我們已經在報告中提到,業務層加密外面會再包裹一層尚稱安全的 MMTLS 加密,那麼業務層加密即使不安全,又會有何實質影響?在騰訊回覆我們的信件中,主要提到的是業務層加密的各種問題,信件中也暗示了它們正在緩慢地將業務層加密中有問題的 AES-CBC 加密法汰換為 AES-GCM,此回覆顯示騰訊對業務層加密的問題有所顧慮。
首先,我們研究了舊版微信(v6.3.16, 2016 發佈),當時業務層加密是微信傳輸網路資料的唯一一層加密。第二,由於業務層加密將內部的請求網址暴露未加密,我們猜測微信設計的伺服器端架構中可能由不同內部伺服器端點來處理不同類型的網路請求(不同類型的網路請求含有不同的 “requestType” 數值,還有不同的 “cgi-bin” 網址)。舉例來說,微信的伺服器端架構可能由最外層的伺服器端點來解開 MMTLS 加密,再依照不同的請求類型將內層請求轉遞至負責的內層伺服器端點(轉遞時不再重新加密,僅仰賴業務層加密提供的安全性)。在這樣假設的架構下,若微信內部網路中存有網路竊聽者,它們將可以直接攻擊這些被轉遞請求所使用的業務層加密。
為何不直接使用 TLS?
根據騰訊自行公開的技術文件,以及我們研究的驗證,MMTLS(微信所使用的「外層」加密)主要是基於 TLS 1.3。該技術文件顯示 MMTLS 的設計者對於非對稱式加密法有良好的理解。
該技術文件闡述了不使用 TLS 的理由:因為微信大多數的網路資料傳輸只要在一次請求和回應循環中即可完成(中國業界術語稱「短連接」),因此特別需要底層協定的 0-RTT 特性。MMTLS 只需要一來一回的下層 TCP 封包建立 TCP 連線,即可馬上開始傳輸資料,相較之下,TLS 1.2 在 TCP 連線建立後需要再增加一來一回的 TLS 交互握手才能開始傳輸資料。
好在TLS1.3草案标准中提出了0-RTT(不额外增加网络延时)建立安全连接的方法,另外TLS协议本身通过版本号、CipherSuite、Extension机制提供了良好的可扩展性。但是,TLS1.3草案标准仍然在制定过程中,基于标准的实现更是遥遥无期,并且TLS1.3是一个对所有软件制定的一个通用协议,如果结合微信自己的特点,还有很大的优化空间。因此我们最终选择基于TLS1.3草案标准,设计实现我们自己的安全通信协议mmtls。
然而,即使在該文件撰寫當時的 2016 年,TLS 1.2 也已經提供會話恢復 (session resumption) 的功能。更有甚者,即使當時 TLS 1.3 在 IETF 協定制定流程中仍屬草案,若微信需要會話恢復的功能,因為微信對伺服器端和客戶端程式碼有完整的控制權,部署當時仍測試中的 TLS 1.3 實作並非難事。
儘管 MMTLS 設計者付出了大量努力,總合來看,微信所使用的安全協定在安全性和效能上均不如 TLS 1.3。一般情況下,設計一套既安全又有效率的傳輸協定並非易事。
傳輸協定為了進行交互握手而使用額外的封包來回造成延遲,長久以來都令應用程式開發者傷透腦筋。TCP 和 TLS 交互握手流程各自需要一次封包來回,意味著在傳輸任何新資料以前,協定需要等待兩次封包來回,造成延遲。今日,已有如 TLS-over-QUIC 等協定,結合了傳輸層和加密層的交互握手,僅需要一次封包來回即可完成握手開始傳輸資料。QUIC 提供了兩全其美的辦法,同時具備強固並且向前保密 (forward secret) 的加密,並且減半先前協定需要的連線建立封包來回時間。我們建議微信改用標準的 QUIC 協定。
最後,除了考量網路效能,客戶端應用程式的效能也是一重要課題。微信的協定設計中,每個網路請求都需要進行兩層加密,意味著相較於業界標準協定只需一次加密,微信客戶端應用程式需要花費接近雙倍的運算資源及時間。
中國應用程式自製加密法的趨勢
本研究的發現與我們早先的研究發現共同指出一項趨勢:中國應用程式廣泛地使用自製的加密法。一般狀況下,選擇不使用業界標竿的 TLS,並且發展自製非標準加密法,與業界公認安全的最佳做法背道而馳。儘管於 TLS 普及初期的 2011 年曾存在眾多讓 TLS 不值得信任的合理原因,例如 EFF 及 Access Now 對於憑證簽發機構生態系的疑慮,TLS 的發展在接下來已經大致穩定下來,機制變得更加透明且可稽核。
如同 MMTLS,我們過往研究過的所有自製協定相較於 TLS 都含有一些安全弱點,在部分情況下,甚至這些自製協定可以輕易地被網路攻擊者破解加密。全球的網際網路發展趨勢正逐步普及國際標準的 QUIC 及 TLS 以保護資料傳輸,中國業界反其道而行的趨勢為中國獨有,令人擔憂。
反域名劫持 (Anti-DNS-hijacking) 機制
類似於騰訊自行設計了加密系統的作法,我們發現在 Mars (微信所使用的網路通訊模組)中,他們也撰寫了一套特製的網域查詢系統。這個系統是 Mars STN 子模組的一部分,能夠透過 HTTP 以域名查詢得到 IP 位址。這個功能在 Mars 中被稱為「NewDNS」。根據我們的動態分析,這個功能在微信中經常被使用。乍看之下,NewDNS 重複了 DNS(域名系統)已經提供的相同功能,而 DNS 已經內建在幾乎所有連接網際網路的設備中。
在中國,使用類似系統的應用程式不只微信一家。中國的主要雲端運算供應商,如阿里巴巴雲和騰訊雲均提供自己的「透過 HTTP 查詢 DNS (DNS over HTTP)」服務。騰訊雲的 DNS over HTTP 服務端點 IP 位於 119.29.29.98,我們嘗試在 VirusTotal (線上的程式行為分析工具及樣本庫)中搜尋試圖聯繫此位址的應用程式,得到了 3,865 個獨特結果。
採用這種系統的一個可能原因是,中國的 ISP (網路服務供應商)經常對網路使用者實施 DNS 劫持,以插入廣告,並重導向網頁流量來進行廣告流量詐欺。此問題非常嚴重,以至於中國的六家網際網路巨頭在 2015 年發表了一份聯合聲明,敦促 ISP 進行改善。根據這篇新聞報導,美團(一個線上購物網站)約有 1-2% 的流量遭受 DNS 劫持。中國 ISP 的廣告流量詐欺問題近年來似乎仍然普遍存在。
與他們的 MMTLS 加密系統相似,騰訊的 NewDNS 網域查詢系統也是為了配合中國特殊的網路環境。多年來的經驗證明,DNS 本質上存在多種安全和隱私問題。我們在本研究中發現,微信的 MMTLS 比起 TLS 存在更多缺陷。然而,NewDNS 與 DNS 相比,是否也存在更多缺陷,仍然是一個未解的問題。我們期待未來針對此問題的研究。
使用微信網路模組 “Mars STN” 的其他應用程式
我們推測在微信以外,還有許多其他應用程式也使用了微信自行開發的網路通訊模組,稱作 “Mars”(STN 又為 Mars 的一部分)。這項推測是基於以下觀察:
- Mars 開源存放於 GitHub 的儲存庫中,Mars 的使用者(其他開發者)回報了眾多問題
- 有許多技術文章概述了如何使用 Mars 建立即時通訊系統
- 市面上已存在一個基於 Mars 開發的白牌即時通訊系統產品
開發者在微信之外採用 Mars 的情況令人擔憂,因為 Mars 預設不提供任何傳輸加密。正如我們在研究報告主文 “Three Parts of Mars” (Mars 的三個部分)段落所提到,在微信中使用的 MMTLS 加密是來自 mars-wechat(Mars 的三部分之一),而 mars-wechat 並非開放原始碼,意味著這一部分僅有騰訊能夠使用。除此之外,Mars 開發者也沒有計劃支援 TLS,若其他開發者要使用 Mars,Mars 開發者認為他們應該在上層自行設計實作加密。更糟的是,在 Mars 的框架中實作 TLS 似乎需要大幅更動架構。儘管騰訊維持 MMTLS 閉源的作法無可厚非,但 MMTLS 仍是 Mars 框架主要配合的加密系統,維持 MMTLS 閉源,不給外部開發者的作法使得其他使用 Mars 的外部開發者必須投入大量資源來另行整合其他加密系統,或者讓所有資料傳輸都不加密。
另一方面,Mars 也缺乏技術說明文件。官方 wiki 只包含幾篇舊文章,說明如何整合 Mars 到應用程式當中。因為缺乏說明文件,許多使用 Mars 的開發者都會在 GitHub 上提出問題,同時也讓開發者更容易犯下技術錯誤,造成整體安全性降低。
這方面需要進一步的研究,以分析使用騰訊 Mars 程式庫的其他應用程式的安全性。
動態程式載入模組 “Tinker”
在本節中,我們暫且稱呼「從 Google Play 商店下載的 APK」為 “WeChat APK”,而稱呼「從微信官方網站下載的 APK」為 “Weixin APK”。WeChat 和 Weixin 的區別似乎很模糊。WeChat APK 和 Weixin APK 所包含的程式碼略有不同,我們稍後會在本節中討論。然而,將這兩個 APK 安裝到系統語系設為英文的 Android 模擬器時(此二 APK 不能同時安裝,因此必須分次),它們的應用程式名稱都顯示為 “WeChat”。它們的應用程式 ID(Android 系統和 Google Play 商店用來識別應用程式的名稱)也都是 “com.tencent.mm”。我們也都能夠使用這兩個 APK 登入我們的美國號碼帳戶。
與 WeChat APK 不同的是,我們發現 Weixin APK 包含一個稱為 “Tinker” 的程式庫,根據 Tinker 的技術文件,它是一個「熱修復解決方案」。Tinker 讓開發者在不呼叫 Android 系統 APK 安裝程式的情況下,仍能安裝應用程式更新,這是透過一種稱為「動態程式碼載入」的技術來達成的。我們在之前的研究中也有發現 TikTok 與抖音有類似的區別:抖音有類似的動態程式碼載入功能,而 TikTok 則沒有。動態程式碼載入技術存有三個常見疑慮:
- 如果下載和載入動態程式碼的流程未能充分驗證下載的程式碼 (例如:該程式碼是以正確的公開金鑰數位簽名、並未過期,以及該程式碼乃是正確的模組,而非只是具有正確簽名且未過期的任意程式碼),攻擊者可能會利用此流程在裝置上執行惡意程式碼 (例如透過下列方法:注入任意程式碼、執行降級攻擊或注入新版但含有漏洞的程式碼)。早在 2016 年,我們就在其他中國應用程式中發現這類情況。
- 即使程式碼下載與載入機制不存在任何弱點,動態程式碼載入技術仍可讓應用程式在不通知使用者的情況下載入程式碼,此作法繞過了使用者的同意權,使用者應有權決定哪些程式可在其裝置上執行。舉例來說,開發者可能會推送使用者不想要的更新,而使用者無法選擇繼續使用舊版本。 此外,開發者也可能選擇性地針對特定使用者推送會危害其安全或隱私的更新。2016 年,一位中國安全分析師指控阿里巴巴向支付寶推送動態載入的程式碼,在他的設備上偷偷拍照和錄音。
- 動態載入的程式碼不需要透過應用程式商店即可安裝在使用者的裝置上,如此一來應用程式商店就無法檢核應用程式的所有程式行為,確保其安全。因此,Google Play 開發者政策不允許應用程式使用動態載入程式碼。
分析 WeChat APK 時,我們發現它仍保留了 Tinker 的某些元件。WeChat APK 保有處理下載應用程式更新的元件,但 Tinker 的核心,也就是負責動態載入並執行程式碼的組件,已被不執行任何動作的 “no-op” 函式取代。我們並未分析來自其他第三方應用程式商店的微信軟體包。
分析 Tinker 應用程式更新流程的安全性、其他來源的 WeChat APK 是否包含動態程式碼載入功能,以及 Wechat APK 與 Weixin APK 之間的其他差異,還需要進一步的研究。
建議
此小節中我們根據研究發現對不同讀者提供建議。
給應用程式開發者
相對於使用廣泛驗證的標準加密法,設計與實作自製的加密法不僅更昂貴、效能更差,而且也更不安全。應用程式經常需要傳輸敏感資料,我們建議應用程式開發者使用身經百戰的加密法組合和協定,避免自行開發加密協定。SSL/TLS 過去近三十年間已經過一次又一次的公眾及學術檢驗,並納入了各式各樣的功能改進。TLS 在現今已比過去更容易於設定和部署,新發展的基於 QUIC 的 TLS 協定也將大幅改善效能。
給騰訊及微信開發者
以下是我們在安全漏洞揭露信件中提供給微信和騰訊的建議:
在這篇 2016 年的文章中,微信開發人員指出,他們希望升級加密,但若使用 TLS 1.2 握手則會額外增加一次封包來回,將顯著降低微信的網路效能,因為微信使用大量的簡短訊息進行通訊。當時 TLS 1.3 尚未成為 RFC(雖然 TLS 1.2 已經有會話恢復的擴充功能),因此他們選擇「閉門造車」,將 TLS 1.3 的會話恢復模型納入 MMTLS。
對所有應用程式開發者來說,這個為連線握手執行額外封包來回的問題存在已久。TCP 和 TLS 的握手各需要一次往返,這意味著每個全新傳送的資料封包就需要兩次往返。如今,TLS-over-QUIC 結合了傳輸層和加密層的握手,只需要單次握手。QUIC 就是為了這個明確的目的而開發的,它既能提供強大的前向保密加密,又能將安全通訊所需的封包往返次數減半。我們也注意到,微信似乎已將 QUIC 用於一些大型檔案的下載。我們的建議是讓微信完全轉換為標準 TLS 或 QUIC+TLS 實作。
除了網路效能外,還有客戶端效能的問題。由於微信的加密方案會對每個請求執行兩層加密,因此相較通用標準中的加密系統僅需一次加密,微信客戶端程式要執行雙倍的工作來加密資料。
給作業系統
在網頁生態系中,客戶端瀏覽器會在未使用 HTTPS 的時候顯示安全警告,搜尋引擎會使用 HTTPS 支援與否作為排序網頁的依據,此二作法推進了 TLS 的廣泛普及。以此為鑑,我們可以將這些作法大致地比照辦理至手機作業系統和應用程式商店,以推進 TLS 在手機應用程式生態系中的普及。
是否有任何平台或作業系統層級的權限機制設計可以顯示應用程式使用了標準的網路加密法?我們在先前研究中文輸入法中的自製加密法的時候,曾提到作業系統設計者可以考慮加入一警告機制,在應用程式未使用標準網路加密法的程式介面,卻直接使用底層系統的網路系統呼叫的時候,顯示警告。
給有隱私疑慮的高風險使用者
許多微信 / WeChat 用戶使用微信是出於需要而非選擇。對於有隱私權疑慮,但基於需要而使用微信的用戶,我們在上一份報告中的建議仍然適用:
- 盡可能避免使用被界定為「微信」服務的功能(盡量只使用國際版 WeChat 所提供的功能)。我們注意到,隱私權政策中規定的許多核心「微信」服務(如搜尋、頻道、小程序)比核心 “WeChat” 服務進行更多的追蹤。
- 在可能的情況下,請選擇網頁或專屬應用程式,而非小程序或其他此類嵌入式功能。
- 套用更嚴格的裝置權限設定,並定期更新軟體和作業系統,以獲得最新安全功能。
對於中國用戶來說,我們建議盡可能改用非中國 (+86) 的手機號碼註冊使用 WeChat。但我們理解中國帳戶中所提供的必備功能在非中國帳戶中可能並未提供,此狀況下可以考慮使用兩隻手機將存有隱私和安全風險的應用程式與較無隱私和安全風險的應用程式分開使用。
此外,由於從官方網站下載的微信存在動態程式碼載入所帶來的風險,我們建議用戶盡可能改從 Google Play 商店下載微信。對於已經從官網安裝了微信的用戶,移除並重新安裝 Google Play 商店版本也可以降低前述風險。
給安全和隱私研究人員
由於微信擁有超過十億的使用者,我們假設全球 MMTLS 使用者的數量級與全球 TLS 使用者的數量級相近。儘管如此,對 MMTLS 的公開分析或查核卻少之又少,與 TLS 的狀況相反。在這樣的影響規模下,MMTLS 應該受到與 TLS 類似程度的公開稽核。我們懇請未來的安全和隱私研究人員在本研究的基礎上繼續研究 MMTLS 協定,因為從我們的通信中得知,騰訊堅持在微信中繼續使用和開發 MMTLS。