热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

OpenSSH用户枚举漏洞(CVE201815473)分析

简介OpenSSH用户枚举漏洞(CVE-2018-15473)已经通过Github公开(https://github.com/openbsd/src/commit/779974d35b4859c07b

简介

OpenSSH用户枚举漏洞(CVE-2018-15473)已经通过Github公开(https://github.com/openbsd/src/commit/779974d35b4859c07bc3cb8a12c74b43b0a7d1e0)。尽管该漏洞不能用来生成有效的用户名列表,但依旧可以拿来枚举猜测用户名。

在本文中,我们将详细分析该漏洞的利用和防范技巧。

 

技术细节

该漏洞涉及到多个OpenSSH中的用户身份验证函数。首先我们来研究下UbuntuOpenSSH中的公钥认证中的这个漏洞。

通过向OpenSSH服务器发送一个错误格式的公钥认证请求,可以判断是否存在特定的用户名。如果用户名不存在,那么服务器会发给客户端一个验证失败的消息。如果用户名存在,那么将因为解析失败,不返回任何信息,直接中断通讯。相关的漏洞利用PoC脚本链接如下:http://www.openwall.com/lists/oss-security/2018/08/16/1

这里涉及的漏洞发生在解析请求前就收到的用户名不存在的请求。修复漏洞的方式也很简单:修改下判断逻辑,先解析信息,再建立通讯。

用来测试该PoC的方式如下:先在调试模式下启动OpenSSH服务器,

然后运行带有已知用户名的脚本:

在服务器端可以看到报错信息:

这个报错信息也可以在/var/log/auth.log目录下找到:

解析请求失败会导致服务器在不返回任何信息的情况下中断客户端和服务器间的通讯:

注意最后一个粉红色的数据包(客户端的数据包),这里没有后续返回的蓝色数据包(服务器数据包)。

当执行一个不存在的用户名的PoC脚本时:

没有发生“incomplete message”的报错信息:

服务器也返回给客户端一条信息:

注意最后的蓝色(服务器)数据包。

这就是利用公钥身份认证中的漏洞来判断用户名是否存在的过程。

通过分析OpenSSH源码中的userauth_pubkey函数,可以发现它对公钥身份认证的过程如下:收到SSH2_MSG-USERAUTH_REQUEST(公钥类型)发来的数据后,调用函数进行验证,验证失败时返回0,验证成功时返回1。然后将结果(SSH2_MSG_USERAUTH_FAILURESSH2_MSG_USERAUTH_SUCCESS)发回给客户端。

函数的相关逻辑如下:


  1. 如果是未知用户名 -> 0

  2. 如果是错误密码的已知用户名 -> 0

  3. 如果是正确密码的用户名 -> 1

漏洞提交者找到的是在第一步和第二步之间,能够设法停止userauth_pubkey函数的执行,从而在第一步userauth_pubkey函数获取客户端发来的信息字符串时,构造特定格式的字符串,在不返回任何信息的情况下停止并关闭这一通讯连接。

这里的关键是packet_get_string函数:

如果存在该用户名,那么第一步后会从消息中提取有效字符串。

第一部分packet_get_char()函数提取的字符串是一个布尔变量(1字节),之后是两个字符串:算法和对应的密钥。在SSH信息中,字符串以长度值的配对方式编码:一个字符串包含4字节(字符串长度)的开头和包含字符串内容的可变大小的字节数(根据之前声明的长度)。这里的长度采用大端的方式进行编码:先声明重要的4字节最高有效字节,再添加次要的有效字节。

packet_get_string函数在验证的同时,也负责提取信息中的字符串,从而用于验证信息的长度是否正确。这个函数也依赖其他函数:

首先是函数中的定义到的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错误(可以在日志中找到该信息)

总的来讲,函数这一过程如下:先用packet_get_string函数来提取信息中的字符串,如果遇到特定的恶意格式字符串,那么会发生一个严重的报错,从而关闭OpenSSH进程。

这也就是Python编写的PoC脚本触发原理:先创建与OpenSSH服务器连接的加密请求,然后发送恶意构造的SSH2_MSG_USERAUTH_REQUEST(公钥格式)请求信息。脚本中将Paramikoadd_boolean函数重新定义为一个空函数,ParamikoPython中用于SSH通讯的模块。通过重新定义add_boolean函数,从而省略了信息中的布尔字段(也就是算法和字符串值之前的内容)。

userauth_pubkey函数解析该恶意构造的信息时,会先读取布尔字段,如果缺少了该字段,那么会读取下一个字段的第一位字节(packet_get_char函数):也就是算法字符串中的4位最高有效字节。之后pakcet_get_string函数会调用来读取(并验证)算法字符串。这一过程将会因为缺少布尔字节而发生错误。

下面是一个正确格式的信息解析过程:

如果是缺少布尔字节的恶意格式信息,那么解析函数在事先不知道的情况下,先将第一位字节解析为布尔字节,使得信息整体左移了一位。

这会导致尝试解析一个1907字节长度的信息(0x00000773的十六进制),也就是超过实际信息长度的信息。那么ssh_packet_get_string函数就会调用fatal函数来结束OpenSSH进程。

 

漏洞总结

这是一个非常巧妙的漏洞,因为它没有涉及到可以远程代码执行的缓冲区溢出漏洞和输入的验证过程。

在整个过程中既没有缓冲区溢出,使用到的输入内容也都符合验证要求。唯一的问题是可能出于性能需求的考虑,在一些函数处理后才进行对输入的验证,先判断用户名是否存在,如果不存在,那么就没必要进一步验证它的后续请求过程。

如果用户名存在,再对后续请求进行验证,那么会导致不返回信息就中断连接。这样就可以用来枚举一个用户名是否存在。

这个问题的解决方法也很简单:改变下顺序,在调用其他函数前先对所有输入进行验证。

在其他的身份验证函数中也有可能存在类似的问题,一个粗暴的,简单的判断方法是:检查所有类似”authctc -> valid”的表达式。

同样的问题也出现在基于主机的身份认证中(相关链接如下:https://github.com/openbsd/src/commit/779974d35b4859c07bc3cb8a12c74b43b0a7d1e0

Kerberos身份认证中也存在该问题:

SSH1 RSA身份认证中也可能存在该问题(考虑到现在的OpenBSD中都已经停止使用,我们就没有进一步进行检查)。

注意备注信息中也提到该风险问题。

 

总结

如果你还在使用OpenSSH,那么在新的官方修复补丁推送前,禁用易受攻击的身份认证机制。例如关闭公钥身份认证后,能够有效地防止PoC脚本和类似的恶意格式认证请求攻击。

也可以检查日志中的报错信息来判断该漏洞是否遭到利用。例如Ubuntu下,会有”incomplete message”的报错信息。然而根据OpenSSH版本的不同,报错信息也会有一些区别。同样对恶意格式的请求进行修改,比如说构造一个字符串超过最大允许值长度的恶意信息,也有可能会产生其他的报错信息。

在默认的配置中,你只会收到一个简单的报错信息,不会记录客户端的IP地址。因此你可以通过调整日志等级(LogLevel),从INFO改为VERBOSE,从而创建包含客户端IP地址等具体信息的日制。但要注意这会生成更大的日志文件,因此还需要监控日志是否超过容量限制。


推荐阅读
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 原文地址:https:www.cnblogs.combaoyipSpringBoot_YML.html1.在springboot中,有两种配置文件,一种 ... [详细]
  • Windows下配置PHP5.6的方法及注意事项
    本文介绍了在Windows系统下配置PHP5.6的步骤及注意事项,包括下载PHP5.6、解压并配置IIS、添加模块映射、测试等。同时提供了一些常见问题的解决方法,如下载缺失的msvcr110.dll文件等。通过本文的指导,读者可以轻松地在Windows系统下配置PHP5.6,并解决一些常见的配置问题。 ... [详细]
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • Imtryingtofigureoutawaytogeneratetorrentfilesfromabucket,usingtheAWSSDKforGo.我正 ... [详细]
  • 解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法
    本文介绍了解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法,包括检查location配置是否正确、pass_proxy是否需要加“/”等。同时,还介绍了修改nginx的error.log日志级别为debug,以便查看详细日志信息。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 本文介绍了使用postman进行接口测试的方法,以测试用户管理模块为例。首先需要下载并安装postman,然后创建基本的请求并填写用户名密码进行登录测试。接下来可以进行用户查询和新增的测试。在新增时,可以进行异常测试,包括用户名超长和输入特殊字符的情况。通过测试发现后台没有对参数长度和特殊字符进行检查和过滤。 ... [详细]
author-avatar
阿连AND王进_893_799
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有