漏洞原理
漏洞相关信息可以在这里找到:链接
COMMIT: bdaa7d66a37adcc1f1d81c9b0f834327a74ffe07
安装:
1 | git reset --hard bdaa7d66a37adcc1f1d81c9b0f834327a74ffe07 |
原因:
函数 NodeProperties::InferReceiverMapsUnsafe负责推断对象的 Map。由此有两种属性,分别为reliable和unreliable,并且该对象的map必然为reliable或者unreliable。
在后一种情况下,调用者必须通过使用 CheckMap 节点或 CodeDependencies 来确保对象具有正确的类型。
在高层次上(需要优先进行内联的函数),InferReceiverMapsUnsafe 函数遍历effect链,直到找到创建问题对象的节点,同时如果遇到没有 kNoWrite 的节点,则将结果标记为unreliable,表示执行该节点可能具有side
effect,例如更改对象的映射。
kJSCreate 的处理有一个错误:如果有问题的对象不是 kJSCreate 的输出,那么循环继续而不将结果标记为不可靠。这是不正确的,因为 kJSCreate 可能会产生副作用,例如使用代理作为 Reflect.construct
的第三个参数。例如,可以通过内联 Array.pop 并在意外副作用期间将元素类型从 SMI 更改为 Doubles (类型混淆的点)来触发该错误。
Patch
1 | diff --git a/src/compiler/node-properties.cc b/src/compiler/node-properties.cc |
POC1
POC1比较好理解,利用smi和double的类型混淆,可以从最后一个Pop的数据看出
1 | ITERATIONS = 10000; |
POC2
这个POC2通过obj与double的混淆修改了a.length,关于%PrepareFunctionForOptimization的作用是为函数执行时,提供feedback栈。
1 | let a = [0, 1, 2, 3, 4]; |
漏洞利用
漏洞利用和常规的类型混淆漏洞利用方式差不多,获取map -> 获取fake_obj -> 任意读写 -> wasm 执行shellcode
exp
1 | var f64 = new Float64Array(1); |
参考链接:
1.browser-pwn cve-2020-6418 漏洞分析
2.CVE-2020-6418漏洞分析
3.Incorrect side effect modelling for JSCreate
4.Reflect.construct()