如何从网络服务器端检测“伪造”的 SSL 证书

信息安全 tls 网络服务器
2021-08-18 11:04:37

我工作的公司有时会拦截员工到 https 网站的 ssl 连接,方法是代表他们从代理建立 ssl 连接,然后使用自己生成的证书将页面发送给用户。显然,这仅有效,因为他们在员工 PC 上安装了自己的根证书,但是您可以知道何时访问 https 网站并查看证书并发现它是由 [company] 而不是通常的 CA 之一/

现在我不打算在这里讨论这种做法的道德或合法性,即使我对此有意见:P

我的问题是,有什么方法可以检测到网络服务器正在发生这种情况,如果页面被这样拦截,则拒绝传递页面?

我在想也许网页上的一些 javscript 可以找出页面是用哪个证书签名的,如果它是错误的,就会发出警告——但我似乎找不到任何方法可以从 javascript 检查证书。(我意识到如果公司可以修改证书,他们也可以修改 javascript,但我假设他们不会为每个网站编写自定义代码)......

我可以使用其他任何技巧来做到这一点吗?

4个回答

我能看到的唯一方法是通过 SSL 打开 XMLHTTPRequest 并将证书从该连接中拉出:

这不适用于网页,但需要从扩展程序运行。

正如已经指出的那样,代理可以轻松更改 javascript 来杀死它。

如果我正确理解了这个问题,您是在问是否可以检测(在 HTTPS 连接的服务器端)连接是来自代理服务器还是实际客户端(浏览器)?

(我最初没有看到证书如何提供任何有价值的信息,但现在意识到我之前错过了什么。建议为用户提供 javascript,通过 HTML 代码触发它并让用户发回提取的来自 SSL 证书的数据,因为它将是代理提供的证书。是的,这应该可以工作,代理服务器似乎不太可能从 javascript 中过滤此类“操作”。聪明的建议!

分析以下内容可能有助于发现连接的发起者:

  • HTTP标头排序
  • 非浏览器特定的 HTTP 标头
  • HTTP cookie 值
  • HTTP 行为

HTTP-header ordering - 理论上应该可以通过分析 HTTP 标头的顺序来检测连接的发起者。浏览器倾向于以特定的“模式”来构建其 HTTP 标头,利用这些知识可以:

  1. 通过确定代理如何排列 HTTP 标头,为代理创建唯一指纹。
  2. 通过“提前”了解常见浏览器如何排序其 HTTP 标头并将其与当前请求的排序进行比较。(显然不是最好的主意......)

非浏览器特定的 HTTP 标头- 代理服务器可能包含浏览器不会包含的特定 HTTP 标头。这些可能用于负载平衡或请求类型重定向等。

HTTP-cookie 值- 如果使用负载平衡或集群,代理将插入特定的 cookie 值来引导与特定服务器的连接也是可以想象的。

HTTP 行为- 虽然实现起来并不容易,但可以通过启动一些特定于 HTTP 的返回代码并分析“客户端”如何响应请求来检测代理的存在。也许这可能允许检测对于常规浏览器来说不常见的异常行为。

假设是一个 Apache HTTP 服务器,可以使用 mod_security 规则来实现上述某些功能。

其他一些可能不太可能且不可靠的检测连接来源的方法是检查协议特定 (IP/TCP) 字段,例如时间戳、IP 选项。假设代理服务器来源,这些可能会以特定方式发生变化。

尽管它们会受到相当多的抖动和噪声的影响,但也可以根据时间来确定来源,理论上可以确定代理是否拦截了连接。我并不是说这完全是可靠的甚至是可能的,但是可以通过时间来确定很多。

如果服务器使用基于证书的客户端身份验证(即客户端也有一个证书并使用他的私钥来验证自己),那么服务器将检测到拦截器——因为在这种情况下,客户端会签署一个根据之前计算的哈希值收到握手消息,其中包括客户端看到的服务器证书。在拦截器存在的情况下,客户端签署了错误的值,拦截器无法纠正。

另一种解决方案是将TLS 与 SRP一起使用,其中身份验证不是基于证书,而是基于密码和相互的。

否则,没有。

按照惯例,标准代理应该包含X-Forwarded-For HTTP 请求标头,即使它不在RFC中,它也被视为事实上的标准。

也就是说,如果代理想要隐藏它的存在,那么简单地忽略将这个标头放入是没有问题的。