(新舊版)對gaeproxy的「https代理」功能之分析和說明

本文系轉載。是對gaeproxy安全性的分析,原文分為新版和舊版二篇文章,為了堵住閱讀方便,一起匯總至本文。

(新版)對gaeproxy的「https代理」功能之分析和說明

舊版地址如下,普通用戶無需閱讀
https://blog.williamgates.net/2013/02/gaeproxy-analysis-deprecated/

經過我舊版文章分析後,gaeproxy的作者Max Lv很誠懇和大度地在項目主頁和官方twitter帳號上解釋了「https代理」功能,並將本地址作為說明放在項目主頁上,故我將較為聳人聽聞的舊版移至另一地址,在本地址重做了一份簡單的說明。
對我的文章給作者帶來的一些誤解表示歉意。
再次聲明,我相信作者從未也永遠不會謀求竊取/篡改用戶數據,作者提供的該功能是基於善意,我個人只是指出整個流程中的一個安全風險,並希望所有用戶都有所了解之後自己選擇是否要使用

  gaeproxy是GoAgent在android上的客戶端,作者是Max Lv,goagent在google code頁面上將其作為android上使用goagent的解決方案來介紹。

  說明1:gaeproxy的「https代理」功能

  該功能實際上是將https的請求和回應通過作者提供的代理伺服器來進行代理,原理如下:
  沒有打開「https代理」功能時,所有的流量都通過goagent伺服器端,而goagent伺服器端是部署在google appengine(GAE)上的,在客戶和伺服器之間,只有google的伺服器存在,這個過程中只要你信任google的伺服器,就是相對安全的。如圖:
(新舊版)對gaeproxy的「https代理」功能之分析和說明

  打開「https代理」功能時,https流量(往往是敏感數據,不過會被加密,並非明文)會通過作者提供的伺服器代理,而不經過goagent的伺服器端,這時候如果有人攻破了作者提供的伺服器,在其上進行中間人欺騙,或者解密用戶與目的伺服器交換的數據(並非完全不可能),會給用戶造成無法估量的損失。如圖:
(新舊版)對gaeproxy的「https代理」功能之分析和說明

  說明2:風險所在

  如上文所述,典型的goagent架構全程只通過google所維護的伺服器來代理,雖然由於gae不支持https connect,所以在google的伺服器上https請求會被解碼並重編碼(我理解如此,未必正確),所以不管是PC還是android上訪問https網站,都需要導入證書。
  而gaeproxy作者提供的https代理不經過google的伺服器,而是經過作者自己提供並維護的伺服器,考量到人力物力上的差距,作者維護的伺服器在安全性上不如google的伺服器來得可信,這就是我們所擔心的。

  說明3:風險到底有多大

  實際上這種風險與你購買收費VPNSSH代理的風險是一樣的,甚至小於使用免費VPN、SSH的風險(包括著名的地下鐵),存在惡意的VPN和SSH提供商能夠給你帶來更大的損害。我只是提出了整個流程中的一種可能性,而且不滿於作者(當時)未明示這一事實而已。實際上我猜測是由於android設備上直接使用典型goagent模式時,https的性能比較差(我實測如此),所以作者才添加了「https代理」這一功能,並非出於惡意,相反自己花費了經費。
  實際上goagent的作者也承認,PC上典型的goagent架構也是不安全的,我們只是信任google的維護能力而已,並不是說goagent就是安全的。
  實際上翻牆的方法無非兩種,一種是通過各類代理,其中加入了一道甚至幾道伺服器後,信息被竊取/篡改的可能性顯然會增加;另一種是通過對網路協議的修改,如西廂計畫等小眾方案,由於需要使用別人編寫的軟體,一樣存在風險。沒有一種翻牆方式是不增加信息被竊取/篡改的風險的,只能說一定程度上降低了被GFW竊取/篡改的風險而已。

  總結:既然gaeproxy的作者明示了「https代理」功能的原理,我對這個軟體及其服務並無進一步的意見,我推薦大家繼續使用這個軟體。就我個人而言,我不會繼續使用「https代理」這個功能,但如果你選擇繼續使用,風險並沒有多麼可怕。

===================

(舊版)對gaeproxy的一些研究,兼談Geek的社會責任

新版地址如下,不需要深入了解的用戶請閱讀新版
https://blog.williamgates.net/2013/02/gaeproxy-analysis/

該文中描述的原理仍然有效,而gaeproxy的作者已經在項目主頁、官方twitter帳號上明確說明了存在這種情況,故「作者未對公眾說明」已經不存在了。
作者Max Lv在這件事上表現出來的誠懇和大度令人欽佩,且已經在項目主頁上放上了我原文的鏈接,所以特將原文移動至此,原地址僅放上我對原理的解釋,不再有較為激進的內容。
對我的文章給作者帶來的一些誤解表示歉意。

核心提示:gaeproxy的「https代理」功能是由作者自建伺服器提供,並非通過GAE轉發,打開這個選項就意味著所有的https請求都會通過第三方代理伺服器;由於種種原因,很多人實際上不能正常連接goagent伺服器端,但手機端看起來還可以使用,是因為這個「https代理」功能讓用戶通過私人VPS進行了代理訪問,而這些伺服器到底是誰擁有、誰運營、安全性如何,我們完全一無所知。這一切,都沒有在google code或google play頁面告知用戶。

  gaeproxy是goagent在android上的客戶端,作者是Max Lv,goagent在google code頁面上將其作為android上使用goagent的解決方案來介紹。使用這個軟體給我帶來了很多便利,但是不記得從什麼時候開始,不打開其中的「https代理」選項就無法訪問任何網站,打開該選項後也會有一些問題——比如G+客戶端不顯示圖片(根據後文,實際上這時候我已經無法連接GAE了)。那個時候我懶得進行深入的研究,也就沒有在意。
  從近期的某次升級開始,gaeproxy不再支持android 2.2系統,其項目主頁上建議2.2用戶使用0.19.1版。但是使用0.19.1版再也打不開「https代理」選項了,只要勾選這個選項就會一直提示gae代理啟用失敗;取消這個選項後,雖然顯示gae代理啟用成功,但任何網站(無論http還是https)都無法訪問,於是我就開始了我的研究之旅:

  1、尋找官方簽名版

  通過閱讀Issue 231,我了解到「所有第三方編譯版本都無法使用 Enable HTTPS Proxy 選項」,「打開此選項後,所有 HTTPS 流量將由遠程伺服器轉發」,為了避免中間人攻擊,gaeproxy會在啟用這個功能的時候驗証apk的簽名。
  於是我就想下載一個官方簽名版,我誤以為google code上的是自動編譯的版本,簽名不正確,所以提交Issue 476,希望作者提供一個簽名正確的版本,作者回應說:「官方版見 Downloads 頁面,另外 HTTPS 模式已不支持 2.2 系統了,請依照 Wiki 自行導入根證書」,這時候我對後半句還不明白(看下文你就明白了),前半句倒是聽懂了,google code上就是官方版,那為什麼我不能打開「https代理」呢?
  搜尋後發現,其實有不少所謂「漢化去廣告版」都自稱可以打開「https代理」功能,又看到這篇文章(需翻越觀看),了解到gaeproxy驗証簽名其實就是訪問一個頁面(https://auth-gaeproxy.rhcloud.com/auth.php)並提供基於時間戳和apk簽名的sig,我發現這個地址已經不能訪問了,而最新版代碼(github上gaeproxy/src/org/gaeproxy/GAEProxyService.java)里訪問的是https://myhosts.sinaapp.com/auth-4.php。看來作者在版本更新過程中放棄了容易被牆的rhcloud,換成了sinaapp。那能不能自己編譯一個版本,將代碼里寫死的rhcloud地址換成sinaapp的,再通過前面說的技巧騙過驗証呢?
  我嘗試向作者要一個修改驗証地址的0.19.1版本(Issue 477),作者回應說「抱歉,0.19.1 已不支持 HTTPS 代理。解決方案:1. 升級你的 ROM 到 2.3。2. 使用偽造證書的 HTTPS 模式。」這時我對「https代理」這個功能的含義發生了懷疑——難道不是「對https流量也進行代理」的意思?經過翻閱,我終於看到了Issue 433,了解到了兩個驚人的事實:
  (1)作者說「gaeproxy 的 https 代理有兩種模式,第一種是由本地偽造證書由GAE轉發的模式,第二種是由第三方伺服器透明轉發的模式。未開啟「HTTPS代理」選項時默認使用第一種方式。第二種方式屬於私有方式,由App中的置頂廣告所得提供伺服器資源。第二部分的伺服器代碼部署在SAE上,是出於可靠性考量,SAE 對於開源應用有資源支持,不涉及收費問題。關閉「HTTPS代理」選項後,即是由GAE轉發。」
  也就是說,「https代理」功能不是指「通過goagent代理https流量」,剛好相反,這個意思是「不通過goagent代理https流量」,而是通過第三方服務,這令人驚出一身冷汗——我們之所以信任goagent就是因為信任GAE,信任google,作者也說「所有 HTTPS 流量將由遠程伺服器轉發,通過惡意修改這部分的代碼可以輕鬆的獲得所有經由 HTTPS 傳輸的敏感信息」,那我們的https訪問原來一直是通過第三方代理的?作者從未明確告知過我們。
  (2)根據作者所說,那麼這個功能如果不打開,應該也能正常訪問http網站;通過導入證書,更應該能訪問https網站。但實際上不只是我,很多人不打開這個功能什麼網站都連接不上,也有很多人打開這個功能後圖片顯示不出來(http訪問不正常),也就說明很多人使用gaeproxy這個軟體,根本只是在用作者提供的第三方代理!

  2、尋找能正常連接GAE的版本

  了解了這些事實後,我再也不敢用「https代理」這個功能了,我導入了證書,只想用正常的goagent(我承認導入證書也有風險),但是無論什麼版本的gaeproxy都無法使用,軟體提示gae服務已啟用,系統log及SuperSU的log中也看出iptables被正確寫入,redsocks正確啟動,goagent的1984連線埠也正常打開,但就是無法連上GAE(應該是goagent客戶端出了問題),也就根本沒法訪問任何網站(見Issue 478)。我也更換了不同的goagent伺服器端,連古老的goagent1.8.11/gaeproxy0.16.7和goagent1.7.8/gaeproxy0.15.6這兩個搭配都試過,沒有一個能夠使用。
  經過翻看代碼的history,發現0.20.2的更新內容是「fix issues on Android 2.2」,奇怪,作者不是說0.19.1之後不再支持2.2么?而且0.20.1的更新還寫著「update to python 2.7.2 for new goagent」,作者稱python 不能用於android 2.2(未見別處有這種說法),0.20.2居然還能在android 2.2上運行?事實證明就是可以,python版本就是2.7,安裝後完全正常,可以訪問http/https網站。
  這一版到底修改了什麼產生了如此神奇的效果,看了代碼也沒明白。首先猜測是該軟體一定要通過某種驗証才能啟用基本的功能,但該版本的驗証地址雖然是sinaapp,但驗証頁面不對,所以也無法打開「https代理」功能,不過這個猜測至少能解釋老版本goagent伺服器端配老版本gaeproxy,當年能用現在卻不行這一問題;另一種猜測是另有寫死的地址(該作者在每一版代碼中都有諸多寫死的地址,甚至IP),但我簡單瀏覽了幾個版本的history,沒發現關鍵所在;還有一種猜測是goagent客戶端不使用python2.7就是不行,因為github上最早版本的goagent 1.7.8已經是python27環境了,但如果是這樣,gaeproxy豈不一直只是一個第三方https代理?應該不可能。所以,這個問題有待進一步研究,可能需要作者去分析了。

  3、「https代理」功能研究

  我雖然不敢再用這個功能,但還是進行了一下研究,發現gaeproxy的原理實際上是通過iptables將設備上所有的請求都經redsocks轉發,而redsocks在http流量上使用goagent生成的代理(1984連線埠),在https流量上,如果你不勾選「https代理」就仍然走1984,如果勾選的話會變成gaeproxy從sinaapp那個頁面取到的一個伺服器,53連線埠的代理,是美國的某VPS。通過顯示客戶地址的網頁(比如https://ip-lookup.net)也可以看出,打開「https代理」選項,我們的地址變成了一台VPS的地址(我測試到的是一個123systems的VPS,臭名昭著啊)。
  據此可以了解到,作者通過這個驗証頁面不僅想防止中間人攻擊,而且想防止他提供的免費代理被人濫用或者被封。實際上很好找——它就在redsocks.conf裡面,只要你有一台2.3以上版本的設備,安裝0.21.1版(0.21.2版在我的Nexus 10上無法使用,見Issue 479),連一次「https代理」就行了……經測試,也能用於無法打開該功能的舊版gaeproxy,但是我強烈建議不要這麼做,更不推薦將其用於gaeproxy以外的地方。

  從整個研究過程可以看出,作者其實很早就發現android設備上goagent的證書無法很好地被使用(即使導入了還有問題),而且在android上goagent對https的轉發性能也很不理想,所以他在0.10.2版本就引入了第三方服務,當時是用FreeSocksProxy.org;後來又改為了這種自建在VPS上的代理。其實我很驚訝53連線埠的代理能帶來這麼強勁的速度和承載能力——coolapk上約467750次下載,google play上100,000 – 500,000次下載,不知道作者到底用了多少伺服器來做這個「https代理」。
  我很佩服作者的這種公益精神和技術能力,但是從未在任何軟體介紹和項目頁面說明這一點,就顯得非常不恰當。從學生時代,不少Geek朋友就有這種理念——我們寫我們的,用戶都是傻x,只管用就好了。實際上我贊同用戶有權也應當是傻瓜,他們應該不用向我這樣研究一個軟體的代碼才能使用它,面對普通用戶的軟體應該是輕鬆易用的;但是這種輕鬆附隨了一個要求——用戶有選擇權。用戶雖然可以傻瓜地使用軟體,但有權在涉及自己切身利益——特別是隱私問題的時候有知情權和選擇權。
  獨立的軟體作者寫東西往往沒有金錢回報,研究問題也純屬興趣和公益心,但是只要你自認是Geek,那麼你就一樣有社會責任,這種責任不僅要求你做對社會有益的事情,而且要求你將這種「你自認為對社會有益的事情」公開出來,由社會監督;這種責任不僅要求你提供給用戶好的東西,還要求你允許用戶自行評判「你自認為好的東西」。這也是自由的要義——精神和意志上的自由才是真正的自由,受蒙蔽而使用免費的「自由軟體」,蒙蔽用戶而發布「自由軟體」,均非真正的自由。
  也許有人不同意,免費為你提供服務,你放下筷子還罵娘?殊不知信息權力已經成為一種真正可以影響社會的權力,比如google,它免費為世界提供Gmail服務,雖然我們沒有支付任何費用,但它有義務保障用戶的數據和隱私安全,而且有義務接受全世界各種眼光(包括駭客)的監督;比如國內的很多商業和半商業網站,明文存儲的密碼給無數人帶來了損失,正是因為信息權力不受監督所致——一方面是政府要求明文存儲密碼的權力,一方面是網站安全流程設計上的權力,均不受公眾監督。任何不受監督的權力必然導致腐敗,即使這種腐敗是一種極為特別的形式——掌握權力者本身甚至可能並未參與,但絕不意味著他可以置身世外。在開源領域,作者的代碼雖然已經公開,但仍有責任向公眾介紹軟體的機制,特別是涉及隱私、涉及代碼外黑箱的部分。
  在gaeproxy這個軟體的問題上,作者從未積極地向公眾介紹其「https代理」功能的原理,而且一直嚴重這一誤導性的名稱,並且在開源的代碼外架設有驗証伺服器、代理伺服器,這是多個黑箱,其中有一個留有陷阱就會讓數萬用戶產生不可估量的損失。即使作者本身不參與竊取隱私的行動,這種不透明的流程仍然可能被人破解及利用。實際上了解到這個軟體使用的第三方代理地址易如反掌,而一旦攻破這些VPS,獲取代理的log後就能得到不少有價值的隱私信息,如果進一步將這些代理伺服器用於中間人攻擊,後果不堪設想。
  即使我們無比相信開源軟體的作者,我們也無法相信不受監督的權力。請將自由還給自由軟體的用戶。

轉載自:https://blog.williamgates.net/2013/02/gaeproxy-analysis/
本文鏈接:(新舊版)對gaeproxy的「https代理」功能之分析和說明
美博園文章均為「原創 - 首發」,請尊重辛勞撰寫,轉載請以上面完整鏈接註明來源!
軟體著作權歸原作者!個別轉載文,本站會註明為轉載。

這裡是你留言評論的地方


請留言


7 + 0 =
【您可以使用 Ctrl+Enter 快速發送】
Copyright © 2007 - 2026 , Design by 美博園. 著作權所有. 若有著作權問題請留言通知本站管理員. 【回到頂部】