首页
社区
课程
招聘
[原创]UnCrackable Level 2.app
发表于: 2022-9-19 20:12 21247

[原创]UnCrackable Level 2.app

2022-9-19 20:12
21247

UnCrackable Level 2.app

没想到ios也有crackme,逆向的过程也是十分曲折,过程大概可以分为5大步,第一步是反调试的去除;第二步是在arm64位设备上运行;第三步是过文件完整性检查(md5);第四步是越狱检查;第五步是找到secret strings。

1.准备过程

首先在https://github.com/OWASP/owasp-mastg/tree/master/Crackmes/iOS/Level_02这里下载该ipa文件,ipa文件就是一个压缩包,里面存放着整个app的数据和运行的程序。

 

在整个过程中,我用的工具和设备包括:mac电脑,iPhone5s,ida pro,ghidra,r2

1.解压ipa文件

使用unzip解压之后出现一个Payload文件夹,检查一下可执行文件的类型

1
2
3
file Payload/UnCrackable\ Level\ 2.app/UnCrackable\ Level\ 2
 
Payload/UnCrackable Level 2.app/UnCrackable Level 2: Mach-O universal binary with 2 architectures: [armv7:Mach-O armv7 executable, flags:<NOUNDEFS|DYLDLINK|TWOLEVEL|PIE>] [arm64:Mach-O 64-bit arm64 executable, flags:<NOUNDEFS|DYLDLINK|TWOLEVEL|PIE>]

发现有armv7和arm64两个程序,这是为了对应手机芯片无论是哪种位数都可以让其运行,由于我的iOS是iPhone5s,是64位芯片,所以我们需要给这个程序瘦身,才能更好的对其进行分析。

1
2
3
lipo -thin arm64 ./UnCrackable\ Level\ 2 -o ./UnCrackable\ Level\ 2
file ./UnCrackable\ Level\ 2
./UnCrackable Level 2: Mach-O 64-bit executable arm64

这就瘦身成功了。也可以用rabin2 -x UnCrackable\ Level\ 2进行瘦身。

2.重打包和重签名

瘦身或者对程序进行了patch之后如何快速上传到手机里可以大大加快我们的分析速度,重打包便是将Payload文件夹压缩之后,将zip后缀改成ipa;重签名便是将ipa文件利用iOS App Signer进行再次签名,通过Xcode上传到手机。

 

我在这篇文章里写了详细步骤:https://bbs.pediy.com/thread-273935.htm

3.pass反调试

在iOS上运行该app时出现闪退情况,一开始以为是手机的问题,查阅资料之后才知道是anti-debugging,我们将首先看一下 viewDidLoad,因为它是在视图控制器之前加载函数和检查的地方,也是实现安全检查的常见地方。

 

这里使用的是r2分析。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
[0x100005520]> pdf @ method.ViewController.viewDidLoad
            ;-- func.1000054f4:
            ; CODE XREF from method.ViewController.viewDidLoad @ 0x100005528(x)
912: method.ViewController.viewDidLoad (int64_t arg1, void *arg_8h, void *instance, int64_t arg_60h, int64_t arg_70h);
│           ; arg int64_t arg1 @ x0
│           ; arg void *arg_8h @ sp+0x78
│           ; arg void *instance @ sp+0x80
│           ; arg int64_t arg_60h @ sp+0xd0
│           ; arg int64_t arg_70h @ sp+0xe0
│           ; var int64_t var_0h_3 @ sp+0x8
│           ; var int64_t var_0h @ sp+0x10
│           ; var int64_t var_0h_2 @ sp+0x18
│           ; var int64_t var_20h @ sp+0x20
│           ; var int64_t var_20h_2 @ sp+0x28
│           ; var int64_t var_30h @ sp+0x30
│           ; var int64_t var_30h_2 @ sp+0x38
│           ; var int64_t var_40h @ sp+0x40
│           ; var int64_t var_40h_2 @ sp+0x48
│           ; var int64_t var_50h @ sp+0x50
│           ; var int64_t var_50h_2 @ sp+0x58
│           ; var int64_t var_60h @ sp+0x60
│           ; var int64_t var_60h_2 @ sp+0x68
│           0x1000054f4      ffc301d1       sub sp, sp, 0x70
│           0x1000054f8      fa6702a9       stp x26, x25, [var_20h]
│           0x1000054fc      f85f03a9       stp x24, x23, [var_30h]
│           0x100005500      f65704a9       stp x22, x21, [var_40h]
│           0x100005504      f44f05a9       stp x20, x19, [var_50h]
│           0x100005508      fd7b06a9       stp x29, x30, [var_60h]
│           0x10000550c      fd830191       add x29, arg_60h
│           0x100005510      f30300aa       mov x19, x0                ; arg1
│           0x100005514      f30b00f9       str x19, [var_0h]
│           0x100005518      1f2003d5       nop
│           0x10000551c      684c0458       ldr x8, section.21.__DATA.__objc_superrefs ; 0x10000dea8
│           ;-- pc:
│           0x100005520      e80f00f9       str x8, [var_0h_2]
│           0x100005524      1f2003d5       nop
│           0x100005528      81360458       ldr x1, str.viewDidLoad    ; 0x100009c94 ; char *selector
│           0x10000552c      e0430091       add x0, instance           ; void *instance
│           0x100005530      89100094       bl sym.imp.objc_msgSendSuper2 ; void *objc_msgSendSuper2(void *instance, char *selector)
│           0x100005534      41018052       movz w1, 0xa
│           0x100005538      000080d2       movz x0, 0
│           0x10000553c      3b100094       bl sym.imp.dlopen
│           0x100005540      f40300aa       mov x20, x0
│           0x100005544      c1cc0210       adr x1, str.ptrace         ; 0x10000aedc
│           0x100005548      1f2003d5       nop
│           0x10000554c      3a100094       bl sym.imp.dlsym
│           0x100005550      e80300aa       mov x8, x0
│           0x100005554      e0130032       orr w0, wzr, 0x1f
│           0x100005558      01008052       movz w1, 0
│           0x10000555c      020080d2       movz x2, 0
│           0x100005560      03008052       movz w3, 0
│           0x100005564      1f2003d5       nop
│           0x100005568      e00314aa       mov x0, x20
│           0x10000556c      2c100094       bl sym.imp.dlclose
│           0x100005570      1f2003d5       nop
│           0x100005574      60460458       ldr x0, reloc.NSThread     ; 0x10000de40 ; void *instance
│           0x100005578      1f2003d5       nop
│           0x10000557c      22340458       ldr x2, 0x10000dc00
│           0x100005580      1f2003d5       nop
│           0x100005584      21340458       ldr x1, str.detachNewThreadSelector:toTarget:withObject: ; 0x100009ca4 ; char *selector
│           0x100005588      e30313aa       mov x3, x19
│           0x10000558c      040080d2       movz x4, 0
│           0x100005590      6e100094       bl sym.imp.objc_msgSend    ; void *objc_msgSend(void *instance, char *selector)
│           0x100005594      580000b0       adrp x24, section.24.__DATA.__data ; 0x10000e000
│           0x100005598      1f430639       strb wzr, [x24, 0x190]
│           0x10000559c      59000090       adrp x25, 0x10000d000
│           0x1000055a0      202747f9       ldr x0, [x25, 0xe48]       ; 0xe0 ; 224 ; void *instance
│           0x1000055a4      1f2003d5       nop
│           0x1000055a8      54330458       ldr x20, str.defaultManager ; 0x100009cd1
│           0x1000055ac      e10314aa       mov x1, x20                ; char *selector
│           0x1000055b0      66100094       bl sym.imp.objc_msgSend    ; void *objc_msgSend(void *instance, char *selector)
│           0x1000055b4      fd031daa       mov x29, x29
│           0x1000055b8      76100094       bl sym.imp.objc_retainAutoreleasedReturnValue ; void objc_retainAutoreleasedReturnValue(void *instance)
│           0x1000055bc      f60300aa       mov x22, x0
│           0x1000055c0      1f2003d5       nop
│           0x1000055c4      b5320458       ldr x21, str.fileExistsAtPath: ; 0x100009ce0
│           0x1000055c8      026f0310       adr x2, str.cstr._Applications_Cydia.app ; 0x10000c3a8
│           0x1000055cc      1f2003d5       nop
│           0x1000055d0      e10315aa       mov x1, x21                ; char *selector
│           0x1000055d4      5d100094       bl sym.imp.objc_msgSend    ; void *objc_msgSend(void *instance, char *selector)
│           0x1000055d8      f70300aa       mov x23, x0
│           0x1000055dc      e00316aa       mov x0, x22                ; void *instance
│           0x1000055e0      63100094       bl sym.imp.objc_release    ; void objc_release(void *instance)
│       ┌─< 0x1000055e4      37070035       cbnz w23, 0x1000056c8
│       │   0x1000055e8      202747f9       ldr x0, [x25, 0xe48]       ; 0xe0 ; 224 ; void *instance
│       │   0x1000055ec      e10314aa       mov x1, x20                ; char *selector
│       │   0x1000055f0      56100094       bl sym.imp.objc_msgSend    ; void *objc_msgSend(void *instance, char *selector)
│       │   0x1000055f4      fd031daa       mov x29, x29
│       │   0x1000055f8      66100094       bl sym.imp.objc_retainAutoreleasedReturnValue ; void objc_retainAutoreleasedReturnValue(void *instance)
│       │   0x1000055fc      f60300aa       mov x22, x0
│       │   0x100005600      426e0310       adr x2, str.cstr._Library_MobileSubstrate_MobileSubstrate.dylib ; 0x10000c3c8
│       │   0x100005604      1f2003d5       nop
│       │   0x100005608      e10315aa       mov x1, x21                ; char *selector
│       │   0x10000560c      4f100094       bl sym.imp.objc_msgSend    ; void *objc_msgSend(void *instance, char *selector)
│       │   0x100005610      f70300aa       mov x23, x0
│       │   0x100005614      e00316aa       mov x0, x22                ; void *instance
│       │   0x100005618      55100094       bl sym.imp.objc_release    ; void objc_release(void *instance)
│      ┌──< 0x10000561c      77050035       cbnz w23, 0x1000056c8
│      ││   0x100005620      202747f9       ldr x0, [x25, 0xe48]       ; 0xe0 ; 224 ; void *instance
│      ││   0x100005624      e10314aa       mov x1, x20                ; char *selector
│      ││   0x100005628      48100094       bl sym.imp.objc_msgSend    ; void *objc_msgSend(void *instance, char *selector)
│      ││   0x10000562c      fd031daa       mov x29, x29
│      ││   0x100005630      58100094       bl sym.imp.objc_retainAutoreleasedReturnValue ; void objc_retainAutoreleasedReturnValue(void *instance)
│      ││   0x100005634      f60300aa       mov x22, x0
│      ││   0x100005638      826d0310       adr x2, str.cstr._bin_bash ; 0x10000c3e8
│      ││   0x10000563c      1f2003d5       nop
│      ││   0x100005640      e10315aa       mov x1, x21                ; char *selector
│      ││   0x100005644      41100094       bl sym.imp.objc_msgSend    ; void *objc_msgSend(void *instance, char *selector)
│      ││   0x100005648      f70300aa       mov x23, x0
│      ││   0x10000564c      e00316aa       mov x0, x22                ; void *instance
│      ││   0x100005650      47100094       bl sym.imp.objc_release    ; void objc_release(void *instance)
│     ┌───< 0x100005654      b7030035       cbnz w23, 0x1000056c8
│     │││   0x100005658      202747f9       ldr x0, [x25, 0xe48]       ; 0xe0 ; 224 ; void *instance
│     │││   0x10000565c      e10314aa       mov x1, x20                ; char *selector
│     │││   0x100005660      3a100094       bl sym.imp.objc_msgSend    ; void *objc_msgSend(void *instance, char *selector)
│     │││   0x100005664      fd031daa       mov x29, x29
│     │││   0x100005668      4a100094       bl sym.imp.objc_retainAutoreleasedReturnValue ; void objc_retainAutoreleasedReturnValue(void *instance)
│     │││   0x10000566c      f60300aa       mov x22, x0
│     │││   0x100005670      c26c0310       adr x2, str.cstr._usr_sbin_sshd ; 0x10000c408
│     │││   0x100005674      1f2003d5       nop
│     │││   0x100005678      e10315aa       mov x1, x21                ; char *selector
│     │││   0x10000567c      33100094       bl sym.imp.objc_msgSend    ; void *objc_msgSend(void *instance, char *selector)
│     │││   0x100005680      f70300aa       mov x23, x0
│     │││   0x100005684      e00316aa       mov x0, x22                ; void *instance
│     │││   0x100005688      39100094       bl sym.imp.objc_release    ; void objc_release(void *instance)
│    ┌────< 0x10000568c      f7010035       cbnz w23, 0x1000056c8
│    ││││   0x100005690      202747f9       ldr x0, [x25, 0xe48]       ; 0xe0 ; 224 ; void *instance
│    ││││   0x100005694      e10314aa       mov x1, x20                ; char *selector
│    ││││   0x100005698      2c100094       bl sym.imp.objc_msgSend    ; void *objc_msgSend(void *instance, char *selector)
│    ││││   0x10000569c      fd031daa       mov x29, x29
│    ││││   0x1000056a0      3c100094       bl sym.imp.objc_retainAutoreleasedReturnValue ; void objc_retainAutoreleasedReturnValue(void *instance)
│    ││││   0x1000056a4      f60300aa       mov x22, x0
│    ││││   0x1000056a8      026c0310       adr x2, str.cstr._etc_apt  ; 0x10000c428
│    ││││   0x1000056ac      1f2003d5       nop
│    ││││   0x1000056b0      e10315aa       mov x1, x21                ; char *selector
│    ││││   0x1000056b4      25100094       bl sym.imp.objc_msgSend    ; void *objc_msgSend(void *instance, char *selector)
│    ││││   0x1000056b8      f50300aa       mov x21, x0
│    ││││   0x1000056bc      e00316aa       mov x0, x22                ; void *instance
│    ││││   0x1000056c0      2b100094       bl sym.imp.objc_release    ; void objc_release(void *instance)
│   ┌─────< 0x1000056c4      75000034       cbz w21, 0x1000056d0
│   │└└└└─> 0x1000056c8      e8030032       orr w8, wzr, 1
│   │       0x1000056cc      08430639       strb w8, [x24, 0x190]
│   └─────> 0x1000056d0      ff0700f9       str xzr, [var_0h_3]
│           0x1000056d4      1f2003d5       nop
│           0x1000056d8      412a0458       ldr x1, str.writeToFile:atomically:encoding:error: ; 0x100009cf2 ; char *selector
│           0x1000056dc      606b0310       adr x0, str.cstr.ABCD      ; 0x10000c448 ; void *instance
│           0x1000056e0      1f2003d5       nop
│           0x1000056e4      226c0310       adr x2, str.cstr._private_wut.txt ; 0x10000c468
│           0x1000056e8      1f2003d5       nop
│           0x1000056ec      f6030032       orr w22, wzr, 1
│           0x1000056f0      e3030032       orr w3, wzr, 1
│           0x1000056f4      e4031e32       orr w4, wzr, 4
│           0x1000056f8      e5230091       add x5, arg_8h
│           0x1000056fc      13100094       bl sym.imp.objc_msgSend    ; void *objc_msgSend(void *instance, char *selector)
│           0x100005700      e00740f9       ldr x0, [arg_8h]           ; 0x4 ; 4 ; void *instance
│           0x100005704      1d100094       bl sym.imp.objc_retain     ; void objc_retain(void *instance)
│           0x100005708      f50300aa       mov x21, x0
│       ┌─< 0x10000570c      150200b4       cbz x21, 0x10000574c
│       │   0x100005710      202747f9       ldr x0, [x25, 0xe48]       ; 0xe0 ; 224 ; void *instance
│       │   0x100005714      e10314aa       mov x1, x20                ; char *selector
│       │   0x100005718      0c100094       bl sym.imp.objc_msgSend    ; void *objc_msgSend(void *instance, char *selector)
│       │   0x10000571c      fd031daa       mov x29, x29
│       │   0x100005720      1c100094       bl sym.imp.objc_retainAutoreleasedReturnValue ; void objc_retainAutoreleasedReturnValue(void *instance)
│       │   0x100005724      f40300aa       mov x20, x0
│       │   0x100005728      1f2003d5       nop
│       │   0x10000572c      e1270458       ldr x1, str.removeItemAtPath:error: ; 0x100009d19 ; char *selector
│       │   0x100005730      c2690310       adr x2, str.cstr._private_wut.txt ; 0x10000c468
│       │   0x100005734      1f2003d5       nop
│       │   0x100005738      030080d2       movz x3, 0
│       │   0x10000573c      03100094       bl sym.imp.objc_msgSend    ; void *objc_msgSend(void *instance, char *selector)
│       │   0x100005740      e00314aa       mov x0, x20                ; void *instance
│       │   ; CODE XREF from str.base64DataFromString: @ +0x1(x)
│       │   0x100005744      0a100094       bl sym.imp.objc_release    ; void objc_release(void *instance)
│      ┌──< 0x100005748      02000014       b 0x100005750
│      │└─> 0x10000574c      16430639       strb w22, [x24, 0x190]
│      │    ; CODE XREF from method.ViewController.viewDidLoad @ 0x100005748(x)
│      └──> 0x100005750      1f2003d5       nop
│           0x100005754      e0370458       ldr x0, reloc.UIApplication ; 0x10000de50 ; void *instance
│           0x100005758      1f2003d5       nop
│           0x10000575c      a1260458       ldr x1, str.sharedApplication ; 0x100009d31 ; char *selector
│           0x100005760      fa0f0094       bl sym.imp.objc_msgSend    ; void *objc_msgSend(void *instance, char *selector)
│           0x100005764      fd031daa       mov x29, x29
│           0x100005768      0a100094       bl sym.imp.objc_retainAutoreleasedReturnValue ; void objc_retainAutoreleasedReturnValue(void *instance)
│           0x10000576c      f40300aa       mov x20, x0
│           0x100005770      1f2003d5       nop
│           0x100005774      20370458       ldr x0, reloc.NSURL        ; 0x10000de58 ; void *instance
│           0x100005778      1f2003d5       nop
│           0x10000577c      e1250458       ldr x1, str.URLWithString: ; 0x100009d43 ; char *selector
│           0x100005780      42680310       adr x2, str.cstr.cydia:__package_com.example.package ; 0x10000c488
│           0x100005784      1f2003d5       nop
│           0x100005788      f00f0094       bl sym.imp.objc_msgSend    ; void *objc_msgSend(void *instance, char *selector)
│           0x10000578c      fd031daa       mov x29, x29
│           0x100005790      00100094       bl sym.imp.objc_retainAutoreleasedReturnValue ; void objc_retainAutoreleasedReturnValue(void *instance)
│           0x100005794      f60300aa       mov x22, x0
│           0x100005798      1f2003d5       nop
│           0x10000579c      21250458       ldr x1, str.canOpenURL:    ; 0x100009d52 ; char *selector
│           0x1000057a0      e00314aa       mov x0, x20                ; void *instance
│           0x1000057a4      e20316aa       mov x2, x22
│           0x1000057a8      e80f0094       bl sym.imp.objc_msgSend    ; void *objc_msgSend(void *instance, char *selector)
│           0x1000057ac      f70300aa       mov x23, x0
│           0x1000057b0      e00316aa       mov x0, x22                ; void *instance
│           0x1000057b4      ee0f0094       bl sym.imp.objc_release    ; void objc_release(void *instance)
│           0x1000057b8      e00314aa       mov x0, x20                ; void *instance
│           0x1000057bc      ec0f0094       bl sym.imp.objc_release    ; void objc_release(void *instance)
│       ┌─< 0x1000057c0      77000034       cbz w23, 0x1000057cc
│       │   0x1000057c4      e8031f2a       mov w8, wzr
│       │   0x1000057c8      08430639       strb w8, [x24, 0x190]
│       └─> 0x1000057cc      e00315aa       mov x0, x21                ; void *instance
│           0x1000057d0      e70f0094       bl sym.imp.objc_release    ; void objc_release(void *instance)
│           0x1000057d4      1f2003d5       nop
│           0x1000057d8      94230458       ldr x20, 0x10000dc48
│           0x1000057dc      e00313aa       mov x0, x19                ; void *instance
│           0x1000057e0      e10314aa       mov x1, x20                ; char *selector
│           0x1000057e4      d90f0094       bl sym.imp.objc_msgSend    ; void *objc_msgSend(void *instance, char *selector)
│           0x1000057e8      fd031daa       mov x29, x29
│           0x1000057ec      e90f0094       bl sym.imp.objc_retainAutoreleasedReturnValue ; void objc_retainAutoreleasedReturnValue(void *instance)
│           0x1000057f0      f50300aa       mov x21, x0
│           0x1000057f4      1f2003d5       nop
│           0x1000057f8      c1220458       ldr x1, str.setNumberOfLines: ; 0x100009d67 ; char *selector
│           0x1000057fc      e2030032       orr w2, wzr, 1
│           0x100005800      d20f0094       bl sym.imp.objc_msgSend    ; void *objc_msgSend(void *instance, char *selector)
│           0x100005804      e00315aa       mov x0, x21                ; void *instance
│           0x100005808      d90f0094       bl sym.imp.objc_release    ; void objc_release(void *instance)
│           0x10000580c      e00313aa       mov x0, x19                ; void *instance
│           0x100005810      e10314aa       mov x1, x20                ; char *selector
│           0x100005814      cd0f0094       bl sym.imp.objc_msgSend    ; void *objc_msgSend(void *instance, char *selector)
│           0x100005818      fd031daa       mov x29, x29
│           0x10000581c      dd0f0094       bl sym.imp.objc_retainAutoreleasedReturnValue ; void objc_retainAutoreleasedReturnValue(void *instance)
│           0x100005820      f50300aa       mov x21, x0
│           0x100005824      1f2003d5       nop
│           0x100005828      81210458       ldr x1, str.setAdjustsFontSizeToFitWidth: ; 0x100009d79 ; char *selector
│           0x10000582c      e2030032       orr w2, wzr, 1
│           0x100005830      c60f0094       bl sym.imp.objc_msgSend    ; void *objc_msgSend(void *instance, char *selector)
│           0x100005834      e00315aa       mov x0, x21                ; void *instance
│           0x100005838      cd0f0094       bl sym.imp.objc_release    ; void objc_release(void *instance)
│           0x10000583c      e00313aa       mov x0, x19                ; void *instance
│           0x100005840      e10314aa       mov x1, x20                ; char *selector
│           0x100005844      c10f0094       bl sym.imp.objc_msgSend    ; void *objc_msgSend(void *instance, char *selector)
│           0x100005848      fd031daa       mov x29, x29
│           0x10000584c      d10f0094       bl sym.imp.objc_retainAutoreleasedReturnValue ; void objc_retainAutoreleasedReturnValue(void *instance)
│           0x100005850      f30300aa       mov x19, x0
│           0x100005854      1f2003d5       nop
│           0x100005858      41200458       ldr x1, str.sizeToFit      ; 0x100009d97 ; char *selector
│           0x10000585c      bb0f0094       bl sym.imp.objc_msgSend    ; void *objc_msgSend(void *instance, char *selector)
│           0x100005860      e00313aa       mov x0, x19                ; void *instance
│           0x100005864      c20f0094       bl sym.imp.objc_release    ; void objc_release(void *instance)
│           0x100005868      fd7b46a9       ldp x29, x30, [var_60h]
│           0x10000586c      f44f45a9       ldp x20, x19, [var_50h]
│           0x100005870      f65744a9       ldp x22, x21, [var_40h]
│           0x100005874      f85f43a9       ldp x24, x23, [var_30h]
│           0x100005878      fa6742a9       ldp x26, x25, [var_20h]
│           0x10000587c      ffc30191       add sp, arg_70h
└           0x100005880      c0035fd6       ret
1
2
3
0x10000553c      bl sym.imp.dlopen #运行dlopen(0,0xa),获取当前进程句柄
0x10000554c      bl sym.imp.dlsym #运行dlsym(x0,"ptrace"),获取ptrace函数地址
0x100005564      blr x8 #运行ptrace(0x1f,0,0,0),

运行ptrace函数时使用了PT_DENY_ATTACH宏,这样的目的就是拒绝调试器附加;

 


运行到ptrace之后就寄了。所以要想调试的话需要对文件进行patch之后再压缩成ipa包,传给iOS。经过lldb得知,运行到 100005564处blr x8就是调用ptrace,所以我们把这行汇编变为nop即可。

 

用r2进行patch很方便,如下

 


4.点击vertify没有反应

重打包之后在iOS内打开app,输入一些数据后点击vertify,但是并没有反应。这是怎么回事呢?我们调试一下试试,点击这个动作对应的是handleButtonClick方法,所以去逆一下该方法流程。在网上搜了一下用r2去patch

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# re-open file in read/write mode
oo+
 
# Fix offset to LC_COMMAND_64
s 0x1000052d8
oo+
wa add x21, x22, 0x20
 
# Remove unnecessary check for LC_COMMAND==LC_SEGMENT
s 0x100005304
oo+
wa NOP
 
# Fix sizeof(segment_command_64)
s 0x100005328
oo+
wa add x20, x23, 0x48
 
# Fix sizeof(section_64)
s 0x100005350
oo+
wa add x20, x20, 0x50
 
# Fix register size for section_64.addr and section_64.size
s 0x100005360
oo+
wa ldp x8, x1, [x20, 0x20]
 
# Fix register size for segment_command_64.vmaddr:
s 0x100005364
oo+
wa ldr x9, [x23, 0x18]
 
# Fix register size for baseaddr and section_64.addr
s 0x100005368
oo+
wa add x8, x8, x22
 
# Fix register size for section_64.addr and segment_command_64.vmaddr
s 0x10000536c
oo+
wa sub x8, x8, x9
 
# Fix register size for CC_MD5's first argument
s 0x100005370
oo+
wa mov x0,x8
 
# Write secret
s 0x10000e000
oo+
wz uMqEK/JCNg+njduTS840mrac3zjLP1kpwV508f0119E=

5.pass jailbreak-check

当我以为能调试的时候,发现这里有检查Cydia的存在来判断设备是否越狱,如果检测到则退出,

 

 

去ida里找一下代码。

 


可以看到fileExistsAtPath判断这些文件是否存在;

 


可以查看该网址是否可以被打开,如果Cydia被安装。

 

观察代码发现,所有的检查都和LABEL_6的 byte_10000E190 = 1有关系,所以我们只需要在最后一个 byte_10000E190 = 1处将 byte_10000E190 = 1修改为 byte_10000E190 = 0即可

 


效果如下

6.Decryption Failed


看字好像是由于加解密有点问题才导致不能正常运行该流程,通过交叉引用字符串找到该函数;好像是进行了md5的校验,如果对程序进行了patch,md5值就会不同。

 

那么如何绕过呢?先把程序进行瘦身为64位的arm,并且对其patch能够在64位机器内运行,然后将text段提取出来算md5。

1
2
3
4
5
6
7
8
9
#!/bin/bash
 
rm -f textSection
out=$(r2 -q -c "iS" "UnCrackable Level 2" | grep text)
echo $out
addr=$(echo $out | cut -d ' ' -f4)
size=$(echo $out | cut -d ' ' -f3)
echo $addr $size
r2 -q -c "pr $size @ $addr > textSection" "UnCrackable Level 2"


最后通过frida-trace对程序检查进行绕过。

 

先运行frida-trace -U Uncrackable2 -m "+[NSString stringWithCString:encoding:]"

 

再修改 handlers/NSStringstringWithCStringencoding.js文件。

 


最后运行frida-trace -U Uncrackable2 -m "+[NSString stringWithCString:encoding:]"出现Failed to attach: process with pid 21420 either refused to load frida-agent, or terminated during injection,出错了,看样子是在注入hook的时候出错了,难道是还有什么没有注意到的地方,再次回到Viewdidload,看到detachNewThreadSelector,这个函数是

 



通过查看得知大概调用的是detachNewThreadSelector(0x10000dc00, x19, 0),x19内是ViewController,这个函数大概意思就是调用ViewController的abc方法,该方法会在新的线程里执行,我们继续追踪一下看看;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
[0x100005488]> pdf @ method.ViewController.abc
        ; CODE XREF from method.ViewController.viewDidLoad @ 0x10000557c
        ; CODE XREF from str.v32_0:8__UIApplication_16__UIUserNotificationSettings_24 @ +0x15
        ;-- func.1000053f4:
256: method.ViewController.abc (int64_t arg1);
│           ; var int64_t var_ch @ sp+0xc
│           ; var int64_t var_44h @ sp+0x44
│           ; var int64_t var_7ch @ sp+0x7c
│           ; var int64_t var_b4h @ sp+0xb4
│           ; var int64_t var_ech @ sp+0xec
│           ; var int64_t var_f0h @ sp+0xf0
│           ; var int64_t var_f8h @ sp+0xf8
│           ; var int64_t var_0h @ sp+0x118
│           ; var int64_t var_119h @ sp+0x119
│           ; var int64_t var_0h_2 @ sp+0x380
│           ; var int64_t var_0h_3 @ sp+0x388
│           ; var int64_t var_0h_4 @ sp+0x38c
│           ; var int64_t var_40h @ sp+0x390
│           ; var int64_t var_40h_2 @ sp+0x398
│           ; var int64_t var_10h @ sp+0x3a0
│           ; var int64_t var_10h_2 @ sp+0x3a8
│           ; var int64_t var_20h @ sp+0x3b0
│           ; var int64_t var_20h_2 @ sp+0x3b8
│           ; var int64_t var_30h @ sp+0x3c0
│           ; var int64_t var_30h_2 @ sp+0x3c8
│           ; arg int64_t arg1 @ x0
│           0x1000053f4      fc6fbca9       stp x28, x27, [var_40h]!
│           0x1000053f8      f65701a9       stp x22, x21, [var_10h]
│           0x1000053fc      f44f02a9       stp x20, x19, [var_20h]
│           0x100005400      fd7b03a9       stp x29, x30, [var_30h]
│           0x100005404      fdc30091       add x29, var_30h
│           0x100005408      ff430ed1       sub sp, sp, 0x390
│           0x10000540c      f3c30391       add x19, var_f0h
│           0x100005410      ff1b01b9       str wzr, [var_0h]          ; arg1
│           0x100005414      ffef00b9       str wzr, [var_ech]         ; arg1
│           0x100005418      e80b1fb2       orr x8, xzr, 0xe0000000e
│           0x10000541c      280080f2       movk x8, 0x1
│           0x100005420      684a01f9       str x8, [var_0h_2]
│           0x100005424      e8030032       orr w8, wzr, 1             ; arg1
│           0x100005428      a8831cb8       stur w8, [var_0h_3]
│           0x10000542c      8b100094       bl sym.imp.getpid          ; int getpid(void)
│                                                                      ; int getpid(void)
│           0x100005430      a0c31cb8       stur w0, [var_0h_4]
│           0x100005434      1f2003d5       nop
│           0x100005438      d45f0358       ldr x20, reloc.mach_task_self_ ; 0x10000c030
│           0x10000543c      f5f30191       add x21, var_7ch
│           0x100005440      16518052       movz w22, 0x288
│       ┌─< 0x100005444      05000014       b 0x100005458
│       │   ; CODE XREF from method.ViewController.abc @ 0x1000054c8
│      ┌──> 0x100005448      e8674439       ldrb w8, [var_119h]        ; [0x119:4]=-1 ; 281
│     ┌───< 0x10000544c      08051837       tbnz w8, 3, 0x1000054ec    ; unlikely
│     │╎│   0x100005450      800c8052       movz w0, 0x64              ; 'd'
│     │╎│   0x100005454      fc100094       bl sym.imp.usleep          ; int usleep(int s)
│     │╎│                                                              ; int usleep(-1)
│     │╎│   ; CODE XREF from method.ViewController.abc @ 0x100005444
│     │╎└─> 0x100005458      800240b9       ldr w0, [x20]
│     │╎    0x10000545c      e1231f32       orr w1, wzr, 0x3fe
│     │╎    0x100005460      e2d30291       add x2, var_b4h
│     │╎    0x100005464      e3b30391       add x3, var_ech
│     │╎    0x100005468      e4f30191       add x4, var_7ch
│     │╎    0x10000546c      e5130191       add x5, var_44h
│     │╎    0x100005470      e6330091       add x6, var_ch
│     │╎    0x100005474      f1100094       bl sym.imp.task_get_exception_ports
│     │╎    0x100005478      e8ef40b9       ldr w8, [var_ech]          ; [0xec:4]=-1 ; 236
│     │╎    0x10000547c      1f000071       cmp w0, 0
│     │╎    0x100005480      0409407a       ccmp w8, 0, 4, eq
│     │╎┌─< 0x100005484      20010054       b.eq 0x1000054a8           ; likely
│     │╎│   0x100005488      090080d2       movz x9, 0
│     │╎│   ; CODE XREF from method.ViewController.abc @ 0x1000054a4
│    ┌────> 0x10000548c      aa7a69b8       ldr w10, [x21, x9, lsl 2]
│    ╎│╎│   0x100005490      4a050011       add w10, w10, 1
│    ╎│╎│   0x100005494      5f090071       cmp w10, 2
│   ┌─────< 0x100005498      a2020054       b.hs 0x1000054ec           ; unlikely
│   │╎│╎│   0x10000549c      29050091       add x9, x9, 1
│   │╎│╎│   0x1000054a0      3f0108eb       cmp x9, x8
│   │└────< 0x1000054a4      43ffff54       b.lo 0x10000548c           ; likely
│   │ │╎│   ; CODE XREF from method.ViewController.abc @ 0x100005484
│   │ │╎└─> 0x1000054a8      760200f9       str x22, [x19]
│   │ │╎    0x1000054ac      a00301d1       sub x0, var_0h_2
│   │ │╎    0x1000054b0      e1031e32       orr w1, wzr, 4
│   │ │╎    0x1000054b4      e2e30391       add x2, var_f8h
│   │ │╎    0x1000054b8      e3c30391       add x3, var_f0h
│   │ │╎    0x1000054bc      040080d2       movz x4, 0
│   │ │╎    0x1000054c0      050080d2       movz x5, 0
│   │ │╎    0x1000054c4      da100094       bl sym.imp.sysctl
│   │ │└──< 0x1000054c8      00fcff34       cbz w0, 0x100005448        ; unlikely
│   │ │     0x1000054cc      00cd0210       adr x0, str.__ViewController_abc_ ; 0x10000ae6c
│   │ │     0x1000054d0      1f2003d5       nop
│   │ │     0x1000054d4      61cd0250       adr x1, str._Users_berndt_Projects_uncrackable_app_iOS_Level2_UnDebuggable_ViewController.m ; 0x10000ae82
│   │ │     0x1000054d8      1f2003d5       nop
│   │ │     0x1000054dc      a3cf0250       adr x3, str.junk__0        ; 0x10000aed2
│   │ │     0x1000054e0      1f2003d5       nop
│   │ │     0x1000054e4      c2118052       movz w2, 0x8e
│   │ │     0x1000054e8      1a100094       bl sym.imp.__assert_rtn    ; void __assert_rtn(const char *assertion, const char *file, unsigned int line, const char *function)
│   │ │                                                                ; void __assert_rtn(-1, -1, -1, -1)
│   │ │     ; CODE XREFS from method.ViewController.abc @ 0x10000544c, 0x100005498
│   └─└───> 0x1000054ec      00008052       movz w0, 0
└           0x1000054f0      54100094       bl sym.imp.exit            ; void exit(int status) ; method.ViewController.viewDidLoad
└                                                                      ; void exit(-1)

task_get_exception_ports:是一个在用户态可以使用的task API,可以查询task的异常端口,而mach的异常消息都会发送到异常端口,所以我们通过它来验证调试器是否设置了这样的端口,看起来好像可以反调试,看看代码中的该函数可以干什么

 

task_get_exception_ports(mac_task_self,0x3fe,arg_b4h,arg_ech,arg_7ch,arg_44h,arg_ch),0x3fe代表EXC_MASK_*全部的情况。就是所有的异常情况只要被检索到,这个app就会被认为在debugger状态中,将会打破循环直接退出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
Function - Return send rights to the target task's exception ports.
SYNOPSIS
 
kern_return_t   task_get_exception_ports
            (task_t                                    task,
             exception_mask_t               exception_types,
             exception_mask_array_t     old_exception_masks,
             old_exception_masks        old_exception_count,
             exception_port_array_t     old_exception_ports,
             exception_behavior_array_t       old_behaviors,
             exception_flavor_array_t           old_flavors);
 
PARAMETERS
 
task
    [in task send right] The task for which to return the exception ports.
 
exception_types
    [in scalar] A flag word indicating the types of exceptions for which the exception ports are desired:
 
    EXC_MASK_BAD_ACCESS
    Could not access memory.
 
    EXC_MASK_BAD_INSTRUCTION
    Instruction failed. Illegal or undefined instruction or operand.
 
    EXC_MASK_ARITHMETIC
    Arithmetic exception
 
    EXC_MASK_EMULATION
    Emulation instruction. Emulation support instruction encountered.
 
    EXC_MASK_SOFTWARE
    Software generated exception.
 
    EXC_MASK_BREAKPOINT
    Trace, breakpoint, etc.
 
    EXC_MASK_SYSCALL
    System call requested.
 
    EXC_MASK_MACH_SYSCALL
    System call with a number in the Mach call range requested.
 
    EXC_MASK_RPC_ALERT
    Exceptional condition encountered during execution of RPC.
 
old_exception_masks
    [out array of exception_mask_t] An array, each element being a mask specifying for which exception types the corresponding element of the other arrays apply.
 
old_exception_count
    [pointer to in/out scalar] On input, the maximum size of the array buffers; on output, the number of returned sets returned.

这里有比较多的patch方法,可以直接把exit给patch了(没有测试),还可以patch掉各种跳转判断

1
2
3
s 0x100005498
oo+
wa nop

重新打包,再次运行,当我认为可以找到secret strings时,发现还是报错,使用frida-trace进行hook时出现decryption failed;

 

在https://hello-sherlock.github.io/2017/03/22/eight-Blog/#%E5%8A%A8%E6%80%81%E6%A3%80%E6%B5%8B得知,还有sysctl也可能有反调试,在0x1000054c4处有调用sysctl。

 

其实不需要查看这么仔细,直接在r2里看调用关系即可,在0x1000054ec处执行exit,而此地址有两个来源,是0x100005498和0x10000544c。都给patch成nop即可,下面是对比图

 

第一部分是没有patch过的;

 


第二部分是将0x10000544c处改为nop,发现在最后少了exit函数。

 


第三部分是0x100005498处改为nop;

 



至此,两处调用exit的函数均已消失。

 

使用frida-trace -U Uncrackable2 -m "+[NSString stringWithCString:encoding:]"进行hook就得到如下结果。

 

7.找到secret strings

我们已经在 ViewController.handleButtonClick 中看到了对 decrypt:password: 的调用,因此为了获取secret strings,我们可以用frida-trace来获取strings。

1
frida-trace -U Uncrackable2 -m "+[AESCrypt decrypt:password:]"

修改 handlers/AESCrypt/decryptpassword.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/*
 * Auto-generated by Frida. Please modify to match the signature of +[AESCrypt encrypt:password:].
 * This stub is currently auto-generated from manpages when available.
 *
 * For full API reference, see: https://frida.re/docs/javascript-api/
 */
 
{
  /**
   * Called synchronously when about to call +[AESCrypt encrypt:password:].
   *
   * @this {object} - Object allowing you to store state for use in onLeave.
   * @param {function} log - Call this function with a string to be presented to the user.
   * @param {array} args - Function arguments represented as an array of NativePointer objects.
   * For example use args[0].readUtf8String() if the first argument is a pointer to a C string encoded as UTF-8.
   * It is also possible to modify arguments by assigning a NativePointer object to an element of this array.
   * @param {object} state - Object allowing you to keep state across function calls.
   * Only one JavaScript function will execute at a time, so do not worry about race-conditions.
   * However, do not use this to store function arguments across onEnter/onLeave, but instead
   * use "this" which is an object for keeping state local to an invocation.
   */
  onEnter(log, args, state) {
  },
 
  /**
   * Called synchronously when about to return from +[AESCrypt encrypt:password:].
   *
   * See onEnter for details.
   *
   * @this {object} - Object allowing you to access state stored in onEnter.
   * @param {function} log - Call this function with a string to be presented to the user.
   * @param {NativePointer} retval - Return value represented as a NativePointer object.
   * @param {object} state - Object allowing you to keep state across function calls.
   */
  onLeave(log, retval, state) {
    var secret = new ObjC.Object(ptr(retval)).toString()
    log(`Decrypted secret: ${secret}`)
  }
}

再使用以下命令hook,然后就可以获得strings了。

1
2
frida-trace -U Uncrackable2 -m "+[NSString stringWithCString:encoding:]" &
frida-trace -U Uncrackable2 -m "+[AESCrypt decrypt:password:]"


得到答案 MysuperSecretString


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 296
活跃值: (435)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
frida-trace -U Uncrackable2 -m "+[NSString stringWithCString:encoding:]" -m  "+[AESCrypt decrypt:password:]"
可以这样的
2022-10-30 15:48
0
游客
登录 | 注册 方可回帖
返回
//