应用砸壳

砸壳

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

砸壳原理

应用加壳(加密)

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

应用砸壳(解密)

  • 静态砸壳
静态砸壳就是已经掌握和了解到壳应用的加密算法和逻辑后在不运行壳应用程序的前提下将壳应用程序进行解密处理,静态脱壳的方法难度大,而且加密方发现应用被破解后可能就会改用更加高级和复杂的加密技术
  • 动态砸壳
动态砸壳就是从运行在进程内存空间中的可执行程序映像(image)入手,来将内存中的内容进行转储(dump)处理来实现脱壳处理,这种方法实现起来相对简单,且不必关心使用的是何种加密技术

iOS应用运行原理

image.png

Clutch

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

安装

  • 官方:https://github.com/KJCracks/Clutch
  • 找到发布版本 35release
  • 下载最新的 Clutch2.0.4

使用

  • 映射端口
sh usbConnect.sh
  • 拷贝到手机
$scp -P 12345 Clutch-2.0.4 root@localhost:/usr/bin
ssh 越狱机器
mv /usr/binClutch-2.0.4 /usr/bin/Clutch
chmod +x /usr/bin/Clutch
  • 列出可以砸壳的应用列表
Clutch -i
可以查看设备安装的应用和Bundle ID,如果找不到目标应用,就使用上面的方法找出Bundle ID,然后使用Clutch -d target.bundle.id 命令进行砸壳
  • 砸壳
Clutch -d target.bundle.id
这一步完成之后,可以在输出的目录下面找到dump出来的ipa文件,并将其导出到Mac中了。其中ipa是一个压缩包,单击右键,在弹出的快捷菜单中选择"打开方式->归档使用工具"选项。解压后,可以在Payload文件夹下找到TargetApp.app的一个包,右键快捷菜单中显示了包的内容,可以查看应用里面的文件和资源。找到Info.plist文件,双击打开,其中Bundle identifier就是它的Bundle ID,Executable file就是可执行文件的名字。可以使用lipo和otool查看可执行文件的架构和加密标识。另外Extension也会被加密,若在使用构成中出现错误,可以增加--verbose 参数来查看详细的日志信息

dumpdecrypted

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

使用

  • 安装
官网:https://github.com/stefanesser/dumpdecrypted 直接Git Clone
$git clone https://github.com/stefanesser/dumpdecrypted.git
通过Mak编译生成动态库
$cd dumpdecrypted && make
编译完成之后会生成一个dumpdecrypted.dylib 的文件在当前目录

远程拷贝到手机
scp -P 12345 dumpdecrypted.dylib root@localhost:~/
通过DYLD_INSERT_LIBRARIES环境变量插入动态库执行
  • 使用教程
  • 1.首先定位到待解密的可执行文件(targetAPP)
登录设备:ssh xxx 
执行ps指令查看进程:ps - e 
  • 获取targetAPP的Documents目录
    注入的动态库需要把解密后的文件写到动态库同名的目录下,所以需要获取targetAPP的Documents目录,然后将动态库复制到沙盒目录的Documents目录下,如何获取?
    每个APP目录下都有一个Info.plist 文件,该文件用于说明App的一些信息,其中就包括App的Bundle ID。可以根据BundleID 调用私有API,获取应用的Documents目录,获取BundleID的命令如下
$cat path/to/targetApp.app/Info.plist | grep CFBundleIdentifier - A 1
将上面获取到的BundleID 写进代码里,如下
NSString * bundleID = @"com.xxx.yyy";//此处为你的Bundle ID
NSURL *dataURL = {{NSClassFromString(@"LSApplicationProxy") performSelector:@selector(applicationProxyForIdentifier:) withObject:bundleID] performSelector:@selector(dataContainerURL)];
NSLog(@"%@",[dataURL.absoluteString stringByAppendingString:@"/Documents"]);

然后新建一个iOS项目,把获Bundle ID的代码复制到application:didFinishLaunchingWithOptions:下,然后到目标设备中运行,即可在控制台看到输出目录。

**另外也可以通过cycript获取这个路径**
在终端中输入cycript -p pid进入该进程,这里的1736是你步骤3中记录的砸壳应用的进程id。等待直到终端输入中出现cy# 后,输入[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask][0]打印出当前进程应用的沙盒路径,记录下打印出的沙盒路径
  • 将dylib复制到Documents目录下
scp ./dumpdecrypted.dylib path/to/targetAppp/Documents
  • 解密
$ cd path/to/targetApp/Documents
$DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib
解密之后会在当前目录下面生成TargetApp.decrypted文件,这个时候可以copy到Mac中备用吧

注意:如果将动态库复制到一个非沙盒目录下,例如/var/tmp/,运行后就会报如下错误

dyld:could not load inserted library 'dumpdecrypted.dylib' because no suitable image found.
Did find:
  dumpdecrypted.dylib:stat() failed with errno=1
Trace/BPT trap:5
  • 查看加密标识
    加密与否是会在文件里面记录的,把刚刚解密的文件复制到Mac中,命令大致如下:
$scp -P port root@localhost:/path/to/targetApp.decrypted ./

然后使用下面命令

$otool -l TargetApp.decrypted | grep crypt
如果在显示的记过中,看到了cryptid的标志,这个标志0代表是解密,1代表还是加密,这个时候可以通过命令lipo targetApp.decrypted -thin arm64 -output targetApp.arm64 抽取出已经解密的架构

到这里这个指令的砸壳操作就完成了

改进之后的dumpdecrypted

为了避免每次复制dumpdecrypted.dylib 文件,并且对App里面使用的framework进行解密,AloneMonkey作者重新整理了一份开源的dumpdecrypted代码与及fork的修改(Github 页面https://github.com/AloneMonkey/dumpdecrypted),将其编译,生成动态库,具体如下

git clone https://github.com/AloneMonkey/dumpdecrypted.git
cd dumpdecrypted && make

但是这个改进版,需要借助MobileLoader进行注入,然后编写dumpdecrypted.plist文件,内容如下

{
      Filter = {
                      Bundles = ("target.bundle.id") 
      };
}

通过dumpdecrypted.plist和dumpdecrypted.dylib复制到设备的/Library/MobileSubstrate/DynamicLibraries/目录下,退出目标应用,重新打开目标应用,使用控制台(/Applications/Utilities/Console.app)查看设备的日志输入,即可看到解密后的文件在Documents中保存的路径

frida-iOS-dump

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

安装frida

  • Mac安装方式:
- 查看python版本,Mac都是自带的python -V 应该是2.7
- 安装pip版本
sudo easy_install pip
- 安装frida
sudo pip install frida-tools
目录不归当前用户所有。请检查该目录的权限和所有权,需要sudo的-H标志
sudo -H . set-home 将HOME变量设为目标用户的主目录
sudo -H pip install frida-tools
  • iOS安装方式
1. 添加源https://build.frida.re
2.安装Frida

>Mac 配置ios-dump
下载脚本:sudo git clone https://github.com/AloneMonkey/frida-ios-dump
>进入目录安装一来
sudo pip install -r /opt/dump/frida-ios-dump/requirements.txt --upgrade
这一步可能报错*frida-tools-1.2.2 has requirement prompt-toolkit<2.0.0>=0.57,but you will have prompt-toolkit2.0.7 which is incompatible*
你可以降低prompt-toolkit版本来解决这个问题
卸载
sudo pip uninstall prompt-toolkit
安装指定版本
sudo pip install prompt-toolkit==1.0.6

设置别名

在终端输入:
vim ~/.bash_profile
在末尾新增下面一段:
alias dump.py="/opt/frida-ios-dump/dump.py"
source ~/.bash_profile
然后通过端口映射之后usb连接上手机

查看手机上安装的app和对应的bundle id

dump.py -l

➜  05-10/09:17-/Users/forest git:(master) ✗ dump.py -l
 PID  Name          Identifier
----  ------------  ---------------------------
7911  微信            com.tencent.xin
7900  支付宝           com.alipay.iphoneclient
 499  邮件            com.apple.mobilemail
   -  App Store     com.apple.AppStore
   -  Cydia         com.saurik.Cydia
   -  FaceTime      com.apple.facetime
   -  Filza         com.tigisoftware.Filza
   -  Game Center   com.apple.gamecenter
   -  Keep          com.gotokeep.keep
   -  PP助手          com.teiron.pphelperns
   -  QQ            com.tencent.mqq
   -  Safari        com.apple.mobilesafari
   -  Wallet        com.apple.Passbook

运行命令砸壳

dump.py [Display name]
或者
dump.py [Bundle identifier]
如果手机已经通过usb连接成功,并且相关环境配置好,那么砸壳之后会在执行命令的目录下生成一个砸壳的ipa
➜  05-10/14:15-/Users/forest/Music git:(master) ✗ ls
Music           PPHelper        iTunes          网易云音乐
➜  05-10/14:15-/Users/forest/Music git:(master) ✗ dump.py 微信
Start the target app 微信
timeout was reached 出现这个是因为微信并没有启动在手机中,所以这个时候需要启动手机
➜  05-10/14:18-/Users/forest/Music git:(master) ✗ ls
Music           PPHelper        iTunes          微信.ipa        网易云音乐
可以看到这个目录下面已经多了一个 微信.ipa,这个就是砸壳过后的包,可以输入下面命令检查是否已经脱壳
- 首先需要解压ipa unzip 微信.ipa
- 进入到WeChat.app 目录 cd Payload/WeChat.app
- 执行otool指令otool -l WeChat | grep crypt
    cryptoff 16384
    cryptsize 65617920
     cryptid 0
发现cryptid 已经为0了,说明已经脱壳成功了

微信砸壳过程输出

➜  05-10/14:16-/Users/forest/Music git:(master) ✗ dump.py 微信
Start the target app 微信
Dumping 微信 to /var/folders/sf/bp_0n89d4hg12g3zc2f8_08m0000gn/T
[frida-ios-dump]: Load ConfSDK.framework success.
[frida-ios-dump]: Load GPUImage.framework success.
[frida-ios-dump]: Load MMCommon.framework success.
[frida-ios-dump]: Load MultiMedia.framework success.
[frida-ios-dump]: Load QBar.framework success.
[frida-ios-dump]: Load QMapKit.framework success.
[frida-ios-dump]: Load TXLiteAVSDK_Smart_No_VOD.framework success.
[frida-ios-dump]: Load WCDB.framework success.
[frida-ios-dump]: Load YTFaceProSDK.framework success.
[frida-ios-dump]: Load mars.framework success.
[frida-ios-dump]: Load matrixreport.framework success.
[frida-ios-dump]: Load zstd.framework success.
start dump /var/mobile/Containers/Bundle/Application/AA2DEB18-65FF-4B41-9661-11736E63B74C/WeChat.app/WeChat
WeChat.fid: 100%|80.3M/80.3M [00:05<00:00, 14.7MB/s]
start dump /private/var/mobile/Containers/Bundle/Application/AA2DEB18-65FF-4B41-9661-11736E63B74C/WeChat.app/Frameworks/zstd.framework/zstd
network_setting.html: 228MB [00:36, 6.59MB/s]
0.00B [00:00, ?B/s]Generating "微信.ipa"
0.00B [00:00, ?B/s]

注意以上直接使用dump.py命令是因为我配到了环境变量,如果没有配的话请进入项目路径使用./dump.py命令
另外需要砸壳的app需要在进程中,也就是运行中
PS:如果砸壳不完全,即部分或全部Framework未砸壳。请参考
https://github.com/AloneMonkey/frida-ios-dump/issues/41

砸壳过程出现的错误

Failed to attach: incompatible Mach-O image
说明手机安装的frida版本错误,64位的机器安装到了32位了
Uninstalling a distutils installed project (six) has been deprecated and will be removed in a future version. This is due to the fact that uninstalling a distutils project will only partially uninstall the project.

解决方法:sudo pip install frida –upgrade –ignore-installed six

出现乱码
ssh [email protected]     #连接到iPhone
mkdir -p /usr/share/locale
cd /usr/share/locale
# 下面的用户名、IP请替换成macOS对应的用户名和IP地址
scp -r [email protected]:/usr/share/locale/en_US.UTF-8 .
echo "export LC_ALL='en_US.UTF-8'" >> ~/.profile

# 下面退出ssh, 重新连接iPhone就成功了,这是为了让修改之后的.profile设置生效
ERROR: Could not find a version that satisfies the requirement frida<13.0.0,>=12.8.12 (from frida-tools->-r /opt/frida-ios-dump/requirements.txt (line 7)) (from versions: none)
ERROR: No matching distribution found for frida<13.0.0,>=12.8.12 (from frida-tools->-r /opt/frida-ios-dump/requirements.txt (line 7))

翻墙即可export http_proxy="http://127.0.0.1:8001"; export HTTP_PROXY="http://127.0.0.1:8001"; export https_proxy="http://127.0.0.1:8001"; export HTTPS_PROXY="http://127.0.0.1:8001" 前提要配置好

参考链接

github frida
frida 官方

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