抵御代码注入攻击与操作系统接口混淆技术
1. 代码注入攻击的应对措施
代码注入攻击仍然是一个非常重要的安全威胁。不同的代码注入攻击方式都有一个共同特点,即都会在某个时刻覆盖代码指针。
1.1 相关技术对比
- 软件容错隔离(SFI) :通过屏蔽数据地址,确保不可信代码无法(意外地)修改内存部分区域。
- 代码指针掩码(CPM) :对代码地址进行掩码处理,保证控制流不能跳转到内存的某些部分。
1.2 执行监控措施
- 程序引导(Program shepherding) :该技术会监控程序的执行,不允许被认为不安全的控制流转移。不过,现有的实现对某些程序会有显著的性能影响,而对另一些程序则是可以接受的。
- 控制流完整性(Control - flow integrity) :也是一种被归类为执行监控的对策。
CPM 为减轻 C 程序中代码注入攻击的风险提供了有效的机制。它在使用代码指针之前对其进行掩码处理,对这些指针施加限制,使攻击者无法利用它们。CPM 提供了出色的性能/安全权衡,在仅付出极小性能代价的情况下,严重限制了代码注入攻击的风险,似乎非常适合处理器速度慢、内存少的手持设备,并且可以与其他对策互补结合使用。
2. 操作系统接口混淆攻击
2.1 背景与动机
许多软件安全解决方案,如恶意软件分析器、信息流跟踪系统、审计实用程序和基于主机的入侵检测器等,都依赖于标准系统调用接口的知识来推断进程执行行为。当前的恶意软件常利用内核模块(rootkits)来隐藏恶意用户级进程的副作用。
我们的目标是研究攻击者隐藏其恶意代码在用户系统上行为的能力,提出了 Illusion 攻击,这是一种强大的方法,可扩展 rootkits 的功能,使它们能够蒙蔽基于系统调用的检测器。
2.2 攻击者能力
攻击者若要发起 Illusion 攻击,必须安装恶意内核模块或驱动程序。安装方式包括获取模块签名、在不检查签名的系统上加载模块、通过绕过模块合法性检查的漏洞加载代码,或诱使天真的用户安装。合法签名是最有效的技术,因为它可以规避针对内核级恶意代码的前沿防御。
攻击者加载的模块可以访问和更改内核中的可变数据,但不能修改静态内核代码和数据,因为这些更改会被当前的监控系统检测到。
2.3 攻击概述
Illusion 攻击会混淆恶意进程向内核请求服务时生成的系统调用序列。恶意进程仍需获得所需的服务,否则恶意软件除了消耗 CPU 资源外将无法产生效果。
正常的内核系统调用执行路径如下:
1. 应用程序调用系统调用时,发出软件中断或系统调用请求,CPU 从用户模式切换到内核模式,开始执行系统调用调度函数。
2. 调度函数读取系统调用号,该号码指示请求的系统服务类型,并将其用作系统服务描述符表(SSDT)中函数指针表的索引。
3. 调度函数从 SSDT 读取指针值后,将执行转移到内核中的目标系统调用处理程序。
4. 处理程序完成后,将结果返回给调度函数。
5. 调度函数将结果复制回应用程序的地址空间,并将控制权返回给应用程序。
然而,一些系统调用允许合法地调度到内核模块或驱动程序中的代码。例如,ioctl 系统调用接受一个任意的、未解释的内存缓冲区作为参数,并将该参数传递给已注册为特殊文件处理程序的内核模块中的函数。恶意软件会将原始系统调用序列化为内存缓冲区,然后将该缓冲区传递给 ioctl 系统调用。恶意内核模块中的处理函数会解序列化该缓冲区,识别恶意软件请求的实际操作,然后直接调用该操作的系统调用处理程序。
Illusion 攻击对攻击者具有以下吸引力:
- 攻击者可以从一系列提供合法调度到模块代码的机制中进行选择,如共享内存、netlink 套接字、proc 文件系统、虚拟文件系统(vfs)调度或字符设备。特定的 Illusion 攻击实例可以组合使用这些操作来替代现有的系统调用。
- 攻击者控制序列化和解序列化操作。虽然了解系统调用序列化格式的系统调用监视器可以通过解序列化参数恢复原始系统调用序列,但攻击者可以不断更改序列化格式,防止监视器掌握这种知识。
- 攻击者不需要混淆所有系统调用,只需要混淆那些会向安全工具暴露恶意软件恶意意图的系统调用。其他系统调用,包括为混淆或模仿而插入的虚拟调用,无需混淆,这降低了对 Illusion 攻击调度操作的调用率,增加了系统调用序列的表面正常性,使攻击更隐蔽。
以下是正常系统调用执行路径的 mermaid 流程图:
graph LR
A[应用程序] -->|发出系统调用请求| B[系统调用调度器]
B -->|读取系统调用号| D[系统服务描述符表]
D -->|获取处理程序指针| C[系统调用处理程序]
C -->|返回结果| B
B -->|复制结果到应用程序| A
| 步骤 | 操作 |
|---|---|
| 1 | 应用程序调用系统调用 |
| 2 | 调度函数读取系统调用号 |
| 3 | 调度函数转移执行到处理程序 |
| 4 | 处理程序完成并返回结果 |
| 5 | 调度函数复制结果并返回控制权 |
抵御代码注入攻击与操作系统接口混淆技术
3. 相关研究对比
前人进行了各种攻击研究,以了解攻击者如何逃避基于主机的安全工具。例如:
-
模仿攻击(Mimicry attacks)
:针对应用程序级入侵检测系统,通过使恶意活动看起来正常来逃避检测。
-
内核级隐身攻击
:提出了一类当前监控方法无法检测到的内核级隐身攻击。
-
ARM 平台 rootkit
:创建了一个非持久的、仅依赖硬件状态修改来隐藏和操作的 ARM 平台 rootkit。
与以往研究不同的是,我们将这种攻击推理应用于系统调用监视器。我们的混淆不需要对现有操作系统的代码和数据进行任何修改,而早期的攻击则修改了系统调用或中断表。
我们使用虚拟机管理程序来观察虚拟机内内核的行为。与其他相关系统相比:
-
Jones 等人的系统
:开发了一种用于虚拟化环境的机制,跟踪与特定进程操作相关的内核操作,但 Sherlock 允许基于插入到相关内核代码执行路径中的监视点进行任意内核行为跟踪。
-
Srivastava 等人的系统
:创建了一个监控驱动程序执行行为的系统,而 Sherlock 更侧重于通过监视点和系统调用处理程序执行行为模型来重建被 Illusion 攻击隐藏的特权操作。
4. 防御 Illusion 攻击的 Sherlock 系统
4.1 设计与实现
为了检测 Illusion 攻击并恢复恶意软件在没有 Illusion 攻击时会调用的原始系统调用,我们开发了基于 Xen 虚拟机管理程序和完全虚拟化的 Linux 来宾操作系统的 Sherlock 原型系统。
Sherlock 通过在系统调用服务期间执行的内核代码路径上插入监视点来跟踪内核的执行行为。当系统调用的调用与服务例程的执行不匹配时,表明 Illusion 攻击改变了系统调用接口的内部语义。
4.2 自适应防御机制
Sherlock 是一个自适应防御系统,会调整自身行为以优化性能。它本身并不提供除 Illusion 攻击之外的其他攻击检测能力,而是为现有的系统调用分析器提供有关隐藏内核操作的信息。
- 正常执行时 :当监视点与请求的系统调用的预期执行匹配时,传统的系统调用监控可以观察到正确的事件。
- 检测到 Illusion 攻击时 :系统调用监视器会记录错误的系统调用序列。此时,Sherlock 会切换到深度检查模式,利用内核的执行行为来重建恶意软件执行的实际系统调用操作。一旦系统调用的恶意调用完成,Sherlock 就会切换回高性能模式。
4.3 性能开销
在启用监视点的良性执行期间,Sherlock 对不同类型的应用程序施加的开销如下:
|应用程序类型|开销|
|----|----|
|磁盘绑定应用程序|10%|
|网络绑定软件|1% - 3%|
|CPU 绑定应用程序|小于 1%|
5. 总结
本文的主要贡献如下:
-
Illusion 攻击
:展示了恶意软件可以仅使用良性模块和驱动程序的合法功能来混淆通用内核的系统调用接口。每个使用 Illusion 攻击的恶意软件实例都可以创建不同的系统调用接口。
-
Sherlock 系统
:讨论了基于虚拟机管理程序的内核执行监视器 Sherlock 的设计和实现。Sherlock 使用监视点和系统调用处理程序执行行为模型来重建被 Illusion 攻击隐藏的特权操作。
-
自适应监控技术
:展示了我们的自适应内核执行监控技术如何通过仅在核执行隐藏操作时深入检查内核状态来平衡安全性和性能。
以下是 Sherlock 系统工作流程的 mermaid 流程图:
graph LR
A[正常执行] -->|监视点匹配| B[传统系统调用监控正常工作]
A -->|监视点不匹配| C[检测到 Illusion 攻击]
C --> D[切换到深度检查模式]
D -->|恶意调用完成| E[切换回高性能模式]
综上所述,代码注入攻击和操作系统接口混淆攻击是当前面临的重要安全威胁,而 CPM 和 Sherlock 等技术为应对这些威胁提供了有效的解决方案。在实际应用中,我们需要根据具体情况选择合适的防御措施,并不断关注安全技术的发展,以保障系统的安全稳定运行。
超级会员免费看
1108

被折叠的 条评论
为什么被折叠?



