***軟件 GoAgent 的安全爲問題分析

GoAgent 利用 Google AppEngine (GAE) 來繞過 GFW的封鎖,以免費、快速、穩定的特點深受網民的歡迎。但是,GoAgent的安裝和配置中存在兩點嚴重安全風險的問題卻鮮爲人知。這兩點安全風險都可能被***者利用進行“中間人***(man-in-the-middle attack)” 來竊取 GoAgent用戶的網絡帳號密碼等敏感信息,其概括描述如下:

GoAgent 在啓動時會嘗試自動往系統的可信根證書中導入一個名爲 “GoAgent CA”的證書。由於這個證書的私鑰是公開的,導致任何人都可以利用這個私鑰來僞造任意網站的證書進行HTTPS 中間人***。即使在不開啓 GoAgent時,這種***的風險仍然存在。換而言之,一旦這個證書被導入,***者可以用此繞過幾乎所有網站的 HTTPS 保護。 GoAgent 本身對 TLS證書的認證存在問題,而且默認時不對證書進行檢查,這導致在使用 GoAgent時存在 HTTPS 中間人***的風險。

事實上曾經有用戶在 GoAgent主頁上的問題跟蹤列表中指出了這兩個安全問題(見以下鏈接),但既沒有修復也沒有廣泛公開,多數用戶,尤其是非中文用戶可能並不知情。下面是這兩個問題的詳細解釋。

https://code.google.com/p/goagent/issues/detail?id=11091

https://code.google.com/p/goagent/issues/detail?id=8031 GoAgent

導入公開私鑰根證書的問題

GoAgent 在啓動時會嘗試在系統中導入一個根證書來避免訪問 HTTPS網站時的證書報警,但在默認情況下所導入證書的私鑰是公開的。因爲私鑰公開,任何人可以作爲“GoAgent CA” 來簽發任何網站的證書。即使在 GoAgent沒有啓動甚至卸載的情況下,這個公鑰仍會遺留在系統中。在有些系統中,GoAgent所導入的根證書不僅被 GoAgent默認使用的瀏覽器信任,其他的瀏覽器也可能會信任這一根證書,從而受到這一問題的影響。

GoAgent 所導入的這一公開私鑰根證書的指紋是:

SHA1 Fingerprint=AB:70:2C:DF:18:EB:E8:B4:38:C5:28:69:CD:4A:5D:EF:48:B4:0E:33 MD5 Fingerprint=56:B1:20:86:1B:0A:B0:61:38:00:1B:C3:67:CF:0C:CC

包含這一 “GoAgent CA” 證書以其私鑰(文件中 -----BEGIN RSA PRIVATEKEY----- 位置)的文件 URL 爲:

https://github.com/goagent/goagent/blob/c4386808ea943e2ebed25f1e5264943354e3f9cb/local/CA.crt

根據版本信息,這一證書和私鑰從 2011 年 6月甚至更早的時間以來一直保持不變。

https://github.com/goagent/goagent/blob/fa9959e577395e48a477fd5495afbc2363a51baa/local/CA.key

GoAgent 主要包含兩個部分:一個在用戶計算機上運行的本地代理程序proxy.py,以及一個在 GAE 上運行的遠程代理程序gae.py。

https://github.com/goagent/goagent/blob/c4386808ea943e2ebed25f1e5264943354e3f9cb/local/proxy.py

https://github.com/goagent/goagent/blob/c4386808ea943e2ebed25f1e5264943354e3f9cb/server/gae/gae.py

安裝時,用戶需要上傳 gae.py 到 GAE。用戶瀏覽器通過設置一個本地代理將 HTTP/HTTPS 請求轉發到proxy.py,再由 proxy.py 和 gae.py進行通信。

默認情況下,GoAgent 在啓動時試圖導入上述 GoAgent CA 證書。具體的代碼爲proxy.py 中的 CertUtil.import_ca:

https://github.com/goagent/goagent/blob/c4386808ea943e2ebed25f1e5264943354e3f9cb/local/proxy.py#L337

這個函數會根據用戶操作系統通過不同的方式嘗試導入證書,在某些情況下會需要管理員(root/administrator)權限。在 Windows 下,這個函數會調用CertAddEncodedCertificateToStore 這一 API。在 OS X下,會嘗試執行系統命令

security find-certificate -a -c "GoAgent" | grep "GoAgent" >/dev/null || security add-trusted-cert -d -r trustRoot -k "/Library/Keychains/System.keychain" "pwd/CA.crt"

在 Ubuntu 下,會拷貝證書文件到/usr/local/share/ca-certificates 然後執行update-ca-certificates。在其他 GNU/Linux發行版中,會嘗試執行以下命令更改 NSS 數據庫:

certutil -L -d sql:$HOME/.pki/nssdb | grep "GoAgent" || certutil -d sql:$HOME/.pki/nssdb -A -t "C,," -n "GoAgent" -i "pwd/CA.crt"

由於 Firefox 採用了不同的方式存儲證書,這一自動安裝過程不會導入 GoAgentCA 證書到 Firefox 中。但是 GoAgent 的安裝指南和 FAQ中說明了如何手動導入這一證書:

https://code.google.com/p/goagent/wiki/InstallGuide

https://code.google.com/p/goagent/wiki/FAQ

這一證書隨後被 proxy.py 用來作爲 HTTPS中間人來避免瀏覽器在訪問 HTTPS 網站時出現報警。GoAgent的工作原理如下:首先 proxy.py 將瀏覽器的 HTTP請求進行編碼並轉發給 gae.py,gae.py完成收到的請求然後將結果進行編碼後返回給 proxy.py,最後proxy.py 將結果轉發給瀏覽器來完成 “***” 過程。由於 GAE 的限制 (免費 app 無法使用 socket 接口),對於 HTTPS請求,proxy.py無法進行透明轉發,只能作爲中間人先和瀏覽器完成連接,然後獲得其中的明文請求以後在轉發給gae.py。當收到 CONNECT請求(這意味着瀏覽器正在瀏覽一個 HTTPS 網站), proxy.py首先利用 GoAgent CA簽發一個假的證書來和瀏覽器完成握手,從用戶的角度,所有的 HTTPS網站的證書都是由事先導入的 “GoAgent CA”認證的,所以不會報警。有些瀏覽器會對少數網站的證書進行特別的檢查(CertificatePinning),這種情況下 "GoAgent CA”所簽發的證書可能會觸發證書不安全的報警。GoAgent 的這種工作方式導致 HTTPS不再是瀏覽器到網站的端到端安全通信,而變成了 proxy.py 到GAE,以及 GAE 到網站兩段獨立的 HTTPS 連接,GAE能夠看到請求和應答的明文。

***軟件 GoAgent 安全問題

***軟件 GoAgent 安全問題

測試頁面

請訪問

https://goagent-cert-test.bamsoftware.com/

來進行測試。這個頁面使用了一個由 GoAgent CA簽發的證書。如果你的瀏覽器沒有受到影響,會顯示報警信息;如果沒有看到報警,則表明你的瀏覽器導入了公開的GoAgent CA 證書,存在嚴重安全風險。

如何防止風險

GoAgent 本身帶有生成證書文件 CA.crt 的功能。只需要刪除 local/CA.crt文件就能保證 GoAgent所導入的證書是唯一的,不會被網絡上的***者利用來進行***。

下面的 “補丁(patch)” 文件會幫助你從 GoAgent 的 git 倉庫中刪除 CA.crt 文件,請下載補丁文件並執行以下命令:git am 0001-Remove-static-CA.crt.patch.如果你不是通過 git 獲得 GoAgent(例如直接從 http://code.google.com/p/goagent/ 上的鏈接下載得到),請手動刪除 local/CA.crt 文件。

0001-Remove-static-CA.crt.patch

如果你以前曾經使用過 GoAgent,務必要檢查系統中任何可能的地方,刪除 SHA-1指紋爲AB:70:2C:DF:18:EB:E8:B4:38:C5:28:69:CD:4A:5D:EF:48:B4:0E:33的 “GoAgent CA”證書(建議使用瀏覽器訪問上面的測試頁面進行檢查)。下面說明在常見系統中檢查和刪除GoAgent CA 證書的方法。

如何刪除 GoAgent CA 證書

Firefox 中,打開 “preferences”,”Advanced”, “Certificates”, “ViewCertificates”, “Authorities”,然後在證書列表中找到 “GoAgentCA”,選中並點擊 “Delete or Distrust...” 按鈕,然後確認。

***軟件 GoAgent 安全問題

Ubuntu 下,刪除/usr/local/share/ca-certificates/GoAgent.crt 然後執行

update-ca-certificates --fresh

Windows 下,請參考以下鏈接:

http://technet.microsoft.com/en-us/library/cc754841.aspx#BKMK_addlocal

中 "Adding certificates to the Trusted Root Certification Authoritiesstore for a local computer" 的步驟,但是在 step 8 時右鍵選中 "GoAgentCA" 然後選擇 "Delete"。

***軟件 GoAgent 安全問題

在 Mac OS X下,打開 “Keychain Access”應用,點擊鎖圖標並輸入密碼解鎖。在邊上的控制面板中,選擇 "System" 以及"Certificates",選中 "GoAgent CA" 然後按 “Delete” 鍵,點擊 "Delete"按鈕並輸入你的密碼確認。

***軟件 GoAgent 安全問題

GoAgent 沒有進行正確的 TLS 驗證,存在中間人***的風險

默認情況下,GoAgent 會通過 HTTPS 來保護本地 proxy.py 和 GAE 服務器上的 gae.py 之間的通信 (在配置文件proxy.ini 中相關的設置默認爲gae.mode=https)。但是同樣在默認情況下,GoAgent 不會要求對GAE 服務器的證書進行驗證(gae.validate=0),這導致本地proxy.py 和 App Engine 服務器之間的通信存在 HTTPS中間人***的風險。此外, gae.validate 配置項同樣控制 AppEngine 上的 gae.py是否對網站服務器的證書進行驗證,默認配置下這一配置爲 0 導致gae.py 也不會對網站證書進行驗證,使得 gae.py和網站之間的通信同樣存在 HTTPS 中間人***的風險

即使修改配置啓用證書驗證(gae.validate=1),GoAgent 對 AppEngine 服務器證書的驗證也並不嚴格:在 proxy.py中只是對證書的 organizationName 進行了粗略的檢查(是否爲 “Google ”開頭),而沒有對主機名(hostname)進行匹配。

https://github.com/goagent/goagent/blob/c4386808ea943e2ebed25f1e5264943354e3f9cb/local/proxy.py#L1623

將配置改爲 gae.validate=1 同時會啓用 gae.py段對網站服務器證書的驗證,這部分的事先沒有明顯的問題。

https://github.com/goagent/goagent/blob/c4386808ea943e2ebed25f1e5264943354e3f9cb/server/gae/gae.py#L184

GoAgent 還提供了一個可選功能,通過 RC4 和一個共享密鑰來對proxy.py 和 gae.py之間的數據進行進一步的混淆。啓用這一功能需要在 proxy.ini中設置 gae.password,以及 gae.options=rc4,並在gae.py 中設置 __password__ 變量。

https://github.com/goagent/goagent/blob/c4386808ea943e2ebed25f1e5264943354e3f9cb/server/gae/gae.py#L5

但是,這裏的 RC4 加密只能起到一個簡單的混淆作用,無法在不啓用 HTTPS的情況下利用這一功能來防止中間人***。GoAgent 中的 RC4無法實現數據的機密性,因爲密碼本身會通過一個 G-password頭在 proxy.py 和 gae.py中傳送,而且在兩段通信中會使用同樣的密碼流(keystream),導致***者很容易通過密文的XOR 操作來獲得 XOR 過的明文(見流密碼的重用問題,Stream Cipher KeyReuse),進而得到明文。在這裏 RC4 只能起到防止其他 GoAgent用戶共享服務端流量的目的,無法提供更多的保護來防止網絡***。

如何防止風險

確認在 proxy.ini 中設置了 gae.mode=https(默認),並且啓用了證書驗證gae.validate=1(非默認)。這樣的設定基本上能夠防止proxy.py 和 GAE 服務器,以及 GAE 服務器和網站服務器之間的HTTPS 中間人***。由於 proxy.py中沒有對證書的主機名進行嚴格匹配,proxy.py 和 GAE 服務器的通信仍存在(相對較小的)風險,如果有人能夠申請到 organizationName字段以 “Google ” 開頭的證書,仍然能夠成功進行HTTPS 中間人***。

更多交流請到青互聯博客www.qing.es


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章