看雪论坛
发新帖

【OSG】对 iOS Apps 打补丁以及重签名&iOS Apps 打补丁及重签名实战操作笔记

ksmokee 2017-7-26 15:51 1052

原文地址:Patching and Re-Signing iOS Apps
作者: Bernhard Mueller
翻译: Chensh  校对: 布兜儿

前言

在没有越狱的设备上运行经过修改的 iOS二进制文件,听起来是一个不错的主意,特别是当你的越狱机子变砖后,再更新为非越狱的 iOS 版本的时候(尽管我和我身边的人重来没遇到过这种事情)。你可以使用这种技术对 app 进行动态分析。又或者你可以做一个虚假的 GPS 定位欺骗来捕捉非洲地区锁定的 Pokemon,但又担心被发现。不管如何,你可以跟着下面的教程来修改一个 app 并且重签名,然后让 它运行在你未越狱的设备上。注意这里的技术实现的前提条件是需要先砸壳,特别是来自 App Store 的 App。

由于苹果令人困扰的配置和代码签名系统,重签名一个 app 确实不是一项简单的挑战。app 的配置描述文件和代码签名头部需要完全 一致,否则会被 iOS 系统拒绝运行。这就需要你学习很多相关的概念——证书、Bundle ID、应用 ID、团队标识符以及如何使用苹果的构 建工具将他们绑定在一起。完全可以说,不使用 Xcode 这种默认方式去构建一个系统可以运行的特定的二进制文件,是一个大挑战。

我们将要使用的工具包括 optool,苹果的构建工具以及一些 Shell 命令。这个方法中的重签脚本灵感来源于 Vincent Tan's Swizzler project。另外可选择的不同的重打包使用工具在 NCC group(https://www.nccgroup.trust/au/about-us/newsroom-and-events/blogs/2016/october/ios-instrumentation-without-jailbreak/)

要复现以下步骤,请先下载 UnCrackable iOS App Level 1,来自 OWASP 移动测试指南。我们的目标是使得 UnCrackable 这个 app 在启动的时 候加载 FridaGadget.dylib 这个动态库,这样我们就能使用 Frida 来进行分析了。

获取一份开发者配置文件和证书

配置文件是是由苹果签名的、将一个或多个设备上的代码签名证书列入白名单的plist文件。就是说,苹果明确的要求你的应用运行在 某一特性的环境里,例如在选定设备的调试模式下。配置文件还列出了你的应用拥有的权限,而代码签名证书里面包含了将要用于真实签名 的私钥。

根据你是否已经注册为 iOS 开发者,你可以选择以下两种方式之一来获取证书和配置文件。

使用iOS开发者账号:

如果你之前曾使用 Xcode 开发和部署过 iOS 应用,那么你已经拥有了一个代码签名证书。使用 security 工具可以列出你当前存在的签名标志:

$ security find-identity -p codesigning -v
1) 61FA3547E0AF42A11E233F6A2B255E6B6AF262CE "iPhone Distribution: Vantage Point Security Pte. Ltd."
2) 8004380F331DCA22CC1B47FB1A805890AE41C938 "iPhone Developer: Bernhard Müller (RV852WND79)"

已注册开发者账号的开发者可用从苹果开发者网站获取配置文件,这里有份指南,可以指导第一次创建相应的证书和配置文件,戳这里。对于重打包来 说,并不特定要求你选择了什么应用 ID,你甚至可以重用一个已经存在的 ID。最重要的事情是拥有一份相匹配的配置文件。确保你创建了 一份开发环境的配置文件,而不是一份分发配置文件,这样你才能对 app 进行调试。

在以下的 shell 命令列表中,我将会使用与我公司的开发团队相关联的个人签名身份。我创建了一个 app-id 为 "sg.vp.repackaged",以及取名为 "AwesomeRepackaging" 的配置文件,这便生成了一个名为 "AwesomeRepacaging.mobileprovision" 的配置文件 ——这里需要更换成你自己的 id 名和配置文件名。

使用常规的 iTunes 账号:

虽然你不是一个付费开发者,但苹果还是提供了一个免费的开发者配置文件。你可以在 Xcode 里面使用你的 Apple 账号获取这个配置 文件,只需简单的编译一个空的 iOS 工程,然后从 app 资源包里面提取出这个 embedded.mobileprovision 文件,具体可以参考 NCC blog 的这篇博文。

当你获取到这个配置文件后,你可以使用 security 这个工具来查看它的内容。除了许可证书以及设备外,你还能在这个描述文件找到 app 的权限授权表。在之 后的代码签名里面,你需要这个表,所以下面将演示如何将他们提取出来到一个 plist 格式的文件里。也可以查看文件的内容,是否跟预 期一样。

$ security cms -D -i AwesomeRepackaging.mobileprovision > profile.plist
$ /usr/libexec/PlistBuddy -x -c 'Print :Entitlements' profile.plist > entitlements.plist
$ cat entitlements.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-

1.0.dtd">
<plist version="1.0">
<dict>
<key>application-identifier</key>
<string>LRUD9L355Y.sg.vantagepoint.repackage</string>
<key>com.apple.developer.team-identifier</key>
<string>LRUD9L355Y</string>
<key>get-task-allow</key>
<true/>
<key>keychain-access-groups</key>
<array>
<string>LRUD9L355Y.*</string>
</array>
</dict>
</plist>

注意到我们的 App ID 是由团队标识符(LRUD9L355Y)以及 Bundle ID(sg.vantagepoint.repackage) 组合而成的。这个配置文件只对 携带这样特定的 app id 才有效。 “get-task-allow” 这个键非常重要,当它为 true 时,才会允许其他进程(比如调试服务器)附加到 应用程序,因此,在分发配置文件中应设置为 “false”。

其他准备工作

为了在我们的 app 启动的时候加载一个附加的库,我们需要插入一条额外的加载命令到主程序的 Mach-O 头中。这里我们使用optool 工具来自动化这个过程:

$ git clone https://github.com/alexzielenski/optool.git
$ cd optool/
$ git submodule update --init --recursive

我们也将使用到 ios-deploy 这个工具,这个 工具能够在不使用 Xcode 的情况下发布或者调试 iOS 。(npm 是 Nodejs 的包管理器,如果你还没有安装 Nodejs,你可以使用 homebrew 来安装,或者到官网直接下载安装包)

$ npm install -g ios-deploy

另外,在教程开始前,你还需要先把 FridaGadget.dylib 这个动态库下载下来。

$ curl -O https://build.frida.re/frida/ios/lib/FridaGadget.dylib

除了以上提到的工具,我们还需要使用一些原生系统工具和 Xcode 的编译工具,所以确保你已经安装了 Xcode 命令 行开发工具。

打补丁,重打包以及重签名

来不及了,快上车吧!

如你所知,IPA 文件其实一种ZIP压缩格式,所以我们可以使用 zip 工具来解压缩。然后将 FridaGadget.dylib 拷贝到文件目录下。 并且使用 optool 工具将一条加载命令插入到 UnCrackable Level 1 这个二进制文件内。

$ unzip UnCrackable_Level1.ipa
$ cp FridaGadget.dylib Payload/UnCrackable\ Level\ 1.app/
$ optool install -c load -p "@executable_path/FridaGadget.dylib" -t Payload/UnCrackable\ Level\ 

1.app/UnCrackable\ Level\ 1
Found FAT Header
Found thin header...
Found thin header...
Inserting a LC_LOAD_DYLIB command for architecture: arm
Successfully inserted a LC_LOAD_DYLIB command for arm
Inserting a LC_LOAD_DYLIB command for architecture: arm64
Successfully inserted a LC_LOAD_DYLIB command for arm64
Writing executable to Payload/UnCrackable Level 1.app/UnCrackable Level 1...

这种对主程序明显的篡改将会使得它的代码签名失效。所以这个无法在非越狱机子上运行。你需要替换掉配置文件,并使用描述文件中 列举的证书对主程序和 FridaGadget.dylib 进行重新签名。

第一步,将我们的自己的配置文件拷贝到资源包里面:

$ cp AwesomeRepackaging.mobileprovision Payload/UnCrackable\ Level\ 

1.app/embedded.mobileprovision\

第二步,我们需要确保在 Info.plist 中的 Bundle ID 是否跟我们的描述文件里面指定的一致。因为在重签的过程中,codesign会检查我们的 Info.plist 文件里面的 Bundle ID,如果不匹配则会返回一个错误值。

$ /usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier 

sg.vantagepoint.repackage" Payload/UnCrackable\ Level\ 1.app/Info.plist

最后,我们需要使用代码签名工具来重签所有的二进制文件:

$ rm -rf Payload/F/_CodeSignature
$ /usr/bin/codesign --force --sign 8004380F331DCA22CC1B47FB1A805890AE41C938 Payload/UnCrackable\ Level\ 

1.app/FridaGadget.dylib
Payload/UnCrackable Level 1.app/FridaGadget.dylib: replacing existing signature
$ /usr/bin/codesign --force --sign 8004380F331DCA22CC1B47FB1A805890AE41C938 --entitlements entitlements.plist 

Payload/UnCrackable\ Level\ 1.app/UnCrackable\ Level\ 1
Payload/UnCrackable Level 1.app/UnCrackable Level 1: replacing existing signature

安装并运行应用

现在你可以开始部署并运行修改后的 app 了,如下操作:

$ ios-deploy --debug --bundle Payload/UnCrackable\ Level\ 1.app/

如果一切顺利的话,app 应该会附加 lldb ,以调试模式运行在设备上。Frida 现在也附加到应用上了,可是使用 frida-ps 命令来验证一下:

$ frida-ps -U
PID Name
--- ------
499 Gadget

现在你可以使用 Frida 来正常调试你的应用了!

故障排除

如果发生什么错误,有可能是配置文件和代码签名头不匹配,这种情况建议阅读一下官方文档,了解一下整 个系统是如何运行的。另外还可以参考苹果授权故障排除这个页面。

关于这篇文件

这篇文章是 Mobile Reverse Engineering Unleashed 的系列之一。你可以访问这里来查看更多相关文章。


iOS Apps 打补丁及重签名实战操作笔记

原文: Patching and Re-Signing iOS Apps

以下笔记内容是基于上面文章的实战操作。

准备工作

1. XCode

从 App Store 安装即可。

2. ipa 包及 Frida 动态库

3. mobileprovision 文件

方法一

拥有开发者账号的,可以直接登录苹果开发者官网,然后新建一个 App ID。

然后创建一个provisioning文件: COM_OSG_UNCRACK.mobileprovision

方法二

a. 打开XCode,新建一个 iOS 工程,在项目属性中,将 General -> Signing -> Team 设置为自己开发账号。

b. 在真机上运行后,找到项目 Products 下以.app结尾的包名 ,右键点击 Show in Finder,然后再在app文件上右键点击 Show Package Contents, 弹出新窗口中则会出现 embedded.mobileprovision 文件,将此文件复制保存到其他文件夹,留以备用。


4. 下载并生成 optool 工具

optool : 修改 Mach-O 文件 Load Commands 中的 LC_LOAD_DYLIB 的工具,即修改文件的动态库链接。

在 Github 上面克隆 optool 的仓库,并更新子模块。


更新完毕后,用Xcode打开工程并运行。在工程目录的 Products 下,点击 optool 右键选择 Show in Finder,然后将 optool 文件拷贝到目录 /usr/bin/ 下。

这样就可以直接使用 optool 命令了。


5. 安装 ios-deploy

npm install -g ios-deploy

6. 安装 Frida

sudo pip install frida

一切准备就绪,让我们磨刀霍霍吧~


开始

1. 解压 ipa 包

unzip UnCrackable_Level1.ipa

会在对应的文件目录下增加一个 Payload 文件夹,里面即是 app 包。

2. 拷贝动态库到 app 包

$ cp FridaGadget.dylib Payload/UnCrackable\ Level\ 1.app/

3. 使用 optool 添加链接路径

$ optool install -c load -p "@executable_path/FridaGadget.dylib" -t 

Payload/UnCrackable\ Level\ 1.app/UnCrackable\ Level\ 1


-c 为指定 load_command 命令,-p 指定动态库的路径, -t 指定目标文件。

4. 拷贝 mobileprovision 文件,并改名为 embedded.mobileprovision

$ cp COM_OSG_UNCRACK.mobileprovision Payload/UnCrackable\ Level\ 

1.app/embedded.mobileprovision

5. 得到 entitlements.plist 文件

$ security cms -D -i embedded.mobileprovision > profile.plist
$ /usr/libexec/PlistBuddy -x -c 'Print :Entitlements' profile.plist > entitlements.plist

最后得到的entitlements.plist文件内容与下面的内容相似:



请注意,其中 3LJGT9578H 为 Team ID, com.clot.Delete 为 Bundle ID,请修改为实际操 作中的对应的值。

6. 将 info.plist 中的 Bundle ID 更改为你自己的 ID

$ /usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier com.clot.Delete" 

Payload/UnCrackable\ Level\ 1.app/Info.plist

7. 重签名

使用security 命令查询本地钥匙串里面可用的证书。
使用  codesign 命令进行签名。


安装运行

到这里基本上打补丁和重签名就完成了,接下来可以使用 ios-deploy 这个工具来安装应用到手机,也可以直接重新压缩为 zip 格式 并改为 ipa 后缀来安装。

$ ios-deploy --debug --bundle Payload/UnCrackable\ Level\ 1.app/

可以看到启动成功,并安装到手机上面,而且进入lldb的调试模式:


运行下面的命令:

$ frida-ps -U

可以看到对应的Server:


也就是说 frida 动态库也被加载起来了。

至此,我们的重签名步骤也全部完成了。

注意事项

1. "SSL:CERTIFICAT_VERIFY_FAILED"

安装frida时,提示:
[SSL:CERTIFICAT_VERIFY_FAILED] certificates verify failed (_ssl.c:749)
这可能是是因为下载软件安装包时,https的SSL证书验证失败。

解决方法:运行 python3 安装目录中的 Install Certificates.command 文件即可,该文件的路径在:

/Applications/Python 3.6/Install Certificates.command

2. "main executable failed strict validation"

如果为 FridaGadget.dylib 签名命令的最后提示有"main executable failed strict validation",说明签名失败, 一个有可能的原因是文件未下载完整,需重新下载文件。


3. "Unable to locate DeviceSupport directory"

如果执行 ios-deploy 时,输出一下信息:

Unable to 

locate DeviceSupport directory. This probably means you don't have Xcode installed, you will need to launch the app 

manually and logging output will not be shown!

则说明运行失败,原因可能是 XCode 没有设备支持的相关文件。

解决方法: 例如:查看 iOS 设备的系统版本,发现是 10.3.2 (14F89),而目录/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport 中只有支持到 10.3.1 (14E8301)的版本。

可以通过以下方法使用10.3.1来启动10.3.2的设备。

$ sudo ln -s /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/10.3.1\ \(14E8301\) /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/10.3



4 运行闪退

检查以下几项:

a. 是否砸壳。
b. 所有 Extension 是否已重签。  codesign -f -s xxxx
c. 所有动态库是否已重签。 codesign -f -s xxxx
d. Bundle ID 是否匹配。


本主题帖已收到 0 次赞赏,累计¥0.00
最新回复 (11)
西海 2017-7-26 15:52
2
MsScotch 2017-7-26 16:02
3
jiuchongnizhegedatuwoyaogeigezan!
CDGod 2017-7-27 13:57
4
xuaninitial 2017-7-29 09:46
5
NIBRoot 2017-7-31 13:54
6
这个APP是从商城下载的APP吗,能再安装的别人手机上或发布出去吗,那样岂不有点乱了
notwenhua 2017-8-1 11:27
7
  过来表示支持,话说论坛编辑器支持md的进度如何了~~
notwenhua 2017-8-1 11:27
8
NIBRoot 这个APP是从商城下载的APP吗,能再安装的别人手机上或发布出去吗,那样岂不有点乱了
可以的。重签就是针对已经上架的app。
NIBRoot 2017-8-3 15:21
9
然后将  optool  文件拷贝到目录  /usr/bin/  下。      这个拷贝不进去啊    ,/usr/bin/文件夹下不允许操作,怎么解决
西海 2017-8-4 08:50
10
NIBRoot 然后将 optool 文件拷贝到目录 /usr/bin/ 下。 这个拷贝不进去啊 ,/usr/bin/文件夹下不允许操作,怎么解决
关闭rootless  需要这样做。
1.  restart  电脑
2.  按  cmd  +  r    进入安全模式
3.  找到实用工具-&gt;ternimal
      输入
      csrutil  disable    #关闭
      csrutil  enable      #打开
4.  再restart

5.  进入系统后,相关目录需要  sudo执行
这样就ok了.
1
隔壁雷哥 2017-9-6 18:32
11
mark
1
隔壁雷哥 2017-9-6 19:34
12
对于新手来说这篇文章很良心,居然不给个精华或者优秀,可惜啊
返回



©2000-2017 看雪学院 | Based on Xiuno BBS | 域名 加速乐 保护 | SSL证书 又拍云 提供 | 微信公众号:ikanxue
Time: 0.053, SQL: 9 / 京ICP备10040895号-17