如果不检查服务器指纹、使用公钥身份验证并且该服务不需要机密性,那么 SSH 对 MiTM 是否安全?

信息安全 验证 中间人 SSH
2021-08-16 10:27:29

首次连接服务器时,ssh 通常会要求用户检查服务器的指纹,然后将信息缓存起来。这是防止 MiTM 所必需的。

要求用户手动检查指纹是否是 SSH 的设计缺陷?我的意思是以下用例。

有一个服务器。有一个客户。服务器为经过身份验证的用户提供一些个性化服务。因此,服务器有责任正确检查用户的凭据。

服务器知道它的指纹。让我们假设客户端(不是 ssh 客户端,而是基于 ssh 构建的应用程序,例如 git 的 GUI 客户端)不愿意检查指纹,因为为了做到这一点,它应该以某种方式获得真正的指纹,这意味着 GUI 有将要执行。

身份验证协议是客户端签署 服务器提供的挑战,服务器对其进行验证,然后允许访问。 这感觉像是一个设计缺陷:恶意服务器可以通过执行 MiTM 并将用户的响应代理到原始服务器来将用户冒充为合法服务器。

解决这个问题的方法是不仅要签署挑战,还要签署服务器的指纹。(见右图接受的答案)然后服务器可以检测到中间人服务器端。尽管它不能防止恶意服务器被冒充给用户。

2个回答

简而言之:这不是设计缺陷。你只是对设计有误解。

身份验证协议是客户端对服务器提供的质询进行签名,服务器对其进行验证,然后允许访问。

客户端不签署服务器提供的质询。相反,客户端签署RFC 4252 第 7 节中定义的结构,其中包括作为主要组件的会话标识符。此会话标识符本身是RFC 4253 第 7.2 节中所述的密钥交换的结果。

...恶意服务器可以通过执行 MiTM 并将用户的响应代理到原始服务器来将用户冒充到合法服务器。

由于 MITM 无权访问客户端私钥,因此无法使用此密钥创建新签名。因此它需要找到一种方法让服务器接受客户端的原始签名。由于签名取决于会话标识符,因此 MITM 需要在客户端和 MITM 之间建立 SSH 连接,并在 MITM 和服务器之间建立另一个连接,它们都具有相同的会话标识符。

但是在 Diffie Hellman 密钥交换中,密钥交换的结果既取决于服务器未知的客户端数据,也取决于客户端未知的服务器数据。由于 MITM 只能控制每个连接的一侧,它无法控制密钥交换的结果,因此无法控制会话标识符。

因此,您描述的攻击将不起作用。只要服务器正确验证客户端,MITM 就不能简单地模拟客户端。身份验证将失败,因为签名被破坏(与会话标识符不匹配),或者因为公钥不是服务器所期望的(如果 MITM 自己制作客户端密钥)而失败。

要求用户手动检查指纹是否是 SSH 的设计缺陷?

它有利有弊(惊喜!)。

网站使用 HTTPS 的“受信任”第三方。我们都相信 Staat Der Nederlanden、中华、源讯和中国金融认证中心会验证您与银行之间的联系,对吗?因为这正是他们正在做的事情,而这在过去众所周知是错误的。但这是我们得到的最好的结果:我们不能指望我们的妈妈打电话给银行询问他们的指纹,所以我们需要使用这些半可信的证书颁发机构。

对于 SSH,它主要由系统管理员或其他高级用户使用,因此期望他们检查指纹或至少了解它是什么是更合理的。如果有安全意识的管理员愿意,他们可以检查它(例如,我在一家 IT 安全咨询公司工作,我们在连接前检查指纹)。否则,至少它是 Sjoerd 已经提到的第一次使用的信任,所以它不能在你不注意的情况下改变。攻击必须从一开始就存在,并且必须无限期地持续下去,才能被忽视。

这感觉像是一个设计缺陷:恶意服务器可以通过执行 MiTM 并将用户的响应代理到原始服务器来将用户冒充为合法服务器。

与任何其他方案一样,对吧?您始终可以 MitM 和代理流量。在 ssh 的情况下,您第一次收到错误的指纹或在任何后续连接时收到胖警报,而在 https 的情况下,您会收到证书警告。

解决这个问题的方法是不仅要签署挑战,还要签署服务器的指纹。然后服务器可以检测 MiTM 服务器端。

想一想:

A: 你好,bob.example.com 的 SSH 服务器!
B:你好,陌生人。这是我的公钥: abcdef
M:截获消息并将 abcdef 更改为 123456
A:您好服务器 bob,公钥为 123456,我是 Alice,密码为 bz8iuqw45。
M:截取消息并将 123456 更改为 abcdef
B:嗨 Alice!您登录成功!

攻击者将使用他们自己的公钥,因此他们可以解密流量。在转发数据时,他们可以替换指纹。您必须进行相互身份验证,其中客户端提供服务器已经信任的公钥。只有这样服务器才能确定客户端使用了正确的密钥并且没有被中间人处理。但是现在你扭转了这个问题:现在服务器必须知道正确的指纹(用户的公钥)而不是服务器的用户。问题,密钥分配,仍然存在。

让我们假设客户端不愿意检查指纹,因为为了做到这一点,它应该以某种方式获得真正的指纹。

您的意思是在连接时不信任指纹就不可能获取指纹?因为在通过 ssh 连接之前,您可以在安装服务器时获取真实指纹。

我觉得有些客户根本不检查指纹

那将是客户端中的一个漏洞。如果您想检查指纹但您的客户端不支持,那么您不能使用这些客户端。说“ssh 协议的作者都做错了,这导致客户端忽略了安全性”有点容易,因为正如我所说,这种默认方案有利有弊。如果要更改它,SSH 支持 paj28 提到的证书颁发机构