OpenSSH用户枚举漏洞:一探究竟

栏目: 服务器 · 发布时间: 5年前

内容简介:本文翻译自:OpenSSH用户枚举漏洞(CVE-2018-15473)是由这个漏洞虽然不会生成有效用户名的列表名单,但它允许猜测用户名。

本文翻译自: https://blog.nviso.be/2018/08/21/openssh-user-enumeration-vulnerability-a-close-look/

介绍

OpenSSH用户枚举漏洞(CVE-2018-15473)是由 GitHub commit 公开的。

这个漏洞虽然不会生成有效用户名的列表名单,但它允许猜测用户名。

在这篇博客文章中,我们对这个漏洞进行了更深入的研究,并提出了缓解措施和监控措施。

技术细节

该漏洞表现在OpenSSH的几个认证功能中。我们密切关注Ubuntu OpenSSH实现的公钥认证中的这个漏洞。

通过向OpenSSH服务器发送格式错误的公钥认证消息,可以确定特定用户名的存在。如果用户不存在,则向客户端发送认证失败消息。如果用户存在,解析消息失败将中止通信:连接将在不发送任何消息的情况下关闭。此漏洞在 Python 的PoC脚本中实现。

该漏洞是因为在对消息进行完全解析之前,存在用户名不存在的通信。修复漏洞本质上是简单的:逆向逻辑。首先完全解析消息,然后进行通信。

测试PoC的一种方法是在调试模式下启动OpenSSH服务器:

OpenSSH用户枚举漏洞:一探究竟

之后,使用已存在的用户名执行PoC脚本

OpenSSH用户枚举漏洞:一探究竟

在服务器端,将会发生错误:

OpenSSH用户枚举漏洞:一探究竟

也可以在/var/log/auth.log中找到这个错误:

OpenSSH用户枚举漏洞:一探究竟

解析消息失败,导致客户端和服务器之间的连接关闭,而且没有来自服务器的消息:

OpenSSH用户枚举漏洞:一探究竟

注意,最后一个报文是粉红色的(即客户端报文),没有后续的蓝色报文(即服务器报文)。

当使用不存在的用户名来执行PoC脚本时:

OpenSSH用户枚举漏洞:一探究竟

没有出现“不完整消息”的错误信息:

OpenSSH用户枚举漏洞:一探究竟

服务器向客户端发回消息:

OpenSSH用户枚举漏洞:一探究竟

在通信结束时注意蓝色服务器报文。

这就是如何利用公钥认证中的漏洞来揭露用户名的有效性。

当然,OpenSSH的行为是在源代码中定义好的。函数 userauth_pubkey 是实现的身份验证功能之一,特别用于通过公钥进行身份验证。验证失败返回0,验证成功则返回1。当收到消息 SSH2_MSG_USERAUTH_REQUEST (类型为publickey)时就会调用它,之后这个结果会被用来将消息 SSH2_MSG_USERAUTH_FAILURESSH2_MSG_USERAUTH_SUCCESS 发送回客户端。

OpenSSH用户枚举漏洞:一探究竟

该函数的逻辑如下:

如果是未知用户名->0

如果是已知用户名,但密钥不正确->0

如果是已知用户名,并且密钥正确 ->1

一个 很聪明的人 想到的是,在步骤1和步骤2之间可以停止执行函数 userauth_pubkey 。步骤1后,函数 userauth_pubkey 从客户端发送的消息中检索字符串。如果这个失败,由于字符串格式错误,进程将停止并关闭连接,而不发送任何消息。

这种情况可能是由函数 packet_get_string 导致的:

OpenSSH用户枚举漏洞:一探究竟

如果用户名存在,则在步骤1之后将从消息中提取字段。

第一个字段为boolean(一个字节),使用 函数packet_get_char() 提取。当认证类型为publickey时,该字段值等于1。接下来是2个字符串:算法和密钥。在SSH消息中,字符串会被编码为 长度-值 键值对。这个字符串由4个字节(即字符串的长度)组成,后面紧跟包含字符串内容的可变字节数。长度会被编码为bigendian(大端)格式,即先存放4字节整数的最高有效字节,然后是较低有效字节。

函数 packet_get_string 从消息中提取并验证字符串, 即检查字符串的长度是否正确。但此功能依赖于其他项:

函数 ssh_packet_get_string 的定义如下:

OpenSSH用户枚举漏洞:一探究竟

函数 ssh_packet_get_string 会调用函数 sshpkt_get_string ,如果其返回值不为0,则调用函数 fatal ,而函数 fatal 会记录严重错误的事件,然后终止OpenSSH进程,且不发回任何消息。

OpenSSH用户枚举漏洞:一探究竟

现在我们来看看另一个函数链:函数 sshpkt_get_string 调用 sshbuf_get_string

OpenSSH用户枚举漏洞:一探究竟

sshbuf_get_string 调用 sshbuf_get_string_direct

OpenSSH用户枚举漏洞:一探究竟

sshbuf_get_string_direct 调用 sshbuf_peek_string_direct

OpenSSH用户枚举漏洞:一探究竟

最后, sshbuf_peek_string_direct 函数实现字符串的验证:

OpenSSH用户枚举漏洞:一探究竟

如果消息中的剩余数据小于4个字节(不能包含字符串的长度),或者消息中的剩余数据小于消息的长度,则返回错误提示信息 SSH_ERR_MESSAGE_INCOMPLETE (在日志中能找到)字符串。

总结这一系列函数:当 packet_get_string 用于从消息中提取字符串时,如果字符串格式错误,则会发生严重的异常,从而导致OpenSSH进程终止。

这正是PoC Python脚本的触发条件。首先,它与OpenSSH服务器建立加密连接,然后发送格式错误的 SSH2_MSG_USERAUTH_REQUEST (类型为publickey)消息。这个脚本将 Paramikoadd_boolean 函数重新定义为 NULL 函数。 Paramiko 是用于SSH通信的Python模块。通过重新定义 add_boolea n函数,消息中省略了布尔字段(就在算法和关键字符串字段之前)。

当函数 userauth_pubkey 解析这个格式错误的消息时,首先读取boolean字段。由于该字段实际上是丢失的,因此读取下一个字段的第一个字节(函数 packet_get_char ):算法字符串的4字节长度的最高有效字节。调用下一个函数 packet_get_string 来读取(并验证)算法字符串。由于缺少boolean字段,毋庸置疑,这注定失败。

以下是格式稍好的消息的解析过程:

OpenSSH用户枚举漏洞:一探究竟

格式错误的消息是缺少boolean值的,但解析函数并不知道这一点,于是它将字符串的第一个字节解析为boolean字段:看起来就像消息向左移一个字节:

OpenSSH用户枚举漏洞:一探究竟

结果就是解析了1907字节长的字符串(0x00000773十六进制),这比消息本身长。因此,函数 ssh_packet_get_string 将调用 fatal 函数,导致OpenSSH进程终止。

漏洞总结

这是一个微妙的错误, 它不是关于缓冲区溢出导致远程代码执行或缺少输入验证的问题。

没有缓冲区溢出,所有输入在使用前都要经过验证。这里的问题是输入验证是在一些功能处理已经发生了之后再发生的:可能出于性能原因,首先检查用户名以查看它是否存在,如果它不存在,那么进一步的输入验证和处理就毫无必要了。

使用已经存在的用户名,将会进行输入验证,并且可以在不发送消息的情况下关闭连接。这可用于导出用户名的存在与否。

这个问题的解决方案很简单:在任何功能处理之前,切换顺序并首先进行所有的输入验证。

在其他身份验证功能中可能会出现相同的错误。一个粗略的,不完整的方法是检查表达式 !authctc-> valid ,如下所示:

OpenSSH用户枚举漏洞:一探究竟

在基于主机的身份验证中的确犯了同样的错误(可以在GitHub commit 中看到):

OpenSSH用户枚举漏洞:一探究竟

以及Kerberos的身份验证:

OpenSSH用户枚举漏洞:一探究竟

并且潜在的SSH1的RSA身份验证(我们没有进一步检查,因为它不再存在于OpenBSD等实现中):

OpenSSH用户枚举漏洞:一探究竟

请注意,这种风险万不可轻视!

结论

您在使用OpenSSH的过程中,可以自己动手来减缓这个漏洞。在修补程序可用并部署之前,可以禁用易受攻击的身份验证机制。例如,通过禁用公钥身份验证,PoC脚本将不再有效,因为已经拒绝了格式错误的身份验证请求。

当然,如果您不使用公钥认证,我们只建议您禁用公钥认证。如果您使用它,请不要切换到密码验证,但继续使用公钥验证!这不是远程执行代码漏洞,而是一个信息泄露漏洞。

您还可以检查日志中是否有利用这个漏洞的迹象。致命错误可能是一个迹象。在Ubuntu上使用这个PoC,致命错误是“不完整的消息”。但是,此消息可能略有不同,具体得看您的OpenSSH版本,其他方法也可以生成格式错误的消息,这可能会导致另一个致命错误。例如,可以构造一个字符串长度超过最大允许值的身份验证请求。

在默认配置中,您只会收到此致命错误。例如,客户端的IP地址将不会被记录。您可以通过将日志级别(LogLevel)从INFO级别提高到VERBOSE级别,从而创建额外的日志条目,其中包含客户端的IP地址。请注意,这将生成更大的日志,并且您应该随时留意日志不会超过您的可用容量。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

算法的陷阱

算法的陷阱

阿里尔•扎拉奇 (Ariel Ezrachi)、莫里斯•E. 斯图克 (Maurice E. Stucke) / 余潇 / 中信出版社 / 2018-5-1 / CNY 69.00

互联网的存在令追求物美价廉的消费者与来自世界各地的商品只有轻点几下鼠标的距离。这诚然是一个伟大的科技进步,但却也是一个发人深思的商业现象。本书中,作者扎拉奇与斯图克将引领我们对由应用程序支持的互联网商务做出更深入的检视。虽然从表面上看来,消费者确是互联网商务兴盛繁荣过程中的获益者,可精妙的算法与数据运算同样也改变了市场竞争的本质,并且这种改变也非总能带来积极意义。 首当其冲地,危机潜伏于计算......一起来看看 《算法的陷阱》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

在线进制转换器
在线进制转换器

各进制数互转换器

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试