There is an HTML version of this document with screenshots at https://www.bamsoftware.com/sec/goagent-advisory.html. * GoAgent installs a root CA certificate with a known private key * Test page * Mitigation * How to remove the GoAgent certificate * Improper TLS validation makes GoAgent susceptible to man-in-the-middle attacks * Mitigation * GoAgent 导入公开ç§é’¥æ ¹è¯ä¹¦çš„问题 * æµ‹è¯•é¡µé¢ * 如何防æ¢é£Žé™© * å¦‚ä½•åˆ é™¤ GoAgent CA è¯ä¹¦ * GoAgent 没有进行æ£ç¡®çš„ TLS 验è¯ï¼Œå˜åœ¨ä¸é—´äººæ”»å‡»çš„风险 * 如何防æ¢é£Žé™© GoAgent (https://github.com/goagent/goagent) is a popular censorship circumvention tool that uses Google App Engine as a proxy to bypass China's Great Firewall. GoAgent has serious security flaws that put its users at risk of man-in-the-middle attacks. * At startup, GoAgent installs trusted root "GoAgent CA" certificate whose private key is publicly known. With this private key, anyone may impersonate a certificate authority to attack GoAgent users. The risk of this flaw exists even when not using GoAgent, if GoAgent has been used any time in the past. * Improper TLS validation, and a lack of validation by default, mean that the HTTPS tunnel used by GoAgent can be subverted by an active attacker. These flaws have been previously identified on GoAgent's issue tracker, but are not yet widely disclosed, especially among the non-Chinese community. https://code.google.com/p/goagent/issues/detail?id=11091 http://translate.google.com/translate?hl=en&ie=UTF8&sl=zh-CN&tl=en&u=http://code.google.com/p/goagent/issues/detail%3Fid%3D11091 https://code.google.com/p/goagent/issues/detail?id=8031 http://translate.google.com/translate?hl=en&ie=UTF8&sl=zh-CN&tl=en&u=http://code.google.com/p/goagent/issues/detail%3Fid%3D8031 == GoAgent installs a root CA certificate with a known private key == At startup, GoAgent installs a system-wide root CA certificate with a fixed and publicly known private key. Because the private key is known, anyone can impersonate the "GoAgent CA" and sign certificates for almost any web site. The trusted root CA certificate remains installed even after GoAgent is turned off or removed. Depending on the circumstances of GoAgent's installation, the certificate may also affect browsers other than the one used with GoAgent, and other users of the same computer. The root CA certificate that GoAgent installs has the fingerprints: 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 The file with "-----BEGIN RSA PRIVATE KEY-----" may be downloaded at this URL, along with the certificate for "GoAgent CA": https://github.com/goagent/goagent/blob/c4386808ea943e2ebed25f1e5264943354e3f9cb/local/CA.crt According to the version history, the key has been the same since June 2011 or earlier: https://github.com/goagent/goagent/blob/fa9959e577395e48a477fd5495afbc2363a51baa/local/CA.key GoAgent has two parts: a local proxy program, proxy.py, that runs on a user's computer, and a remote proxy program, gae.py, that runs on App Engine. https://github.com/goagent/goagent/blob/c4386808ea943e2ebed25f1e5264943354e3f9cb/local/proxy.py https://github.com/goagent/goagent/blob/c4386808ea943e2ebed25f1e5264943354e3f9cb/server/gae/gae.py Users upload a personal copy of gae.py to App Engine. The user's browser talks to proxy.py on localhost, and proxy.py talks to gae.py on App Engine. When run, GoAgent attempts to install the GoAgent CA certificate. The responsible function is CertUtil.import_ca: https://github.com/goagent/goagent/blob/c4386808ea943e2ebed25f1e5264943354e3f9cb/local/proxy.py#L337 The installation code is different for different operating systems, and varies as to what browsers and users it affects. In some cases it requires administrator privileges. On Windows, it calls the CertAddEncodedCertificateToStore function. On OS X, it runs the command 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" On Ubuntu, it copies the certificate file to /usr/local/share/ca-certificates and calls update-ca-certificates. On other varieties of GNU/Linux, it attempts to modify the NSS database with the command certutil -L -d sql:$HOME/.pki/nssdb | grep "GoAgent" || certutil -d sql:$HOME/.pki/nssdb -A -t "C,," -n "GoAgent" -i "<pwd>/CA.crt" The automatic installation is ineffective for Firefox, which has its own certificate store. GoAgent's installation guide and FAQ show how to import the certificate into Firefox manually. https://code.google.com/p/goagent/wiki/InstallGuide http://translate.google.com/translate?hl=en&ie=UTF8&sl=zh-CN&tl=en&u=http://code.google.com/p/goagent/wiki/InstallGuide https://code.google.com/p/goagent/wiki/FAQ http://translate.google.com/translate?hl=en&ie=UTF8&sl=zh-CN&tl=en&u=http://code.google.com/p/goagent/wiki/FAQ The GoAgent CA certificate is used to do a local (intentional) man-in-the-middle of HTTPS connections between the browser and proxy.py. GoAgent works by encoding HTTP requests received by proxy.py and sending them to gae.py, where gae.py makes the encoded request. gae.py then encodes the HTTP response and sends it back to proxy.py, where it is decoded and returned to the browser. In order for GoAgent to work with HTTPS sites, it needs to undo the encryption so that gae.py will know what URL to request. When proxy.py receives a CONNECT request (meaning an HTTPS site is requested), it generates and serves a fake certificate signed by the GoAgent CA. From the user's point of view, all HTTPS sites are verified by "GoAgent". In some browsers, certificate pinning prevents the GoAgent technique from working for a small number of sites. (A consequence of GoAgent's model is that HTTPS is not end-to-end. It is HTTPS between the user and App Engine, and HTTPS between App Engine and the web site, but App Engine gets to see the plaintext.) === Test page === To test whether you are affected by the GoAgent CA vulnerability, access this web page: https://goagent-cert-test.bamsoftware.com/ The web page uses a certificate signed by the GoAgent CA. If you are not vulnerable, your browser will display a certificate warning. If you are vulnerable, the web page will be shown with no warning. === Mitigation === GoAgent has the ability to regenerate CA.crt with a new, truly private key. Delete the file local/CA.crt and start GoAgent again. The new certificate and private key will be unique to your installation, and only those with access to your computer will be able to attack your HTTPS sessions. This patch file removes the CA.crt file from a GoAgent Git repository. Apply it with the command "git am 0001-Remove-static-CA.crt.patch". If you have a copy of the code that is not a Git repository, delete the file local/CA.crt manually. https://www.bamsoftware.com/sec/0001-Remove-static-CA.crt.patch If you have ever run GoAgent in the past, it is important to also remove the "GoAgent CA" certificate with SHA-1 fingerprint AB:70:2C:DF:18:EB:E8:B4:38:C5:28:69:CD:4A:5D:EF:48:B4:0E:33 from anywhere it might be installed. See the next section for how to do that on selected operating systems. === How to remove the GoAgent certificate === In Firefox, open the preferences, then go to Advanced, Certificates, View Certificates, Authorities, and select "GoAgent CA" in the list. Click the "Delete or Distrust..." button, then click OK. On Ubuntu, delete the file /usr/local/share/ca-certificates/GoAgent.crt and run the command update-ca-certificates --fresh On Windows, refer to these instructions: http://technet.microsoft.com/en-us/library/cc754841.aspx#BKMK_addlocal Follow the instructions under "Adding certificates to the Trusted Root Certification Authorities store for a local computer", but at step 8, right-click on "GoAgent CA" and select "Delete". A screenshot of the Windows Trusted Root Certification Authorities store with "GoAgent CA" selected On Mac OS X, open the application called Keychain Access. Click the lock to unlock it and enter your password. In the side panel, select "System" and "Certificates". Highlight "GoAgent CA" and press the delete key on the keyboard. Click the "Delete" button and enter your password again. == Improper TLS validation makes GoAgent susceptible to man-in-the-middle attacks == By default, GoAgent establishes an HTTPS tunnel between the local proxy.py and gae.py running on App Engine. (In the default proxy.ini configuration file, the default setting is gae.mode=https.) However by default, it does not validate the server's certificate (gae.validate=0), making possible an HTTPS man-in-the-middle attack between GoAgent and App Engine. Further, the gae.validate option also controls whether validation is done between App Engine and the remote web server, so that is disabled by default as well, enabling HTTPS man-in-the-middle between App Engine and the destination web site. Even when validation is enabled (gae.validate=1), the validation works differently than usual: It does not match against the remote hostname, but rather checks that the certificate's organizationName begins with "Google ". https://github.com/goagent/goagent/blob/c4386808ea943e2ebed25f1e5264943354e3f9cb/local/proxy.py#L1623 Setting gae.validate=1 causes gae.py to validate its HTTP transactions. Except that validation is not enabled by default, there doesn't appear to be a problem with the validation in gae.py. https://github.com/goagent/goagent/blob/c4386808ea943e2ebed25f1e5264943354e3f9cb/server/gae/gae.py#L184 GoAgent optionally obfuscates its encoded HTTP requests and responses by encrypting them with RC4 and a password-derived key. The obfuscation option is enabled by setting gae.password and gae.options=rc4 in the proxy.ini configuration file, as well as the __password__ variable in gae.py. https://github.com/goagent/goagent/blob/c4386808ea943e2ebed25f1e5264943354e3f9cb/server/gae/gae.py#L5 However, the RC4 encryption is intended only for obfuscation, and does not mitigate a man-in-the-middle attack. It offers no confidentiality, because the password is sent along with each ciphertext in a G-password header. Also, the same keystream is reused for all messages in both directions, making it possible to XOR ciphertexts and get the XOR of plaintexts. The RC4 feature prevents other users from trivially using up your App Engine bandwidth quota, but doesn't provide additional protection against a network adversary. === Mitigation === In the proxy.ini configuration file, make sure to set gae.mode=https (the default) and gae.validate=1 (not the default). These settings enable validation both between GoAgent and App Engine, and between App Engine and the remote web site. There remains a risk of man-in-the-middle by someone able to get a valid certificate with "Google " in the organizationName. ------------------------------------------------------------------------ GoAgent (https://github.com/goagent/goagent) 利用 Google App Engine (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 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.py,gae.py å®Œæˆæ”¶åˆ°çš„请求然åŽå°†ç»“果进行编ç åŽè¿”回给 proxy.pyï¼Œæœ€åŽ proxy.py 将结果转å‘ç»™æµè§ˆå™¨æ¥å®Œæˆ “翻墙†过 程。由于 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 能够看到请求和应ç”的明文。 === 测试页é¢=== 请访问 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 文件。 https://www.bamsoftware.com/sec/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...†按钮,然åŽç¡®è®¤ã€‚ 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"。 在 Mac OS X下,打开 “Keychain Access†应用,点击é”å›¾æ ‡å¹¶è¾“å…¥å¯†ç è§£é”。在 è¾¹ä¸Šçš„æŽ§åˆ¶é¢æ¿ä¸ï¼Œé€‰æ‹© "System" ä»¥åŠ "Certificates"ï¼Œé€‰ä¸ "GoAgent CA" ç„¶åŽæŒ‰ “Delete†键,点击 "Delete" æŒ‰é’®å¹¶è¾“å…¥ä½ çš„å¯†ç 确认。 == 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 ä¸é—´äººæ”»å‡»ã€‚