From Assembly to JavaScript and Back: Turning Memory Errors into Code Execution with Client-Side Compilers


Compilers of interpreter languages were developed in order to speed up execution in the race for web browser performance. Various different compilers and analysis stages are involved to aggressively transform JavaScript code into machine code of the architecture the browser runs on. With the aim to squeeze the very last bit of performance out of our precious and indispensable browsers, Just-In-Time (JIT) compilation gained widespread adoption. It provides near-native run time for otherwise slowly interpreted JavaScript code. It turns out that it is only the beginning, and Ahead-of-Time (AOT) compilers such as ASM.JS and its successor WebAssembly are emerging and won’t disappear any time soon. Despite the intended performance gain, security concerns come into play.

Attackers welcomed JIT compilers in their own way and started to abuse the possibility to emit native machine code derived from controlled script constants. By filling predictable address regions with hidden assembly instructions, the JIT-Spray technique was born. Since then, many client-side JIT-Spray primitives were developed to ease the exploitation of various memory errors, which we’ll revisit in the beginning of this talk. Afterwards, we go a step further and analyze flaws we found in ASM.JS of Mozilla Firefox, tracked as CVE-2017-5375 and CVE-2017-5400, allowing an attacker to jump to “JIT” sprayed executable code. Furthermore, we’ll dive into three different Firefox CVEs and demonstrate alternative exploitation with ASM.JS JIT-Spray. On the way to remote code execution, we show how arbitrary ASM.JS payloads are crafted and transformed automatically, providing you with the ability to run your favorite code implant on vulnerable Firefox versions.

Location: BALLROOM 1 Date: August 30, 2018 Time: 11:00 am - 12:00 pm Robert Gawlik