软件脱壳,顾名思义,就是对软件加壳的逆操作,把软件上存在的壳去掉(解密)。
砸壳原理
-
应用加壳(加密)
提交给Appstore
发布的App
,都经过官方保护而加密,这样可以保证机器上跑的应用是苹果审核过的,也可以管理软件授权。经过App Store
加密的应用,我们无法通过Hopper
等反编译静态分析,也无法Class-Dump
,在逆向分析过程中需要对加密的二进制文件进行解密才可以进行静态分析,这一过程就是大家熟知的砸壳(脱壳) - 应用砸壳(解密)
静态砸壳
静态砸壳就是在已经掌握和了解到了壳应用的加密算法和逻辑后在不运行壳应用程序的前提下将壳应用程序进行解密处理。静态脱壳的方法难度大,而且加密方发现应用被破解后就可能会改用更加高级和复杂的加密技术动态砸壳
动态砸壳就是从运行在进程内存空间中的可执行程序映像(image
)入手,来将内存中的内容进行转储(dump
)处理来实现脱壳处理。这种方法实现起来相对简单,且不必关心使用的是何种加密技术。
Clutch
Clutch是由KJCracks开发的一款开源砸壳工具。工具支持iPhone、iPod Touch、iPad,该工具需要使用iOS8.0以上的越狱手机应用。
找到releases版本
下载最新的版本
查看
Clutch
文件类型,可以看到Clutch
是一个可执行文件,而且是iOS
架构,要copy
到手机。
$ file Clutch-2.0.4
Clutch-2.0.4: Mach-O universal binary with 3 architectures: [arm_v7:Mach-O executable arm_v7] [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的使用
在砸壳之前请看iOS逆向-越狱(Ⅹ),不然不清楚下面的命令
1. 映射端口
$ sh usbConnect.sh
Forwarding local port 10010 to remote port 22
2. Command+t新开终端页面,拷贝Clutch-2.0.4工具到手机
$ cd /Users/niujf/Desktop/xxxx //Clutch-2.0.4文件
$ ls
AliPayHeaders dumpdecrypted-master hank.cy 越狱SSH.pdf
Clutch-2.0.4 frida-ios-dump 越狱SSH.html
$ scp -P 10010 Clutch-2.0.4 root@127.0.0.1:/usr/bin
Clutch-2.0.4 100% 1204KB 6.9MB/s 00:00
手机端查看Clutch-2.0.4工具,发现没有可执行权限
$ sh usbLogin.sh
iPhone:~ root# cd /usr/bin
iPhone:/usr/bin root# ls -l Clutch-2.0.4
-rw-r--r-- 1 root wheel 1232832 Nov 14 16:31 Clutch-2.0.4
添加可执行权限
iPhone:/usr/bin root# chmod +x Clutch-2.0.4
iPhone:/usr/bin root# ls -l Clutch-2.0.4
-rwxr-xr-x 1 root wheel 1232832 Nov 14 16:31 Clutch-2.0.4
3. 列出可以砸壳的应用列表
iPhone:/usr/bin root# cd ~
iPhone:~ root# pwd
/var/root
iPhone:~ root# Clutch-2.0.4
Usage: Clutch-2.0.4 [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
iPhone:~ root# Clutch-2.0.4 -I
Installed apps:
1: 支付宝 - 让生活更简单 <com.alipay.iphoneclient>
2: WeChat <com.tencent.xin>
3: TestFlight <com.apple.TestFlight>
4: 爱思加强版 <com.pd.A4Player>
5: 抖音短视频 <com.ss.iphone.ugc.Aweme>
6: Messenger <com.facebook.Messenger>
7: PG Client - a better client for dribbble <com.az.azdribbble>
8: こつこつ家計簿-無料のカレンダー家計簿 <com.doubibi74.money76>
9: 火山小视频 - 分享生活,让世界为你点赞 <com.ss.iphone.ugc.Live>
10: 应用兔 <hk.itools.apper>
11: 微信读书 <com.tencent.weread>
12: QQ <com.tencent.mqq>
13: 腾讯新闻-事实派的热点资讯阅读软件 <com.tencent.info>
14: 五条-每日五条看尽世界 <com.kingnet.wutiao>
4. 砸壳
iPhone:~ root# Clutch-2.0.4 -d 2 //2是应用id对应是第三步应用列表的序列号
下面是砸壳过程
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: 0x100040000
Dumping <WeChatShareExtensionNew> (arm64)
Patched cryptid (64bit segment)
ASLR slide: 0x1000e0000
Dumping <WeChatSiriExtension> (arm64)
Patched cryptid (64bit segment)
ASLR slide: 0x100050000
Dumping <WeChatSiriExtensionUI> (arm64)
Patched cryptid (64bit segment)
Writing new checksum
Writing new checksum
Writing new checksum
Dumping <ProtobufLite> arm64
Successfully dumped framework ProtobufLite!
Child exited with status 0
Dumping <matrixreport> arm64
Dumping <marsbridgenetwork> arm64
Successfully dumped framework matrixreport!
Child exited with status 0
Dumping <mars> arm64
Successfully dumped framework marsbridgenetwork!
Child exited with status 0
Successfully dumped framework mars!
Child exited with status 0
ASLR slide: 0x100048000
Dumping <WeChat> (arm64)
Patched cryptid (64bit segment)
Zipping ProtobufLite.framework
Zipping mars.framework
Zipping marsbridgenetwork.framework
Zipping matrixreport.framework
Zipping WeChatShareExtensionNew.appex
Zipping WeChatSiriExtension.appex
Zipping WeChatSiriExtensionUI.appex
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 78.7 seconds
我们可以看到砸壳后的ipa包的路径
DONE: /private/var/mobile/Documents/Dumped/com.tencent.xin-iOS9.0-(Clutch-2.0.4).ipa
根据上面的路径,通过iFunBox查看砸壳后的ipa包
将ipa包导出到电脑,解压缩,查看WeChat可执行文件是否脱壳
$ otool -l WeChat | grep crypt
cryptoff 16384
cryptsize 99434496
cryptid 0
可以看到脱壳成功了!😊
插入动态库
1. 新建一个动态库insertLib,添加类InjectCode,并加入如下代码
#import "InjectCode.h"
@implementation InjectCode
+(void)load
{
NSLog(@"🍺🍺🍺🍺🍺🍺🍺");
}
@end
2. command+B编译,生成insertLib.framework
3. 将insertLib.framework拷贝到手机中
映射端口
$ sh usbConnect.sh
Forwarding local port 10010 to remote port 22
Command+t
新开终端页面,拷贝insertLib.framework
到手机~/目录
cd /Users/niujf/Desktop/xxxxxx
$ ls
alipaypwddemo insertLib insertLib.framework
$ scp -r -P 10010 insertLib.framework/ root@127.0.0.1:~/
insertLib 100% 66KB 2.3MB/s 00:00
insertLib.h 100% 489 240.1KB/s 00:00
module.modulemap 100% 99 53.0KB/s 00:00
Info.plist 100% 750 265.9KB/s 00:00
在手机根目录查看
$ sh usbLogin.sh
iPhone:~ root# cd ~
iPhone:~ root# ls
Application Support Library Media insertLib.framework
如何让insertLib.framework在手机端执行?可以通过DYLD_INSERT_LIBRARIES环境变量,让insertLib.framework临时附加在一个进程中
4. 查看当前手机进程
iPhone:~ root# ps -A
PID TTY TIME CMD
1 ?? 2:28.91 /sbin/launchd
239 ?? 2:16.00 /usr/sbin/syslogd
242 ?? 0:02.22 /usr/sbin/WirelessRadioManagerd
245 ?? 0:47.66 /usr/libexec/securityd
247 ?? 0:03.42 /System/Library/PrivateFrameworks/DataAccess.framework/Support/dataacc
251 ?? 0:06.67 /usr/sbin/wirelessproxd
253 ?? 0:07.34 /usr/libexec/atc
...
5. 随便附加在一个当前进程执行如下命令
iPhone:~ root# DYLD_INSERT_LIBRARIES=insertLib.framework/insertLib /usr/sbin/syslogd
2019-11-14 19:38:29.181 syslogd[2500:220293] 🍺🍺🍺🍺🍺🍺🍺
可以看到insertLib.framework
的代码执行了
dumpdecrypted
Github开源工具。 dumpdecrypted这个工具就是通过建立一个名为dumpdecrypted.dylib
的动态库,插入目标应用实现脱壳。
1. 先Git Clone,然后cd到下载的文件,make编译
cd /Users/niujf/Desktop/xxxxx/dumpdecrypted-master
$ ls
Makefile README dumpdecrypted.c
$ make
....
$ ls
Makefile dumpdecrypted.c dumpdecrypted.o
README dumpdecrypted.dylib
编译后发现生成了dumpdecrypted.dylib和dumpdecrypted.o
生成的dumpdecrypted.dylib可能有问题,这里有处理过的dumpdecrypted
2. 把dumpdecrypted.dylib远程拷贝到手机
先映射端口
$ sh usbConnect.sh
Forwarding local port 10010 to remote port 22
Command+t
新开终端页面,拷贝dumpdecrypted.dylib
到手机的~/目录
cd /Users/niujf/Desktop/xxx/dumpdecrypted-master
$ ls
Makefile dumpdecrypted.c dumpdecrypted.o
README dumpdecrypted.dylib
$ scp -P 10010 dumpdecrypted.dylib root@127.0.0.1:~/
dumpdecrypted.dylib 100% 209KB 4.4MB/s 00:00
Command+t
新开终端页面,在手机端查看,发现拷贝成功
$ cd ~
$ sh usbLogin.sh
iPhone:~ root# ls
Application Support Library Media dumpdecrypted.dylib insertLib.framework
3. 查看当前手机进程
$ ps -A
...
2461 ?? 0:06.68 /var/mobile/Containers/Bundle/Application/9DB7C1F3-C795-48CB-AE6B-A739E82885CA/WeChat.app/WeChat
...
4. 砸壳
iPhone:~ root# DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/mobile/Containers/Bundle/Application/9DB7C1F3-C795-48CB-AE6B-A739E82885CA/WeChat.app/WeChat
下面是砸壳过程
mach-o decryption dumper
DISCLAIMER: This tool is only meant for security research purposes, not for application crackers.
[+] detected 64bit ARM binary in memory.
[+] offset to cryptid found: @0x1000a0cf8(from 0x1000a0000) = cf8
[+] Found encrypted data at address 00004000 of length 99434496 bytes - type 1.
[+] Opening /private/var/mobile/Containers/Bundle/Application/9DB7C1F3-C795-48CB-AE6B-A739E82885CA/WeChat.app/WeChat for reading.
[+] Reading header
[+] Detecting header type
[+] Executable is a plain MACH-O image
[+] Opening WeChat.decrypted for writing.
[+] Copying the not encrypted start of the file
[+] Dumping the decrypted data into the file
[+] Copying the not encrypted remainder of the file
[+] Setting the LC_ENCRYPTION_INFO->cryptid to 0 at offset cf8
[+] Closing original file
[+] Closing dump file
在当前手机端~/目录查看,发现生成了WeChat.decrypted
的可执行文件
iPhone:~ root# ls
Application Support Library Media WeChat.decrypted dumpdecrypted.dylib
5. 拷贝WeChat.decrypted到桌面的文件夹
scp -P 10010 root@127.0.0.1:~/WeChat.decrypted /Users/niujf/Desktop/xxx
WeChat.decrypted 100% 118MB 12.9MB/s 00:09
查看WeChat.decrypted
,发现cryptid 0
,砸壳完成
$ cd /Users/niujf/Desktop/xxx
$ ls
WeChat.decrypted
$ otool -l WeChat.decrypted | grep crypt
WeChat.decrypted:
cryptoff 16384
cryptsize 99434496
cryptid 0
frida-ios-dump(一条命令脱壳👍)
该工具基于frida
提供的强大功能通过注入js
实现内存dump
然后通过python
自动拷贝到电脑生成ipa
文件。
1. 查看python版本,Mac都是自带的
$ python -V
Python 2.7.10
2. 安装pip
$sudo easy_install pip
...
$ pip -V
pip 19.3.1 from /Library/Python/2.7/site-packages/pip-19.3.1-py2.7.egg/pip (python 2.7)
3. 安装frida
$ sudo pip install frida-tools
如果碰到如下错误
ERROR: Cannot uninstall 'six'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.
执行如下命令
$ sudo pip install six --upgrade --ignore-installed six
然后再次安装即可
$ sudo pip install frida-tools
...
Successfully installed frida-tools-5.2.0 prompt-toolkit-2.0.10 pygments-2.4.2
4. 手机安装Frida插件
5. Mac配置frida-ios-dump
下载脚本
sudo mkdir /opt/dump && cd /opt/dump && sudo git clone https://github.com/AloneMonkey/frida-ios-dump
添加依赖
sudo pip install -r /opt/dump/frida-ios-dump/requirements.txt --upgrade
6. 修改dump.py配置
$ sudo vim /opt/dump/frida-ios-dump/dump.py
配置修改如下(跟上一章节iOS逆向-越狱(Ⅹ)配置ssh登录的别名类似):
User = 'root'
Password = 'alpine'
Host = 'localhost'
Port = 10010
7. 映射端口
$ sh usbConnect.sh
Forwarding local port 10010 to remote port 22
8. 查看运行的进程
$ frida-ps -U
PID Name
---- --------------------------------------------------------
2290 Cydia
2789 SafariViewService
2311 ScreenshotServicesService
2883 微信
2536 支付宝
2534 设置
2505 邮件
9. 砸壳
$ cd /xxx //随便在桌面建一个文件夹,保存生成的ipa文件
$ /opt/dump/frida-ios-dump/dump.py 微信
下面是砸壳过程
Start the target app 微信
Dumping 微信 to /var/folders/2r/gswfk35n5938fbdhf6s4xw_c0000gp/T
[frida-ios-dump]: mars.framework has been loaded.
[frida-ios-dump]: OpenSSL.framework has been loaded.
[frida-ios-dump]: andromeda.framework has been loaded.
[frida-ios-dump]: matrixreport.framework has been loaded.
[frida-ios-dump]: ProtobufLite.framework has been loaded.
[frida-ios-dump]: marsbridgenetwork.framework has been loaded.
start dump /var/containers/Bundle/Application/765305E6-F74E-4371-8255-E378BBD747FA/WeChat.app/WeChat
WeChat.fid: 100%|██████████| 122M/122M [00:05<00:00, 21.9MB/s]
start dump /private/var/containers/Bundle/Application/765305E6-F74E-4371-8255-E378BBD747FA/WeChat.app/Frameworks/OpenSSL.framework/OpenSSL
OpenSSL.fid: 100%|██████████| 2.38M/2.38M [00:00<00:00, 14.8MB/s]
start dump /private/var/containers/Bundle/Application/765305E6-F74E-4371-8255-E378BBD747FA/WeChat.app/Frameworks/ProtobufLite.framework/ProtobufLite
ProtobufLite.fid: 100%|██████████| 137k/137k [00:00<00:00, 2.09MB/s]
start dump /private/var/containers/Bundle/Application/765305E6-F74E-4371-8255-E378BBD747FA/WeChat.app/Frameworks/marsbridgenetwork.framework/marsbridgenetwork
marsbridgenetwork.fid: 100%|██████████| 2.40M/2.40M [00:00<00:00, 14.2MB/s]
start dump /private/var/containers/Bundle/Application/765305E6-F74E-4371-8255-E378BBD747FA/WeChat.app/Frameworks/matrixreport.framework/matrixreport
matrixreport.fid: 100%|██████████| 469k/469k [00:00<00:00, 7.17MB/s]
start dump /private/var/containers/Bundle/Application/765305E6-F74E-4371-8255-E378BBD747FA/WeChat.app/Frameworks/andromeda.framework/Andromeda
andromeda.fid: 100%|██████████| 8.61M/8.61M [00:00<00:00, 20.5MB/s]
start dump /private/var/containers/Bundle/Application/765305E6-F74E-4371-8255-E378BBD747FA/WeChat.app/Frameworks/mars.framework/mars
mars.fid: 100%|██████████| 9.70M/9.70M [00:00<00:00, 15.6MB/s]
Expression_46@2x.png: 230MB [00:19, 12.2MB/s]
0.00B [00:00, ?B/s]Generating "微信.ipa"
0.00B [00:00, ?B/s]
10. 查看生成的ipa文件,解压,查看生成可执行文件是否脱壳
$ ls
微信.ipa
$ otool -l WeChat | grep crypt
cryptoff 16384
cryptsize 99434496
cryptid 0
脱壳成功!😊
frida配置脚本文件
1. 将frida-ios-dump文件夹拷贝如下目录
2. 创建脚本文件
3. 配置环境变量(已配置不用管)
$ cd ~/
$ vim .bash_profile
添加如下环境变量
export NJSHELL=/Users/niujf/NJShell
export PATH=$CY_PATH_ROOT:$PATH:$NJSHELL
如果以前没有配置环境变量就是
export PATH=$NJSHELL
4. 映射端口
$ sh usbConnect.sh
Forwarding local port 10010 to remote port 22
5. 脚本砸壳
$ cd /Users/niujf/Desktop/xxxx 保存生成的ipa的文件
$ sh dumpIPA.sh 微信