这些 SSL 证书验证漏洞的潜在影响是什么?

信息安全 tls 证书
2021-08-23 12:35:51

我刚刚通读了 Georgiev 等人的这篇论文,它展示了各种非浏览器软件、库和中间件中 SSL 证书验证的广泛严重安全漏洞,包括 EC2 的 Java 库、PayPal 的商家库、osCommerce、ZenCart 等.

摘要令人印象深刻:

我们证明 SSL 证书验证在许多安全关键的应用程序和库中完全被破坏。易受攻击的软件包括亚马逊的 EC2 Java 库和所有基于它的云客户端;亚马逊和 PayPal 的商家 SDK,负责将支付细节从电子商务网站传输到支付网关;osCommerce、ZenCart、Ubercart、PrestaShop等集成购物车;移动网站使用的 AdMob 代码;Chase 手机银行和其他几个 Android 应用程序和库;Java Web 服务中间件——包括 Apache Axis、Axis 2、Codehaus XFire 和适用于 Android 的 Pusher 库——以及使用该中间件的所有应用程序。来自任何这些程序的任何 SSL 连接对于中间人攻击都是不安全的。

据我所知,如果故障和提议的攻击是现实的,那么后果将是深远的,而且相当令人不安。

我不会假装完全理解他们发起的攻击背后的理论,这就是我问这个问题的原因——这里真正的潜在影响是什么?是否存在真正的严重风险,或者所有这些都是 FUD 的练习?

4个回答

文章中列出的所有攻击都是真实的、严重的,它们都符合相同的通用模式:服务器的证书没有经过适当的验证,即验证属于相关 标准中指定的目标服务器。

这是 SSL 的缺陷吗?不,协议本身很好。如果知道正确的、真正的服务器公钥,那么 SSL 隧道机制就满足了它所期望的安全特性(前提是实现是正确的并且使用了不太旧的版本,这意味着 TLS 1.1 或更高版本 - - 看到这个答案)。

这是 X.509 的缺陷吗?是还是不是。众所周知, X.509很复杂。事实上,认证的整个概念很复杂,X.509 试图预先处理它。通过可疑技术选择的悠久历史(让我说“UTCTime”和“TeletexString”——如果你不知道这意味着什么,那么相信我,你会更快乐),X.509 可能会使复杂性更高。但是,正确地执行PKI本身就有些困难。这不是新信息;看看 1999 年初的一个以前的版本,超过 13 年前:它已经显示了所有棘手的元素(特别是撤销检查)。

这是 SSL 库中的缺陷吗?在某种程度上,是的。文章作者指出,这些库文档不足,默认值很容易受到攻击,API 也很糟糕。他们是完全正确的。很难正确使用这些库,除非您已经对SSL 的工作原理有了一些精确的概念。

是共同开发模式的缺陷吗?确实。我们经常说:“不要发明或实施自己的加密货币!使用现有的库。” 意图是好的,但还远远不够。安全架构设计很难。制作一个安全的应用程序需要大量的专业知识,并且从结构层面开始。不幸的是,具有安全意识的开发人员是极少数。对于绝大多数开发人员来说,安全的应用程序设计是一个陌生的概念。值得注意的是,就软件开发而言,安全设计是倒退的:大多数开发人员专注于让正常的事情在正常条件下发生,而安全性则专注于避免在异常条件下发生坏事(恶意异常,而不仅仅是统计上的坏事)运气)。

要求将架构设计保留给安全专家这是不切实际的(不过,它可以保证我从失业到死亡)。据我所知,没有已知的解决方案——它类似于生产无错误的软件,但附加的问题是,安全性是关于积极尝试触发错误的对手。有些人主张让开发商对安全漏洞负法律责任事实上,如果软件行业中的“隐藏缺陷”得到与汽车行业相同的处理方式,那么错误就会少得多——软件也会少得多。

其影响是在此类系统上可能会发生中间人攻击。对于“MitM 真的存在严重风险吗?”这个问题的答案。看:

如果没有 SSL,那么 MITM 非 SSL 的 HTTP 需要什么优势?

“中间人”攻击极其罕见吗?

TL;DR:是的,这是一个“真正的严重风险”。

可以使用伪造的开放 WiFi 服务来设置典型的攻击。我想说,当人们坐在酒吧或任何类似的情况下,他们会尝试连接到他们可以找到的开放 WiFi 网络,这是非常现实的。

尤其是在移动设备上,警告消息似乎比桌面软件上的更加晦涩难懂(此外,在酒吧中,用户血液中的少量酒精可能会促使警告更加被忽略)。假设某些应用程序可能会定期轮询其服务器也是相当现实的,即使设备在用户的口袋里:编程不当的应用程序很可能会以这种方式泄露凭据或其他信息。

BBC 新闻最近的一篇文章( Android 应用程序“泄露”个人详细信息指出了这篇论文:为什么 Eve 和 Mallory 喜欢 Android:Android SSL (In)Security 的分析

以这种方式指责 Android 听起来有点危言耸听,但不幸的是,它确实反映了许多应用程序的状态。Android 的情况可能来自 Java 传统,默认情况下不进行主机名验证,如果您直接使用SSLSocket.

iOS 家族的情况可能会好一些,因为苹果似乎拒绝了禁用证书验证的应用程序(我对此没有任何个人经验)。不过,我不确定是否允许匿名密码套件,这可能与此类拒绝政策不一致。

我认为开发人员倾向于认为证书很复杂,也许不是每个人,但至少有相当数量的开发人员。诚然,证书处理起来有点麻烦,但如果你妥善管理它们的使用,为开发设置测试 CA 并不比为单元测试设置其他形式的虚拟数据难多少(让我们只是假设您在测试环境中不需要 CRL/OCSP,尽管理想情况下您也需要)。

您是否想责怪图书馆或开发人员是有争议的。

并非所有库都是平等的,也并非所有库都针对相同类别的用户/开发人员。

SSL/TLS 堆栈默认不验证主机名的一大原因是主机名验证机制取决于顶部使用的应用程序协议最常见的一种当然是 HTTPS(RFC 2818,第 3.1 节)。这通常被用作不在那里实施主机名验证的原因。不过情况正在发生变化:RFC 6125尝试在所有协议中统一主机名验证方法。它尚未广泛实施,但无论如何它与 HTTPS 行为并没有太大区别。此外,Java 7 现在有一种使用特定SSLParameters(启用X509ExtendedTrustManager)验证主机名的方法,这使得打开主机名验证更加方便,即使使用SSLSocket直接(没有额外的层HttpsURLConnection)。

同样的原因不应该适用于更高级别的库,例如那些提供 HTTPS 访问的库。不幸的是,一些用户无论如何都希望以一种或另一种方式禁用证书验证。(不幸的是,有些图书馆似乎不想解决这个问题。)

根据我在 StackOverflow 上的经验,有很多关于忽略证书错误的问题(今天又是一个)。一些建议完全禁用任何信任管理的答案被接受,有时甚至得到高度评价(有时,您甚至会因为建议做正确的事情而遭到反对,尽管不可否认,这确实不能完全回答问题。)

我不确定在这种情况下更好的默认库行为是否会有所帮助,因为那些询问的人只想忽略错误。考虑 Java 示例,大多数人抱怨当他们收到异常时发生的错误,因为远程主机不受信任。关于如何验证主机名的问题要少得多(SSLSocket直接使用 s 时默认不会这样做)。

我不确定 SO 社区的代表性有多大,但有些人只想快速修复,至少要开始使用应用程序的其余部分。我的猜测是,即使在它保留在“发布前修复”列表中的情况下,由于它是静默的,在某些情况下它实际上从未得到修复(特别是因为“正在使用 SSL/TLS”框仍然打勾) .

当然,提前发布的压力加上对证书似乎缺乏了解导致了这类问题。

并非该领域的所有参与者都有帮助(例如,一些主要的认证机构)。如果您是一个对证书知之甚少的开发人员,并尝试从您从 CA 站点获得的文档中学习,这通常会很困难。(经典的是,大多数 CA 暗示他们提供执行 256 位加密的证书,这充其量是误导性的。其他人的常见问题解答中充满了错误和/或误导性信息。其他人让您购买“SSL”(请参阅页面底部)。)

如果您不以某种方式对服务器进行身份验证,则任何活跃的攻击者都可以冒充服务器。这意味着在面对主动攻击者时,没有身份验证(例如证书验证)的 SSL 完全被破坏。

将 SSL 与服务器证书一起使用时,问题是攻击者是否可以获得客户端为要与之通信的服务器接受的证书。如果他可以,你就输了。这些攻击是实用的并且相对容易执行。验证服务器证书对于安全至关重要。