移动安全之IOS基础篇

记录以前的移动安全IOS端渗透测试基础

学习文章

Scrounger:iOS和Android移动应用程序渗透测试框架

IOS渗透测试第一步-基础知识统一放送

iOS渗透测试第一步—环境配置及简单基础

iOS应用程序安全性

靶机

安卓漏洞靶机

IOS应用程序安全

iOS安全系列汇总

看雪:

看雪2018峰会回顾_iOS App安全设计与案例分享

[原创]苹果2017年漏洞学习总结

[翻译]iOS应用安全评估方法论

root的默认密码是:alpine

ios程序安全检测姿势

①未注销我的账户再次打开APP时,APP跳转到了输入手势密码的页面,你的用户名和密码已经通过数据包发往了服务端,这样手势密码就形同虚设。

本地存储的敏感数据:首先我们需要一个越狱手机,还需要iTools工具来帮助我们。其实过程很简单,用iTools连接你的iPhone,通过共享文件打开某一APP,里边的结构一目了然。

什么是恶意程序是由苹果来定义的,苹果使用AppStore来控制或限制iOS平台上的应用程序的功能,这就意味着如果要实现某个特定的功能,唯一的手段就是要将设备越狱或者骗过应用商店的审查。比如通过某些特殊的操作(摇动手机XX次,出现一个控制按钮)开启隐藏功能。

当启动一台iOS设备时,系统首先会从只读的ROM中读取初始化指令,也就是系统的引导程序(事实上所有的操作系统启动时都要经过这一步,只是过程略有不同)。这个引导ROM包含苹果官方权威认证的公钥,他会验证底层启动加载器(LLB)的签名,一旦通过验证后就启动系统。LLB会所一些基础工作,然后验证第二级引导程序iBoot。iBoot启动后,设备就可以进入恢复模式或启动内核。在iBoot验证完内核签名的合法性之后,整个启动程序开始步入正轨:加载驱动程序、检测设备、启动系统守护进程。

这个信任链会确保所有的系统组件都有苹果官方写入、签名、分发,不能来自第三方机构,特别是那些恶意攻击者或者是给设备越狱的黑客。应用程序启动时也会用信任链去审查签名。所有的应用都必须直接或间接地由苹果签名(这就是为什么要申请开发者账号,生成开发和发布证书以及申请App ID的原因。很多开发者也经历过安装测试APP时提示你信任开发者证书,这些都是验证组件的功劳)。

越狱的工作原理正是攻击这一信任链。所有的越狱工具的作者都需要找到这一信任链上的漏洞,从而禁止掉信任链中负责验证的组件。破解引导ROM通常是最可取的办法,因为该组件不会因为苹果今后的软件更新而改变。

目录结构

Data目录中最重要的是Application子目录。Data/Applications目录包含了应用程序运行所需的其他数据:参数设置,缓存,cookie等。这个目录也是需要重点检查的对象。因为大部分数据泄露都发生在这里。下面我来深入的介绍一下这些子目。

iOS应用剖析 ---- Data目录

Documents和Inbox目录

Documents目录主要用来存储非临时状态的应用数据,比如用户创建的内容或应用程序在离线模式下需要的本地缓存信息。 如果你在应用的Info.plist文件中设置了UIFileSharingEnabled,那么可以通过iTunes访问这些文件。

其他应用发送过来的文件储存在Documents/Index目录中。这些应用可以使用UIDocumentInteractionController类来发送文件。

你只能读取和删除存储在Inbox目录下的文件。这些来自于其他应用程序的文件不能写入你的应用目录里,他们将被一个优先级更高的系统进程处理。 你可以定期删除这些文件也可以让用户选择是否删除,这样用户就可以知道这里有没有敏感信息。

如果你正在开发一个应用想确保磁盘上不会遗留任何敏感信息,那么可以将Inbox目录中的文档复制到另外一个位置,从而对数据进行保护,然后从Inbox目录中移除这些文件。

注意,你的应用程序请求打开的任意文件都有可能永久的遗留在磁盘中。如果你尝试打开一个应用程序无法处理的文件类型,那么这个文件将会被传递给第三方应用,我们无法知道第三方应用是否会将它删除或者也许会将文件永久保留下来。换句话说,你无法清理那些要求第三方应用打开的文件即使只是用Quick Look API来简单预览一下内容。Inbox文件在外面存放太长时间很危险,应该考虑让你的应用能够查看自己的数据,而不是依赖一个帮手,你保证最后正确的清除这些文件。

Library目录

Library目录包含应用程序相关的大部分文件包括由应用程序和网络产生的缓存数据。Library目录下的文件可以通过iTunes和iCloud进行备份,Cache目录除外。

Application Support目录

由用户创建和接受的文件不会储存在Application Support目录中,该目录主要用来存储应用程序使用的数据文件。例如,一个应用程序内购买的下载内容,配置文件,积分榜等。正如它名字所暗示的那样,该目录下的文件,主要用来支持应用程序运行,这些文件可以在应用程序安装时不熟也可以由应用程序创建或从网络上下载。

默认情况下iiTunes会备份这个目录下的数据到你的计算机和iCloud中。但是如果你不放心将数据保存在苹果的云端也可以通过为新创建的文件设置NSURLIsExcludedFromBackupKey属性来禁止备份到云端。

值得注意的是,苹果只要求应用备份用户数据到iCloud,包括用户创建的文档配置文件等,不要求应用程序备份数据。如果一个应用程序,允许将应用相关的内容备份到iCloud上,比如可下载内容,那么该应用,一定会被App Store拒绝上架。

Caches和Snapshots目录

Caches目录在功能上类似网页浏览器的缓存:应用程序保留数据的主要目的是为了性能,而不是因为数据本身很重要。所以iTunes不会备份此目录。

虽然苹果声明应该由你的应用程序管理Caches目录但是操作系统,其实也会操作该目录下的内容和子文件夹Snapshots。我们应该形成一种思维定式:Caches目录用来存放临时内容,伴随着应用程序的启动与退出,这些内容将会被丢弃。iOS在系统运行空间不足时也会自动删除这些话传目录,不过并不会删除当前正在运行程序的缓存。

Caches目录有时也会把网页缓存内容存储在子目录Caches/com.mycompany.myapp

中。该位置也容易泄露敏感信息,因为通过https进行长时间传输数据可以被iOS缓存。如果开发者没有禁止数据缓存和尽快使缓存数据过期,那么攻击者总能在这里尝到甜头。

最后,当应用程序,进入后台操作系统会自动把当前应用的屏幕快照存储在Snapshots子目录中,这样做会无形中把一些敏感信息存储在本地。操作系统的初衷是好的:应用被切回前台时操作系统可以使它的屏幕快照创建一个快速的动画。不幸的是,在很多应用中经常看到由此产生的副作用:截图中包含了用户的社会保险号码,用户的详细信息以及其他敏感内容。

Cookies目录

由URL加载系统所产生的Cookie都存储在Cookies目录中。创建NSURLRequest请求时,你将指定相关的Cookie策略,或者选择系统默认的策略。和OS X不同,iOS上的Cookie不会在应用程序之间共享,每个应用都有单独的目录来存储自己的Cookie。

Preferences目录

iOS将应用的偏好设置存储在Preferences目录下,但是不允许应用,直接编辑目录中的文件。 取而代之,此目录下文件的创建,读取和操作都通过NSUserDefaults或CFPreferences API来完成。

这些API将应用设置文件已传文本的格式存储,因此绝不能用它们来存储敏感的用户信息和证书。审查一个应用的本地存储信息时一定要记得检查Preference目录中的plist文件。有时候你会在这些plist文件中,发现用户名和密码API访问密钥和不应该暴露给用户的安全设置。

保存应用程序状态的目录

用户期待应用能够记住他们输入文本框的内容和启用的设置。如果一个用户切换到另外一个应用,片刻后又切回之前的应用,原先的应用可能已经在后台被操作系统杀掉了。为了在应用启动时使它的界面和之前保持一致,新版本的iOS通过State Preservation API将对象状态信息存储在Saved Application State目录中。开发者可以将需要保存状态的UI标记出来。

tmp目录

正如你猜测的那样,tmp用来存储临时文件。和Caches目录一样,当你的应用程序停止运行时,该目录中包含的文件可能会被操作系统自动删除。此目录的使用方法与Caches目录类似,不同之处在于Caches意味着缓存的这些文件可能会被再次获取和重新创建。比如,你从远程服务器下载了特定的应用数据,然后为了提高性能,会将数据缓存在Caches中,如果输就消失了,可以重新去下载。另一方面tmp严格存储着由应用产生的临时数据,也就是说如果这些文件在重新访问前被删除,你并不能重新获取到他们。此外,和Caches目录一样,tmp也不会被分到iTunes或iCloud中。

iOS应用剖析 ---- 设备目录

这些标识符由两部分组成:一部分是从Xcode启动模拟器时选择的设备类型,另一部分是系统版本。所有目录都有一个plist文件记录当前的设备信息。

在这个plist文件中,想找出设备信息并不容易。为了找出设备信息,要么去Devices目录下查看.default_created.plist文件,要么使用grep命令找出所有的device.plist文件。

打开终端,输入(这里举例子,具体路径还要根据自己的电脑酌情改变):

  • $ cd /User/me/Library/Developer/CoreSimulator/Devices && ls
  • $ for dir in 'ls|grep -v default'
  • do
  • echo $dir
  • grep -Cl name $dir/device.plist |tail -l|sed -e 's/</*string>//g'
  • done

进入正在运行的应用程序目录后,你会看到data目录,它包含所有的模拟器文件,还包括应用的相关数据。应用数据被分别放到了三个目录中,他们在data/Containers目录下,分别是Bundle、Data和Shared目录。

这篇文章主要介绍一下Bundle和Shared目录

Bundle目录

Bundle目录中有一个Applications目录,该目录包含设备上的所有的应用目录,这些应用目录用应用程序的bundle ID命名。

在应用目录中,.app文件夹存储应用程序的核心二进制代码、图像资源、本地化信息等;info.plist文件包含应用程序的核心配置信息,包括bundle标识、主程序包、应用程序的UI信息以及应用程序需要向设备请求的功能。

在文件系统中,这些plist会以XML或二进制格式进行存储,后者通常是默认的存储方式。你可以通过代码的方式获取info.plist中的信息,及引用[NSBundle mainBundle]中的字典属性;一般通过这种方式来载入一些样式或本地化信息。

info.plist文件中值得我们关注的条目是UIRequiredDeviceCapabilities,他看上去像这样

  • UIRequiredDeviceCapabilities
  • armv7
  • location-services
  • sms

UIRequiredDeviceCapabilities描述了应用所需要的系统资源。

虽然这不是强制要求的,但还是暗示了这个应用将涉及哪些活动类型。

Shared目录

Shared目录是一个特殊的目录,用来为应用程序提供一个共享的应用组(为了支持iOS8的扩展extensions),比如通知中心的“今日”视图中的任务或键盘行为,widget。苹果要求所有的扩展必须对应一个容器应用,每一个容器应用会拥有自己的应用ID。扩展及其应用容器可以通过Shared目录来共享数据。

例如,用户可以使用NSUserDefaults的初始化方法,制定一个名字来访问用户数据中共享的数据库。

Shared目录不常用,但是当我们检查存储在perferences中的敏感信息或其他隐私数据时,别忘了它。

iOS应用剖析 ---- 对plist文件进行处理

想要理解iOS应用所面临的某些问题,最好能熟知应用如何存储和操作私有目录下的各种数据,包括配置文件、资源文件、二进制我呢间以及文档。在这里你会发现各种信息的泄露方式,同时也能深入理解应用程序的核心。

要找出应用在本地存储的所有数据,最快的方法是查看/Library/Developer/CoreSimulator/Devices目录。从Xcode6开始,只要在模拟器上运行过的应用,Xcode都会根据当前设备类型和系统版本建立一个文件夹并分配一个UUID。相关应用的数据也会被存储在这里。其中应用的二进制和资源文件(包括.nib文件和图形文件)都放置在/data/Containers/Bundle/Application/目录下。而经常变化的动态数据则存储在/data/Containers/Data/Application/目录中。系统数据(如全局配置文件)将存储在其余的目录下。

如果你的设备已经越狱,那么你可以使用SSH连接到设备,并研究一下它的目录结构。但是你也可以使用iExplorer这样的工具来查看和安装应用程序的目录结构,不论你越狱与否。

对plist文件进行处理:

iOS将应用程序的配置数据存储在属性列表(plist)文件里,这些信息都是CoreFoundation数据类型,比如CFArray和CFString。从安全角度来说,你需要重点检查plist文件中不是纯文本的值,比如证书,他们有可能会被修改从而改变应用程序的行为。

举个例子:默认情况下支付功能是金庸的,但是当相应的值被修改时,该功能就可使用。

属性列表有两种格式:二进制和XML。XML文件具有良好的可读性。其中的配置文件里存储了程序的基本信息,包括该应用能够运行的平台,代码签名等(在模拟器上运行的程序是不会显示代码签名的)

如果用命令行查看文件或在代码中处理plist,就会经常遇到二进制格式的plist文件。二进制文件的可读性与可写性就不是那么理想了,但是你可以使用plutil(1)命令将plist文件转换成XML格式。

  1. $ plutil -convert xml1 Info.plist -o -
  2. $ plutil -convert xml1 Info.plist -o Info-xml.plist
  3. $ plutil -convert binary1 Info-xml.plist -o Info-bin.plist

第一条命令将一个二进制的plist转换成XML,然后打印到标准输出(stdout),之后可以通过管道(pipe)把内容传给less(1)或者类似的命令。当然你也可以向第二条命令那样,使用-o filename参数直接将内容输出到一个文件。第三条命令,binary1转换类型,将XML格式的plist转换为二进制格式。不过两种格式系统都能识别,所以一般不做转换。

为了无缝读取和编辑plist,可以提前配置好你的文本编辑器,使其在读写plist文件的时候自动转换。。你可以在你所熟悉的环境里配置,比如你习惯用Vim,那么就可以在.vimrc配置文件中添加以下内容:

  1. command -bar PlistXML :set binary | :1,$!plutil -convert xml1 /dev/stdin -o -
  2. command -bar Plistbbin :1,$!plutil -convert binary1 /dev/stdin -o -
  3. func ReadPlist()
  4. if getline("'[") =~ "^bplist"
  5. :PlistXML
  6. set filetype=xml
  7. endif
  8. endfunction
  9. augroup misc
  10. au BufWinEnter *.plist, call ReadPlist()
  11. augroup end

这个配置使用:PlistXML命令自动将需要编辑的二进制格式plist转换为XML文件,从而在肉眼可读的情况下对文件进行修改。当我们准备将这些修改保存到文件中时,改文件将再次使用:Plistbin命令将XML转换成二进制进行保存。

你可以使用Xcode查看plist文件,优势在于他可以用下拉菜单来显示所有可用的键,这些键对应不同类型的值。不过你最好掌握在命令行中处理plist文件的做法,这样将来可以通过SSH与越狱设备进行交互。

可以通过man手册来查看更多关于plist(5)和plutil(1)的信息。如果你正在使用越狱设备,则可以直接使用Erica Sadum的Erica Utilities(可以在Cydia下载安装)中的plutil命令在设备上处理plist文件。

-------------本文结束感谢您的阅读-------------