Modifications to Archived Data

Questions and Answers about all things *OS (macOS, iOS, tvOS, watchOS)

Modifications to Archived Data

Postby patrick » Mon Jun 22, 2015 10:45 pm

Apple's 'Validating Input' document https://developer.apple.com/library/ios/documentation/Security/Conceptual/SecureCodingGuide/Articles/ValidatingInput.html contains a section that says one should treat archived data as untrusted. It goes on to say that if de-serialization code uses the decodeObjectForKey method instead of decodeObjectOfClass:forKey: then an attacker may be able to coerce the deserialization and (re)constructing of an 'unexpected' object. This makes sense.

However, I've seen claims that "this can cause serious problems” (http://nshipster.com/nssecurecoding/) and Apple states that "if your initWithCoder: method calls the decodeObjectForKey: method, by the time that call returns, it may already be too late to prevent misbehavior.” Sure, if the decodeObjectForKey returns, say a NSString object, instead of an expected NSData object, and then the code calls some NSData method (e.g. 'subdataWithRange’), the code would likely throw an 'unrecognized selector sent to instance’ exception. The Apple documentation isn't clear on the risks of using decodeObjectForKey. I'm concerned an attacker could do something more evil. Like could they craft some ‘malicious’ object that during the de-serialization (decodeObjectForKey) process provides generic code execution? Or is a successful attack non-generic and dependent upon what the code does with the object once the decodeObjectForKey returns?

As always, thanks for your time and input :)
patrick
 
Posts: 7
Joined: Mon May 04, 2015 5:04 am

Re: Modifications to Archived Data

Postby morpheus » Fri Aug 21, 2015 4:14 am

Oops. Missed this one too. Sheesh.

dofk is dangerous like any other deserialization, and there are actually lower hanging fruit than it - XPC's type confusion, described perfectly by Ian Beer in his presentation and research, shows the dangers associated. As you lay objects in memory in one end of the IPC, and attempt to recover them on the other end, it works - so much as the two sides are sync'ed and "playing by the rules". If the sender maliciously crafts a different object, and passes it to the recipient, the latter blindly reconstructs it in what amounts to a memcpy, instantly populating fields without performing any bounds check or validation. What follows is that if there is any sort of "type confusion", what should be a pointer in, say, a CFDictionary, becomes a dangling pointer which the application can overwrite by mistake thereby gaining arbitrary memory overwrite by the attacker, who can use this to predictably subvert the app to write over, say, a return address, and hijack EIP/PC.

Exploiting this, however, requires intimate knowledge of the actual message, and its expected format. Not all messages are thus exploitable, and some may be exploitable in different ways. E.g a message composed of just integers may not be exploitable, or may be - if, say, the integers are used as indices to some array (think a[i] = v), where i and v may be under the attacker control.

Hurdles remain - notably, since you have Data execution prevention, you still need to chain ROP gadgets or similar. An attacker will likely try for some gadget that mprotects rwx the serialized object (assuming OS X, not iOS) itself and jumps to it, or something of the like.

Btw, this is *way* easy to achieve with Objective-C classes, as when the object is constructed its data and vtable/method cache are in close proximity, so the latter two can be easily overwritten, again subverting execution.
morpheus
Site Admin
 
Posts: 530
Joined: Thu Apr 11, 2013 6:24 pm


Return to Questions and Answers

Who is online

Users browsing this forum: No registered users and 2 guests