为什么不能通过"数据执行预防"修复Javascript shellcode漏洞?

End*_*ies 11 javascript exploit data-execution-prevention shellcode

"堆喷洒"维基百科的文章表明,许多的JavaScript漏洞涉及脚本的可执行代码或数据存储空间的某处定位的shellcode,然后有解释跳到那里,然后执行它.我不明白的是,为什么不能将解释器的整个堆标记为"数据",以防止解释器通过DEP执行shellcode?同时javascript派生字节码的执行将由虚拟机完成,该虚拟机不允许它修改属于解释器的内存(这在V8似乎执行机器代码时不起作用,但可能适用于使用某种类型的Firefox字节码).

我想上面的声音听起来很微不足道,而且很可能就是这样的事情.所以,我试图了解推理中的缺陷或现有解释器实现中的缺陷.例如,当javascript请求内存时,解释器是否依赖于系统的内存分配而不是实现自己的内部分配,从而使得分离属于解释器和javascript的内存过于困难?或者为什么基于DEP的方法不能完全消除shellcode?

Ort*_*kni 4

为了回答你的问题,我们首先需要定义数据执行预防即时编译JIT 喷射

\n\n

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

\n\n

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

\n\n
\n

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

\n\n

[...]

\n\n

例如,诸如 \xe2\x80\x9cvar x = 0x41414141 + 0x42424242;\xe2\x80\x9d 之类的 Javascript 语句可能会被编译为在可执行映像中包含两个 4 字节常量(例如 \xe2\x80\x9cmov eax ,0x41414141;mov ecx,0x42424242;添加eax,ecx\xe2\x80\x9d)。通过在这些常量的中间开始执行,会显示出完全不同的指令流。

\n\n

[...]

\n\n

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

\n
\n\n

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

\n\n

现在应该清楚的是

\n\n
\n

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

\n
\n\n

参考

\n\n

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

\n\n

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

\n\n

[3] JIT 喷射和缓解措施

\n