19.11.2016 Views

Technical Analysis of the Pegasus Exploits on iOS

eNQc3Ry

eNQc3Ry

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

deserialized, <str<strong>on</strong>g>the</str<strong>on</strong>g> object’s reference count is decremented by calling o->release(), which will<br />

lead to <str<strong>on</strong>g>the</str<strong>on</strong>g> object being free()ed in most cases. The excepti<strong>on</strong> to this behavior occurs within<br />

kOSSerializeObject objects.<br />

Since a kOSSerializeObject object represents an object that is referenced by o<str<strong>on</strong>g>the</str<strong>on</strong>g>r entries,<br />

it is necessary to retain <str<strong>on</strong>g>the</str<strong>on</strong>g> object after serializati<strong>on</strong>. As a result, during deserializati<strong>on</strong><br />

kOSSerializeObject objects will call o->retain(), <str<strong>on</strong>g>the</str<strong>on</strong>g>reby incrementing <str<strong>on</strong>g>the</str<strong>on</strong>g> reference<br />

count for <str<strong>on</strong>g>the</str<strong>on</strong>g> object and preventing its removal from memory.<br />

A serialized data blob allows for <str<strong>on</strong>g>the</str<strong>on</strong>g> same key to be used more than <strong>on</strong>ce. In o<str<strong>on</strong>g>the</str<strong>on</strong>g>r words, it is<br />

possible to have XML code that looks like:<br />

<br />

KEY1<br />

1<br />

KEY1<br />

2<br />

<br />

The above XML, <strong>on</strong>ce serialized, will c<strong>on</strong>tain five objects. The first object will be <str<strong>on</strong>g>the</str<strong>on</strong>g> dicti<strong>on</strong>ary<br />

c<strong>on</strong>tainer ( as a kOSSerializeDicti<strong>on</strong>ary object), followed by a symbol<br />

representing <str<strong>on</strong>g>the</str<strong>on</strong>g> key (as a kOSSerializeSymbol entry c<strong>on</strong>taining “KEY1”) and its data object<br />

(a kOSSerializeNumber entry for <str<strong>on</strong>g>the</str<strong>on</strong>g> integer 1). The fourth entry specifies ano<str<strong>on</strong>g>the</str<strong>on</strong>g>r key<br />

object, assigned KEY1 again, which is now a string object (kOSSerializeString) c<strong>on</strong>taining<br />

<str<strong>on</strong>g>the</str<strong>on</strong>g> string “2”. As part <str<strong>on</strong>g>of</str<strong>on</strong>g> <str<strong>on</strong>g>the</str<strong>on</strong>g> deserializati<strong>on</strong> process, <str<strong>on</strong>g>the</str<strong>on</strong>g> reuse <str<strong>on</strong>g>of</str<strong>on</strong>g> KEY1 results in <str<strong>on</strong>g>the</str<strong>on</strong>g> object that<br />

follows replacing <str<strong>on</strong>g>the</str<strong>on</strong>g> original value assigned to KEY1. This reassignment <str<strong>on</strong>g>of</str<strong>on</strong>g> a key with new data<br />

is <str<strong>on</strong>g>the</str<strong>on</strong>g> situati<strong>on</strong> where OSUnserializeBinary is vulnerable to attack.<br />

As stated previously, when an object is deserialized, and so l<strong>on</strong>g as that object is not a<br />

kOSSerializeObject, <str<strong>on</strong>g>the</str<strong>on</strong>g> object is stored in <str<strong>on</strong>g>the</str<strong>on</strong>g> objsArray for later reference. This<br />

storage is <str<strong>on</strong>g>the</str<strong>on</strong>g> result <str<strong>on</strong>g>of</str<strong>on</strong>g> <str<strong>on</strong>g>the</str<strong>on</strong>g> setAtIndex macro seen here:<br />

#define setAtIndex(v, idx, o) \<br />

if (idx >= v##Capacity) \<br />

{ \<br />

uint32_t ncap = v##Capacity + 64; \<br />

type<str<strong>on</strong>g>of</str<strong>on</strong>g>(v##Array) nbuf = (type<str<strong>on</strong>g>of</str<strong>on</strong>g>(v##Array)) kalloc_c<strong>on</strong>tainer(ncap * size<str<strong>on</strong>g>of</str<strong>on</strong>g>(o)); \<br />

if (!nbuf) ok = false; \<br />

if (v##Array) \<br />

{ \<br />

bcopy(v##Array, nbuf, v##Capacity * size<str<strong>on</strong>g>of</str<strong>on</strong>g>(o)); \<br />

kfree(v##Array, v##Capacity * size<str<strong>on</strong>g>of</str<strong>on</strong>g>(o)); \<br />

} \<br />

v##Array = nbuf; \<br />

v##Capacity = ncap; \<br />

} \<br />

if (ok) v##Array[idx] = o;<br />

Page 27

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

Saved successfully!

Ooh no, something went wrong!