软件脱壳,顾名思义,就是对软件加壳的逆操作,把软件上存在的壳去掉(解密)。
砸壳原理
应用加壳(加密)
提交给
AppStore
发布的App
,都经过官方保护而加密,这样可以保证机器上跑的应用是苹果审核过的,也可以管理软件授权经过
AppStore
加密的应用,我们无法通过Hopper
等反编译静态分析,也无法Class-Dump
在逆向分析过程中,需要对加密的二进制文件进行解密,然后才能进行静态分析,这一过程就是大家熟知的砸壳(脱壳)
应用砸壳(解密)
- 静态砸壳:在已经掌握和了解到了壳应用的加密算法和逻辑后,在不运行壳应用程序的前提下,将壳应用程序进行解密处理。静态脱壳的方法难度大,而且加密方发现应用被破解后,就可能会改用更加高级和复杂的加密技术
- 动态砸壳:从运行在进程内存空间中的可执行程序映像(
image
)入手,将内存中的内容进行转储(dump
)处理来实现脱壳处理。这种方法实现起来相对简单,且不必关心使用的是何种加密技术
iOS
应用运行原理
在
iOS
系统中,应用砸壳所使用的都是动态砸壳技术
Clutch
Clutch
是由KJCracks
开发的一款开源砸壳工具。工具支持iPhone
、iPod Touch
、iPad
,该工具需要使用iOS8.0
以上的越狱手机应用。
Clutch
属于命令行工具,适用于完美越狱的设备。如果是非完美越狱,砸壳时可能会出现问题
Clutch
安装官网地址:https://github.com/KJCracks/Clutch
直接找到
Release
版本
下载最新的
Clutch-2.0.4
使用
file
命令,查看Clutch
工具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
Clutch
是通用二进制文件,可以支持不同CPU
架构的设备
Clutch
使用将
Clutch-2.0.4
拷贝到手机的/var/root
目录下,并且重命名为Clutch
scp -P 12345 ./Clutch-2.0.4 root@127.0.0.1:/var/root/Clutch ------------------------- Clutch-2.0.4 100% 1204KB 28.2MB/s 00:00
- 使用
-P
参数,指定USB
连接的映射端口,传输速度更快- 前面是本地文件路径
- 后面是手机路径,
IP
地址要和登录时设置的一致- 拷贝的同时,可以修改名称
- 如果拷贝的是文件夹,增加
-r
参数为
Clutch
增加可执行权限chmod +x Clutch
查看
Clutch
的用法./Clutch ------------------------- Usage: Clutch [OPTIONS] -b --binary-dump <value> Only dump binary files from specified bundleID -d --dump <value> Dump specified bundleID into .ipa file -i --print-installed Print installed applications --clean Clean /var/tmp/clutch directory --version Display version and exit -? --help Display this help and exit -n --no-color Print with colors disabled
-b
:仅从指定的bundleID
转储二进制文件-d
:将指定的绑定文件转储到.ipa
文件中-i
:打印安装的应用程序查看安装的应用程序
./Clutch -i ------------------------- 1: 老司机汽车 <com.driver.feng> 2: 爱思加强版 <com.pd.A4Player> 3: 微信 <com.tencent.xin>
- 这里列出的软件,都可以进行砸壳
选择对
./Clutch -d 3 ------------------------- com.tencent.xin contains watchOS 2 compatible application. It's not possible to dump watchOS 2 apps with Clutch 2.0.4 at this moment. Zipping WeChat.app ASLR slide: 0x1000b0000 Dumping <WeChatNotificationServiceExtension> (arm64) Patched cryptid (64bit segment) Writing new checksum ... DONE: /private/var/mobile/Documents/Dumped/com.tencent.xin-iOS9.0-(Clutch-2.0.4).ipa Finished dumping com.tencent.xin in 44.8 seconds
Clutch
同样使用动态砸壳,所以理论上,砸壳前应该启动Clutch
发现目标App
未启动,会自动将其启动- 砸壳成功,给出
.ipa
包的路径将砸壳后的
.ipa
包,导出到Mac
电脑。解压出MachO
文件,查看加密状态otool -l WeChat | grep crypt ------------------------- cryptoff 16384 cryptsize 107446272 cryptid 0
cryptid
为0
,处于未加密状态,证明
dumpdecrypted
Github
开源工具。dumpdecrypted
这个工具就是通过建立一个名为dumpdecrypted.dylib
的动态库,插入目标应用实现脱壳。
dumpdecrypted
和Clutch
一样,都是砸壳领域的经典插件。它们同样岁月沧桑,适用于完美越狱的设备。如果是非完美越狱,砸壳时可能会出现问题越狱环境的代码注入,可以使用不污染三方应用的插件完成。插件只会影响当前进程,无需修改
MachO
文件,从而使三方应用防护难度增大在
dyld
的源码中,有一个DYLD_INSERT_LIBRARIES
环境变量,用于插入动态库并执行
越狱环境,将自定义动态库插入
WeCath
进程创建
Inject
动态库,添加InjectCode
类打开
InjectCode.m
文件,写入以下代码:#import "InjectCode.h" @implementation InjectCode +(void)load { NSLog(@"\n\n\n\n\n🍺🍺🍺🍺🍺\n\n\n\n\n"); } @end
编译项目,生成
Inject.framework
将
Inject.framework
拷贝到手机的/var/root
目录下scp -r -P 12345 ./Inject.framework root@127.0.0.1:/var/root ------------------------- CodeResources 100% 2402 917.0KB/s 00:00 Inject 100% 85KB 6.4MB/s 00:00 Inject.h 100% 424 214.9KB/s 00:00 module.modulemap 100% 93 47.5KB/s 00:00 Info.plist 100% 744 588.3KB/s 00:00
Inject.framework
是文件夹,所以需要加上-r
参数,让其循环拷贝
USB
连接手机usb-5s.sh
查看
WeCath
进程ps -A | grep WeChat ------------------------- 5380 ?? 0:03.70 /var/mobile/Containers/Bundle/Application/B1661526-3E43-4397-9E86-A9735DE89AE1/WeChat.app/WeChat 5388 ttys000 0:00.01 grep WeChat
使用
DYLD_INSERT_LIBRARIES
,将Inject.framework
插入到WeCath
进程DYLD_INSERT_LIBRARIES=Inject.framework/Inject /var/mobile/Containers/Bundle/Application/B1661526-3E43-4397-9E86-A9735DE89AE1/WeChat.app/WeChat
注入的代码在
对
iOS 9.1
以上系统的兼容问题上述案例,使用
iOS 9.1
系统进行演示在
iOS 9.1
以上系统,使用DYLD_INSERT_LIBRARIES
插入动态库,会提示以下错误:Killed:9
- 问题产生:在
9.1
以上系统,不允许root
用户插入动态库- 解决办法:需要切换成
mobile
用户,才可执行成功
dumpdecrypted
安装官网地址:https://github.com/stefanesser/dumpdecrypted
克隆
dumpdecrypted
git clone https://github.com/stefanesser/dumpdecrypted.git
进入
dumpdecrypted
目录,执行make
命令make
编译生成动态库:
dumpdecrypted.dylib
dumpdecrypted
使用将
dumpdecrypted.dylib
拷贝到手机的/var/root
目录下scp -P 12345 ./dumpdecrypted.dylib root@127.0.0.1:/var/root ------------------------- dumpdecrypted.dylib 100% 209KB 13.3MB/s 00:00
使用
DYLD_INSERT_LIBRARIES
,将dumpdecrypted.dylib
插入到WeCath
进程DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/mobile/Containers/Bundle/Application/B1661526-3E43-4397-9E86-A9735DE89AE1/WeChat.app/WeChat ------------------------- objc[5571]: Class MarsReachability is implemented in both /private/var/mobile/Containers/Bundle/Application/B1661526-3E43-4397-9E86-A9735DE89AE1/WeChat.app/Frameworks/mars.framework/mars and /private/var/mobile/Containers/Bundle/Application/B1661526-3E43-4397-9E86-A9735DE89AE1/WeChat.app/Frameworks/matrixreport.framework/matrixreport. One of the two will be used. Which one is undefined. objc[5571]: Class WCLogger is implemented in both /System/Library/Frameworks/WatchConnectivity.framework/WatchConnectivity and /var/mobile/Containers/Bundle/Application/B1661526-3E43-4397-9E86-A9735DE89AE1/WeChat.app/WeChat. One of the two will be used. Which one is undefined. mach-o decryption dumper ... [+] Closing original file [+] Closing dump file
在当前目录下,导出
WeChat.decrypted
文件,是砸壳后的MachO
文件将
WeChat.decrypted
文件,导出到Mac
电脑otool -l WeChat.decrypted | grep crypt ------------------------- WeChat.decrypted: cryptoff 16384 cryptsize 107446272 cryptid 0
cryptid
为0
,处于未加密状态,证明导出的WeChat.decrypted
砸壳成功
使用
dumpdecrypted
工具,要求Xcode SDK
与越狱设备iOS SDK
版本一致例如:对
iOS 9.1
的设备插入dumpdecrypted.dylib
,就要使用老版本的Xcode
对dumpdecrypted
进行make
否则在插入
dumpdecrypted.dylib
时,会出现以下错误DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/mobile/Containers/Bundle/Application/B1661526-3E43-4397-9E86-A9735DE89AE1/WeChat.app/WeChat ------------------------- dyld: Symbol not found: ___chkstk_darwin Referenced from: dumpdecrypted.dylib Expected in: /usr/lib/libSystem.B.dylib in dumpdecrypted.dylib Trace/BPT trap: 5
frida-ios-dump
该工具基于frida
提供的强大功能,通过注入js
实现内存dump
,然后通过python
自动拷贝到电脑生成ipa
文件。
frida-ios-dump
支持众多版本的系统,非完美越狱的环境也可使用,是目前最常用、最稳定的砸壳工具
pip
安装
pip
的安装和python
版本有关,python
安装使用pip
,而python3
安装使用pip3
查看
python
版本python --version ------------------------- Python 2.7.16
查看
python3
版本python3 --version ------------------------- Python 3.8.2
查看
pip
版本pip -V
查看
pip3
版本pip3 -V
使用
easy_install
命令,安装pip
sudo easy_install pip
使用
easy_install
的方式,我没有安装成功。pip
和pip3
都尝试过,安装后一直提示版本问题,无法使用
这里介绍另一种方式,使用
get-pip
克隆
get-pip
git clone https://github.com/pypa/get-pip.git
来到
public
目录下
使用
python3
执行get-pip.py
脚本,安装pip3
python3 get-pip.py
frida
安装在
iOS
设备,安装frida
打开
Cydia
,添加源:https://build.frida.re安装
Frida
在
Mac
电脑,安装frida
sudo pip3 install frida-tools
可能会出现警告:
you may want sudo's -H flag
- 目录不归当前用户所有。请检查该目录的权限和所有者,需要
sudo
的-H
标志
sudo -H
:set-home
将HOME
变量设为目标用户的主目录sudo -H pip3 install frida-tools
出现
Uninstalling a distutils installed project (six)
提示,执行以下命令:sudo pip3 install frida --upgrade --ignore-installed six
frida
使用查看
Mac
电脑的进程frida-ps ------------------------- PID Name 17799 360压缩大师 5668 AccessibilityVisualsAgent 602 AirPlayUIAgent 381 AppSSOAgent 13006 Code ...
USB
连接设备,查看手机上的进程frida-ps -U ------------------------- PID Name 5574 Cydia 5480 iTunes 5569 老司机汽车 6318 邮件 ...
进入
frida -U 微信
输出
[iPhone::微信]-> ObjC ------------------------- "_SFPBSearchSuggestion": { "handle": "0x1db5319f8" }, "_SFPBSectionHeaderCardSection": { "handle": "0x1db49d2b8" }, ...
frida
更多语法,可查看:官方文档
frida
擅长将js
和python
脚本,注入到目标程序并执行,它并不适合作为动态分析的工具使用
frida-ios-dump
就是将dump.py
,通过frida
注入目标程序,从而实现应用砸壳
在
Mac
电脑,配置frida-ios-dump
官网地址:https://github.com/AloneMonkey/frida-ios-dump
克隆
frida-ios-dump
sudo git clone https://github.com/AloneMonkey/frida-ios-dump
进入
frida-ios-dump
目录
安装依赖
sudo pip3 install -r requirements.txt --upgrade
安装过程中,可能出现的错误
prompt-toolkit
版本不兼容问题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
版本卸载
prompt-toolkit
sudo pip uninstall prompt-toolkit
安装指定版本
sudo pip install prompt-toolkit==1.0.6
如果出现
-H
警告,同样使用sudo -H
解决sudo -H pip3 install -r requirements.txt --upgrade
frida-ios-dump
使用进入
frida-ios-dump
目录,执行dump.py
脚本./dump.py 微信 ------------------------- Traceback (most recent call last): File "./dump.py", line 11, in <module> import frida ImportError: No module named frida
遇到上述问题,先检查
frida-ios-dump
目录的读写权限右键
frida-ios-dump
目录,选择“显示简介”,添加“本用户”的读写权限,并选择“应用到包含的项目...”
打开
dump.py
文件,需要将python
修改为python3
执行
dump.py
脚本./dump.py 微信 ------------------------- [Errno None] Unable to connect to port 2222 on 127.0.0.1, ::1 or fe80::1 Try specifying -H/--hostname and/or -p/--port
还是执行失败了,因为在
dump
的时候,会将ipa
包导出到Mac
电脑,此时需要USB
连接设备。所以在dump
之前,应该先执行usbConnect.sh
脚本检查
dump.py
文件中的User
、Password
、Host
、Port
,是否和usbConnect.sh
脚本中的配置一致修改
Port
,将2222
修改为12345
执行
dump.py
脚本./dump.py 微信 ------------------------- Start the target app 微信 Dumping 微信 to /var/folders/jl/d06jlfkj2ws74_5g45kms07m0000gn/T [frida-ios-dump]: ilink_network.framework has been loaded. ... Generating "微信.ipa"
执行成功,在
frida-ios-dump
目录下,成功导出微信.ipa
可以将其配置为环境变量,方便使用
iOS终端支持中文
iOS
终端默认是不支持中文的创建
.inputrc
隐藏文件,写入以下代码:set convert-meta off set output-meta on set meta-flag on set input-meta on
将
.inputrc
文件,拷贝到手机的/var/root
目录下scp -P 12345 .inputrc root@localhost:/var/root ------------------------- .inputrc 100% 75 8.2KB/s 00:00
在
iOS
终端,输入中文
总结
砸壳原理
- 应用加壳:一般应用为了防止反编译分享,会对应用进行加密(加壳)
- 应用砸壳:砸壳(脱壳)就是解密的过程
◦ 静态砸壳:已经知道了解密方式,不需要运行应用的情况下,直接解密
◦ 动态砸壳:在应用启动后,从内存中找到应用的位置,dump
(内存中导出)数据
Clutch
- 是一个命令行工具
Clutch -i
:查看安装的应用程序Clutch -d 应用编号
:导出ipa
包
dumpdecrypted
- 是一个动态库,不能独立运行
- 通过
DYLD_INSERT_LIBRARIES
环境变量,插入动态库。载入某个进程DYLD_INSERT_LIBRARIES = 库路径(库的可执行文件) MachO路径
9.1
以上系统,不允许root
用户使用DYLD_INSERT_LIBRARIER
方式插入动态库,需要切换成mobile
用户
frida-ios-dump
- 利用
frida
加载脚本砸壳- 安装
frida
,Mac
和iPhone
都需要安装- 下载
frida-ios-dump
脚本工具- 执行
dump.py
,参数是应用名称或BundleID
iOS
终端支持中文
- 创建
.inputrc
隐藏文件,写入代码- 拷贝到手机的
/var/root
目录下