指针和固定大小缓冲区只能在不安全的上下文中使用_libssh C 库的安全评估报告(下):其他杂项问题...

9f6aa047fef85e0f2c85eb89728aeb56.gif

libssh渗透测试报告(上):已识别的漏洞解析

a6720b0d93117d43eb8c20b84dec44b9.png目录

· 引言

· 评估范围

· 已识别的漏洞

         · 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:通过未初始化的堆栈缓冲区泄漏信息(低危)

· 结论

7d96bf0f30e0093e0ff756a970d64ec7.png杂项问题

本节涵盖了一些值得注意的发现,这些发现不会导致漏洞利用,但可能有助于攻击者在未来实现其恶意攻击目标。这些结果中的大多数都是有缺陷的代码片段,无法提供简单的调用方法。总而言之,当存在漏洞时,利用漏洞并不总是会成功。

SSH-01-001 状态机:应明确设置状态机的初始状态(信息)

在整个代码库中,不同的变量用于跟踪不同的状态。这包括整个会话状态,即处于身份验证状态或正在验证的会话。另一个示例是跟踪握手状态的变量。

我们发现无论何时首次声明这些变量,都不会显式设置初始状态。相反,初始状态是隐式强加的,因为分配的内存是在分配时用空字节初始化的。

在测试期间,这并没有导致任何问题。但是,将这些变量显式设置为初始状态有助于全面理解代码,并且可以在假定某个状态但未给定初始状态的情况下防止问题的发生。因此,建议对这一问题作出更明确的说明,在声明中规定初始状态。

SSH-01-002 Kex:迭代同一个数组时使用了不同的边界宏(信息)

在检查不同 SSH 消息的处理程序函数时,我们发现在迭代同一个数组时使用了两个不同的宏作为上界。例如,两个 for-loop 迭代了一个名为 string 的数组,而第一个循环使用上界 KEX_METHODS_SIZE 和 SSH_KEX_METHODS 进行迭代。这可能会导致超出边界的读和写操作,因为这两个界限是相互独立定义的。下面的代码摘要显示了两个迭代并突出显示了相关的部分。

受影响的文件

libssh-0.9.0/src/kex.c

受影响的代码

bddaae984b2299d1c5e844d38b8cc7e3.png

在这个测试期间,两个上界被定义为相同的大小,因此不会引起任何问题。但是,如果未来对代码进行了更改导致其中某个定义也发生了更改,则可能会出现超出边界的问题。

因此,建议在两个循环迭代中使用相同的上界,或者使这两个定义相互依赖。例如,让 KEX_METHODS_SIZE 始终与 SSH_KEX_METHODS 相同。

SSH-01-005 代码质量:分配期间的整数符号混乱(低危)

在更一般的源代码分析中,我们注意到变量声明和赋值经常改变符号。这通常会导致意外的控制流,特别是在隐式转换发生的时候。为了发现将有符号整数转换为无符号整数(或相反)的所有潜在问题,我们使用了以下 Semmle 查询。

SemmleQuery

9349b47ef7502f6523cec23198dd4a42.png

LGTM 结果

https://lgtm.com/query/6155169963772014869/

值得注意的发现

libssh-0.9.0/src/sftp.c (count 是有符号的, sftp->ext->count 是无符号的):

int count = sftp->ext->count;

• ibssh-0.9.0/src/sftpserver.c (val is 无符号的, i 是有符号的):

val = i;

• ibssh-0.9.0/src/sftp.c (ssh_buffer_get_len 返回的是无符号的, packetlen 有符号的):

packetlen=ssh_buffer_get_len(buffer);

尽管上面提到的发现和 LGTM 链接中的发现都没有导致安全漏洞,但它们仍然是糟糕的编码实践的结果,可能会在未来导致安全漏洞。建议检查上面的每个 Semmle 结果,并确保不发生隐式强制转换。这可以通过声明左侧变量的类型来实现。

SSH-01-008 SCP:通过未转义的文件名进行协议注入(低危)

我们发现在 SCP 协议消息中使用文件名时没有正确编码。如果未经过过滤的用户输入被传递给相关的库函数,攻击者可以注入任意 SCP 协议消息并在当前 SCP 目的 IP 的服务器中创建任意文件。下面的代码片段显示了 SCP 协议中如何包含文件名。除了提取路径的基本名称外,没有进行其他的过滤处理。

受影响的代码

f2e9e172f7312b82b2f1e8abd774f3d8.png

建议采用与 OpenSSH 相同的方法,并使用可见编码对路径进行编码。

SSH-01-009 SSH:未实现 RFC4255(信息)

我们发现 libssh 不支持 RFC4255,它描述了通过 DNS 记录检查实现 SSH 指纹验证,尽管它已经出现在了支持的互联网标准的 libssh 列表中。

建议要么实现该标准,要么将其标记为当前不受 libssh 支持,因为建议的功能不会出现在用户流的任何位置。

SSH-01-012 PKI:通过未初始化的堆栈缓冲区泄漏信息(低危)

我们发现,在私钥的解密过程中,堆栈缓冲区没有初始化,从而导致潜在的信息泄漏。为了将密码读入缓冲区,我们调用了 auth_fn() 回调函数,它基本上等同于一个用户定义的回调函数。在示例应用程序中,这个回调只是将缓冲区传递给 ssh_getpass()。

受影响的文件

libssh-0.9.0/src/pki_container_openssh.c

受影响的代码

f73f492ccdda1c0f7cd00aecbc19634e.png

ssh_getpass() 函数的作用是禁用stdin的显示,并调用ssh_gets()函数,在这里输出提供的缓冲区是为了防止第一个字节不为零。由于缓冲区不是用pki_private_key_decrypt()初始化的,所以可能会发生堆栈内容泄漏。

受影响的文件

libssh-0.9.0/src/getpass.c

受影响的代码

1e4a02694bce7b88bf288bb288f7148d.png

依赖用户在提供的回调函数中正确初始化缓冲区是不安全的。因此,建议使用零初始化pki_private_key_decrypt()和pki_private_key_encrypt() 中的passphrase缓冲区,以防止堆栈字节的潜在泄漏。

7d96bf0f30e0093e0ff756a970d64ec7.png结论

正如引言中所指出的,对libssh软件的评估得出了积极的结果。在2019年9月和10月对评估范围进行了32天的研究之后,Cure53团队的6名高级成员可以确认libssh软件基本上是安全的,基本上没有重大风险。同时,测试工作显示了所有范围项和工作包的漏洞,表明libssh软件的维护人员可以考虑和部署一些改进和更细粒度的方法。

值得注意的是,Mozilla MOSS 项目的慷慨资助使这项任务成为可能。此外,由于libssh团队在整个测试过程中的出色准备和可用性,Cure53能够有效地处理代码库,提供并接收全面的反馈。

尽管功能很大,攻击面也很大,但是Cure53发现libssh的代码库非常干净,易于理解和审计。在这个领域中只有一个例外,即对于 libssh 混乱的状态机,该状态机过去已经暴露了该项目的漏洞。在这次评估中,Cure53还花费了相当大的精力来审核遍布整个源代码的所有控制流的可能性。尽管Cure53团队普遍认为现在已经安全地实现了状态机,但仍然强烈建议设计并提供一个清理和集中的重写。

乍一看,发现的了十四个问题的数量似乎相当多。然而,研究结果必须在上下文中阅读,值得注意的是,风险的聚合仍然导致相当低的临界得分。绝大多数问题必须被评估为小的、影响不大的错误。尽管如此,还是有一些值得关注的发现,比如通过scp进行命令注入,以及在密钥解析中可以利用的双重释放。虽然这些发现对攻击者来说是一个难以攻击的目标,但特别值得修正,因为主要的应用程序不安全地实现了导致这个缺陷的场景。

除此之外,Cure53还发现了一些DOS问题,这些问题主要是一些未进行过滤的代码模式造成的。例如,已经确定libssh充斥着未检查的函数调用和整数符号混淆。Cure53强烈建议仔细检查所有 Semmle 查询并一个一个地修复这些错误,以免它们在将来导致实际的可利用条件。

关于libssh的加密实现,Cure53实际上在审查时并没有什么严重的问题。几乎所有的 UI(在SSH-01-009中记录的RFC4255除外)都符合标准。libssh使用的密码原语是可靠的,能够抵抗侧信道攻击。但是,我们发现了一个协议级别的小问题(请参阅 SSH-01-010),这个问题与已弃用的哈希函数的使用有关。应该注意的是,这个问题不是特定于libssh的,在不破坏与其他SSH客户端的兼容性的情况下很可能无法避免。因此,我们鼓励在所有SSH库之间进行协调,以缓解这个问题。最后,在本文中,Cure53描述了在基于 Curve25519 的密码原语上实现点验证的方案。之所以这样做,是为了避免一些问题,这些问题可能是有效的且严重的,但由于对这次审计施加的时间限制及其错综复杂的程度而无法得到充分证实。

总而言之,Cure53团队对libssh软件的印象非常好。需要对开发小组表示赞扬,并适用于从筹备阶段开始并包括沟通和后续工作的整个审计过程。显然,在libssh的代码库中可以发现一些bug和安全问题,但是Cure53对测试软件的可靠性和编写良好的代码库总体上很有信心。至关重要的是,记录在案的问题可以相当容易地解决掉,特别是在不可能出现危及整个库的重大逻辑错误的情况下。最后,在2019年9月至10月的评估期间,libssh软件被评估为安全的。

Cure53 感谢 Mozilla 的JochaiBen-Avie在本次任务之前和期间所做的出色的项目协调、支持和协助工作。Cure53 还要感谢红帽公司的安德烈亚斯·施耐德以及其他维护团队,他们为这次任务提供了宝贵的意见和建议。

本文参考自:https://cure53.de/pentest-report_libssh.pdf

5ed6b4a0bdc6802d2ee3b8d6cbbdae56.png

a2241a07383ccca1c62eb96dc9d6835f.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值