iOS安全测试-dumpdecrypted脱壳

脱壳背景

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

iOS脱壳工具目前主要有一下3种:

  • Clutch
  • dumpdecrypted
  • frida-ios-dump

由于Clutch脱壳不太稳定,frida-ios-dump环境配置比较复杂,所以本文以dumpdecrypted这个工具做为脱壳工具。

脱壳环境

  • iPhone 6
  • iOS 11.4.1

dumpdecrypted

下载安装

下载地址:https://github.com/stefanesser/dumpdecrypted

下载后打开终端进入该砸壳工具的路径,输入make命令开始编译文件

1
2
3
4
atxdeMac-mini:dumpdecrypted-master atx$ 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 -c -o dumpdecrypted.o dumpdecrypted.c
`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

执行成功后会生成文件dumpdecrypted.dylib

如果出现如下报错说明xcode-select 配置路径不对。

1
2
3
`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 -c -o dumpdecrypted.o dumpdecrypted.c 
/bin/sh: /Applications/Xcode: No such file or directory
make: *** [dumpdecrypted.o] Error 127

解决方案:重新配置xcode-select路径。

1
atxdeMac-mini:dumpdecrypted-master atx$ sudo xcode-select --switch  /Applications/Xcode.app

重签名

  1. 首先查询可用证书
    1
    2
    3
    4
    5
    6
    atxdeMac-mini:dumpdecrypted-master atx$ security find-identity -v -p codesigning
    1) C9C1B7D09BC10EA24339xxxxD7E2 "iPhone Developer: xx (WKQZHDVG49)"
    2) EDBEF3DF258E0C8E93Exxxxx "iPhone Developer: xxx@xx.com (953S5US289)"
    3) 5FF97332735E86982AD562xxxx "navicat"
    3 valid identities found

  2. 进入dumpdecrypted.dylib所在目录,执行签名命令。
1
2
atxdeMac-mini:dumpdecrypted-master atx$ codesign --force --verify --verbose --sign  "iPhone Developer: xxx@mgtv.com (953S5US289)"  dumpdecrypted.dylib 
dumpdecrypted.dylib: signed Mach-O universal (armv7 armv7s arm64) [dumpdecrypted]

脱壳操作

设备环境要求

  1. 使用越狱手机务必在Cydia中安装cycriptadv-cmdspstree
  2. 远程连接手机,在设备上打开要脱壳的应用,本文以微信为例。

dumpdecrypted文件拷贝

  1. 远程SSH连接设备将签名之后的dumpdecrypted.dylib拷贝到设备/usr/lib目录。
1
2
3
λ scp C:\Users\Shuqing\Desktop\dumpdecrypted.dylib   root@127.0.0.1:/usr/lib
root@127.0.0.1's password:
dumpdecrypted.dylib 100% 244KB 13.3MB/s 00:00
  1. 进入/usr/lib目录查看文件dumpdecrypted.dylib 是否拷贝成功。
1
2
3
4
5
6
7
8
9
10
11
12
klygteki-iPhone: root# cd /usr/lib
klygteki-iPhone:/usr/lib root# ls -l
total 32880
-rw-r--r-- 1 root wheel 26105 Apr 14 2018 FDRSealingMap.plist
lrwxr-xr-x 1 root wheel 34 May 12 10:15 SubstrateInjector.dylib -> /usr/lib/substitute-injector.dylib
lrwxr-xr-x 1 root wheel 8 Aug 5 15:46 _ncurses -> /usr/lib/
lrwxr-xr-x 1 root wheel 14 Sep 4 2019 apt -> ../libexec/apt/
drwxr-xr-x 31 root wheel 992 Jul 21 16:56 bash/
drwxr-xr-x 25 root wheel 800 May 28 2018 bbmasks/
drwxr-xr-x 2 root wheel 64 Apr 14 2018 closure/
drwxr-xr-x 4 root wheel 128 Aug 6 16:01 cycript0.9/
-rw-r--r-- 1 root wheel 249552 Aug 6 16:43 dumpdecrypted.dylib

从上面文件路径可以看到dumpdecrypted.dylib拷贝成功。

3.打开微信应用执行命令ps aux | grep "WeChat" 查看进程信息

1
2
3
4
klygteki-iPhone:~ root# ps aux | grep "WeChat"
root 9166 7.8 0.2 1595184 1720 s000 S+ 10:46AM 0:00.03 grep WeChat
mobile 8328 1.2 3.7 1963744 37232 ?? Ss Wed07PM 0:13.33 /var/containers/Bundle/Application/D24DBE0F-73A9-4F6E-B763-37114DE691B0/WeChat.app/WeChat

4.如上面执行结果所示,在最后可以看到微信的进程和bundle信息。确保手机已经下载了cycript工具,首先使用命令cycript -p 进程id/进程名称,进行进程关联。

5.然后使用命令[NSHomeDirectory() stringByAppendingString:@"/Documents"]获取沙盒路径。如下所示,/var/moible/xxx就是沙盒路径

1
2
3
4
klygteki-iPhone:/usr/lib root# cycript -p 8328/(WeChat)
cy# [NSHomeDirectory() stringByAppendingString:@"/Documents"]
@"/var/mobile/Containers/Data/Application/978087D3-6F1A-431E-A431-4A9D5023DB3E/Documents"

  1. 拷贝签名之后的dumpdecrypted.dylib到应用沙盒目录。
    1
    2
    3
    scp C:\Users\Shuqing\Desktop\dumpdecrypted.dylib  root@127.0.0.1:/var/mobile/Containers/Data/Application/978087D3-6F1A-431E-A431-4A9D5023DB3E/Documents
    root@127.0.0.1's password:
    dumpdecrypted.dylib 100% 244KB 7.6MB/s 00:00

脱壳执行

  1. 首先将用户切换到mobile,然后进入到沙盒路径
1
2
klygteki-iPhone:/ mobile$ su mobile
Password:
  1. 在该沙盒路径下指定环境变量DYLD_INSERT_LIBRARIES,然后执行脱壳。
1
DYLD_INSERT_LIBRARIES=/usr/lib/dumpdecrypted.dylib 可执行文件的路径(即之前获取到的Bundle路径)

脱壳过程如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
klygteki-iPhone:/ mobile$ DYLD_INSERT_LIBRARIES=/usr/lib/dumpdecrypted.dylib /var/containers/Bundle/Application/D597E9A7-A9A4-45A0-886B-E7079A87FC64/WeChat.app/WeChat
objc[8194]: Class MarsReachability is implemented in both /private/var/containers/Bundle/Application/D24DBE0F-73A9-4F6E-B763-37114DE691B0/WeChat.app/Frameworks/mars.framework/mars (0x10d7918d8) and /private/var/containers/Bundle/Application/D24DBE0F-73A9-4F6E-B763-37114DE691B0/WeChat.app/Frameworks/matrixreport.framework/matrixreport (0x10cb71590). One of the two will be used. Which one is undefined.
objc[8194]: Class MarsReachability is implemented in both /private/var/containers/Bundle/Application/D24DBE0F-73A9-4F6E-B763-37114DE691B0/WeChat.app/Frameworks/mars.framework/mars (0x10d7918d8) and /private/var/containers/Bundle/Application/D24DBE0F-73A9-4F6E-B763-37114DE691B0/WeChat.app/Frameworks/marsbridgenetwork.framework/marsbridgenetwork (0x10cffb9c8). One of the two will be used. Which one is undefined.
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: @0x1002811a8(from 0x100280000) = 11a8
[+] Found encrypted data at address 00004000 of length 154255360 bytes - type 1.
[+] Opening /private/var/containers/Bundle/Application/D597E9A7-A9A4-45A0-886B-E7079A87FC64/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 11a8
[+] Closing original file
[+] Closing dump file
  1. 脱壳完成之后,可以在沙盒目录看到脱壳后的文件:WeChat.decrypted
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
klygteki-iPhone:/ mobile$ cd /var/mobile/Containers/Data/Application/AC83D268-2FE9-434E-8D76-0935AACB2AC3/Documents
klygteki-iPhone:~/Containers/Data/Application/AC83D268-2FE9-434E-8D76-0935AACB2AC3/Documents mobile$ ls -l
total 130176
drwxr-xr-x 11 mobile mobile 352 Aug 6 18:13 00000000000000000000000000000000
drwxr-xr-x 29 mobile mobile 928 May 13 17:44 093b7963fc416ce228a44cfec0fa0e93
drwxr-xr-x 39 mobile mobile 1248 May 13 17:44 0fc3dbad09d2d795ae46d93b65b021d8
drwxr-xr-x 3 mobile mobile 96 Aug 29 2019 CrashReport
-rw-r--r-- 1 mobile mobile 310 Jul 5 2018 Ksid
-rw-r--r-- 1 mobile mobile 1349 Aug 6 18:13 LocalInfo.lst
-rw-r--r-- 1 mobile mobile 234 May 13 17:46 LoginInfo2.dat
drwxr-xr-x 19 mobile mobile 608 Sep 10 2019 MMResourceMgr
drwxr-xr-x 134 mobile mobile 4288 May 13 17:47 MMappedKV
drwxr-xr-x 4 mobile mobile 128 Aug 6 18:13 MemoryStat
drwxr-xr-x 2 mobile mobile 64 May 13 17:46 OpenImResource
-rw-r--r-- 1 mobile mobile 17 Aug 6 18:18 SafeMode.dat
-rw-r--r-- 1 mobile mobile 124234896 Aug 6 16:44 WeChat.decrypted #脱壳文件
drwxr-xr-x 32 mobile mobile 1024 May 13 17:44 d08726a472ac9f7b6f439b2512128105
-rw-r--r-- 1 mobile mobile 8 Aug 29 2019 db.globalconfig
-rw-r--r-- 1 root mobile 249552 Aug 6 16:35 dumpdecrypted.dylib
drwxr-xr-x 40 mobile mobile 1280 May 13 17:46 fdd3050fd85ea125a574eea36b1a05d3
-rw-r--r-- 1 mobile mobile 592 Jul 5 2018 heavy_user_id_mapping.dat
-rw-r--r-- 1 mobile mobile 483 Dec 28 2018 mmupdateinfo.archive
  1. 可以将该脱壳文件拷贝出来,用于解析。
1
2
3
4
 scp root@127.0.0.1:/var/mobile/Containers/Data/Application/978087D3-6F1A-431E-A431-4A9D5023DB3E/Documents/WeChat.decrypted   C:\Users\Shuqing\Desktop
root@127.0.0.1's password:
WeChat.decrypted 100% 118MB 29.7MB/s 00:03

Class-dump解析

砸壳之后的.decrypted文件是不可读的,使用Class-dump 可以将Objective-C编写的二进制文件反编出头文件。

下载安装

  1. 下载地址:http://stevenygard.com/projects/class-dump/ 下载.dmg的文件即可。
  2. 打开工程选择class-dump 运行,把class-dump 放在/usr/local/bin 下,在终端输入 class-dump 查看是否安装成功。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
atxdeMac-mini:dumpdecrypted-master atx$ class-dump
class-dump 3.5 (64 bit)
Usage: class-dump [options] <mach-o-file>

where options are:
-a show instance variable offsets
-A show implementation addresses
--arch <arch> choose a specific architecture from a universal binary (ppc, ppc64, i386, x86_64, armv6, armv7, armv7s, arm64)
-C <regex> only display classes matching regular expression
-f <str> find string in method name
-H generate header files in current directory, or directory specified with -o
-I sort classes, categories, and protocols by inheritance (overrides -s)
-o <dir> output directory used for -H
-r recursively expand frameworks and fixed VM shared libraries
-s sort classes and categories by name
-S sort methods by name
-t suppress header in output, for testing
--list-arches list the arches in the file, then exit
--sdk-ios specify iOS SDK version (will look in /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS<version>.sdk
--sdk-mac specify Mac OS X version (will look in /Developer/SDKs/MacOSX<version>.sdk
--sdk-root specify the full SDK root path (or use --sdk-ios/--sdk-mac for a shortcut)

执行解析

解析命令:class-dump -H Mach-O文件路径 -o 头文件存放目录

  • -H表示要生成头文件
  • -o用于制定头文件的存放目录
1
2
3
4
5
atxdeMac-mini:~ atx$ class-dump -H /Users/atx/Downloads/WeChat.decrypted -o /Users/atx/Desktop/wechat 
2020-08-06 17:06:31.115 class-dump[99575:3084316] Warning: Parsing instance variable type failed, _udpEngine
2020-08-06 17:06:31.116 class-dump[99575:3084316] Warning: Parsing instance variable type failed, _lockstepLogic
2020-08-06 17:06:32.258 class-dump[99575:3084316] Warning: Parsing method types failed, glkmatrix4Fromfloat4x4:
2020-08-06 17:06:46.683 class-dump[99575:3084316] Warning: Parsing method types failed, glkmatrix4Fromfloat4x4:

解析完成后,如下图所示可以看到微信App的头文件。

wechat

参考资料