Tuesday, 22 January 2013

iOS - Run application with root privileges

Please view this page in desktop version, or visit it from a PC. It contains syntax-highlighted code snippets which are badly displayed on mobile devices.

As you may already know, regular iOS apps run as Unix user "mobile", with limited privileges (most notably, limited filesystem access). If you wish to gain full control over the whole directory tree, your app has to run as user "root".

In order to accomplish this, your app has to satisfy the following conditions:

  1. Its bundle must be located in "/Applications".
  2. Its executable must belong to the root user.
  3. Its executable must be able to set user and group IDs.
  4. It has to explicitly set user and group ID at runtime.
  5. It must not be run directly. Rather, something else should launch it (keep reading to learn how to do this).


How do I do all of that? Well, that's actually pretty simple:

  1. Put your .app bundle in the ./Applications folder of your debian package.
  2. Set ownership of your app binary to "root:wheel":
    chown root:wheel ./Applications/my.app/myApp
  3. Give your app binary the "set user ID" and "set group ID" flags.
    chmod 6755 ./Applications/my.app/myApp
  4. Explicitly call "setuid(0)" and "setgid(0)" very early in your code (specifically in "main", somewhere before calling "UIApplicationMain"). Here's a quick example:
    #import <UIKit/UIKit.h>
    #import "MyAppDelegate.h"
    int main(int argc, char *argv[]){
        @autoreleasepool
        {
            // Set uid and gid
            if (!(setuid(0) == 0 && setgid(0) == 0))
            {
                NSLog(@"Failed to gain root privileges, aborting...");
                exit(EXIT_FAILURE);
            }
    
            // Launch app
            return UIApplicationMain(argc, argv, nil, NSStringFromClass([MyAppDelegate class]));
        }
    }
Well that was easy, wasn't it? But what about that "don't run directly" madness?

Essentially, you need to add a "launch script" to the app bundle, which will be called when you tap on the SpringBoard icon, and will actually launch the app.

Not doing this will result in your app being terminated as soon as it attempts to setuid.

Assuming the executable of your app is named "myApp", all you have to do is rename it to "myApp_", and add a script called "myApp" to the .app bundle. The script should be structured like this:

#!/bin/bash
myAppPath=$(dirname "$0")
exec "$myAppPath"/myApp_ "$@"

Finally, make sure to set the ownership of the script to "root:wheel" and its permissions to "755".

Whew! After all of this, your app will finally be able to run as root.

Notes:
  • This doesn't apply to regular AppStore apps. Running as root is only possible on jailbroken devices.
  • The fact that your app will be running with root privileges does not mean you can skip the code signature step. Your app has to be properly pseudo-signed or self-signed in order to run. See this article from Saurik about bypassing code signature.
  • You should only give root privileges to your app if it really needs them. Misusing root access may potentially have catastrophic consequences if you don't know what you're doing.

2 comments:

  1. I have an ipa file for install my app, it always install in /var/mobile/Applicaitons folder, how can i install it to ./Applications ?

    ReplyDelete
    Replies
    1. I don't think .ipa files generated by Xcode can be installed to /Applications via the default iOS installation system. You'd have to extract the .app bundle out of the .ipa (as an .ipa is basically just a zip file) and then move it to /Applications.

      Your best bet would be creating a debian archive of your application, and distributing it via a Cydia repository or just let users download the .deb from your website and install it via iFile or similar means. You can find plenty of tutorials online about creating debian packages and setting up your Cydia repo.

      You can also just create a .deb file, and ask one of the community Cydia repositories (BigBoss, ModMyI, etc.) to host it for you, which is the best choice for visibility, as users don't need to add your own repository to install your app.

      Delete

Please only use comments to give feedback or suggestions. Support requests are only accepted via email.