丝绸之路 漏洞 2020-02-15 09:55:05
收藏
目录
· 引言
· 评估范围
· 已识别的漏洞
· SSH-01-003 客户端:在错误的状态下缺少NULL检查导致崩溃(低危)
· SSH-01-004 SCP:未经过滤的位置参数导致命令执行(高危)
· SSH-01-006 通用:各种未检查的空指针解引用导致DOS(低危)
· SSH-01-007 PKI Gcrypt:潜在的使用 RSA 公钥的 UAF/双重释放(中危)
· SSH-01-010 SSH:指纹识别中使用了弃用的哈希函数(低危)
· SSH-01-011 SSH:X25519和Ed25519上缺少点验证(中危)
· SSH-01-011 SSH:X25519和Ed25519上缺少点验证(中危)
· SSH-01-014 配置解析:整数下溢导致OOB数组访问(低危)
· 杂项问题
· SSH-01-001 状态机:应明确设置初始计算机状态(信息)
· SSH-01-002 Kex:用于迭代同一数组的不同绑定的宏(信息)
· SSH-01-005 代码质量:分配期间的整数符号混乱(低危)
· SSH-01-008 SCP:通过未转义的文件名进行协议注入(低危)
· SSH-01-009 SSH:未实现 RFC4255(信息)
· SSH-01-012 PKI:通过未初始化的堆栈缓冲区泄漏信息(低危)
· 结论
引言
“libssh是一个在客户端和服务器端实现SSHv2协议的多平台C语言库。通过libssh,你可以远程执行程序、传输文件、使用安全和透明的通道、管理公钥等等。”
来自:https://www.libssh.org/
本报告记录了针对libssh软件的安全性评估的结果。这个项目由Cure53在2019年9月和10月进行渗透测试和源代码审计。重点放在libssh软件上,该软件可作为开源软件使用,当前版本为v0.9。Cure53已经在评估范围内发现了十四个与安全有关的问题,其中一个被标记为“高危”问题。
需要澄清的是,这项评估是由Mozilla慷慨资助的。预算来源于Mozilla开源支持(MOSS)计划框架,特别是安全开源资助计划。Mozilla将Cure53介绍给libssh团队及其维护者。从那时起,就开始计划合作计划。在资源方面,Cure53与一个由六名高级测试人员组成的团队完成了libssh的评估工作。完成这次评估的总时长达到了三十二人日。所有涉及核心测试、文档、报告和编写的工作都在2019年9月底和10月初完成。
为了有组织地实现这一评估的目标,我们创建了三个工作包(WP)。WP1包括libssh源代码审计,在此期间,Cure53侧重于研究可用的源代码,总体目标是确定易受攻击的部分。在WP2期间执行了代码辅助渗透测试,这种测试依赖于参考服务器和客户端实现的使用,以及由Cure53创建的本地设置。最后,WP3将通过使用AFL的libssh协议进行模糊测试和形式验证。后半部分工作将与测试工作并行执行,同时也伴随着形式验证工具的使用。为了阐明这一目标,应该说明的是,Cure53试图找出协议握手是否像预期应该的那样安全。
为了准备评估工作,我们举行了几次简报会议。此外,libssh团队向Cure53提供了一个评估范围文档,其中包含与测试设置相关的说明、有趣的区域以及关于测试和评估结果的预期的一般信息。因此,项目可以按时开始并有效地进行。评估期间的交流沟通发生在Freenode上的IRC频道中,由libssh项目的维护人员提供。Cure53 定期更新评估状况,并在报告产出时提供相关调查结果,而不是等待报告最后完成。
在发现的十四个问题中,8个被归类为安全漏洞,6个被定为一般的缺陷和较低的潜在利用价值。虽然有一个项目收到了“高危”标记,但必须指出,它的可利用性并不扩展到利用libssh API的每一个软件。然而,已经证明,像cURL这样的流行软件容易受到本报告中提及的攻击场景的影响,从而导致漏洞被标记为比最初提议的级别要更高一些。令人印象深刻的是,所有其他问题只有“中等”和较低的分数,这表明Cure53 对 libssh 软件的这个评估报告的总体结果是很不错的。
在接下来的章节中,报告将首先简要地重申评估范围和三个具体的WP。然后是专门的按时间顺序阐述评估过程,这些品谷过程逐一揭示了发现的问题。除了PoC之类的技术方面的东西,Cure53还提供了今后改进libssh的缓解建议。该报告以一个更广泛的结论作为结束,其中Cure53总结了2019年秋天的项目,并对测试范围做出了定论。此外,关于libssh软件的安全性和隐私状况的详细建议和说明将在本文的最后部分提供。
评估范围
libssh服务器和客户端代码
· WP1:libssh源代码审计,源码地址:https://www.libssh.org/files/0.9/
· WP2:libssh渗透测试,代码辅助(使用参考服务器和客户端)
· WP3:libssh协议fuzzing&
· Libssh维护人员向Cure53提供了一个详细的范围文档
· 提供了构建说明
已识别的漏洞
以下部分列出了测试期间发现的漏洞和实现问题。请注意,调查结果是按时间顺序列出的,而不是按其严重程度和影响程度列出的。上述严重性等级只是在每个漏洞的标题后面的括号中给出。每个漏洞都会额外获得一个唯一标识符(例如SSH-01-001),以方便日后的跟进沟通。
SSH-01-003客户端:在错误的状态下缺少NULL检查导致崩溃(低危)
我们发现加密函数不能正确检查空指针,从而允许恶意服务器导致基于libssh的客户端应用程序崩溃。在某些情况下,这可能导致信息泄露攻击,例如当核心转储被写入并提供给攻击者时。
当SSH客户端建立连接时,服务器发回其公钥。如果无法正确解析此密钥,libssh客户端就无法设置所需的加密参数。因此,它会导致sshconnect()函数返回一个错误。如果在这种错误状态下调用sshdisconnect()函数,客户端将在加密disconnect-message时崩溃。这是因为所需的数据结构尚未初始化。下面的代码片段显示了崩溃发生的位置。可以看到,out_cipher 没有初始化,在尝试访问out_cipher->blocksized时导致空指针解引用(Null Pointer Dereference)。
受影响的文件:
libssh-0.9.0/src/packet.c
受影响的代码:
尽管这个库在连接失败时返回一个错误,但在这种状态下调用disconnect函数时不应发生崩溃。经过进一步研究,发现这个问题会影响使用libssh编译时的cURL等应用程序。建议根据NULL值检查out_cipher 指针。
SSH-01-004SCP:未经过滤的位置参数导致命令执行(高危)
当libssh SCP客户端连接到服务器时,将在服务器端执行包含用户提供的路径的SCP命令。如果以用户可以影响 ssh_scp_new() 的第三个参数的方式使用该库时,那么攻击者就有可能注入任意命令,导致远程目标的被入侵。如下面的代码片段所示,提供的位置是直接传递的,而不需要事先转义。
受影响的文件:
libssh-0.9.0/src/scp.c
受影响的代码:
危险的库调用:
虽然这个问题需要应用程序将未经过滤的用户输入传递给libssh API,但是用户控制的数据到达接收器的设置是切合实际的。这一点尤其重要,因为libssh文档在提供位置参数时没有提到任何形式的安全风险。
我们对受影响的 API 调用的危险使用方式进行进一步分析后还表明使用libssh支持编译的libcurl的漏洞。
使用libcurl+“--with-libssh”的概念验证(PoC):
$curl-uuserscp://localhost:”/etc/passwd;touch/tmp/xxx”
使用 PHP+libcurl+“--with-libssh”的概念验证(PoC):
因此,我们建议正确地转义位置参数,并将其置于单引号之间。这也应该可以解决包含特定字符的路径的问题。
SSH-01-006通用:各种未检查的空指针解引用导致DOS(低危)
在应用 Semmle 的扩展污点跟踪查询时,可能会注意到未检查的函数调用导致的一些空指针解引用。下面的Semmle 查询表明可能的结果是完整的。
使用 Semmle Query:
LGTM 链接:
https://lgtm.com/query/8016580153808805310/
下面的列举了一些解释潜在问题的值得注意的发现。每当调用突出显示(黄色部分)的函数之一时,其返回值都是经过检查的。这将导致赋值操作左侧的变量未初始化或为NULL。因此,下一个解引用将访问空指针,导致依赖于底层代码内存区段错误的应用程序崩溃。
值得注意的发现:
libssh-0.9.0/src/gssapi.c:
libssh-0.9.0/src/messages.c:
libssh-0.9.0/src/packetcrypt.c:
建议检查上面的 Semmle 结果,并确保正确检查所有函数调用的返回值。每当调用失败时,也需要相应地将它们从控制流中保留出来。
SSH-01-007PKI Gcrypt:潜在的使用 RSA 公钥的 UAF/双重释放(中危)
libssh的内存分配功能提供了一个名为SAFE_FREE的宏。释放指针后,这个宏将指针变量设置为NULL。但是,如果宏在包装函数中使用,指针变量仍然可能是非NULL的。其中一个包装函数是ssh_string_free,而该函数的调用方保留一个非NULL指针。这可能导致双重释放或释放后使用(UAF)漏洞。
下面是一段代码摘录,显示了一个潜在的双重释放漏洞,并突出显示了其相关部分。
受影响的文件:
libssh-0.9.0/src/pkigcrypt.c
受影响的代码:
在处理给定switch语句的特定情况之后,使用的指针e和n释放后又由ssh_string_free使用。但是,如果在switch语句失败后执行的两个函数中有一个失败,那么同样的指针将再次释放,从而导致双重释放。
建议在调用ssh_string_free 之后显式地将指针变量设置为NULL,因为这是在src/pkicrypto.c中定义的类似函数中完成的。
SSH-01-010SSH:指纹识别中使用了弃用的哈希函数(低危)
SSH 协议标准目前通过指纹为带外公共密钥认证定义了一种方法。这是通过RFC4251完成的,RFC4251(https://tools.ietf.org/html/rfc4251)引用FIPS-180-2,并在公钥和相关身份信息上表示SHA-1哈希的十六进制编码字节。除了libssh之外,大部分SSH实现都默认支持这种带外相互身份验证方法。
虽然使用SHA-1作为指纹哈希函数并不存在明显的安全问题,但应注意到SHA-1目前正在几乎所有主要因特网协议中被弃用,最明显的是TLS协议和证书协议。此外,在SHA-1上发现了许多实际的攻击,使得碰撞攻击变得可行。
由于这些原因,建议尽可能不推荐在libssh中使用SHA-1。不幸的是,这个建议会受到与其他SSH实现的交叉兼容性概念的限制,因此如果不在SSH生态系统的其他主要实现之间进行协调,可能无法实现交叉兼容。
SSH-01-011SSH:X25519和Ed25519上缺少点验证(中危)
libssh实现了对RFC4253的扩展,允许在密钥交换阶段使用更现代的Diffie-Hellman和签名原语,即X25519和Ed25519。但是,这些原语的实现方式使得点或密钥验证不会在标量乘法步骤中发生。在Curve25519的案例中,这为小型子群攻击提供了可能性,同时在Ed25519中提出了各种可塑性问题。
Cas Cremers等人最近发表了两篇论文,特别是第一篇论文(https://eprint.iacr.org/2019/779.pdf)的第3.4节和第二篇论文(https://eprint.iacr.org/2019/526.pdf)的第7.1节,展示了基于这些缺陷的实际攻击。在本次审计的时间框架内,我们作出了相当大的努力,以确定类似的问题是否适用于RFC4253第8节所述的Diffie-Hellman密钥交换。到目前为止,还没有得到任何缺陷的明确确认。但是,这可能完全是由于需要对在Ed25519中获取碰撞签名的要求条件进行更多研究。分析工作的其他部分暗示了更多的确定性。例如,如果强制使用低阶子群,则前向保密性可能会降低。
如果有可能在不修改服务器公钥的情况下获得碰撞签名或通过中间人攻击获得服务器的公钥(正如上面引用的文章的第3.4节强烈建议的那样),那么在某些协议执行中使用Curve25519和Ed25519可能会导致所有SSH的安全性降低,而不仅仅是libssh。再加上可能通过主动攻击在SSH实现中强制使用某些密码套件,如果这些错误得到确认,这将成为一个严重的问题。
鉴于在审计范围内没有足够的时间进行研究以确认这种复杂的攻击,所以我们提出这个问题是为了强烈鼓励Curve25519中的点验证。这样,无论如何都可以避免潜在的攻击。需要注意的是,在这两个原语上执行点验证并不会破坏与其他SSH实现的互操作性——除非概率极低。这意味着可以在不产生任何问题的情况下部署该方法。
SSH-01-013 配置解析:解析主机名中的递归通配符导致DOS(低危)
虽然对parse_config.c和knownhosts.c进行模糊测试后发现使用了诸如“*”(星号)这样的通配符会导致底层解析逻辑中的递归问题,最终导致拒绝服务。这个问题的根本原因是match.c中的匹配模式函数试图在出现两个通配符时,递归地将子模式与主机名进行匹配。受影响的文件和代码行的两个PoC 如下所示。
受影响的文件:
libssh-0.9.0/src/match.c
受影响的代码:
建议要么以迭代的方式编写代码,要么使用静态计数器来跟踪递归的深度,这样在深度太大时就可以跳出来。必须为该计数器找到合理的值。
SSH-01-014 配置解析:整数下溢导致OOB数组访问(低危)
在对 SSH 配置文件的解析过程进行模糊测试时,发现空行(即只有一个空字节的行)会导致整数下溢。反过来,这表示一个超出界限的数组访问。受影响的文件和代码如下所示。
受影响的文件:
libssh-0.9.0/src/config.c
受影响的代码:
为了捕获这样的边缘情况,建议检查所提供的行的长度是否大于0,或重构循环初始化。
本文翻译自:https://cure53.de/pentest-report_libssh.pdf如若转载,请注明原文地址: