First off, I wrote this at 1am so yeah, expect grammar mistakes.

So, what is rootme? Rootme is a Command line tool that allows a app run by Xcode to gain root uid 0 + gid 0, and unsandbox status via the struct ucred->cr_label->sandbox being nulled by a kwrite.

Installation

Add my Cydia repo and the package should be called rootme, just install it, and it should add the main binary to /usr/bin/rootme with proper entitlements.

  • Update 2022, My cydia repo has been offline for almost a year, this post is for educational purposes only.

How does it work?

First, we need to run rootme in the terminal/ssh, this should act more like a daemon waiting for calls from the app.

Now, after this, we need to setup some code in our app along with some dependencies.

  • Grab LightMessaging headers and add them into your include path
  • Grab RocketBootstrap headers
  • Take any xcode project and link it with librocketbootstrap.dylib (Take this from your device, it’s on /usr/lib))
  • Include “rocketbootstrap.h” and “LightMessaging.h” on your main.m file
#include "rocketbootstrap.h"
#include "LightMessaging.h"
  • Add this code on it:
    LMConnection connection = {
        MACH_PORT_NULL,
        "org.brandonplank.rootme"
    };
    LMResponseBuffer buffer;
    NSString *pid = [NSString stringWithFormat:@"%d", getpid()];
    const char *msg = [pid UTF8String];
    SInt32 messageId = 0x69; //0x69 is the identity of rootme
    printf("UID before: %d\n", getuid());
    LMConnectionSendTwoWay(&connection, messageId, msg, strlen(msg) + 1, &buffer);
    LMMessage *response = &(buffer.message);
    const char *data = LMMessageGetData(response);
    printf("Finished? %s\n", data);
    LMResponseBufferFree(&buffer);
    printf("should have been rooted by now\n");
    printf("uid after: %d\n", getuid());
    setgid(0);
    printf("gid after: %d\n", getgid());
    
  • Done!

Rootme creation?

Well, you see, Jake James had created this project originally(closed source), and it was not updated from newer iOS versions > 12.0, so i dragged his binary into IDA to see how it worked. HAZA, it had not been stripped thus giving me symbols to go off of. This was a major help in this projects creation. For the same reason he did, i’m going to keep this project closed source. It would be really easy for someone to manipulate it to become malware.

Problems that arose with iOS 14

You see, most research on the kernel is pretty difficult unfortunately, so I turned to some friends for help, well, that didn’t work out. So I switched to plan B, trying it on my own.

Issue #1, patchfinding Issue #2, ucred

So the issue was that we needed a way to get the applications proc struct in the kernel. That can be done 2 ways, 1, Find allproc(Last process in the kernel) or, 2, the kernproc(The kernels process structure). Unfortunately I faced a problem with the allproc method in iOS 14, so I ended up using kernproc. So this is what my process finder ended up looking like.

uint64_t proc_of_processid(pid_t pid) {
    uint64_t proc = rk64(kernel_proc); // Use the kernel proc and walk up :)
    uint64_t pd;
    while (proc) { //iterate over all processes till we find the one we're looking for
        pd = rk32(proc + 0x68); // proc_t::p_pid
        if (pd == pid){
             return proc;
        }
        proc = rk64(proc + 8);
    }
    return 0;
}

So that worked :), now lets get on to the second issue. ucred. The ucred struct is where a few important things are that we need, for example, part of the actual root patch

wk32(ucred_addr + 0x18, 0); // 0x18 ucred::cr_uid

The ucred struct offset used to be 0x100 for as long as I can remember, but that all changed in iOS 14. I took a look at the XNU source, the structure look identical, but the kernel read 64 said otherwise, so I, yet again, through the kernel into IDA, lets see what I could find.

IDA picture

And there it is! Our actual ucred offset for iOS 14! 0xF0

Support?

  • iOS 12 - 14ish

What’s next?

  • kexecute, so we can modify the app’s entitlements so it can have task-for-pid-allow

In action

This is something like what you should see.

rootme output

Notes:

  • rootme will give your app root permissions on uid and gid
  • rootme will fully unsandbox your app
  • killing an app using the stop button on Xcode doesn’t seem to work but you can kill it from the app switcher yourself
  • if you find any bugs tell me
  • Will not open-source because it’ll be easy for people to manipulate it, besides, you can re make it like i did lol.
  • Credits to: Jake James, xerub, 0x7ff.
  • Some pointers: Raz Mashat

Resources: