11

堆喷射”维基百科文章表明,许多 javascript 漏洞利用涉及将 shellcode 定位在脚本的可执行代码或数据空间内存中的某个位置,然后让解释器跳转到那里并执行它。我不明白的是,为什么解释器的整个堆不能被标记为“数据”,这样解释器就会被 DEP 阻止执行 shellcode?同时,javascript派生字节码的执行将由不允许它修改属于解释器的内存的虚拟机完成(这不适用于似乎执行机器代码的V8,但可能适用于使用某种类型的Firefox字节码)。

我想上面的内容听起来微不足道,实际上可能正在做类似的事情。所以,我试图了解推理的缺陷在哪里,或者现有解释器实现的缺陷在哪里。例如,解释器是否依赖于系统的内存分配,而不是在 javascript 请求内存时实现其自己的内部分配,因此很难将属于解释器和 javascript 的内存分开?或者为什么基于 DEP 的方法不能完全消除 shellcode?

4

1 回答 1

4

要回答您的问题,我们首先需要定义数据执行保护即时编译JIT 喷射

数据执行保护是一项安全功能,可禁止从不可执行的内存区域执行代码。DEP 可以通过 NX 位等硬件机制和/或通过添加运行时检查的软件机制来实现。

即时 (JIT) 编译器是在运行时将字节码转换为机器码的动态编译器。目标是结合解释代码的优势和编译代码的速度。只有在编译所花费的额外时间可以通过编译代码预期的性能增益来摊销时,它才应该编译方法。[1]

JIT 喷射是强制 JIT 引擎编写许多带有嵌入式 shellcode 的可执行页面的过程。

[……]

例如,诸如“var x = 0x41414141 + 0x42424242;”之类的 Javascript 语句 可能被编译为在可执行映像中包含两个 4 字节常量(例如,“mov eax, 0x41414141; mov ecx, 0x42424242; add eax, ecx”)。通过在这些常量中间开始执行,一个完全不同的指令流被揭示出来。

[……]

关键的见解是 JIT 是可预测的,并且必须将一些常量复制到可执行页面。给定一个统一的语句(例如长和或任何重复模式),这些常量可以编码小指令,然后控制流到下一个常量的位置。[2]

然后必须使用超出此答案范围的高级技术来查找 JIT 喷射块的地址并触发漏洞利用。

现在应该清楚的是

如果攻击者的代码是由 JIT 引擎生成的,它也将驻留在可执行区域中。换句话说,DEP 不参与对 JIT 编译器发出的代码的保护。[3]

参考

[1] Java 即时编译器的动态优化框架

[2]解释器利用:指针推理和 JIT 喷射

[3] JIT 喷洒和缓解措施

于 2015-03-20T16:44:06.613 回答