iOS 安全模型浅析(四) ---- 防御代码漏洞和越狱检测

防御代码漏洞:

iOS用两套标准机制来预防代码执行攻击:地址空间结构随机化(ASLR)和XN bit(eXecute Never的缩写,标记该段内存区域不包含可执行代码)。每次执行程序时,ASLR都会随机分配内存、数据、堆和栈的内存位置。共享库需要在多个进程中使用,因此共享库的内存地址只在每次系统重启时随机设置,而不是每次执行程序时。函数和哭的内存地址很难预测,这就预防了缓冲区溢出攻击(return-to-libc),这种攻击依赖于基本库函数的已知地址。

XN bit一般对于非ARM平台的NX(No-eXecute) bit,允许操作系统将某段内存标记为不可执行,这是由CPU来控制的,学过计算机组成原理的同学都知道,每个CPU指令都有专门的地址存放。在ios中,这个机制默认应用在程序的堆和栈上。这就意味着,哪怕攻击者可以将恶意代码注入程序的堆和栈,他们也无法重定向应用程序来执行攻击代码。

每个程序都有一段既能写又能执行的内存,前提是他必须经过苹果的官方签名授权系统的签名。Safari中的JavaScript即时(JIT)编译器会用到这段内存。你平时在应用程序中经常使用的WebView并不具备访问相同功能的权利,这样就可以避免代码执行攻击。苹果一直禁止第三方的JIT,好处是更安全,而坏处也很明显,就是iOS平台上的Chrome等其他浏览器无法做到像Safari那样好用,因为他们只能使用WebView。

越狱检测:

越狱的本质就是通过一系列步骤来禁用掉苹果的签名机制,从而允许设备运行未经苹果官方审核的应用。越狱还允许你使用那一些便利的开发和测试工具,当然这些工具永远不会通过AppStore的审核。越狱的用户有能力做正常情况下其他iOS用户做不到的事。越狱还有一个至关重要的能力,就是黑箱测试应用程序。

和大多数人想的不一样,越狱不一定要禁用掉iOS的沙盒机制,他只是允许你在沙盒外安装应用程序。安装在移动用户主目录下的应用程序(即从AppStore下载的)仍然受到沙盒的限制。第三方的iOS应用程序需要安装在越狱设备中权限更高的/Applications目录下,与苹果股票应用安装在一起(就是那些你删不掉的系统应用).

越狱检测很早就有,不过没啥用。他的目的是检测设备是否存在不受信任、未经签名的第三方应用程序,从而判断设备是否处在高风险环境中。公平地说,第三方程序库中不乏恶意软件和行为不端的应用程序(像XX万能钥匙。。大家应该很清楚为什么能直接连上别人家的网),但总体来说,越狱检测不值得你浪费时间去做,因为他无法阻止一个坚定地攻击者。

有一段时间苹果官方推出过越狱检测的API,但很快就在后续的iOS版本中删掉了。具体原因众说纷纭,但是即使没有此API,开发者也找到了一些越狱检测的方法,大家知道就行了,没必要在这里费太多精力。

1.创建一个新进程,例如调用fork()、vfork()、popen()等方法。这是明显会被沙盒机制所禁止的事情。当然,大部分越狱系统上沙河依然是有效的,所以这种检测毫无意义。无论你设备是否越狱,总是可以从AppStore下载应用的。

2.读取沙盒外部的文件,开发者通常想要尝试访问一些二进制代码,这些二进制代码通常对应于ssh、bash,还有一些位于Cydia.app目录和Cydia经常使用的apt仓库等位置。但是这些检测很容易被绕过,并且Xcon6之类的工具也能帮助用户绕过这些自动检查。

3.不要使用太直白的方法名,比如isJailbroken,否则攻击者可以轻易定位并禁掉越狱检测。根据渗透测试同事多年的工作经验来看,像那种不改默认密码或者密码一猜就中的服务器数据库,简直是弱智写的。。还有这些很容易知道是做什么用函数。

还有些更复杂的技术,比如苹果的iBooks应用会尝试运行随着应用打包的未签名代码,而精明的开发者同样会尝试使用_dyld_image_count()和_dyld_get_image_name()来检查载入动态库(dynamiclibrartes, dylibs)的数量和他们的名字,并使用_dyld_get_image_header()来检查他们在内存中的位置。想要绕过这些检测通常需要给应用程序打一个二进制补丁。

想必读者都注意到了,我不是很喜欢搞越狱检测。就像二进制混淆技术和DRM一样,越狱检测被攻击者绕过时只会显得你更加愚蠢。毕竟对于攻击者来说,一些粗略的越狱检测只能拖慢自己前进的脚步几个小时而已。你要知道,对手的爱好就是破解程序,他们通常有大把的时间用来暴力破解,几个小时的时间对于他们而言并没有什么实际意义。我曾经看别人开发过一个二进制混淆程序,然后找渗透测试的同事帮忙测试,仅仅一个工作日就被搞清了算法。

你可能感兴趣的:(iOS 安全模型浅析(四) ---- 防御代码漏洞和越狱检测)