防止损坏的可执行文件在 OS X 上启动

Prevent corrupted executable from launching on OS X

我有一个进程(启动守护进程),由 OS X 中的根上下文中的 launchd 启动。该进程是代码签名的。如果我破坏了二进制文件,它仍然会再次加载。为了破坏二进制文件,我在十六进制编辑器中打开可执行文件,然后查找并替换任何字符串。有没有办法阻止此进程在损坏的情况下启动?

通常 OS X 的 Gatekeeper 不会阻止您执行未经代码签名或错误签名的二进制文件,只要您在下载后已删除隔离属性以批准它 ("xxx is an applications downloaded from the Intenet...").如果您似乎是故意执行它(右键单击,打开或在终端中执行),它也会停止运行。在 运行 获得批准后,GateKeeper 就完成了。

坦率地说,这是一个很好的保护措施,但非常薄弱。一点也不像 iOS.

出于您的目的,您可能需要查看 Ostiarius。这是最近发布的工具,它将导致 OS X 内核拒绝执行任何未签名(或修改)的二进制文件,以及来自 运行ning 期间的互联网。您可以使用 xattr 将隔离属性添加到您的二进制文件,这样它就会受到影响。

And/or,在调用它的 launchd 脚本中,使用 codesign -dv 自己检查签名,然后才愿意启动它。您还可以将应用程序沙箱化,以确保如果它被劫持,它就无权做任何事情。

因为这是一个 launchd 进程,所以同一位安全研究人员还有另一个名为 BlockBlock 的免费工具,您可能会感兴趣。我相信它首先会阻止二进制文件被替换,直到您批准它。

坦率地说,这家伙所做的一切都非常酷。可能想看看其余的。

Apple 提供 code signing framework 允许可执行文件检查自己的签名并测试应用程序是否已被篡改。

首先通过调用 SecCodeCopySelf, then use the retrieved SecCodeRef to call SecCodeCheckValidity or SecCodeCheckValidityWithErrors.

获取代码对象

如果遇到有效性问题,是否退出取决于您的应用程序。因为它在根上下文中是 运行,所以它也可以从 launchd 卸载自身。

请注意,验证应用程序所需的时间取决于其大小和文件数量。一个非常大的应用程序包,例如 XCode,可能需要大约 3 分钟,但一个小的应用程序几乎不会被注意到。