iOS/macOS xpc_data Objects Sandbox Escape Privelege Escalation

2017.08.01
Risk: Medium
Local: No
Remote: Yes
CWE: N/A


CVSS Base Score: 6.8/10
Impact Subscore: 6.4/10
Exploitability Subscore: 8.6/10
Exploit range: Remote
Attack complexity: Medium
Authentication: No required
Confidentiality impact: Partial
Integrity impact: Partial
Availability impact: Partial

When XPC serializes large xpc_data objects it creates mach memory entry ports to represent the memory region then transfers that region to the receiving process by sending a send right to the memory entry port in the underlying mach message. By crafting our own xpc message (or using an interposition library as this poc does) we can pass different flags to mach_make_memory_entry_64 such that the memory entry received by the target process actually represents a region of shared memory such that when the xpc_data deserialization code maps the memory entry port the memory region remains mapped in the sender's address space and the sender can still modify it (with the receiver seeing the updates.) Perhaps this is intended behaviour but there's definitely plenty of code which doesn't expect the contents of xpc_data objects to change. In this PoC I target NSXPC, a high-level RPC mechanism which uses XPC for its low-level transport layer. NSXPC is widely used across privilege boundaries. NSXPCDecoder is implemented in Foundation. Clients send serialized NSInvocation objects representing the methods they wish to call on the remote objects. These NSInvocations are serialized using the NSSecureCoding method which ends up creating a bplist16 serialized byte stream. That bplist16 buffer gets sent in an xpc message as an xpc_data object. NSXPCDecoder wraps the bplist16 deserialization and for selectors such as decodeCStringForKey: ,if the key is present, the value returned will be a pointer directly into the xpc_data object in which it was received. By crafting our own memory entry object this means the pointers returned by decodeCStringForKey: actually point into shared memory which can still be modified by the caller. This can be turned directly into controlled memory corruption by targetting the serialized method type signature (key 'ty') which is parsed by [NSMethodSignature signatureWithObjCTypes]. This method is implemented in CoreFoundation. If the method signature string isn't in a cache of parsed signatures then the string is passed to __NSMS1. This function calls __NSGetSizeAndAlignment to determine the size of a buffer required to parse the signature string which __NSMS1 then allocates using calloc before parsing the signature string into the allocated buffer. If we change the types represented by the signature string (which is in shared memory) between these two calls we can cause the parsing code to write out of bounds as it assumes that the length computed by __NSGetSizeAndAlignment is correct. The most direct path to trigger memory controlled memory corruption is to use a type signature like this: @"ABCD" That will cause 7 bytes of buffer space to be allocated for the parsed signature (which will just contain a copy of the string.) If we increase the length of the string in shared memory eg to: @"ABCDOVERFLOW_OVERFLOW_OVERFLOW" then __NSMS1 will copy the extra bytes up until it encounters a '"' character. This PoC targets the airportd daemon which runs as root but should work for any NSXPC service. This is a race condition so you may have to run the PoC multiple times (./run.sh) and also use libgmalloc to see the corruption directly rather than its effects. ################################################################################ triple_fetch - ianbeer This is an exploit for CVE-2017-7047, a logic error in libxpc which allowed malicious message senders to send xpc_data objects that were backed by shared memory. Consumers of xpc messages did not seem to expect that the backing buffers of xpc_data objects could be modified by the sender whilst being processed by the receiver. This project exploits CVE-2017-7047 to build a proof-of-concept remote lldb debugserver stub capable of attaching to and allowing the remote debugging all userspace processes on iOS 10.0 to 10.3.2. Please see the README in the nsxpc2pc folder in the attached archive for further discussion and details. ################################################################################ The exploit isn't hugely reliable - the race condition needs quite exact timing and sometimes it just doesn't work or it does but the heap groom fails. You should just hard reboot the device and try again. It may take a couple of attempts but it should work. Once the debugserver is running it should be stable. If you take a look at the xcode stdout/debugger window you can see some more status information.

References:

https://bugs.chromium.org/p/project-zero/issues/detail?id=1247


Vote for this issue:
50%
50%


 

Thanks for you vote!


 

Thanks for you comment!
Your message is in quarantine 48 hours.

Comment it here.


(*) - required fields.  
{{ x.nick }} | Date: {{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1
{{ x.comment }}

Copyright 2017, cxsecurity.com

 

Back to Top