执行文件的运行时完整性检查

5
我刚刚完成了一个Linux安全模块,它在可执行文件启动时验证其完整性(使用数字签名)。现在我想深入一点,想要在运行时检查文件的完整性(即定期检查它们-因为我大多数情况下处理的是开始并一直运行的进程...),以便攻击者无法在主内存中更改文件而不被识别(至少在一段时间之后)。
问题在于我完全不知道如何检查文件的当前内存映像。我上面提到的身份验证方法利用了一个mmap-hook,每当一个文件在其执行之前被映射时就会调用它,但据我所知,LSM框架没有提供定期检查工具。
所以我的问题是:有什么提示可以帮助我开始吗?我该如何读取内存映像并检查其完整性?
谢谢

你打算如何处理那些在堆、栈空间、malloc分配的内存等地方创建和存储变量的应用程序? - fpmurphy
由于这部分内存是动态的,我认为在程序运行时没有好的验证方法。我可能需要坚持使用固定的部分,并确保攻击者没有更改其中任何内容。 - Chris
你的安全模块是驻留在HLOS还是内核中?对于内核,确保使用kmalloc而不是vmalloc来使地址连续。 - Ursa Major
@Chris - 这真是个好主意。我更感兴趣的是你是如何实现“在执行之前检查文件的完整性(校验和或哈希)?”我正在尝试实现类似的功能,但还没有找到任何方法。 - jigar137
1个回答

2
我明白你想做什么,但我真的很担心这可能是一种安全特性,让你没有充分的理由感到安全;而这些是最危险的安全特性。另一个例子就是与您的 LSM 相邻的 SElinux。虽然我认为我在这个观点上是少数派......
进程的程序数据不是影响其行为的唯一因素。堆栈溢出,其中恶意代码被写入堆栈并跳转,使得对原始程序文本的完整性检查无效。更不用说攻击者可以利用未经改变的原始程序文本来获得优势。
此外,如果您不断地在内核中计算 DSA,可能会遇到一些性能问题。而且,您还要将更多的特权内核代码添加到可能在以后被利用的长列表中。
无论如何,回答这个问题:您可能可以编写一个内核模块,实例化一个内核线程,定时跳转到每个进程并检查其完整性。这可以通过使用每个进程的页表,映射只读页面,并检查它们的完整性来完成。不过,这可能不起作用,因为每个内存页面可能都需要有自己的签名,除非您以某种方式将它们全部连接在一起。
值得注意的是,共享库只需要在每次扫描中进行一次完整性检查,因为它们被重新映射到所有使用它们的进程。不过要实现这一点需要熟练掌握技术,因此也许应该将其列入设计中的“美好愿景”部分。
如果您不同意我认为这可能不是一个好主意的理由,我会非常感兴趣听听您的想法。我在工作中曾经遇到过这个想法,所以带来新思路对我们的讨论会很有益处。

谢谢您的想法,我最近几天进行了一些研究,确实似乎不是一个合理的安全功能。您已经提到了一个原因(缓冲区溢出攻击可以利用已经存在的代码而无需更改它),此外这样的系统需要比内核更高的特权才能有效运行,因此所有现有的解决方案都依赖于硬件(例如TPM模块)或在虚拟机中运行完整性检查作为VMM。 - Chris
TPM是确立RoT(Root of trust)的一种方法,但还有其他方式。您也必须小心,因为TCG中TPM的版本现在是2.0,但迄今为止,市场上较大的部分仍在使用1.2,尽管2.0将是更好的选择。 - Ursa Major

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接