内容简介:这个漏洞虽然不能生成有效用户名列表,但是它可以允许攻击者猜测用户名。目前这个OpenSSH用户枚举漏洞(
介绍
这个漏洞虽然不能生成有效用户名列表,但是它可以允许攻击者猜测用户名。目前这个OpenSSH用户枚举漏洞( CVE-2018-15473 )的详细信息已经上传至了GitHub,感兴趣的同学可以自行查看【 传送门 】。
在这篇文章中,我们将对该漏洞进行深入分析,并提供一些可行的缓解方案。
技术细节
这个漏洞存在于OpenSSH所实现的一些认证功能之中,首先我们一起看一看Ubuntu OpenSSH的公共密钥认证漏洞。
通过向一台OpenSSH服务器发送恶意的公共密钥认证消息,攻击者将能够获取特定的用户名信息。如果用户不存在,服务器将会向客户端发送认证失败的消息。如果用户存在,消息将无法解析并终止通信,即通信连接会在没有任何消息回传的情况下断开。关于该漏洞的漏洞利用代码可以从这个Python PoC脚本中获取:【 传送门 】。
这个漏洞之所以存在,是因为服务器在对消息完整解析之前,用户查询了不存在的用户名。想要修复该漏洞也很简单,按攻击逻辑反着来就行了:首先对消息进行完整解析,然后再建立通信连接。
测试漏洞利用PoC的一种方法就是在调试模式下开启OpenSSH服务器:
然后用已存在的有效用户名运行PoC脚本:
在服务器端将会查看到错误提示:
相关错误信息还可以在/var/log/auth.log中找到:
如果无法正确解析消息,会导致客户端跟服务器端之间的通信中断,而且中断时不会收到服务器发送的提示信息:
注意粉红色标记的最后一个数据包(客户端数据包),这里没有后续的蓝色数据包(服务器数据包)。
当PoC脚本以不存在的用户名运行之后:
不会弹出“imcomplete message”错误提示:
注意通信数据结尾处的蓝色服务器数据包。
这就是该漏洞(公共密钥认证漏洞)暴露有效用户名的整个流程了。
其中,userauth_pubkey函数是认证功能所实现的其中一个函数,专门用于根据公共密钥来完成身份验证。如果认证失败,则返回“0”,成功则返回“1”。当服务器端接收到了SSH2_MSG_USERAUTH_REQUEST请求后,便会调用该函数,之后的结果会用来给客户端回传SSH2_MSG_USERAUTH_FAILURE或SSH2_MSG_USERAUTH_SUCCESS消息。
该函数的运行逻辑为:
1. 如果用户名不存在:返回“0”; 2. 如果用户名存在但密钥错误:返回“0”; 3. 如果用户名存在且密钥正确:返回“1”;
但是有人发现,我们竟然可以在第一步和第二步中间终止userauth_pubkey函数的运行。第一步执行完后,userauth_pubkey函数会从客户端获取消息字符串,如果获取失败(恶意字符串导致),整个过程都会终止,并在不发送任何回传消息的情况下关闭连接。
packet_get_string所导致的情况如下:
如果用户名存在,第一步会在程序从消息域中提取完数据后进行。
第一个提取的数据域是一个布尔值(1字节),对应函数为packet_get_char()。如果认证类型为publickey,返回值就是“1”。后续跟着的是两个字符串:算法和密钥。在SSH消息中,字符串会以一个“长度-值“键值对进行编码,一个字符串为4个字节。
函数packet_get_string可以从消息中提取字符串,并对其进行验证,这个函数还需要依赖另一个函数:ssh_ssh_packet_get_string。
ssh_packet_get_string函数会调用sshpkt_get_string函数,如果返回的值不是“0”,它还会调用fatal函数。函数fatal会记录致命的错误事件,然后终止生成的OpenSSH进程(不回传任何错误信息)。
接下来会执行sshpkt_get_string函数并调用sshbuf_get_string函数:
然后sshbuf_get_string函数会调用sshbuf_get_string_direct:
然后sshbuf_get_string_direct会调用sshbuf_peek_string_direct:
最后,sshbuf_peek_string_direct会进行字符串验证:
如果消息中剩余数据小于4字节,或者说消息中的剩余数据小于字符串长度,则会返回SSH_ERR_MESSAGE_INCOMPLETE 错误消息。这就是我们之前那个Python PoC脚本所要触发的东西。首先,它会跟OpenSSH服务器建立一条加密的通信链接,然后向其发送恶意的SSH2_MSG_USERAUTH_REQUEST消息。通过重定义add_boolean函数,消息中的布尔值域会被忽略。
当函数userauth_pubkey解析了恶意消息之后,首先会读取布尔值域,由于这个域其实是不存在的,因此读取的会是下一个域(函数packet_get_char):加密算法字符串的4字节长度值。然后调用下一个函数packet_get_string来读取加密算法字符串。
下面是解析合法消息的过程:
下面是解析恶意消息的过程:
结果就是,代码解析了一个1907字节的字符串(十六进制为0×00000773),这比整个消息的长度还要长,这会导致ssh_packet_get_string调用fatal函数,并中断OpenSSH进程。
漏洞总结
这是一个非常隐蔽的漏洞,它不是一个缓冲区溢出漏洞,也不是远程代码执行漏洞,更不是错误输入验证漏洞。这里不存在任何的缓冲区溢出问题,所有的输入都在使用之前进行了验证。问题就是,输入验证是在进行了一些函数处理之后完成的。
问题的解决方法也比较简单:更换函数的调用顺序即可,也就是首先进行输入验证,然后再进行函数处理就可以了。
* 参考来源: nviso ,FB小编Alpha_h4ck编译,转载请注明来自FreeBuf.COM
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 【漏洞分析】CouchDB漏洞(CVE–2017–12635, CVE–2017–12636)分析
- 【漏洞分析】lighttpd域处理拒绝服务漏洞环境从复现到分析
- 漏洞分析:对CVE-2018-8587(Microsoft Outlook)漏洞的深入分析
- 路由器漏洞挖掘之 DIR-815 栈溢出漏洞分析
- Weblogic IIOP反序列化漏洞(CVE-2020-2551) 漏洞分析
- 【漏洞分析】Joomla!3.7.0 Core SQL注入漏洞详细分析(含PoC)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Smarter Than You Think
Clive Thompson / Penguin Press HC, The / 2013-9-12 / USD 27.95
It's undeniable—technology is changing the way we think. But is it for the better? Amid a chorus of doomsayers, Clive Thompson delivers a resounding "yes." The Internet age has produced a radical new ......一起来看看 《Smarter Than You Think》 这本书的介绍吧!