转: GoAgent 漏洞可能导致中间人攻击

2014/06/06

------------------------------

英文原文 http://seclists.org/fulldisclosure/2014/Jun/9。对少数句子词语和标点进行了调整。
———————————-
GoAgent 导入公开私钥的根证书的问题
·测试页面
·如何防范风险
·如何删除GoAgentCA证书

GoAgent没有进行正确的TLS验证,存在中间人攻击的风险

·如何防范风险

GoAgent(https://github.com/goagent/goagent)利用GoogleAppEngine(GAE)来代理上网的一个工具,深受网民的欢迎。但是,GoAgent的安装和配置中存在两点严重安全风险的问题却鲜为人知。这两点安全风险都可能被攻击者利用进行“中间人攻击(man-in-the-middleattack)”来窃取GoAgent用户的网络帐号密码等敏感信息,其概括描述如下:
- GoAgent在启动时会尝试自动往系统的可信根证书中导入一个名为“GoAgentCA”的证书。由于这个证书的私钥是公开的,导致任何人都可以利用这个私钥来伪造任意网站的证书,进行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网站时的证书报警,但在默认情况下所导入证书的私钥是公开的。因为私钥公开,任何人可以作为“GoAgentCA”来签发任何网站的证书。即使在GoAgent没有启动甚至卸载的情况下,这个公钥仍会遗留在系统中。在有些系统中,GoAgent所导入的根证书不仅被GoAgent默认使用的浏览器信任,其他的浏览器也可能会信任这一根证书,从而受到这一问题的影响。

GoAgent所导入的这一公开私钥根证书的指纹是:
SHA1Fingerprint=AB:70:2C:DF:18:EB:E8:B4:38:C5:28:69:CD:4A:5D:EF:48:B4:0E:33
MD5Fingerprint=56:B1:20:86:1B:0A:B0:61:38:00:1B:C3:67:CF:0C:CC
包含这一“GoAgentCA”证书以其私钥(文件中“—–BEGINRSAPRIVATE 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在启动时试图导入上述GoAgentCA证书。具体的代码为proxy.py中的CertUtil.import_ca:
https://github.com/goagent/goagent/blob/c4386808ea943e2ebed25f1e5264943354e3f9cb/local/proxy.py#L337

这个函数会根据用户操作系统通过不同的方式尝试导入证书,在某些情况下会需要
管理员(root/administrator)权限。在Windows下,这个函数会调用CertAddEncodedCertificateToStore这一API。在OSX下,会尝试执行系统命令
securityfind-certificate-a-c"GoAgent"|grep"GoAgent">/dev/null||securityadd-trusted-cert-d-rtrustRoot-k"/Library/Keychains/System.keychain""<pwd>/CA.crt"
在Ubuntu下,会拷贝证书文件到/usr/local/share/ca-certificates然后执行update-ca-certificates。在其他GNU/Linux发行版中,会尝试执行以下命令更改NSS数据库:
certutil-L-dsql:$HOME/.pki/nssdb|grep"GoAgent"||certutil-dsql:$HOME/.pki/nssdb-A-t"C,,"-n"GoAgent"-i"<pwd>/CA.crt"

由于Firefox采用了不同的方式存储证书,这一自动安装过程不会导入GoAgentCA证书到Firefox中。但是GoAgent的安装指南和FAQ中说明了如何手动导入这一证书:
https://code.google.com/p/goagent/wiki/InstallGuidehttps://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首先利用GoAgentCA签发一个假的证书来和浏览器完成握手,从用户的角度,所有的HTTPS网站的证书都是由事先导入的“GoAgentCA”认证的,所以不会报警。有些浏览器会对少数网站的证书进行特别的检查(CertificatePinning),这种情况下"GoAgentCA”所签发的证书可能会触发证书不安全的报警。GoAgent的这种工作方式导致HTTPS不再是浏览器到网站的端到端安全通信,而变成了proxy.py到GAE,以及GAE到网站两段独立的HTTPS连接,GAE能够看到请求和应答的明文。

测试页面

请访问https://goagent-cert-test.bamsoftware.com/来进行测试。这个页面使用了一个由GoAgentCA签发的证书。如果你的浏览器没有受到影响,会显示报警信息;如果没有看到报警,则表明你的浏览器导入了公开的GoAgentCA证书,存在严重安全风险。
如何防范风险

GoAgent本身带有生成证书文件CA.crt的功能。只需要删除local/CA.crt文件就能保证GoAgent所导入的证书是唯一的,不会被网络上的攻击者利用来进行攻击。

下面的“补丁(patch)”文件会帮助你从GoAgent的git仓库中删除CA.crt文件,请下载补丁文件并执行以下命令:
gitam0001-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
的“GoAgentCA”证书(建议使用浏览器访问上面的测试页面进行检查)。下面说明在常见系统中检查和删除GoAgentCA证书的方法。

如何删除GoAgentCA证书
Firefox中,打开“preferences”,”Advanced”,“Certificates”,“ViewCertificates”,“Authorities”,然后在证书列表中找到“GoAgentCA”,选中并点击“DeleteorDistrust…”按钮,然后确认。

Ubuntu下,删除/usr/local/share/ca-certificates/GoAgent.crt然后执行
update-ca-certificates--fresh

Windows下,请参考以下链接:
http://technet.microsoft.com/enus/library/cc754841.aspx#BKMK_addlocal
中"AddingcertificatestotheTrustedRootCertificationAuthoritiesstoreforalocalcomputer"的步骤,但是在step8时右键选中"GoAgentCA"然后选择"Delete"。

在MacOSX下,打开“KeychainAccess”应用,点击锁图标并输入密码解锁。在边上的控制面板中,选择"System"以及"Certificates",选中"GoAgentCA"然后按“Delete”键,点击"Delete"按钮并输入你的密码确认。
GoAgent没有进行正确的TLS验证,存在中间人攻击的风险

默认情况下,GoAgent会通过HTTPS来保护本地proxy.py和GAE服务器上的gae.py之间的通信(在配置文件proxy.ini中相关的设置默认为gae.mode=https)。但是同样在默认情况下,GoAgent不会要求对GAE服务器的证书进行验证(gae.validate=0),这导致本地proxy.py和AppEngine服务器之间的通信存在HTTPS中间人攻击的风险。此外,gae.validate配置项同样控制AppEngine上的gae.py是否对网站服务器的证书进行验证,默认配置下这一配置为0导致gae.py也不会对网站证书进行验证,使得gae.py和网站之间的通信同样存在HTTPS中间人攻击的风险。

即使修改配置启用证书验证(gae.validate=1),GoAgent对AppEngine服务器证书的验证也并不严格:在proxypy中只是对证书的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过的明文(见流密码的重用问题,StreamCipherKeyReuse),进而得到明文。在这里RC4只能起到防止其他GoAgent用户共享服务端流量的目的,无法提供更多的保护来防止网络攻击。

如何防范风险

确认在proxy.ini中设置了gae.mode=https(默认),并且启用了证书验证gae.validate=1(非默认)。这样的设定基本上能够防止proxy.py和GAE服务器,以及GAE服务器和网站服务器之间的HTTPS中间人攻击。由于proxy.py中没有对证书的主机名进行严格匹配,proxy.py和GAE服务器的通信仍存在(相对较小的)风险,如果有人能够申请到organizationName字段以“Google”开头的证书,仍然能够成功进行HTTPS中间人攻击。

如文中未特别声明转载请注明出自:FreebuF.COM

Related Posts