随机 PID 会带来更高的安全性吗?

信息安全 操作系统 随机的
2021-09-01 08:23:57

使用随机 PID 代替传统顺序 PID 的具体优势是什么?

前段时间,我在法国杂志 MISC(2014 年 7 月/8 月第 74期)上阅读了一篇文章,该文章发表了影响stunnellibssh的缺陷,该文章由这些缺陷的发现者本人撰写。

简而言之,这个缺陷依赖于这样一个事实,即服务器创建的 hello cookie 是使用当前的 Unix 时间戳(直到第二个时间戳)和处理请求的进程的 PID 生成的。该漏洞利用发送大量连接尝试以强制服务器生成重复的 cookie。最后,这种攻击旨在推断服务器私钥。

作者解释说,这种攻击在使用顺序 PID 的系统上是无法实现的,因为它需要在不到一秒的时间内进行超过 65000 次连接尝试。

然而,多亏了随机 PID,作者证明,在每秒 20 次连接尝试的情况下,从统计上讲,在不到 5 分钟的时间内生成重复的机会不止一次。

对我来说,这清楚地表明随机 PID 比顺序 PID 产生了新的安全漏洞。

因此,我想知道随机 PID 试图解决的确切威胁是什么。我从这里这里那里得到的答案和我的个人经历都不能让我满意:

  • 编码不佳的软件正在使用 PID 生成“唯一”临时文件名并作为熵的主要来源:编码不佳的软件应仅限于“Hello world”项目和扫雷端口,并且绝不应用于敏感任务。此外,为了给此类软件带来边际安全收益而削弱整个操作系统似乎会适得其反。最后,上面的缺陷表明,只要考虑熵,顺序PID甚至比随机PID更安全……
  • 防范未知的未来威胁:我看不出打开严重的当前和已知威胁以防止潜在的未来和未知威胁背后的逻辑......
  • 竞争条件:如果它是指使用 PID 生成临时文件名的劣质软件,那么我已经涵盖了这一点。否则,上面的缺陷表明随机 PID 比顺序 PID 更容易出现竞争条件。
  • OpenBSD 已经使用了它:这确实是对这种措施的时尚方面的一个很好的解释,但它与安全性无关。
1个回答

在对我更熟悉的操作系统进行了更深入的比较之后,我完成了自己的答案,这些操作系统的方向截然不同……

PID 随机化由 OpenBSD 推广,并于 1997 年加入当时它追求两个主要目标:

  • 防止 PID 预测漏洞影响主要使用 PID 值生成临时文件名的软件。这在当时是一个普遍的担忧,但今天我认为,仍然很少会遇到生产级软件仍然没有使用正确的方法。

  • 作为一般的预防措施,“如果某些东西可以是随机的,那就让它随机吧。 ”,包括在操作系统的几个地方(从 IP 堆栈到内存分配)放置随机性。虽然这种随机性产生的一些保护被证明是有用的并且变得更加普遍,但 PID 随机化的历史更加麻烦。

正如我的问题中所详述的,治愈可能比疾病更糟由于更快的 PID 重用,完全随机的 PID 可能允许远程利用漏洞,而顺序 PID 主要允许本地攻击。

附带说明一下,在理想世界中,所有这一切都不应该引起任何问题(是的,我说的是这个软件没有错误和漏洞的理想世界)。事实上,这些漏洞的根源通常在于 PID 的错误使用。Wikipedia将 PID 定义为“用于 [...] 唯一标识活动进程的数字”。所以:

  • PID 不是为构建临时文件名而设计的临时文件通常是在共享的地方创建的,这意味着危险因此,必须使用专用函数创建临时文件,这将确保以原子(不间断)方式完成三个必需的操作(检查文件是否不存在、创建文件并设置受限访问权限)。C 语言提出mkstemp()and tmpfile(),并且大多数 Unix 环境都提供mktemp命令供 shell 脚本等使用。

  • PID 并非旨在为随机数生成器提供种子或生成会话 ID 或 cookie在这里,您必须再次参考您的语言或环境文档以获得正确的熵源。在 UNIX 系统上,/dev/urandom设备文件就是为此目的而存在的。

  • 维基百科定义明确指出活动进程并非偶然在诸如 C 之类的语言上,您一直拥有子进程的 PID,直到您wait获得它为止,但这并非适用于所有语言(例如在 shell 脚本中......),并且对于不是您的孩子的进程来说永远不会如此。在这些情况下,PID 只是一个共享资源,您应该记住这个“共享”概念意味着“危险”,因此必须确保您采取适当的措施并使用旨在满足您的情况和需求的正确功能。


Linux

Linux 内核主流从未实现 PID 随机化,但是这个特性通常通过一个面向安全的第三方补丁提供了好几年,最终决定放弃它。

大约在 2000-2001 年,有几个人试图为 Linux 内核实现 PID 随机化(示例可以在这里那里找到),但是这些补丁都没有被内核开发团队接受,他们大多拒绝它们,因为它们是“通过默默无闻的安全”。

但是,由于随机性实际上可能会增加操作系统的全局安全态势并防止一些攻击,因此这些内核修改最终通过第三方项目公之于众:grsecurity

这个项目始于 2001 年,为 Linux 内核带来了几个新的和高级的安全特性。它允许使用特定sysctl参数启用/禁用随机 PID kernel.grsecurity.rand_pids:. 然而,在2006 年末(我猜——我讨厌新闻线程提到没有年份的日期!)他们最终决定放弃随机 PID 功能:

grsecurity 2.1.10 今天针对 Linux 2.4.34 和 2.6.19.2 发布。此版本中的更改包括:

  • 删除随机 PID 功能,因为它没有提供有用的额外安全性,并且使用 2.6 内核的 pid 位图浪费内存

OpenBSD

OpenBSD 已经启动了随机 PID 功能,它仍然出于历史目的而存在,但现在没有真正的安全范围。由应用程序自己来确保它们正确处理快速 PID 重用。

OpenBSD 的目标是鼓励良好的开发实践和彻底的代码安全审计。这就是为什么他们认为操作系统没有责任保护他们的用户免受有缺陷的应用程序的侵害相反,应尽快检测到应用程序缺陷并在应用程序中纠正,而不是被操作系统隐藏(“我们越早破解它,我们就能越早修复”)。

作为旁注,虽然这样的断言证明了在 OpenBSD 团队直接控制下的基本操作系统是合理的,但对于第三方软件来说,这变得更有争议:

然而,在这种情况下,OpenBSD 团队假设,对于一个正确开发和审计的软件,操作系统选择的 PID 生成算法必须对软件行为没有影响(稳定性和安全性都没有)。如果某些软件容易受到利用 PID 被重用的攻击,那么由软件来纠正,而不是由操作系统来确保 PID 不会被太快地重用¹。


¹:出于好奇,OpenBSD 在 2013 年添加了一个硬编码表,用于存储最后释放的 100 个 PID,以限制低负载系统的可靠性问题。但是,这并不构成安全措施,因为随着负载的增加,它会很快变得无效,这种负载是由真正的活动引起的还是作为攻击的一部分。


自由BSD

FreeBSD 提供了一个sysctl参数,允许管理员将 PID 生成算法从顺序调整为完全随机。默认情况下是顺序的。

FreeBSD在 1999 年(FreeBSD 4)实现了随机 PID,参考 OpenBSD 并对其进行了改进,以让管理员在顺序 PID 引起的潜在问题(主要是 PID 预测)和 PID 随机化引起的潜在问题(PID 重用和资源消耗)。

事实上,FreeBSD 的设计看起来很原始,因为它实际上不是随机的 PID,而是 PID 增量,它是一个介于 1 和kern.randompid参数之间的随机值:

  • 如果禁用 PID 随机化,则增量将始终为 1,
  • 最多可以将此参数设置为PID_MAX³,在这种情况下,下一个PID将完全随机选择。

默认情况下,PID 随机化被禁用(PID 是按顺序生成的)。要生效,该kern.randompid参数必须至少大于 100。

如果顺序 PID 仍然是一个问题,我个人建议将此参数设置为一个较低的值,例如几百:这应该足以限制琐碎的 PID 预测问题,同时避免由 PID 重用引起的更严重的问题。


³:对于纯粹主义者来说,它实际上是PID_MAX - 100只覆盖非保留PID范围,也可以使用特殊值来设置-1设置参数时会立即纠正超出范围的值,sysctl因此无论如何都不会在此处造成任何损坏。