与安卓应用相比,逆向工程 iOS 应用稍显复杂。主要是由于 iOS 实施的安全控制以及苹果在所有 iOS 设备上管理应用安装和验证的方式。例如,要从运行该应用程序的设备上获取 iOS 应用商店包(IPA),你不能简单地提取 IPA 并将其安装到另一台 iOS 设备上。这是因为从苹果应用商店安装的所有应用都会在设备上进行加密。在这种情况下,你需要提取一个解密的 IPA,然后再次签名才能在另一台 iOS 设备上运行它。
在本章中,我们将涵盖以下主题:
- 了解 iOS 应用程序的开发方式
- 了解 iOS 可执行文件格式
- 探索更多关于 iOS 应用程序逆向工程工具及其使用方法的内容
- 对 SecureStorage iOS 应用进行逆向工程
技术要求
我们将继续使用在上一章中使用的 Ubuntu 虚拟机设置。然而,如果你有一台 Mac 笔记本电脑或计算机以及一个 iOS 设备会更有用。 在本章中,需要安装以下工具:
- Hopper 反汇编器(www.hopperapp.com/ -- 免费版本足以开始使用)
- Ghidra(ghidra-sre.org/)。
iOS 应用开发
iOS 应用通常使用 Swift 或 Objective-C 语言开发。Objective-C 是一种通用的编程语言,具有面向对象的能力和动态运行时。直到 2014 年,Objective-C 都是 iOS 应用开发的官方语言。
苹果于 2014 年推出了 Swift,这是一种通用的高级编程语言,旨在为苹果的操作系统开发应用程序。最初,它是一种专有语言,但版本 2.2 在 Apache 许可证 2.0 下开源。
对于 iOS 应用开发,Xcode 是官方的集成开发环境(IDE)。开发人员还可以选择其他 IDE,如 JetBrains 的 AppCode 或微软的 Visual Studio Code,但这些 IDE 也需要 Xcode 的支持才能正常工作。Xcode 包括所需的软件开发工具包(SDK)、工具、编译器 API 等。Xcode 使用 swiftc 编译器处理 Swift 代码,使用 clang 编译器处理 Objective-C 代码。
以下图表说明了 Swift 源代码如何通过 Xcode 的构建系统进行处理和编译:
编译过程完成后,集成开发环境(IDE)会生成最终的打包文件 - 即 IPA 文件。IPA 文件包含所有必要的资源、证书、资产和二进制文件。在开始反向工程之前,了解可执行二进制文件的结构非常重要。
理解二进制格式
对于基于 Mach 内核的系统,如 macOS 和 iOS,Mach-O 是用于可执行文件和共享库的格式。Mach-O 代表 Mach 对象文件格式。应用程序预计要在不同的处理器类型上运行,大多数情况下,可执行代码应该与不同的指令集兼容。
根据其包含的指令集,一个二进制文件如果只包含一个架构的单个可执行文件,则称为"thin"二进制文件;如果它包含单个文件中不同 CPU 指令集的代码,则称为"fat"二进制文件 --- 即,它已被"加肥"(或扩展)。
每个二进制文件都以一个头部开始(称为 mach 头部),其中包含一个用于识别它的魔数。对于"thin"二进制文件,头部包含一个魔数;但是,对于"fat"二进制文件,头部是一个"fat"头部。"fat"头部包含其中其他可执行文件的 mach 头部的位置。
随着我们深入研究二进制结构并进行逆向分析,我们将使用一个示例应用程序并执行相同的步骤。在这里,我们将使用 iOS 版本的 SecureStorage 应用程序。iOS 应用程序有两个变体------一个是使用 Objective-C 开发的,另一个是使用 Swift 开发的。在本章中,我们将使用应用程序的 Objective-C 版本。
您可以从以下 GitHub 链接下载应用程序的 Objective-C 版本:
- SecureStorage(Objective-C 版本)应用程序包(github.com/0ctac0der/S...
用于 iOS 应用程序的 IDE 仅可以在基于 Mac 的系统上运行。然而,由于我们正在进行应用程序的逆向工程,因此我们不需要 Xcode IDE。我们需要开始的唯一东西是应用程序包------即 IPA 文件------可以从前面提到的链接中下载。iOS 版本的应用程序也与 Android 版本相同。以下是运行在 iOS 上的 SecureStorage 应用程序的一些屏幕截图:
好的,我们已经讨论了二进制格式的基础知识,并对 SecureStorage 应用程序有了一定的了解。现在,让我们学习如何逆向工程这些应用程序以及其中的二进制文件的过程。
iOS 应用程序的逆向工程
在"黑盒"渗透测试中,渗透测试人员的工作是从设备中提取应用程序包(IPA)。当应用程序从苹果应用商店安装时,它受到数字版权管理(DRM)的保护。应用程序二进制文件在存储到 iOS 设备时是加密的。这就是为什么简单地从设备中提取二进制文件并进行逆向工程是行不通的原因。
从 iOS 设备中提取未加密的应用程序可以使用工具,例如 frida-ios-dump(github.com/AloneMonkey... frida-ipa-dump(github.com/integrity-s...)。本书不涵盖提取未加密 IPA 的步骤,因为这是渗透测试过程的一部分。但是,要了解有关如何提取未加密 IPA 的更多信息,建议按照 frida-ios-dump(或 frida-ipa-dump)GitHub 页面上给出的步骤进行操作。
重要提示
要提取未加密的 IPA,我们需要一个运行目标应用程序的越狱 iOS 设备。当应用程序在设备内存(进程内存)中运行时,它处于未加密状态。frida-ios-dump 和 frida-ipa-dump 等实用工具从内存中提取所有未加密的应用程序文件,并将它们合并到 IPA 中。然后可以对提取的 IPA 进行逆向工程,但要在另一台设备上重新安装该 IPA,需要使用苹果开发者证书对其进行签名。还可以使用另一个实用程序(www.iosappsigner.com/)来对IPA 进行签名。
现在,让我们从先前提到的 GitHub 链接(github.com/0ctac0der/S...)下载包,并将其保存在虚拟机环境桌面上的名为iOS 的目录中。正如我们已经知道的那样,IPA 也是一个包含不同资产和文件的压缩(ZIP)文件。因此,让我们在 Linux 中直接使用 unzip 实用工具解压该文件。
如前面的截图所示,一旦文件被解压,将会创建一个名为 Payload 的新文件夹。所有的 iOS 包都包含一个 Payload 文件夹。这个 Payload 文件夹包含一个 .app 文件,通常与二进制文件(应用程序)同名。在这种情况下,如果你进入 Payload 文件夹,你会找到 .app 文件 - 即 SecureStorageObjC.app:
在 Mac 操作系统上,.app 文件显示为一个包文件,右键单击它会显示"显示包内容"的选项。
在我们的 Ubuntu 虚拟机上,我们可以简单地运行以下命令来进入 .app 文件内部。
这个 .app 文件包含了应用程序的所有资源,例如图片、证书和支持组件,这些组件是应用程序正常运行所必需的。其中一个重要的文件是 Info.plist 文件。这类似于 Android 应用程序中的 AndroidManifest.xml 文件。Info.plist 文件包含了与应用程序配置和组件相关的信息,例如 bundle 的名称、传输层安全配置、URL 方案和 MinimumOSVersion。
为了更深入地了解应用程序,我们应该从分析所有这些资源文件开始。一些值得关注的文件包括 .plist 文件、配置文件等。所有这些文件可能都包含有趣的信息。
除了支持文件之外,还有一个与应用程序同名的可执行文件。这就是应用程序的二进制文件。
我们将对这个可执行文件进行逆向工程,以提取有用的信息。我们将利用不同的工具来逆向工程这个二进制文件。
提取二进制文件中的字符串
第一步是收集有关不同应用程序组件的信息。为此,我们可以使用 strings 工具来转储二进制文件中硬编码的所有字符串。
要在二进制文件上运行 strings 实用程序,并将提取的所有字符串保存在单独的文件中(strings.txt),请在应用程序目录内执行以下命令:
bash
#ls -l(列出目录的所有内容)
#strings SecureStorageObjC >> strings.txt
以下屏幕截图显示了这些命令的输出:
一旦所有字符串都已存储在 strings.txt 文件中,我们可以打开文本文件以阅读其内容。
分析应用程序二进制文件中的所有字符串在测试应用程序时非常重要,以查找应用程序代码中的任何敏感硬编码信息。应用程序中可能存在一些有趣的硬编码信息,例如内部 IP 地址、内部应用程序 URL、硬编码的密钥和秘密、加密密钥等等。
现在我们已经有了二进制文件的所有字符串。在这一点上,我们可以分析它们以找到有趣的硬编码细节。
在开发 iOS 应用程序时,所有应用程序代码都被编译成机器代码。这就是为什么我们需要一个反汇编器来分析 iOS 应用程序的二进制文件。因此,让我们继续使用更高级的逆向工程工具 Ghidra 对二进制文件进行反汇编。
反汇编应用程序二进制文件
在这一部分,我们将学习如何使用 Ghidra 和 Hopper 等工具来反汇编应用程序二进制文件。
使用 Ghidra
在第 1 章《逆向工程基础------理解移动应用程序的结构》中,您学习了如何在我们的虚拟机环境中安装 Ghidra。现在,让我们使用相同的安装步骤来反汇编二进制文件:
- 要启动 Ghidra,请打开一个"终端",然后导航到下载 Ghidra 的目录。该目录应包含一个名为 ghidraRun 的文件。
- 要运行它,只需在终端窗口中运行以下命令:
bash
./ghidraRun
- 这将打开 Ghidra 项目窗口。选择 Tools | CodeBrowser 选项以打开代码浏览器实用程序。(请参阅第 2 章,图 2.5.1 -- 启动 Ghidra CodeBrowser。)
- 在 CodeBrowser 窗口中,您可以拖放二进制文件以开始对其进行反汇编。当二进制文件被拖放到 CodeBrowser 窗口中时,它将自动查找二进制文件的格式和体系结构。
- 点击 CodeBrowser 窗口中的"确定"后,二进制文件将被导入并进行反汇编。在此过程中,Ghidra 工具可能还会提示您选择自动分析选项,它将分析文件的操作码和其他值。
重要提示:操作码(opcode)也称为指令码、指令串或操作字符串。它是机器语言指令的一部分,用于说明要执行的操作。
- 点击"是"后,Ghidra 将显示所有可用的分析选项,如下图所示:
- 默认设置是开始的好方法,但您可以根据需要从列表中选择和取消选择分析器。单击"分析"按钮将启动自动分析过程并显示文件结果。
重要提示
自动分析过程可能会在结束时显示一些警告。通常,可以忽略这些警告,因为从逆向工程的角度来看,它们并不重要。 在本章的前面部分,我们讨论了每个二进制文件都以一个头部(称为mach头部)开始,其中包含一个用于识别它的魔术数字。该二进制文件的mach头部可在中间的窗格中看到,如下图所示:
mach头部包含加载命令,其具有8字节的结构,并指定文件的逻辑结构、链接库的路径、代码的结构以及文件在内存中的布局。
在反汇编的二进制文件中,我们现在可以导航到各种点和部分。例如,让我们导航到Functions | entry。这是在运行时调用的第一个函数。
当选择入口函数时,Ghidra会自动显示一些近似的代码(伪代码)。阅读这段代码并理解应用程序的功能会更容易一些。
在进行逆向工程时,您可能正在寻找特定问题的答案,例如正在使用何种类型的加密,或者您对了解应用程序在后台是如何工作感兴趣。一旦成功提取了应用程序包和字符串,您就能够获取关于应用程序的大量信息。在诸如Ghidra之类的工具中反汇编二进制文件后,您可以浏览不同的函数、标签等,然后阅读伪代码以弄清楚应用程序的工作原理。Ghidra还有助于获取交叉引用;只需右键单击所需函数,然后选择显示引用。
对于SecureStorage应用程序,您可能会想要查找应用程序是否对数据进行了加密,如果是,则需要查明正在使用何种类型的加密以及加密密钥位于何处。
到目前为止,我们已经使用不同的工具对应用程序进行了逆向工程并进行了分析。了解如何手动审查反汇编的应用程序二进制文件以找到您要查找的内容也是很重要的。
使用 Hopper Disassembler
Ghidra 是逆向工程 iOS 应用程序(以及许多其他二进制文件)的绝佳工具。Hopper Disassembler 是另一个可用于反汇编 iOS 应用程序二进制文件的工具。它可以用于反汇编、反编译和调试应用程序。Hopper Disassembler 是一个付费工具,但也提供带有一些限制的限制性演示许可证。
选择 Hopper 还是 Ghidra 是个人选择。例如,我更喜欢 Hopper 的界面,而不是 Ghidra。安装 Hopper Disassembler 非常简单:
- 前往 Hopper Disassembler 网站 www.hopperapp.com/index.html。
- 单击 "Try It Free" 按钮,前往 www.hopperapp.com/download.ht...
- 在 Linux 部分下载 .deb 文件。
- 一旦在虚拟机内下载了 .deb 文件,请运行以下命令进行安装:
css
sudo dpkg -i Hopper-v4-5.3.0-Linux-demo.deb
(将 deb 文件名替换为您拥有的正确文件名)
- 安装完成后,从应用程序目录运行该应用程序。
当首次运行 Hopper Disassembler 时,它会要求您提供许可文件,但由于我们只打算使用演示版本,请单击 "Try the Demo" 按钮。
之后,只需将应用程序二进制文件拖放到 Hopper Disassembler 的中间窗格中。与 Ghidra 类似,Hopper 也会提供它正在导入的二进制文件的详细信息。点击 "OK",不要更改任何其他选项的选中状态(除非您确切知道自己在做什么)。
一旦二进制文件被导入,您会看到类似以下的屏幕:
左侧窗格中的选项卡是开始的有趣部分。最重要的选项卡是标签、字符串和进程。标签选项卡包含不同的内存地址,以及它们关联的名称和指令集。字符串选项卡显示二进制文件中的所有字符串(类似于我们使用 strings 实用工具提取的内容)。应用程序中使用的所有方法都可以在进程选项卡中找到。Hopper 还在选择特定部分/函数时显示伪代码。要查看任何部分的伪代码,请选择该部分,然后单击工具栏上的"显示过程的伪代码"按钮。以下屏幕截图显示了"+[GeneralUtilssave:]"标签的伪代码:
到目前为止,我们已经使用了不同的工具对应用程序进行了逆向工程,并对其进行了分析。了解如何手动审查反汇编的应用程序二进制文件以找到您正在寻找的内容也是非常重要的。
手动审查反汇编二进制文件以发现安全问题
迄今为止,我们已经使用了Ghidra和Hopper对二进制文件进行了反汇编,并且还从应用程序包中提取了许多有趣的信息。在渗透测试期间,会手动审查逆向工程的代码,以查找任何安全问题。对于SecureStorage 应用程序而言,其中一个有趣的问题是找到正在执行的加密类型以及可能的加密密钥。
让我们在Hopper中对已反汇编的应用程序中的 Strs 标签页中搜索与 encrypt 关键字相关的内容:
在所有结果中,encrypt:Key:IV: 字符串看起来很有趣。我们还可以检查应用程序对此字符串的所有引用。为此,请选择该字符串,在中间窗格中右键单击该字符串,然后选择"References to "aEncryptKeyiv""选项。
这将导致Hopper显示给我们所有对aEncryptKeyiv关键字的引用。从列表中选择第一个引用。
仔细观察所选引用,您会注意到它上方有一个长整数,如下图所示。这就是正在使用的加密密钥。
由于这是应用程序代码中的静态硬编码密钥,它应该也是提取的字符串的一部分。让我们通过以下命令在 secrets.txt 文件上验证一下(我们正在查找所有的秘密并用部分加密密钥进行筛选)。
shell
#cat secrets.txt | grep 2D4A614E6352665
您会发现加密密钥是最初提取的秘密之一。然而,如果没有反汇编的二进制文件进行分析,要弄清楚这个密钥是用来做什么的可能会有些困难。
这只是反向工程 iOS 应用程序二进制文件如何帮助您找到安全问题,并理解应用程序功能的一个例子。
为了进一步分析应用程序的反汇编代码,我们必须理解 Objective-C 运行时。分析反汇编的本机代码也是有帮助的,但这也需要对底层平台使用的调用约定和指令有很好的理解。要学习这些知识,您必须了解 ARM 架构和 ARM 汇编基础知识。
在反向工程过程中,还可以使用一些专门针对 Mac 的工具来为您提供有用的信息。让我们在下一节中看看这些工具。
使用仅限于 Mac 系统的工具进行 iOS 应用程序的反向工程
除了我们用于反向工程应用程序二进制文件的工具之外,还有一些其他有用的工具,这些工具主要仅适用于 Mac 系统。让我们看看这些工具以及它们如何帮助反向工程过程:
- otool:此工具用于转储不同的库,并查找正在使用的任何已弃用的库。可以使用以下命令列出 SecureStorage 应用程序中使用的所有库:
less
#otool -L [二进制文件路径]
以下屏幕截图显示了 SecureStorage 应用程序的 otool 输出:
- codesign:此工具用于分析签名、验证权限等。在反向工程中 codesign 的一个常见用途是查找应用程序的权限和配置。要转储 SecureStorage 应用程序的权限,运行以下命令:
css
#codesign -d --entitlements - [应用程序文件路径]
以下屏幕截图显示了使用 codesign 时 SecureStorage 应用程序的权限:
拥有一台 Mac 并能够在反向工程 iOS 应用程序时运行 Mac 实用程序可能会很有帮助。但是,像 strings、Hopper 和 Ghidra 这样的工具使 Linux 用户几乎可以执行所有必要的任务。