19.11.2016 Views

Technical Analysis of the Pegasus Exploits on iOS

eNQc3Ry

eNQc3Ry

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!