ChromeV8漏洞
shellcode写入位置
本地环境
xbrew install cmake
git clone https://github.com/juj/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
source ./emsdk_env.sh
代码
xxxxxxxxxx
int main(int argc, char ** argv) {
printf("Hello World\n");
}
编译命令
xxxxxxxxxx
emcc hello.c -Os -s WASM=1 -s SIDE_MODULE=1 -s EXPORTED_FUNCTIONS="['main']" -o hello.wasm
调试
通过在线编译环境(WasmExplorer)编写测试代码
xxxxxxxxxx
int hack(int x) {
int ret = puts("the gay is lazy, nothing left.");
return ret + x;
}
生成js代码:
xxxxxxxxxx
function 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调试:
xxxxxxxxxx
gdb --args ./v8/out.gn/ia32.debug/d8 --allow-natives-syntax ./test.js
断下来之后:
xxxxxxxxxx
DebugPrint: 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:
xxxxxxxxxx
pwndbg> job 0xf349c961
0xf349c961: [Code]
- map: 0x4c2045b1 <Map>
kind = JS_TO_WASM_FUNCTION
compiler = turbofan
address = 0xf349c961
Instructions (size = 180)
0xf349c9a0 0 55 push ebp
0xf349c9a1 1 89e5 mov ebp,esp
0xf349c9a3 3 56 push esi
0xf349c9a4 4 57 push edi
0xf349c9a5 5 83ec08 sub esp,0x8
0xf349c9a8 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],eax
0xf349c9b4 14 894df4 mov [ebp-0xc],ecx
0xf349c9b7 17 89c2 mov edx,eax
0xf349c9b9 19 8b4508 mov eax,[ebp+0x8]
0xf349c9bc 1c e81f693940 call 0x338332e0 (ToNumber) ;; code: Builtin::ToNumber
0xf349c9c1 21 a801 test al,0x1
0xf349c9c3 23 0f8539000000 jnz 0xf349ca02 <+0x62>
0xf349c9c9 29 d1f8 sar eax,1
0xf349c9cb 2b f20f2ac8 cvtsi2sd xmm1,eax
0xf349c9cf 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,1
0xf349c9dd 3d f20f2cd1 cvttsd2si edx,xmm1
0xf349c9e1 41 83fa01 cmp edx,0x1
0xf349c9e4 44 0f8051000000 jo 0xf349ca3b <+0x9b>
0xf349c9ea 4a 03c8 add ecx,eax
0xf349c9ec 4c 89d0 mov eax,edx
0xf349c9ee 4e ffd1 call ecx
0xf349c9f0 50 89c1 mov ecx,eax
0xf349c9f2 52 03c8 add ecx,eax
0xf349c9f4 54 0f802b000000 jo 0xf349ca25 <+0x85>
0xf349c9fa 5a 89c8 mov eax,ecx
0xf349c9fc 5c 89ec mov esp,ebp
0xf349c9fe 5e 5d pop ebp
0xf349c9ff 5f c20800 ret 0x8
0xf349ca02 62 8b4df4 mov ecx,[ebp-0xc]
0xf349ca05 65 39413f cmp [ecx+0x3f],eax
0xf349ca08 68 0f8407000000 jz 0xf349ca15 <+0x75>
0xf349ca0e 6e f20f104803 movsd xmm1,[eax+0x3]
0xf349ca13 73 ebba jmp 0xf349c9cf <+0x2f>
0xf349ca15 75 660f76c9 pcmpeqd xmm1,xmm1
0xf349ca19 79 660f73f134 psllq xmm1,52
0xf349ca1e 7e 660f73d101 psrlq xmm1,1
0xf349ca23 83 ebaa jmp 0xf349c9cf <+0x2f>
0xf349ca25 85 8945f4 mov [ebp-0xc],eax
0xf349ca28 88 e85376623c call 0x2fac4080 (AllocateHeapNumber) ;; code: Builtin::AllocateHeapNumber
0xf349ca2d 8d f20f2a4df4 cvtsi2sd xmm1,[ebp-0xc]
0xf349ca32 92 f20f114803 movsd [eax+0x3],xmm1
0xf349ca37 97 89c1 mov ecx,eax
0xf349ca39 99 ebbf jmp 0xf349c9fa <+0x5a>
0xf349ca3b 9b 83ec08 sub esp,0x8
0xf349ca3e 9e f20f110c24 movsd [esp],xmm1
0xf349ca43 a3 e8b809c963 call 0x5712d400 (DoubleToI) ;; code: Builtin::DoubleToI
0xf349ca48 a8 8b1424 mov edx,[esp]
0xf349ca4b ab 83c408 add esp,0x8
0xf349ca4e ae eb9a jmp 0xf349c9ea <+0x4a>
0xf349ca50 b0 90 nop
0xf349ca51 b1 0f1f00 nop
漏洞利用中写shellcode的地方位置:
xxxxxxxxxx
pwndbg> job 0x2ce9740d
0x2ce9740d: [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: 0
pwndbg> job 0x2ce973f9
0x2ce973f9: [WasmExportedFunctionData] in OldSpace
- map: 0x4c207389 <Map[20]>
- wrapper_code: 0xf349c961 <Code JS_TO_WASM_FUNCTION>
- instance: 0x2ce97321 <Instance map = 0x33c88ae9>
- function_index: 1
pwndbg> job 0x2ce97321
0x2ce97321: [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 0x56f6db10
56f6db10 563144e0 00000000 00000000 00000011
56f6db20 00000000 00000000 00000000 00000021
56f6db30 f7ec43ac 00000000 00000000 56f6daf0
56f6db40 31619bea 56f76360 00000001 00000021
查找链为:
xxxxxxxxxx
JSFunciton -> SharedFunctionInfo -> WasmExportedFunctionData -> instance -> imported_function_targets[x]
最终的imported_function_targets
依次存放着导入函数的代码.
如 0x563144e0 处为 hack
函数的实现:
xxxxxxxxxx
pwndbg> db 0x563144e0 80
563144e0 55 89 e5 6a 0c 56 83 ec 18 8b 4e 13 8b 56 2f 8b
563144f0 52 07 8b 5e 3f 8b 7a 0f 89 55 f0 8b 51 17 89 4d
56314500 f4 89 c1 03 c8 0f 80 74 00 00 00 ff f2 ff f1 b8
56314510 01 00 00 00 89 f1 89 fe 8b 7d f0 89 da 3b 77 0f
56314520 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
漏洞挖掘的问题
主流的挖掘流程:
- 目标选择是否合理
- 目标代码逻辑难以理解
- 优化机制使代码覆盖率提高难度极大
- 崩溃可利用率极低
漏洞利用的问题
类型混淆的职业受害者:
- 受害高度一致性
- 利用套路一致性
- 蝴蝶效应的思考
- 新的挖掘模型
蝴蝶效应引发的漏洞模型?
- 避开所有难点
- 持续积累
- 历史漏洞复现
- 理论可行性分析
没有评论:
发表评论