漏洞分析:OpenSSH⽤户枚举漏洞(CVE-2018-15473)分析
介绍
这个漏洞虽然不能⽣成有效⽤户名列表,但是它可以允许攻击者猜测⽤户名。⽬前这个OpenSSH⽤户枚举漏洞(CVE-2018-15473)的详细信息已经上传⾄了GitHub,感兴趣的同学可以⾃⾏查看【传送门】。
在这篇⽂章中,我们将对该漏洞进⾏深⼊分析,并提供⼀些可⾏的缓解⽅案。
技术细节
这个漏洞存在于OpenSSH所实现的⼀些认证功能之中,⾸先我们⼀起看⼀看Ubuntu OpenSSH的公共密钥认证漏洞。
通过向⼀台OpenSSH服务器发送恶意的公共密钥认证消息,攻击者将能够获取特定的⽤户名信息。如果⽤户不存在,服务器将会向客户端发送认证失败的消息。如果⽤户存在,消息将⽆法解析并终⽌通信,即通信连接会在没有任何消息回传的情况下断开。关于该漏洞的漏洞利⽤代码可以从这个Python PoC脚本中获取:【传送门】。
这个漏洞之所以存在,是因为服务器在对消息完整解析之前,⽤户查询了不存在的⽤户名。想要修复该漏洞也很简单,按攻击逻辑反着来就⾏了:⾸先对消息进⾏完整解析,然后再建⽴通信连接。
测试漏洞利⽤PoC的⼀种⽅法就是在调试模式下开启OpenSSH服务器:
然后⽤已存在的有效⽤户名运⾏PoC脚本:
在服务器端将会查看到错误提⽰:
相关错误信息还可以在/var/log/auth.log中到:
如果⽆法正确解析消息,会导致客户端跟服务器端之间的通信中断,⽽且中断时不会收到服务器发送的提⽰信息:cve漏洞库
注意粉红⾊标记的最后⼀个数据包(客户端数据包),这⾥没有后续的蓝⾊数据包(服务器数据包)。当PoC脚本以不存在的⽤户名运⾏之后:
不会弹出“imcomplete message”错误提⽰:
注意通信数据结尾处的蓝⾊服务器数据包。
这就是该漏洞(公共密钥认证漏洞)暴露有效⽤户名的整个流程了。
其中,userauth_pubkey函数是认证功能所实现的其中⼀个函数,专门⽤于根据公共密钥来完成⾝份验证。如果认证失败,则返回“0”,成功则返回“1”。当服务器端接收到了SSH2_MSG_USERAUTH_REQUEST请求后,便会调⽤该函数,之后的结果会⽤来给客户端回传SSH2_MSG_USERAUTH_FAILURE或SSH2_MSG_USERAUTH_SUCCESS消息。
该函数的运⾏逻辑为:
1. 如果⽤户名不存在:返回“0”;
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进程(不回传任何错误信息)。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。