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.

The macro will expand <str<strong>on</strong>g>the</str<strong>on</strong>g> objsArray to accommodate <str<strong>on</strong>g>the</str<strong>on</strong>g> additi<strong>on</strong>al object and assign <str<strong>on</strong>g>the</str<strong>on</strong>g><br />

object to <str<strong>on</strong>g>the</str<strong>on</strong>g> end <str<strong>on</strong>g>of</str<strong>on</strong>g> <str<strong>on</strong>g>the</str<strong>on</strong>g> objsArray without increasing its reference count by means <str<strong>on</strong>g>of</str<strong>on</strong>g> a o-<br />

>retain() call. The problem with this method is that when a sec<strong>on</strong>d object replaces an<br />

existing object (in our example this is whenever <str<strong>on</strong>g>the</str<strong>on</strong>g> string object replaces <str<strong>on</strong>g>the</str<strong>on</strong>g> number object for<br />

KEY1), <str<strong>on</strong>g>the</str<strong>on</strong>g> first object is released and subsequently freed, but a pointer to <str<strong>on</strong>g>the</str<strong>on</strong>g> now freed object<br />

exists within <str<strong>on</strong>g>the</str<strong>on</strong>g> objsArray. Normally this would simply be a bad programming design issue,<br />

but <str<strong>on</strong>g>the</str<strong>on</strong>g> problem is compounded if a reference is made to <str<strong>on</strong>g>the</str<strong>on</strong>g> object via a<br />

kOSSerializeObject entry. If a kOSSerializeObject entry references, by index, <str<strong>on</strong>g>the</str<strong>on</strong>g> now<br />

dangling pointer <str<strong>on</strong>g>of</str<strong>on</strong>g> <str<strong>on</strong>g>the</str<strong>on</strong>g> freed object, <str<strong>on</strong>g>the</str<strong>on</strong>g> call to o->retain() will attempt to execute a virtual<br />

functi<strong>on</strong> that is attacker-c<strong>on</strong>trolled.<br />

In order to exploit this use-after-free c<strong>on</strong>diti<strong>on</strong>, 32Stage2 must take c<strong>on</strong>trol <str<strong>on</strong>g>of</str<strong>on</strong>g> <str<strong>on</strong>g>the</str<strong>on</strong>g> memory<br />

locati<strong>on</strong> that was deallocated and place a custom vtable that will have <str<strong>on</strong>g>the</str<strong>on</strong>g> entry for retain<br />

directed to a functi<strong>on</strong> <str<strong>on</strong>g>of</str<strong>on</strong>g> its own choosing. Installing a custom vtable requires having access to<br />

two deallocated, adjacent memory locati<strong>on</strong>s. Since it is not possible to directly overwrite <str<strong>on</strong>g>the</str<strong>on</strong>g><br />

vtable <str<strong>on</strong>g>of</str<strong>on</strong>g> an object during <str<strong>on</strong>g>the</str<strong>on</strong>g> serializati<strong>on</strong> process, by allocating and <str<strong>on</strong>g>the</str<strong>on</strong>g>n freeing two memory<br />

locati<strong>on</strong>s, 32Stage2 can use an OSData or OSString object to replace two memory locati<strong>on</strong>s<br />

at <strong>on</strong>ce with <strong>on</strong>e <str<strong>on</strong>g>of</str<strong>on</strong>g> <str<strong>on</strong>g>the</str<strong>on</strong>g> memory locati<strong>on</strong>s c<strong>on</strong>taining <str<strong>on</strong>g>the</str<strong>on</strong>g> malicious vtable. The easiest way to<br />

understand this c<strong>on</strong>cept is to look at <str<strong>on</strong>g>the</str<strong>on</strong>g> payload that 32Stage2 generates to exploit <str<strong>on</strong>g>the</str<strong>on</strong>g><br />

OSUnserializeBinary UAF vulnerability.<br />

The malicious payload that 32Stage2 generates for this vulnerability depends <strong>on</strong> <str<strong>on</strong>g>the</str<strong>on</strong>g> <strong>iOS</strong><br />

versi<strong>on</strong>. For <strong>iOS</strong> versi<strong>on</strong> 9.3.2 through at least 9.3.3, <str<strong>on</strong>g>the</str<strong>on</strong>g> payload takes <str<strong>on</strong>g>the</str<strong>on</strong>g> following form:<br />

[0x00] kOSSerializeBinarySignature<br />

[0x04] kOSSerializeEndCollect<strong>on</strong> | kOSSerializeDicti<strong>on</strong>ary | 0x10<br />

[0x08] kOSSerializeString | 4<br />

[0x0C] “sy2”<br />

[0x10] kOSSerializeData | 0x14<br />

[0x14] {payload buffer}<br />

[0x28]kOSSerializeEndCollect<strong>on</strong> | kOSSerializeObject | 1<br />

For <strong>iOS</strong> 9.0 through 9.3.1, <str<strong>on</strong>g>the</str<strong>on</strong>g> payload takes <str<strong>on</strong>g>the</str<strong>on</strong>g> following form:<br />

[0x00] kOSSerializeBinarySignature<br />

[0x04] kOSSerializeEndCollect<strong>on</strong> | kOSSerializeDicti<strong>on</strong>ary | 0x10<br />

[0x08] kOSSerializeString | 4<br />

[0x0C] “sy2”<br />

[0x10] kOSSerializeEndCollect<strong>on</strong> | kOSSerializeArray | 0x10<br />

[0x14] kOSSerializeDicti<strong>on</strong>ary | 0x10<br />

[0x18] kOSSerializeSymbol | 4<br />

[0x1C] “sy1”<br />

[0x20] kOSSerializeData | 0x14<br />

[0x24] ”ffff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0”<br />

[0x38] kOSSerializeSymbol | 4<br />

[0x3C] “sy1”<br />

[0x40] kOSSerializeEndCollect<strong>on</strong> | kOSSerializeSymbol | 4<br />

[0x44] “sy1”<br />

[0x48] kOSSerializeString | 0x1C<br />

[0x4C] {payload buffer}<br />

Page 28

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

Saved successfully!

Ooh no, something went wrong!