Series of Articles
- iOS Jailbreak Principles - Analysis of Sock Port Vulnerability (One) UAF and Heap Spraying
- iOS Jailbreak Principles - Analysis of Sock Port Vulnerability (Two) Leaking Port Address through Mach OOL Message
- iOS Jailbreak Principles - Analysis of Sock Port Vulnerability (Three) IOSurface Heap Spraying
- iOS Jailbreak Principles - Analysis of Sock Port Vulnerability (Four) The tfp0 !
Preface
In the Sock Port series of articles, we introduced the entire process of obtaining tfp0 through Socket UAF from 0 to 1. Starting with this article, we will analyze Undecimus This article introduces the whole process from tfp0 to jailbreak.
The operations that can be done through tfp0 alone are only basic operations such as kread, kwrite, etc. To achieve rootfs read/write, kexec, and other complex tasks, it requires very complicated steps. This article will introduce the principles and process of escaping the sandbox through tfp0 to achieve rootfs read/write.
The Sandbox

There are two important kernel extensions in iOS, namely AppleMobileFileIntegrity.kext
and Sandbox.kext
.
Apple Mobile File Integrity
According to the definition of AMFI in The iPhone Wiki [1]:
AppleMobileFileIntegrity(.kext), which can also be referred to by its full name com.apple.driver.AppleMobileFileIntegrity, is an iOS kernel extension that serves as the cornerstone of iOS's code entitlements model. It is one of the dependencies of the Sandbox (com.apple.security.sandbox), along with com.apple.kext.AppleMatch (which, like on OS X, is responsible for parsing the Sandbox language rules).
that is AMFI.kext
to implement iOS Code Entitlements
basic components, and it is related to AppleMatch.kext
(used for parsing Sandbox DSL) are Sandbox.kext
its dependencies.
Some may not be familiar with Entitlements, which represent the permissions possessed by the App. In positive development, if we enable Capability for the App, corresponding XML Units will be inserted into App.entitlements
Certain Capabilities can only generate legitimate signatures with specific certificates. This method can limit the permissions of Userland Apps, thereby ensuring system security.
At runtime, the kernel extension will register Mac Policy and hook specific Mach Calls[1]:
Affectionately known as AMFI, this kext can be found in the iOS 5.0 iPod 4,1 kernel around 0x805E499C (start) and 0x805E3EE8 (Initialization function). The latter function registers a MAC policy (using the kernel exported mac_policy_register), which is used to hook various system operations and enforce Apple's strict security policy.
According to the Wiki, AMFI will hook task_for_pid-allow
permission Mach Call[1]:
This kext recognizes the task_for_pid-allow entitlement (among others) and is responsible for hooking this Mach call, which retrieves the Mach task port associated with a BSD process identifier. Given this port, one can assume control of the task/PID, reading and writing its memory, debugging, etc. It is therefore enabled only if the binary is digitally signed with a proper entitlement file, specifying task_for_pid-allow.
that is AMFI.kext
will identify task_for_pid-allow
And hooks related Mach Call, this Mach Call will return the task port of a specific process to the caller through BSD process identifier, allowing the caller to tamper with the process's task or PID, even to perform read and write operations on the target process's memory and debugging; AMFI.kext
will check whether the binary of the caller has the right to access before the call is made. task_for_pid-allow
the legitimate signature.
Sandbox Kext
The implementation of Sandbox is related to AMFI.kext
Similarly, it also hooks a series of Mach Calls and checks specific Policies to ensure the legitimacy of access. According to the description in Dionysus Blazakis's Paper: The Apple Sandbox [2]:
Once the sandbox is initialized, function calls hooked by the TrustedBSD layer will passthrough Sandbox.kext for policy enforcement. Depending on the system call, the extension will consult the list of rules for the current process. Some rules (such as the example given above denying access to files under the /opt/sekret path) will require pattern matching support. Sandbox.kext imports functions from AppleMatch.kext to perform regular expression matching on the system call argument and the policy rule that is being checked. For example, does the file being read match the denied path /opt/sekret/.*? The other small part of the system is the Mach messages used to carry tracing information (such as which operations are being checked) back to userspace for logging.
The above references mainly include 3 key points:
- After the Sandbox is initialized, the Mach Call Hooked by the TrustedBSD layer will go through
Sandbox.kext
Execute permission check; Sandbox.kext
It will go throughAppleMatch.kext
Parse the rule DSL and generate a checklist;- Checked through a checklist, for example, whether the file path read is in the denied path list.
Kernel representation of Policy
In the proc structure of the process, there is a p_ucred member used to store the process's Identifier (Process owner's identity. (PUCL)), which is equivalent to the process's Passport:
struct proc { LIST_ENTRY(proc) p_list; /* List of all processes. */ void *task; /* corresponding task (static) */ struct proc *p_pptr; /* Pointer to parent process. (LL) */ pid_t p_ppid; // ... /* substructures: */ kauth_cred_t p_ucred; /* Identity of the process owner. (PUCL) */
PUCL is a ucred object:
struct ucred { TAILQ_ENTRY(ucred) cr_link; /* never modify this without KAUTH_CRED_HASH_LOCK */ u_long cr_ref; /* reference count */ // .. struct label *cr_label; /* MAC label */
Among which cr_label
The member points to the data structure storing MAC Policies label
:
struct label { int l_flags; union { void *l_ptr; long l_long; } l_perpolicy[MAC_MAX_SLOTS]; };
l_perpolicy
The array records the MAC Policy list, and the policies of AMFI and Sandbox will be inserted into the corresponding process's l_perpolicy
in the article.
Based on the article in Quarkslab Blogs Post-Exploitation of Modern JailbreaksAMFI and Sandbox are inserted at positions 0 and 1 respectively [3]:
Each l_perpolicy "slot" is used by a particular MACF module, the first one being AMFI and the second one the sandbox. LiberiOS calls ShaiHulud2ProcessAtAddr to put 0 in its second label l_perpolicy[1]. Being the label used by the sandbox (processed in the function sb_evaluate), this move will neutralize it while keeping the label used by AMFI (Apple Mobile File Integrity) l_perpolicy[0] untouched (it's more precise and prevents useful entitlement loss).
i.e., each l_perpolicy
All slots are used for specific MACF modules, the first slot is used for AMFI, and the second is used for Sandbox. LiberiOS achieves this by calling ShaiHulud2ProcessAtAddr
To achieve more precise and stable sandbox escape, set the pointer of the second slot to 0 without modifying the first slot.
Escape Now
With tfp0 and the above theoretical foundation, the path to implement sandbox escape becomes clear. We just need to set the cr_label of the current process l_perpolicy[1]
Set it to 0 to escape the sandbox.
Firstly, read the current process's label, the path is proc->p_ucred->cr_label
After that, set the Policy Slot at index 1 to 0:
#define KSTRUCT_OFFSET_PROC_UCRED 0xf8 #define KSTRUCT_OFFSET_UCRED_CR_LABEL 0x78 kptr_t swap_sandbox_for_proc(kptr_t proc, kptr_t sandbox) { kptr_t ret = KPTR_NULL; _assert(KERN_POINTER_VALID(proc)); kptr_t const ucred = ReadKernel64(proc + koffset(KSTRUCT_OFFSET_PROC_UCRED)); _assert(KERN_POINTER_VALID(ucred)); kptr_t const cr_label = ReadKernel64(ucred + koffset(KSTRUCT_OFFSET_UCRED_CR_LABEL)); _assert(KERN_POINTER_VALID(cr_label)); kptr_t const sandbox_addr = cr_label + 0x8 + 0x8; kptr_t const current_sandbox = ReadKernel64(sandbox_addr); _assert(WriteKernel64(sandbox_addr, sandbox)); ret = current_sandbox; out:; return ret; }
Here is an explanation sandbox_addr
calculation:
kptr_t const sandbox_addr = cr_label + 0x8 + 0x8;
Let's review the label structure again:
struct label { int l_flags; union { void *l_ptr; long l_long; } l_perpolicy[MAC_MAX_SLOTS]; };
although l_flags
itself only has 4 bytes, but l_perpolicy
occupies 8n bytes, in order to align with the largest member,l_flags
will also occupy 8B, therefore cr_label + 8
points to l_perpolicy
and offset 8B further points to the Policy Slot of Sandbox.
By the above operations, we can bypass Sandbox.kext
For sandbox-related checks of the process, to achieve sandbox escape, whether through C or OC's File API, we can read and write to rootfs. In Undecimus Jailbreak, kernelcache was read in this way to determine Kernel Slide and critical offsets.
We can verify the success of sandbox escape through simple experiments. The following code reads the kernelcache and Applications directories:
NSArray *extractDir(NSString *dirpath) { NSError *error = nil; NSArray *contents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:dirpath error:&error]; if (error) { NSLog(@"failed to get application list"); return nil; } return contents; } void sandbox_escape_test() { NSError *error = nil; BOOL success = [NSData dataWithContentsOfFile:@"/System/Library/Caches/com.apple.kernelcaches/kernelcache" options:NSDataReadingMappedAlways error:&error]; if (!success) {}} NSLog(@"error occurred !!! %@", error); } // list applications dir error = nil; NSFileManager *mgr = [NSFileManager defaultManager]; NSString *applicationRoot = @"/var/containers/Bundle/Application/"; NSArray *uuids = [mgr contentsOfDirectoryAtPath:applicationRoot error:&error]; if (error) { NSLog(@"failed to get application list"); return; } for (NSString *uuid in uuids) { NSString *appPath = [applicationRoot stringByAppendingPathComponent:uuid]; NSArray *contents = extractDir(appPath); for (NSString *content in contents) { if ([content hasSuffix:@".app"]) { NSLog(@"find %@ at %@ !!!", content, appPath); } } } }
Summary
This article briefly introduces the principle and process of achieving Sandbox Escape through tfp0, so that readers can have a simple understanding of what tfp0 can do. In the following articles, we will introduce exploits based on kexec and other techniques using tfp0.
Reference Materials

评论已关闭