SSD Advisory – Chrome Type Confusion in JSCreateObject Operation to RCE

Vulnerabilities Summary
The following advisory discusses a vulnerability found in turbofan, the JIT compiler. We can trigger the JavaScript code in a way that leads to type confusion that can be exploited in order to execute code remotely on Google Chrome Versions 69.0 and before.

Vendor Response
Vendor has fixed the issue in Google Chrome version 70.


Independent security researcher, Samuel Groß, had reported this vulnerability to Beyond Security’s SecuriTeam Secure Disclosure program.

Affected systems
Google Chrome Versions 69.0 and before.

Vulnerability Details
In turbofan, the JIT compiler for v8, code is represented in a custom intermediate representation (IR) suitable for the various optimizations. To be able to detect and remove redundant checks, turbofan has to be able to model the side effects of all its IR operations. If this modelling is incorrect, safety checks, such as type checks, will incorrectly be removed from the emitted code, resulting in type confusions at runtime. See for more information about this type of vulnerability. Turbofan assumes that the JSCreateObject operation, used for JavaScript code such as “let newObj = Object.create(proto)”, is completely side-effect free, as can be seen in the definition of the operation in (the kNoWrite flag essentially means that the operation is sideeffect free):

This assumption is, however, not correct: when creating a new object with the given prototype object, this prototype object is modified if this is the first time that the object is used as a prototype. In particular, if the object had fast storage of properties before (all properties in a linear array), it will be converted to dictionary mode (properties stored in a hash map). However, due to the incorrect side-effect modelling, following JIT code still assumes that the prototype object has fast property storage. This leads to a type confusion between a PropertyArray and a NameDictionary when accessing properties of the prototype.

The initial type confusion gained from the bug can be turned into a confusion between two properties of an object as both the PropertyArray and the NameDictionary store property values inline. As such, the code following the CreateObject operation might load a property X from the object but will actually load the value of property Y. This in turn can be used to construct additional type confusion primitives due to the fact that v8 traces the types of properties of an object. For example, v8 might know that some property will always contain a pointer to an object with a certain Map and will remove type checks based on that. When it then fetches a different property due to the bug, it might load a double value which it would then use as a pointer. The exploit constructs two type confusions to obtain arbitrary read/write of the process’ memory: The addrof function in the attached PoC exploit constructs a confusion between an unboxed double property and a JSObject pointer property, thus leaking the value of the pointer and defeating ASLR. The corrupt_arraybuffer function then constructs a confusion between an ArrayBuffer and an object with inline properties, allowing it to corrupt the pointer to the backing storage of the ArrayBuffer with an arbitrary address. This way the exploit obtains an arbitrary read/write primitive. Finally, a Blink object with a vtable is corrupted and a virtual call performed on it, leading to RIP control, the execution of a small ROP chain, and finally shellcode execution.

*** This is a Security Bloggers Network syndicated blog from SecuriTeam Blogs authored by SSD / Ori Nimron. Read the original post at: