ChromeV8漏洞

shellcode写入位置
本地环境
xbrew install cmakegit clone https://github.com/juj/emsdk.gitcd emsdk./emsdk install latest./emsdk activate latestsource ./emsdk_env.sh代码
xxxxxxxxxxint main(int argc, char ** argv) { printf("Hello World\n");}编译命令
xxxxxxxxxxemcc hello.c -Os -s WASM=1 -s SIDE_MODULE=1 -s EXPORTED_FUNCTIONS="['main']" -o hello.wasm调试
通过在线编译环境(WasmExplorer)编写测试代码
xxxxxxxxxxint hack(int x) { int ret = puts("the gay is lazy, nothing left."); return ret + x;}生成js代码:
xxxxxxxxxxfunction webAssembly() { let wasmCode = null let wasmModel = null let wasmInstance = null let wasmImports = null let wasmBuffer = null let wasmFunc = null wasmCode = new Uint8Array([0,97,115,109,1,0,0,0,1,138,128,128,128,0,2,96,0,1,127,96,1,127,1,127,2,140,128,128,128,0,1,3,101,110,118,4,112,117,116,115,0,1,3,130,128,128,128,0,1,1,4,132,128,128,128,0,1,112,0,0,5,131,128,128,128,0,1,0,1,6,129,128,128,128,0,0,7,145,128,128,128,0,2,6,109,101,109,111,114,121,2,0,4,104,97,99,107,0,1,10,143,128,128,128,0,1,137,128,128,128,0,0,65,16,16,0,32,0,106,11,11,165,128,128,128,0,1,0,65,16,11,31,116,104,101,32,103,97,121,32,105,115,32,108,97,122,121,44,32,110,111,116,104,105,110,103,32,108,101,102,116,46,0]) wasmImports = { env: { puts: function puts (i32) { // eval(`hacking('xxooxxoo')`) return 0x41414141 } } } wasmInstance = new WebAssembly.Instance(new WebAssembly.Module(wasmCode), wasmImports) wasmBuffer = new Uint8Array(wasmInstance.exports.memory.buffer) wasmFunc = wasmInstance.exports.hack ;%DebugPrint(wasmFunc); ;%SystemBreak(); console.log('WebAssembly function return: 0x' + wasmFunc().toString(16))}webAssembly()挂上d8调试:
xxxxxxxxxxgdb --args ./v8/out.gn/ia32.debug/d8 --allow-natives-syntax ./test.js断下来之后:
xxxxxxxxxxDebugPrint: 0x2ce97431: [Function] in OldSpace- map: 0x33c86131 <Map(HOLEY_ELEMENTS)> [FastProperties]- prototype: 0x2ce853b1 <JSFunction (sfi = 0x43505701)>- elements: 0x4c2046d1 <FixedArray[0]> [HOLEY_ELEMENTS]- function prototype: <no-prototype-slot>- shared_info: 0x2ce9740d <SharedFunctionInfo 1>- name: 0x4c206495 <String[1]: 1>- formal_parameter_count: 1- kind: NormalFunction- context: 0x2ce84f5d <NativeContext[248]>- code: 0xf349c961 <Code JS_TO_WASM_FUNCTION>- WASM instance 0x2ce97321- WASM function index 1- properties: 0x4c2046d1 <FixedArray[0]> {#length: 0x435106dd <AccessorInfo> (const accessor descriptor)#name: 0x435106a5 <AccessorInfo> (const accessor descriptor)#arguments: 0x43510635 <AccessorInfo> (const accessor descriptor)#caller: 0x4351066d <AccessorInfo> (const accessor descriptor)}
优化后的代码 JS_TO_WASM_FUNCTION:
xxxxxxxxxxpwndbg> job 0xf349c9610xf349c961: [Code]- map: 0x4c2045b1 <Map>kind = JS_TO_WASM_FUNCTIONcompiler = turbofanaddress = 0xf349c961Instructions (size = 180)0xf349c9a0 0 55 push ebp0xf349c9a1 1 89e5 mov ebp,esp0xf349c9a3 3 56 push esi0xf349c9a4 4 57 push edi0xf349c9a5 5 83ec08 sub esp,0x80xf349c9a8 8 8b470b mov eax,[edi+0xb]0xf349c9ab b 8b4003 mov eax,[eax+0x3]0xf349c9ae e 8b4807 mov ecx,[eax+0x7]0xf349c9b1 11 8945f0 mov [ebp-0x10],eax0xf349c9b4 14 894df4 mov [ebp-0xc],ecx0xf349c9b7 17 89c2 mov edx,eax0xf349c9b9 19 8b4508 mov eax,[ebp+0x8]0xf349c9bc 1c e81f693940 call 0x338332e0 (ToNumber) ;; code: Builtin::ToNumber0xf349c9c1 21 a801 test al,0x10xf349c9c3 23 0f8539000000 jnz 0xf349ca02 <+0x62>0xf349c9c9 29 d1f8 sar eax,10xf349c9cb 2b f20f2ac8 cvtsi2sd xmm1,eax0xf349c9cf 2f 8b75f4 mov esi,[ebp-0xc]0xf349c9d2 32 8b4677 mov eax,[esi+0x77]0xf349c9d5 35 8b4df0 mov ecx,[ebp-0x10]0xf349c9d8 38 8b490b mov ecx,[ecx+0xb]0xf349c9db 3b d1f9 sar ecx,10xf349c9dd 3d f20f2cd1 cvttsd2si edx,xmm10xf349c9e1 41 83fa01 cmp edx,0x10xf349c9e4 44 0f8051000000 jo 0xf349ca3b <+0x9b>0xf349c9ea 4a 03c8 add ecx,eax0xf349c9ec 4c 89d0 mov eax,edx0xf349c9ee 4e ffd1 call ecx0xf349c9f0 50 89c1 mov ecx,eax0xf349c9f2 52 03c8 add ecx,eax0xf349c9f4 54 0f802b000000 jo 0xf349ca25 <+0x85>0xf349c9fa 5a 89c8 mov eax,ecx0xf349c9fc 5c 89ec mov esp,ebp0xf349c9fe 5e 5d pop ebp0xf349c9ff 5f c20800 ret 0x80xf349ca02 62 8b4df4 mov ecx,[ebp-0xc]0xf349ca05 65 39413f cmp [ecx+0x3f],eax0xf349ca08 68 0f8407000000 jz 0xf349ca15 <+0x75>0xf349ca0e 6e f20f104803 movsd xmm1,[eax+0x3]0xf349ca13 73 ebba jmp 0xf349c9cf <+0x2f>0xf349ca15 75 660f76c9 pcmpeqd xmm1,xmm10xf349ca19 79 660f73f134 psllq xmm1,520xf349ca1e 7e 660f73d101 psrlq xmm1,10xf349ca23 83 ebaa jmp 0xf349c9cf <+0x2f>0xf349ca25 85 8945f4 mov [ebp-0xc],eax0xf349ca28 88 e85376623c call 0x2fac4080 (AllocateHeapNumber) ;; code: Builtin::AllocateHeapNumber0xf349ca2d 8d f20f2a4df4 cvtsi2sd xmm1,[ebp-0xc]0xf349ca32 92 f20f114803 movsd [eax+0x3],xmm10xf349ca37 97 89c1 mov ecx,eax0xf349ca39 99 ebbf jmp 0xf349c9fa <+0x5a>0xf349ca3b 9b 83ec08 sub esp,0x80xf349ca3e 9e f20f110c24 movsd [esp],xmm10xf349ca43 a3 e8b809c963 call 0x5712d400 (DoubleToI) ;; code: Builtin::DoubleToI0xf349ca48 a8 8b1424 mov edx,[esp]0xf349ca4b ab 83c408 add esp,0x80xf349ca4e ae eb9a jmp 0xf349c9ea <+0x4a>0xf349ca50 b0 90 nop0xf349ca51 b1 0f1f00 nop
漏洞利用中写shellcode的地方位置:
xxxxxxxxxxpwndbg> job 0x2ce9740d0x2ce9740d: [SharedFunctionInfo] in OldSpace- map: 0x4c204589 <Map[36]>- name: 0x4c206495 <String[1]: 1>- kind: NormalFunction- function_map_index: 137- formal_parameter_count: 1- expected_nof_properties:- language_mode: sloppy- data: 0x2ce973f9 <WasmExportedFunctionData>- code (from data): 0xf349c961 <Code JS_TO_WASM_FUNCTION>- function token position: -1- start position: -1- end position: -1- no debug info- scope info: 0x4c2046c9 <ScopeInfo[0]>- length: 1- feedback_metadata: 0x4c2055b9: [FeedbackMetadata]- map: 0x4c204a25 <Map>- slot_count: 0pwndbg> job 0x2ce973f90x2ce973f9: [WasmExportedFunctionData] in OldSpace- map: 0x4c207389 <Map[20]>- wrapper_code: 0xf349c961 <Code JS_TO_WASM_FUNCTION>- instance: 0x2ce97321 <Instance map = 0x33c88ae9>- function_index: 1pwndbg> job 0x2ce973210x2ce97321: [WasmInstanceObject] in OldSpace- map: 0x33c88ae9 <Map(HOLEY_ELEMENTS)>- module_object: 0x4c112bd5 <Module map = 0x33c88819>- exports_object: 0x4c112d01 <Object map = 0x33c898a9>- native_context: 0x2ce84f5d <NativeContext[248]>- memory_object: 0x2ce973c1 <Memory map = 0x33c88fe9>- imported_function_instances: 0x4c112cb9 <FixedArray[1]>- imported_function_callables: 0x4c112cc5 <FixedArray[1]>- managed_native_allocations: 0x4c112cb1 <Foreign>- memory_start: 0xf3550000- memory_size: 65536- memory_mask: ffff- imported_function_targets: 0x56f6db10- globals_start: (nil)- imported_mutable_globals: 0x56f6db20- indirect_function_table_size: 0- indirect_function_table_sig_ids: (nil)- indirect_function_table_targets: (nil)pwndbg> dd 0x56f6db1056f6db10 563144e0 00000000 00000000 0000001156f6db20 00000000 00000000 00000000 0000002156f6db30 f7ec43ac 00000000 00000000 56f6daf056f6db40 31619bea 56f76360 00000001 00000021
查找链为:
xxxxxxxxxxJSFunciton -> SharedFunctionInfo -> WasmExportedFunctionData -> instance -> imported_function_targets[x]
最终的imported_function_targets依次存放着导入函数的代码.
如 0x563144e0 处为 hack 函数的实现:
xxxxxxxxxxpwndbg> db 0x563144e0 80563144e0 55 89 e5 6a 0c 56 83 ec 18 8b 4e 13 8b 56 2f 8b563144f0 52 07 8b 5e 3f 8b 7a 0f 89 55 f0 8b 51 17 89 4d56314500 f4 89 c1 03 c8 0f 80 74 00 00 00 ff f2 ff f1 b856314510 01 00 00 00 89 f1 89 fe 8b 7d f0 89 da 3b 77 0f56314520 0f 84 2a 00 00 00 89 e0 83 ec 08 83 e4 f0 89 44
下断点并执行

中断到wasm执行代码中:
xxxxxxxxxx ► 0x563144e0 push ebp 0x563144e1 mov ebp, esp 0x563144e3 push 0xc 0x563144e5 push esi 0x563144e6 sub esp, 0x18 0x563144e9 mov ecx, dword ptr [esi + 0x13] 0x563144ec mov edx, dword ptr [esi + 0x2f] 0x563144ef mov edx, dword ptr [edx + 7] 0x563144f2 mov ebx, dword ptr [esi + 0x3f] 0x563144f5 mov edi, dword ptr [edx + 0xf] ... 0x56314550 mov ecx, dword ptr [edi + 0x17] 0x56314553 add ecx, 0x3f 0x56314556 call ecx // 执行 hack 函数也可以直接通过 wasmInstance 直接找到 imported_function_targets
漏洞挖掘的问题
主流的挖掘流程:

- 目标选择是否合理
- 目标代码逻辑难以理解
- 优化机制使代码覆盖率提高难度极大
- 崩溃可利用率极低
漏洞利用的问题
类型混淆的职业受害者:

- 受害高度一致性
- 利用套路一致性
- 蝴蝶效应的思考
- 新的挖掘模型
蝴蝶效应引发的漏洞模型?

- 避开所有难点
- 持续积累
- 历史漏洞复现
- 理论可行性分析