You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
}<br />
return JSValue::encode(jsUndefined());<br />
This binding takes two arguments: <str<strong>on</strong>g>the</str<strong>on</strong>g> first is an ImpureGetter, and <str<strong>on</strong>g>the</str<strong>on</strong>g> sec<strong>on</strong>d is a generic<br />
JSObject that will be set as <str<strong>on</strong>g>the</str<strong>on</strong>g> ImpureGetter’s delegate. The issue results from <str<strong>on</strong>g>the</str<strong>on</strong>g> lack <str<strong>on</strong>g>of</str<strong>on</strong>g><br />
validati<strong>on</strong> that <str<strong>on</strong>g>the</str<strong>on</strong>g> JSObject passed as <str<strong>on</strong>g>the</str<strong>on</strong>g> first argument is in fact a well-formed ImpureGetter.<br />
When ano<str<strong>on</strong>g>the</str<strong>on</strong>g>r object type is passed as <str<strong>on</strong>g>the</str<strong>on</strong>g> first argument, <str<strong>on</strong>g>the</str<strong>on</strong>g> object pointer will be improperly<br />
downcast to an ImpureGetter pointer.<br />
Subsequently, when <str<strong>on</strong>g>the</str<strong>on</strong>g> m_delegate member is set via setDelegate(), a pointer to <str<strong>on</strong>g>the</str<strong>on</strong>g> JSObject<br />
passed as <str<strong>on</strong>g>the</str<strong>on</strong>g> sec<strong>on</strong>d argument will be written to <str<strong>on</strong>g>the</str<strong>on</strong>g> <str<strong>on</strong>g>of</str<strong>on</strong>g>fset that aligns with m_delegate (16<br />
bytes into <str<strong>on</strong>g>the</str<strong>on</strong>g> supplied object). This issue can be used to create a primitive that allows a pointer<br />
to an arbitrary JSObject to be written 16 bytes into any o<str<strong>on</strong>g>the</str<strong>on</strong>g>r JSObject.<br />
Exploitati<strong>on</strong><br />
<str<strong>on</strong>g>Pegasus</str<strong>on</strong>g> leverages this issue to achieve unsigned code executi<strong>on</strong> from within an <strong>iOS</strong><br />
applicati<strong>on</strong> c<strong>on</strong>text. In order to gain c<strong>on</strong>trol <str<strong>on</strong>g>of</str<strong>on</strong>g> executi<strong>on</strong> flow, <str<strong>on</strong>g>the</str<strong>on</strong>g> exploit uses a number <str<strong>on</strong>g>of</str<strong>on</strong>g><br />
DataView objects. DataViews are used because <str<strong>on</strong>g>the</str<strong>on</strong>g>y provide a trivial mechanism to read and<br />
write arbitrary <str<strong>on</strong>g>of</str<strong>on</strong>g>fsets into a vector. The DataView object also c<strong>on</strong>veniently has a pointer to <str<strong>on</strong>g>the</str<strong>on</strong>g><br />
backing buffer at its 16 byte <str<strong>on</strong>g>of</str<strong>on</strong>g>fset. Using <str<strong>on</strong>g>the</str<strong>on</strong>g>se corrupted DataView objects, <str<strong>on</strong>g>the</str<strong>on</strong>g> exploit sets up<br />
<str<strong>on</strong>g>the</str<strong>on</strong>g> tools needed to gain arbitrary native code executi<strong>on</strong> - namely, a read/write primitive and <str<strong>on</strong>g>the</str<strong>on</strong>g><br />
ability to leak <str<strong>on</strong>g>the</str<strong>on</strong>g> address <str<strong>on</strong>g>of</str<strong>on</strong>g> an arbitrary JavaScript object. Once this setup is complete, <str<strong>on</strong>g>the</str<strong>on</strong>g><br />
exploit can create an executable mapping c<strong>on</strong>taining <str<strong>on</strong>g>the</str<strong>on</strong>g> native code payload. The following<br />
secti<strong>on</strong>s detail <str<strong>on</strong>g>the</str<strong>on</strong>g> various stages <str<strong>on</strong>g>of</str<strong>on</strong>g> this process.<br />
Acquiring an arbitrary read/write primitive<br />
A read/write primitive for arbitrary <str<strong>on</strong>g>of</str<strong>on</strong>g>fsets into a DataView object can be obtained using <str<strong>on</strong>g>the</str<strong>on</strong>g><br />
following code snippet.<br />
var dummy_ab = new ArrayBuffer(0x20);<br />
var dataview_init_rw = new DataView(dummy_ab);<br />
...<br />
var dataview_rw = new DataView(dummy_ab);<br />
…<br />
setImpureGetterDelegate(dataview_init_rw, dataview_rw);<br />
First, two DataViews are created using a dummy ArrayBuffer as <str<strong>on</strong>g>the</str<strong>on</strong>g> backing vector for both.<br />
Next, <str<strong>on</strong>g>the</str<strong>on</strong>g> issue is exploited to corrupt <str<strong>on</strong>g>the</str<strong>on</strong>g> m_vector member <str<strong>on</strong>g>of</str<strong>on</strong>g> <str<strong>on</strong>g>the</str<strong>on</strong>g> dataview_init_rw object with<br />
a pointer to <str<strong>on</strong>g>the</str<strong>on</strong>g> dataview_rw object. Subsequent reads and writes into <str<strong>on</strong>g>the</str<strong>on</strong>g> dataview_init_rw<br />
DataView will allow arbitrary members <str<strong>on</strong>g>of</str<strong>on</strong>g> <str<strong>on</strong>g>the</str<strong>on</strong>g> dataview_rw to be leaked or overwritten. Next,<br />
c<strong>on</strong>trol over this object is used to gain a read/write primitive for <str<strong>on</strong>g>the</str<strong>on</strong>g> entirety <str<strong>on</strong>g>of</str<strong>on</strong>g> process memory.<br />
Page 40