GoAgent的安全風險

jopen 10年前發布 | 16K 次閱讀 GoAgent

        GoAgent 利用 Google App Engine (GAE) 來實現安全上網,以免費、快速、穩定的特點深受網民的歡迎。但是,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:33MD5 Fingerprint=56:B1:20:86:1B:0A:B0:61:38:00:1B:C3:67:CF:0C:CC

        包含這一 “GoAgent CA” 證書以其私鑰(文件中 -----BEGIN RSA PRIVATE KEY----- 位置)的文件 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 采用了不同的方式存儲證書,這一自動安裝過程不會導入 GoAgent CA 證書到 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.pygae.py 完成收到的請求然后將結果進行編碼后返回給 proxy.py,最后 proxy.py 將結果轉發給瀏覽器來完成 “KX上網” 過程。由于 GAE 的限制 (免費 app 無法使用 socket 接口),對于 HTTPS 請求,proxy.py 無法進行透明轉發,只能作為中間人先和瀏覽器完成連接,然后獲得其中的明文請求以后在轉發給 gae.py。當收到 CONNECT 請求(這意味著瀏覽器正在瀏覽一個 HTTPS 網站), proxy.py 首 先利用 GoAgent CA 簽發一個假的證書來和瀏覽器完成握手,從用戶的角度,所有的 HTTPS 網站的證書都是由事先導入的 “GoAgent CA” 認證的,所以不會報警。有些瀏覽器會對少數網站的證書進行特別的檢查(Certificate Pinning),這種情況下 "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”, “View Certificates”, “Authorities”,然后在證書列表中找到 “GoAgent CA”,選中并點擊 “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 Authorities store for a local computer" 的步驟,但是在 step 8 時右鍵選中 "GoAgent CA" 然后選擇 "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 配置項同樣控制 App Engine 上的 gae.py 是否對網站服務器的證書進行驗證,默認配置下這一配置為 0 導致 gae.py 也不會對網站證書進行驗證,使得 gae.py 和網站之間的通信同樣存在 HTTPS 中間人攻擊的風險

        即使修改配置啟用證書驗證(gae.validate=1),GoAgent 對 App Engine 服務器證書的驗證也并不嚴格:在 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 Key Reuse),進而得到明文。在這里 RC4 只能起到防止其他 GoAgent 用戶共享服務端流量的目的,無法提供更多的保護來防止網絡攻擊。

        如何防止風險

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

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!