iOS逆向之app脱壳

2022-08-14 20:48:42 浏览数 (1)

什么是脱壳

iOS端App在上线之前会有苹果商店进行FairPlayDRM数字版权加密保护,我们称之为“加壳”。要对App Store分发的iOS App进行分析,我们需要先对App进行解密,我们称之为“脱壳”,有些人也称为“砸壳”。脱壳之后的二进制文件就是原始的、未加密的二进制文件。

注意,对于macOS上的App,苹果官方是不会对其进行加壳的。所以分析macOS App不需要执行脱壳操作。

判断是否加壳

网上有很多文章介绍如何判断iOS App是否被加壳。这里进行简单的介绍。

大家通常使用的判断加壳的方式是是使用machOView可视化工具或otool命令行工具。

这两个工具本质上都是看LC_ENCRYPTION_INFO(LC代表load command)中的Crypt ID字段。

使用otool检测

otool是Xcode自带的命令行工具,安装了Xcode的macOS系统不需要额外安装otool。

使用otool的如下命令可以检测App是否被加壳。如下:

代码语言:javascript复制
otool -l mach-O文件 | grep crypt 

例如:

image.png

如上:TEST是笔者App的已经脱壳的可执行文件。cryptid为0说明未加壳或已脱壳,cryptid为1说明App已加壳

使用MachOView检测

不想使用otool命令行还可以使用MachOView,MachOView是一款开源的Mach-O可视化工具。通过MachOView可以清晰的查看Mach-O问价的内部结构。这里是MachOView的地址

)。将代码下载到本地使用Xcode编译成功后打开APP即可。使用MachOView打开目标Mach-O文件。展开“Load Commands”节点,选择“LC_ENCRYPTION_INFO_64”节点,右边的crypt ID即代表了是否加密。为0则代表未加密(没有壳或已脱壳),为1则代表已加密(已加壳)。

image.png

脱壳

按照脱壳的时机来区分,给App脱壳的方式分为两种:静态脱壳、动态脱壳。

静态脱壳:破解App的加壳原理,通过反向操作给App去壳。

动态脱壳:将App加载进内存,直接dump加载进内存的App的即可。

从操作难度上来看动态脱壳相对简单一些,因笔者也没有实践过静态脱壳,本文只介绍动态脱壳。

笔者了解到的冬天脱壳方式主要有三种:Clutch、dumpdecrypted、Frida。

关于Clutch和dumpdecrypted的使用方式网上教材众多,本文只是简单的罗列步骤,重点讲解Frida的使用。

Clutch

1.下载Clutch:https://github.com/KJCracks/Clutch/releases并重命名为Clutch

image.png

2.将Clutch文件拷贝到越狱iPhone的/usr/bin目录下

image.png

3.以root管理员身份登录iPhone,给Clutch赋予执行权限 chomd x /usr/bin/Clutch

image.png

4.Clutch -i查看已经安装的App

5.Clutch -d app bundleId执行脱壳操作。比如给上图的微信脱壳,命令如下:

代码语言:txt复制
// 通过bundleId来指定脱壳的App
# Clutch -d com.tencent.xin
// 或者 通过App的序号来指定脱壳的App
# Clutch -d 5

注意:因为是动态脱壳,使用Clutch脱壳前需要先启动目标App。

  1. 脱壳后的文件路径。脱壳成功后,命令行会列出脱壳后的文件在:/private/var/mobile/Documents/Dumped/ 目录下。 如果脱壳中遇到错误,但仍有部分文件脱壳成功(比如下面要说的Clutch -d 报错),那么此时产生的临时文件路径是:/var/tmp/clutch
  2. 将脱壳的文件从iPhone导出到电脑。有多重方式,可以用iOS逆向之必要软件安装 - 简书 中介绍的可视化工具。也可以用scp命令。该命令在iPhone上执行,命令格式如下(scp的详细使用见Linux scp命令 | 菜鸟教程):
代码语言:javascript复制
iPhone:/ root# scp iPhone本地源文件 电脑userName@电脑ip地址:电脑目标路径

执行Clutch 命令报错:killed 9

执行Clutch -i报错:killed 9,如下图:

代码语言:txt复制
iPhone:/usr/bin root# Clutch -i
Killed: 9
iPhone:/usr/bin root# Clutch -i
Killed: 9

解决办法:

iPhone 终端输入以下4条命令(参考自:越狱设备运行Clutch报错:Killed: 9_jinrui_w的博客-CSDN博客)

代码语言:txt复制
iPhone:/usr/bin root# cd /private/var/mobile/Documents/
iPhone:/private/var/mobile/Documents root# ldid -e `which bash` > end.xml
iPhone:/private/var/mobile/Documents root# ldid -Send.xml `which Clutch`
iPhone:/private/var/mobile/Documents root# inject `which Clutch`

Clutch -d 命令报错:Error: Could not obtain mach port, either the process is dead (codesign error?) or entitlements were not properly signed!

如下图:

Clutch -d 报错Clutch -d 报错

参考文章:Error: Could not obtain mach port, either the process is dead (codesign error?) or entitlements were not properly signed! · Issue #144 · KJCracks/Clutch · GitHub

按照提问者的说法,在/var/tmp/clutch目录下找到了dump出来的部分文件。

dumpdecrypted

dumpdecrpyted是开源的,需要先进行编译,然后再将编译好的dylib复制到越狱iPhone上。具体步骤如下:

1.通过git地址下载源码。

2.目录下执行make命令执行编译操作。

image.png

3.编译成功后目录下会多出一个dylib动态库文件。

image.png

4.将dylib复制到越狱设备的/var/root目录下(以root用户身份登录)

image.png

5.root身份登录iPhone并进入到dylib所在的iPhone目录

image.png

6.使用环境变量DYLD_INSERT_LIBRARIES将动态库dumpdecrpyted注入到需要脱壳的目标mach-O文件中。命令格式DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib 可执行文件路径

例如:

代码语言:javascript复制
 DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/containers/Bundle/Application/5B7E8BAE-3F8E-448A-829E-452912476BC8/TEST.app/TEST

7.执行成功后目录下会多出一个xxx.decrypted文件。该文件就是脱壳后的可执行文件。

Frida

Frida-ios-dump基于Frida(一款跨平台的轻量级的Hook框架)提供的强大的功能,通过注入JS实现内存dump,然后利用Python脚本自动将内存复制到macOS,从而生成最终的脱壳后的ipa文件。

Frida-ios-dump的原理和dumpdecrypted一样,都是通过把内存汇总已解密的数据dump出来再修复mach-O,dan dumpdecrypted仅能dump主程序,对于框架需要自行修改源代码才能完成,操作比较麻烦。Frida-ios-dump提供的强大功能允许我们一键快速完成脱壳。

使用Frida脱壳要求越狱设备上安装Frida插件。具体操作步骤如下:

1.首先Cydia中添加源Frida源:https://build.frida.re

2.搜索并安装对应版本的Frida。笔者的越狱iPhone是64位的,iOS 版本是10.13.5,所以下载并安装了Frida for pre-A12 devices

3.Mac上在github上下载Frida-ios-dump:https://github.com/AloneMonkey/frida-ios-dump

4.进入本地的Frida-ios-dump目录下执行sudo pip install -r requirements.txt --upgrade 来安装python依赖

注意:如果这一步安装Python依赖失败:可以尝试手动逐个安装requirements.txt中的python依赖库

5.mac终端执行iproxy 2222 22。把Mac上的2222端口映射到iPhone的22。前提是要保证此时iPhone已经和Mac通过usb进行了连接

注意:如果这一步出现command not found:iproxy。说明Mac本地还没有iproxy。只需终端执行brew install usbmuxd。在安装usbmuxd的过程中iproxy会被自动安装。安装好后执行iproxy 2222 22

6.电脑当前目录下继续执行./dump.py -l命令。列出iPhone上当前的所有应用

image.png

7.终端执行./dump.py bundleId即可对app进行脱壳。

注意:这一步需要我们把app启动

8.脱壳成功后,会在电脑的当前目录新增一个ipa文件。该文件就是脱壳后的APP包。

分离架构

我们最终脱壳出的二进制文件和使用的越狱设备有关。即arm64的越狱设备只能脱壳出arm64的可执行文件。Mach-O通常是胖二进制格式,也就是一个Mach-O文件包含多种架构,比如:arm64、armv7、armv7s等。胖二进制的目的是为了支持更多架构的iPhone。关于每款iPhone的架构可以自行Google。

搞过静态库和动态库的开发者对于分离架构应该并不陌生。在合并和分离二进制文件的时候,我们通常使用lipo命令。lipo是macOS自带的工具,其功能非常强大。下面列举了lipo命令常用的几个命令:

代码语言:javascript复制
# 查看可执行文件的架构信息
命令格式:lipo -info Mach-O文件
# lipo -info WeChat

# 分离出某种特定架构
命令格式:lipo  mach-O文件  -thin  架构类型  -output  分离的mach-O文件  
# lipo WeChat -thin arm64 -output WeChat_arm64

# 合并多种架构
命令格式:lipo  mach-O文件1  mach-O文件2  -output  合成的mach-O文件
# lipo WeChat_arm64 WeChat_armv7 -output WeChat

补充:查看可执行文件架构还可以使用file命令:file Mach-O文件 例如:file WeChat

参考文章&链接

MachOView:https://github.com/gdbinit/MachOView

Clutch:https://github.com/KJCracks/Clutch/releases

dumpdecrypted:https://github.com/stefanesser/dumpdecrypted

frida-ios-dump:https://github.com/AloneMonkey/frida-ios-dump

《iOS应用逆向与安全之道》

0 人点赞