iOS砸壳

一、砸壳

软件脱壳,顾名思义,就是对软件加壳的逆操作,把软件上存在的壳去掉(解密)。

1.1 砸壳原理

1.1.1 应用加壳(加密)

提交给Appstore发布的App,都经过官方保护而加密,这样可以保证机器上跑的应用是苹果审核过的,也可以管理软件授权(企业包默认情况下也是没有加密的,TF是加壳的。)。经过App Store加密的应用,我们无法通过Hopper等反编译静态分析,也无法Class-Dump,在逆向分析过程中需要对加密的二进制文件进行解密才可以进行静态分析,这一过程就是大家熟知的砸壳(脱壳)。

App Store是通过对称加密(AES)加壳的,为了速度和效率。

1.1.2 应用砸壳(解密)

静态砸壳
静态砸壳就是在已经掌握和了解到了壳应用的加密算法和逻辑后在不运行壳应用程序的前提下将壳应用程序进行解密处理。静态脱壳的方法难度大,而且加密方发现应用被破解后就可能会改用更加高级和复杂的加密技术。

动态砸壳
动态砸壳就是从运行在进程内存空间中的可执行程序映像(image)入手,来将内存中的内容进行转储(dump)处理来实现脱壳处理。这种方法实现起来相对简单,且不必关心使用的是何种加密技术。在iOS中都是用的动态砸壳。

1.2 iOS应用运行原理

image.png
  • 加了壳的程序CPU是读不懂的,只有解密后才能载入内存。
  • iOS系统内核会对MachO进行脱壳。
  • 所以我们只需要将解密后的MachO拷贝出来。
  • 非越狱手机做不到跨进程访问,越狱后拿到root权限就可以访问了。这就是砸壳的原理。(按页加解密-代码段)

二、Clutch

Clutch是由KJCracks开发的一款开源砸壳工具。工具支持iPhoneiPod TouchiPad。该工具需要使用iOS8.0以上的越狱手机应用。

2.1安装

Clutch官网找到发布的版本下载:

Clutch下载

查看这个文件可以看到支持arm_v7arm_v7sarm64设备:

➜ file Clutch-2.0.4
Clutch-2.0.4: Mach-O universal binary with 3 architectures: [arm_v7:Mach-O executable arm_v7] [arm_v7s:Mach-O executable arm_v7s] [arm64:Mach-O 64-bit executable arm64]
Clutch-2.0.4 (for architecture armv7):  Mach-O executable arm_v7
Clutch-2.0.4 (for architecture armv7s): Mach-O executable arm_v7s
Clutch-2.0.4 (for architecture arm64):  Mach-O 64-bit executable arm64

2.2 使用

  1. 映射端口,python或者iproxy都可以 具体可以参考openssl中的内容
usbConnect.sh
  1. 拷贝Clutch到手机(注意加可执行权限)
    scp -P 端口 文件 用户@地址:目录/别名
➜ scp -P 12345 ./Clutch-2.0.4  root@localhost:/var/root/Clutch
Clutch-2.0.4                                  100% 1204KB  32.1MB/s   00:00

手机端查看:

zaizai:~ root# ls
Application\ Support/  Clutch  Library/  Media/

zaizai:~ root# ls -l
total 1204
drwxr-xr-x  3 root wheel      96 Mar 17  2018 Application\ Support/
-rw-r--r--  1 root wheel 1232832 May 25 16:59 Clutch
drwxr-xr-x 11 root wheel     352 Oct 23  2019 Library/
drwxr-xr-x  2 root wheel      64 Feb 27  2008 Media/

加可执行权限:

zaizai:~ root# chmod +x Clutch
zaizai:~ root# ls -l
total 1204
drwxr-xr-x  3 root wheel      96 Mar 17  2018 Application\ Support/
-rwxr-xr-x  1 root wheel 1232832 May 25 16:59 Clutch*
drwxr-xr-x 11 root wheel     352 Oct 23  2019 Library/
drwxr-xr-x  2 root wheel      64 Feb 27  2008 Media/
  1. 列出可以砸壳的应用列表 Clutch -i
root# ./Clutch -i
  1. 砸壳 Clutch –d 应用ID
root# Clutch –d  4

砸壳成功后的应用在Device->private->var->mobileDocuments->Dumped目录下。

自己拷贝的应用是加壳的。

  1. 在手机端通过ps -A找到进程:
14837 ??         0:03.93 /var/containers/Bundle/Application/8F382114-BBA7-4D81-AA3E-3CD02E03E23E/WeChat.app/WeChat
16560 ttys000    0:00.02 grep WeChat
  1. 然后拷贝:
scp -P 12345 root@localhost://var/containers/Bundle/Application/8F382114-BBA7-4D81-AA3E-3CD02E03E23E/WeChat.app/WeChat
➜ otool -l WeChat  | grep crypt
    cryptoff 28672
   cryptsize 4096
     cryptid 1

三、插入动态库

是通过DYLD_INSERT_LIBRARIES来实现的。

  1. 创建一个HPHook动态库,创建一个类实现一个+load方法:
+ (void)load {
    NSLog(@"\n\n\nInject SUCCESS \n\n\n");
}

编译拷贝出HPHook.framework

  1. 拷贝HPHook.framework到越狱手机
➜ scp -r -P 12345 HPHook.framework root@localhost:/var/root
CodeResources                                                                   100% 2258   301.0KB/s   00:00
HPHook                                                                          100%   85KB   9.0MB/s   00:00
HPHook.h                                                                        100%  422    91.2KB/s   00:00
module.modulemap                                                                100%   93    25.4KB/s   00:00
Info.plist                                                                      100%  744   187.8KB/s   00:00
  • -r:代表循环拷贝文件夹。
  1. 查看手机App进程(任意一个)
zaizai:/var/root mobile$ ps -A | grep InsertDemo
16708 ??         0:00.13 /var/containers/Bundle/Application/5AC46FE0-EB40-4FE2-BEA5-1AED9C95E7E9/InsertDemo.app/InsertDemo
16710 ttys000    0:00.01 grep InsertDemo
  1. HPHook.framework插入步骤3中的App
zaizai:/var/root mobile$ DYLD_INSERT_LIBRARIES=HPHook.framework/HPHook  /var/containers/Bundle/Application/5AC46FE0-EB40-4FE2-BEA5-1AED9C95E7E9/InsertDemo.app/InsertDemo
2021-05-25 18:32:07.606 InsertDemo[16797:7420505]


Inject SUCCESS 

这个时候就插入成功了。

iOS9.1以后root用户不能用DYLD_INSERT_LIBRARIES(会报错kill 9),需要切换到mobile用户(su mobile)。
主流App会有防护,可以自己创建一个App插入。
高版本的iOS系统可能会遇到错误。

四、dumpdecrypted

dumpdecryptedGithub开源工具。这个工具就是通过建立一个名为dumpdecrypted.dylib的动态库,插入目标应用实现脱壳。

4.1 安装

  1. dumpdecrypted官网直接git clone

  2. 通过make编译生成动态库:

➜  dumpdecrypted-master make
`xcrun --sdk iphoneos --find gcc` -Os  -Wimplicit -isysroot `xcrun --sdk iphoneos --show-sdk-path` -F`xcrun --sdk iphoneos --show-sdk-path`/System/Library/Frameworks -F`xcrun --sdk iphoneos --show-sdk-path`/System/Library/PrivateFrameworks -arch armv7 -arch armv7s -arch arm64 -dynamiclib -o dumpdecrypted.dylib dumpdecrypted.o
ld: warning: directory not found for option '-F/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.4.sdk/System/Library/PrivateFrameworks'
ld: warning: directory not found for option '-F/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.4.sdk/System/Library/PrivateFrameworks'
ld: warning: directory not found for option '-F/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.4.sdk/System/Library/PrivateFrameworks'

直接在clone的目录make,最后会生成dumpdecrypted.dylib

dumpdecrypted动态库

  1. 拷贝到手机
➜  dumpdecrypted-master scp  -P 12345  dumpdecrypted.dylib  mobile@localhost:/var/mobile/
mobile@localhost's password:
dumpdecrypted.dylib                           100%  209KB  24.6MB/s   00:00
  1. 通过DYLD_INSERT_LIBRARIES 环境变量插入动态库执行
DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/containers/Bundle/Application/36B02DC8-B625-4633-A2C7-45079855BFAC/Aweme.app/Aweme

需要将dumpdecrypted.dylib拷贝到mobile路径中,为了导出有写的权限。dumpdecrypted.dylib会导出和自己同一目录。

五、frida-iOS-dump

该工具基于frida提供的强大功能通过注入js实现内存dump然后通过python自动拷贝到电脑生成ipa文件。

5.1 安装

5.1.1 Mac安装

  1. 查看python版本(Mac自带)
➜  ~ python --version
Python 2.7.16

image.png

如果是python3这里需要改成python3。根据自己的版本进行配置。

2.查看pip版本

➜  ~ pip --version
pip 19.0.1 from /Library/Python/2.7/site-packages/pip-19.0.1-py2.7.egg/pip (python 2.7)

如果没有安装,执行:

sudo easy_install pip

卸载pip:python -m pip uninstall pip,如果是python3就安装pip3

3.安装frida

sudo pip install frida-tools

image.png

出现这个提示表明目录不归当前用户所有。请检查该目录的权限和所有者。需要sudo-H标志。

sudo -H pip install frida-tools
  • sudo -H: set-homeHOME 变量设为目标用户的主目录
  • pip list :列出所有安装的库
    pip list --outdated:列出所有过期的库
    pip install --upgrade 库名:更新库

5.1.2 iOS安装

  1. 添加源(可能需要科学上网)
https://build.frida.re
  1. 安装Frida


    frida安装

iOS端插件版本要与macfrida版本对应,不一致可能会导致无法dump。可以通过pip升级。另外需要检查dump.pypython版本的配置。

5.2 Mac配置ios-dump

  1. 下载脚本
sudo git clone https://github.com/AloneMonkey/frida-ios-dump

或者直接去github下载。然后拷贝到/opt目录。

当然如果电脑上安装了Monkey那直接在monkey目录中安装frida就好了。不然的话导出环境变量可能会有冲突。(monkey中已经导出dump.py了)。直接在Monkey/bin目录进行安装,将安装需要的内容直接从下载的frida-ios-dump中拷贝到Monkey/bin目录(其实只需要requirements.txtdump.jsdump.py。然后在该目录下安装依赖。

  1. 安装依赖
//sudo pip install -r /opt/frida-ios-dump/requirements.txt –upgrade
sudo pip install -r requirements.txt --ignore-installed six

在这个过程中有可能报错:

*frida-tools 1.2.2 has requirement prompt-toolkit<2.0.0,>=0.57, but you'll have >prompt-toolkit 2.0.7 which is incompatible.

需要降低 prompt-toolkit 版本:

//卸载
$sudo pip uninstall prompt-toolkit
//安装指定版本
$sudo pip install prompt-toolkit==1.0.6
  1. 修改dump.py
User = 'root'
Password = 'alpine'
Host = 'localhost'
Port = 12345

一般只需要修改Port就好了,和自己映射的本地端口一致。

5.3 frida 命令

  • frida-ps:列出电脑上的进程
➜  ~ frida-ps
  PID  Name
-----  --------------------------------------------------------------------------------
  514  AirPlayUIAgent
  573  AppSSOAgent
65527  Backup and Sync from Google
  533  Backup and Sync from Google
  636  CoreLocationAgent
73560  CoreServicesUIAgent
  • frida-ps -U:列出手机进程
➜  ~ frida-ps -U
  PID  Name
-----  -----------------------------------------------
15758  AlipayWallet
16643  BTFuwa
18079  CAReportingService
11127  CMFSyncAgent
 1644  CommCenter
17367  ContainerMetadataExtractor
 6691  EscrowSecurityAlert
16196  HeuristicInterpreter
11204  IDSRemoteURLConnectionAgent
16218  MQQSecure
11119  MobileGestaltHelper
17611  PhotosReliveWidget
10051  PinCleaner
  • frida -U 微❤:进入微❤进程,调试微❤
➜  ~ frida -U AlipayWallet
     ____
    / _  |   Frida 14.2.18 - A world-class dynamic instrumentation toolkit
   | (_| |
    > _  |   Commands:
   /_/ |_|       help      -> Displays the help system
   . . . .       object?   -> Display information about 'object'
   . . . .       exit/quit -> Exit
   . . . .
   . . . .   More info at https://frida.re/docs/home/

更多信息查看官网:https://frida.re/docs/ios/

5.4 砸壳

5.4.1 查看安装的应用

dump.py -l可以查看已经安装的应用

➜  ~ dump.py -l
/Library/Python/2.7/site-packages/paramiko/transport.py:33: CryptographyDeprecationWarning: Python 2 is no longer supported by the Python core team. Support for it is now deprecated in cryptography, and will be removed in the next release.
  from cryptography.hazmat.backends import default_backend
  PID  Name          Identifier
-----  ------------  -------------------------------
13582  微❤            com.tencent.xin
10769  支付宝           com.alipay.iphoneclient
 9912  相机            com.apple.camera
11265  腾讯手机管家        com.tencent.mqqsecure
    -  Acrobat       com.adobe.Adobe-Reader
    -  App Store     com.apple.AppStore
    -  Cydia         com.saurik.Cydia
    -  Enframe       me.sspai.Enframe
    -  Excel         com.microsoft.Office.Excel

这个时候是不需要映射的。

5.4.2 导出ipa

dump.py bundleId/displayName:

//dump.py 微❤ 
dump.py com.tencent.xin
  • 可以通过bundleId或者displayName导出应用,推荐使用bundleIddisplayName可能会有同名。如果有同名哪个排在前面导出哪个。
  • 导出ipa包时需要app在运行状态(正常情况下会自动打开App),最好在前台不锁屏。
  • 导出的ipa包一般在你执行导出命令的目录。(如果配置了环境变量,任何目录都可以执行)目录没有权限会报错。
  • 导出包的时候是需要打开端口映射的。

验证(需要解压拿到.app):

➜ otool -l WeChat.app/WeChat | grep crypt
     cryptoff 16384
    cryptsize 101646336
      cryptid 0
  • cryptid0表示没有加密,否则是加密的包。

错误信息

  1. ImportError: No module named typing
    pip安装后报错:
➜  ~ sudo pip install frida-tools
Traceback (most recent call last):
  File "/usr/local/bin/pip", line 11, in 
    load_entry_point('pip==21.1.1', 'console_scripts', 'pip')()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/pkg_resources/__init__.py", line 489, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/pkg_resources/__init__.py", line 2843, in load_entry_point
    return ep.load()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/pkg_resources/__init__.py", line 2434, in load
    return self.resolve()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/pkg_resources/__init__.py", line 2440, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
  File "/Library/Python/2.7/site-packages/pip-21.1.1-py2.7.egg/pip/__init__.py", line 1, in 
    from typing import List, Optional
ImportError: No module named typing

解决方案:
pip版本

sudo easy_install pip==19.0.1

直接指定版本安装。

2.Invalid requirement: '–upgrade'
直接替换掉–upgrade命令:

//sudo pip install -r /opt/frida-ios-dump/requirements.txt –upgrade
sudo pip install -r requirements.txt --ignore-installed six

3.如果遇见命令输入没有反映,电脑端frida没有问题。那么需要重新安装手机端frida

4.Start the target app QQMusic unable to launch iOS app: The operation couldn’t be completed. Application info provider (FBSApplicationLibrary) returned nil for ""
如果App启动后还是无法dump,直接通过BundleId dump就好了。

总结

  • 应用砸壳:一般应用为了防止反编译分析会对应用进行加密(加壳)。砸壳就是解密的过程。
    • 静态砸壳:已经知道了解密方式,不需要运行应用的情况下直接解密。
    • 动态砸壳:在应用启动之后从内存中找到应用的位置,dump(内存中)数据。
  • Clutch( 命令行工具)
    • Clutch -i:列出可以砸壳的应用列表。
    • Clutch –d 应用ID:砸壳
  • dumpdecrypted(动态库)
    • 通过DYLD_INSERT_LIBRARIES环境变量插入动态库载入某个进程。
    • 配置DYLD_INSERT_LIBRARIES=dumpdecrypted路径 Macho路径
  • frida-iOS-dump(利用frida加载脚本砸壳)
    • 安装frida(MaciPhone都需要)
    • 下载frida-iOS-dump脚本工具
    • 执行dump.py displayName /BundleId

你可能感兴趣的:(iOS砸壳)