是否有任何操作系统在执行程序签名之前验证它们?

信息安全 电子签名 操作系统
2021-09-04 17:51:36

如果是这样,这些操作系统是什么?它们是特制的吗?将这种程序验证应用到我们使用的日常操作系统中有多难?

如果没有,为什么人们没有发明这样的操作系统?

包签名验证在当今的包管理器中非常普遍。我要问的是加载时的签名验证。

4个回答

iOS 和 Android 都在将每段代码加载到内存之前验证它们的签名。

Windows UWP 应用程序在加载之前也会进行签名检查。

包签名验证在当今的包管理器中非常普遍。我要问的是加载时的签名验证。

就性能而言,差异是巨大的。软件包签名在安装时检查,而不是在安装后检查。

为了有效,必须在执行或加载每个二进制文件之前检查代码签名。

此外,操作系统(或运行时环境)必须特别小心,以确保标记为可执行的内存页面已签名(或至少,已从已正确签名的内容加载)。在设计时没有考虑到代码签名的任何环境都很难执行该要求,因为它往往会破坏许多遗留代码。

为什么不是所有操作系统都验证程序的签名?只是因为在早期,大多数程序都是在本地编写和编译的,而现在,一些业务应用程序是专门在本地构建的。许多高质量的程序作为源代码分发,可以在本地编译。它在高性能服务器上通常很有意义,因为编译选项可用于根据特定需求调整程序。如果您只能使用来自知名来源的签名可执行文件,那么这一切都是不可能的。

当然,对于面向最终用户的操作系统,如 Android 或 iOS,情况会有所不同,只允许从知名来源安装可执行文件是有意义的。

但即使在我的 Windows 机器上,如果我不能用 C 或 C++ 编写、构建和执行程序,我也会感到非常失望......

偶尔在教育和企业环境中使用的一个示例是AppLocker,它可以根据管理员定义的属性(包括签名中的发布者名称或特定文件的哈希)将应用程序执行限制在白名单中。

最大的问题当然是管理开销,必须专门将用户可能需要的所有程序列入白名单。此外,许多出版商不签署他们的申请。当然,这不是一个万无一失的解决方案——例如,白名单程序中的错误仍然可以被利用来运行任意代码1

实际上,可执行文件的签名甚至不是重要的部分。白名单可以通过路径来实现它所产生的所有差异——在这个方案中重要的是用户对程序目录没有写权限2假设这是真的,执行时的验证比安装时的验证有什么优势?没有人可以更改已安装的程序。如果攻击向量是文件的脱机编辑,那么全盘加密是正确的答案。


1大多数此类错误在正常环境中不会被认为是严重的,它们不会导致权限提升。W^X仍然可以用ROP绕过。

2默认情况下,即使是对可执行文件签名的验证也会遗漏外部模块(例如动态链接库)。并且启用它会对性能产生重大影响

Linux 在内核中已经有了必要的机制(从 3.7 版开始),称为IMA

内核完整性子系统的目标是检测文件是否被远程和本地意外或恶意更改,根据作为扩展属性存储的“良好”值评估文件的测量值,并强制执行本地文件完整性。这些目标是对 LSM 模块(例如 SElinux 和 Smack)提供的强制访问控制 (MAC) 保护的补充,这些模块可以根据策略尝试保护文件完整性。

使用 IMA,可以将敏感文件标记为“不可变”(这是您对可执行文件所做的),并使用特殊的 RSA 密钥对它们进行签名。签名在文件访问时得到验证,防止离线篡改。可以通过 SElinux 策略禁止执行不可变的文件。

当然,这种系统的可用性降低了。要在这样的系统上构建和执行您自己的文件,您首先需要一个受信任的私钥对它们进行签名。软件升级可能需要重新启动才能在锁定之前更新不可变文件。