Post

동적으로 로드되는 실행 파일에 대한 고찰 - 3

malware analysis a encrypted string

동적으로 로드되는 실행 파일에 대한 고찰 - 3

Introduction

지난 글에서 동적으로 로드하는 부분을 봤는데 문자열을 암호화 처리하여 가려놓은 걸 확인할 수 있었다. 이번 장에서는 복호화하여 어떤 내용들이 있는지 확인해볼 예정이다.

What is that

소스코드를 봤을 때 아래와 같은 방법으로 문자열을 가려놓았다.

1
2
    public static final String D0 = j("//v38fM", 150, false);
    public static final String E0 = j("uPT/+A", 150, false);

String j(String, int, boolean) 함수를 따라가면 아래와 같이 로직이 나와있는 걸 확인할 수 있다.

해당 호출을 따라가보면 아래와 같은 로직을 확인할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    static String j(String str, int i2, boolean z5) {
        byte b6 = (byte) i2;
        int i6 = 0;
        try {
            if (z5) {
                byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
                while (i6 < bytes.length) {
                    bytes[i6] = (byte) (bytes[i6] ^ b6);
                    i6++;
                }
                return Base64.encodeToString(bytes, 3);
            }
            byte[] decode = Base64.decode(str, 3);
            while (i6 < decode.length) {
                decode[i6] = (byte) (decode[i6] ^ b6);
                i6++;
            }
            return new String(decode, StandardCharsets.UTF_8);
        } catch (Exception unused) {
            return "";
        }
    }

위 로직을 보면 z5 에 따라서 인코딩할지 디코딩할지 볼 수 있다. 또한 XOR 연산을 통하여 바이트를 꼬는 걸 볼 수 있다. XOR 의 특징은 원본의 형태를 알 수 없으며 하나의 키로 암/복호화가 가능하다. 단점이 있다면 키는 Brute-force attack 로 발췌가 가능할 수 있다는 점이다.

아래를 보면 이에 대하여 이해하기 쉬울 것이다.

출처: https://m.blog.naver.com/wndcl1212/221021309133

왼쪽부터 AND/OR/XOR 연산을 수행한 상태이다. XOR 은 원본의 형태를 알아볼 수 없다.

따라서 해당 로직에 따라 암호화된 문자열을 복호화시키면 다음과 같다.

1
2
3
4
5
[*] Encrypted String: //v38fM
=> Decrypted String: image

[*] Encrypted String: uPT/+A
=> Decrypted String: .bin

그러면 아래와 같은 문자열이 떠오른다.

1
image.bin

A Critical Breakthrough

위 프로세스처럼 다른 문자열들도 복호화가 가능해진다. 그 외 dex 파일 내에 존재하는 모든 암호화된 문자열을 확인해보면 아래와 같다.

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
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
[*] Encrypted String: //v38fM
=> Decrypted String: image

[*] Encrypted String: uPT/+A
=> Decrypted String: .bin

[*] Encrypted String: 39I
=> Decrypted String: ID

[*] Encrypted String: 2Nfb0w
=> Decrypted String: NAME

[*] Encrypted String: 4u/m8w
=> Decrypted String: type

[*] Encrypted String: 9OP48vrz
=> Decrypted String: bundle

[*] Encrypted String: +/ny8w
=> Decrypted String: mode

[*] Encrypted String: 9/Xi/+D34vM
=> Decrypted String: activate

[*] Encrypted String: 19PF
=> Decrypted String: AES

[*] Encrypted String: 19PFudXU1bnG3dXFo8b38vL/+PE
=> Decrypted String: AES/CBC/PKCS5Padding

[*] Encrypted String: 9/Pl+f3x4uXj/6f986ekpaKj//vv9+L05/nm4uHu5eI
=> Decrypted String: aesokgtsui1ke12345imyatbqoptwxst

[*] Encrypted String: qvTkqA
=> Decrypted String: <br>

[*] Encrypted String: qvfm5qg
=> Decrypted String: <app>

[*] Encrypted String: 4OLk
=> Decrypted String: vtr

[*] Encrypted String: 4u/m8w
=> Decrypted String: type

[*] Encrypted String: 5uTz8A
=> Decrypted String: pref

[*] Encrypted String: +Pf78w
=> Decrypted String: name

[*] Encrypted String: +/ny
=> Decrypted String: mod

[*] Encrypted String: 4PPk
=> Decrypted String: ver

[*] Encrypted String: 5v3x
=> Decrypted String: pkg

[*] Encrypted String: 4+T/
=> Decrypted String: uri

[*] Encrypted String: ++Xx
=> Decrypted String: msg

[*] Encrypted String: ++XxyfP4
=> Decrypted String: msg_en

[*] Encrypted String: ++Xxyf35
=> Decrypted String: msg_ko

[*] Encrypted String: 4+T6
=> Decrypted String: url

[*] Encrypted String: 9fr35eU
=> Decrypted String: class

[*] Encrypted String: /+Y
=> Decrypted String: ip

[*] Encrypted String: 5vnk4g
=> Decrypted String: port

[*] Encrypted String: //ji8+Tg9/o
=> Decrypted String: interval

[*] Encrypted String: 9/Ly
=> Decrypted String: add

[*] Encrypted String: 9P/4
=> Decrypted String: bin

[*] Encrypted String: 5vPk+8nz+Pf0+vPy
=> Decrypted String: perm_enabled

[*] Encrypted String: +vPx9/Xv
=> Decrypted String: legacy

[*] Encrypted String: +vf48Q
=> Decrypted String: lang

[*] Encrypted String: 8vPg//Xz
=> Decrypted String: device

[*] Encrypted String: 8P/k88nj5Po
=> Decrypted String: fire_url

[*] Encrypted String: 5vPk+8n49+Dz5Mn35f3z8g
=> Decrypted String: perm_naver_asked

[*] Encrypted String: 9/jy5Pn/8sn35v8
=> Decrypted String: android_api

[*] Encrypted String: +fg
=> Decrypted String: on

[*] Encrypted String: +fDw
=> Decrypted String: off

[*] Encrypted String: 9fn48A
=> Decrypted String: conf

[*] Encrypted String: 9fny8w
=> Decrypted String: code

[*] Encrypted String: 8fP48+T/9Q
=> Decrypted String: generic

[*] Encrypted String: 4/j9+Pnh+A
=> Decrypted String: unknown

[*] Encrypted String: 8fn58frzyeXy/Q
=> Decrypted String: google_sdk

[*] Encrypted String: 0/vj+vfi+eQ
=> Decrypted String: Emulator

[*] Encrypted String: 8/vj+vfi+eQ
=> Decrypted String: emulator

[*] Encrypted String: 5f/74/r34vnk
=> Decrypted String: simulator

[*] Encrypted String: 1/jy5Pn/8rbF0t229OP/+uK28Pnktu6uoA
=> Decrypted String: Android SDK built for x86

[*] Encrypted String: 5fL9yfH5+fH68w
=> Decrypted String: sdk_google

[*] Encrypted String: 5fL9
=> Decrypted String: sdk

[*] Encrypted String: 5fL9ye6uoA
=> Decrypted String: sdk_x86

[*] Encrypted String: 5fL9yfHm/vn486Ciyffk+6Ci
=> Decrypted String: sdk_gphone64_arm64

[*] Encrypted String: 4PT57q6g5g
=> Decrypted String: vbox86p

[*] Encrypted String: 8fn58frzueXy/cnx5v75+PPJ
=> Decrypted String: google/sdk_gphone_

[*] Encrypted String: rOPl8+S55PP68/fl87v98+/l
=> Decrypted String: :user/release-keys

[*] Encrypted String: 0fn58frz
=> Decrypted String: Google

[*] Encrypted String: 8fn58frz
=> Decrypted String: google

[*] Encrypted String: 5fL9yfHm/vn488k
=> Decrypted String: sdk_gphone_

[*] Encrypted String: 0fP47/v54v/5+A
=> Decrypted String: Genymotion

[*] Encrypted String: 1OP/+vKk
=> Decrypted String: Build2

[*] Encrypted String: 8fn68vD/5f4
=> Decrypted String: goldfish

[*] Encrypted String: 5Pf49f7j
=> Decrypted String: ranchu

[*] Encrypted String: x9XJxPPw8+Tz+PXzycb++fjz
=> Decrypted String: QC_Reference_Phone

[*] Encrypted String: zv/3+fv/
=> Decrypted String: Xiaomi

[*] Encrypted String: 8+7i5PfJ8vnh+Pr59/LJ//I
=> Decrypted String: extra_download_id

[*] Encrypted String: 5vf1/ffx86w
=> Decrypted String: package:

[*] Encrypted String: 9/jy5Pn/8rj/+OLz+OK48+7i5Pe42NnCycPY3djZwdjJxdnDxNXT
=> Decrypted String: android.intent.extra.NOT_UNKNOWN_SOURCE

[*] Encrypted String: 9/jy5Pn/8sn/8g
=> Decrypted String: android_id

[*] Encrypted String: 8vnh+Pr59/I
=> Decrypted String: download

[*] Encrypted String: 9/X18+Xl//T/+v/i7w
=> Decrypted String: accessibility

[*] Encrypted String: +/Py//fJ5uT5/PP14v/5+A
=> Decrypted String: media_projection

[*] Encrypted String: 5vnh8+Q
=> Decrypted String: power

[*] Encrypted String: 9+Py//k
=> Decrypted String: audio

[*] Encrypted String: +Pni//D/9ffi//n4
=> Decrypted String: notification

[*] Encrypted String: 8v/l5vr37w
=> Decrypted String: display

[*] Encrypted String: 9Pfi4vPk7/v3+Pfx8+Q
=> Decrypted String: batterymanager

[*] Encrypted String: 5eL55Pfx8w
=> Decrypted String: storage

[*] Encrypted String: 9/jy5Pn/8rj/+OLz+OK49/Xi//n4uMXVxNPT2MnZ0NA
=> Decrypted String: android.intent.action.SCREEN_OFF

[*] Encrypted String: 9/jy5Pn/8rj/+OLz+OK49/Xi//n4uMXVxNPT2MnZ2A
=> Decrypted String: android.intent.action.SCREEN_ON

[*] Encrypted String: 9/jy5Pn/8rj/+OLz+OK49/Xi//n4uNLZwdja2dfSydXZ28ba08LT
=> Decrypted String: android.intent.action.DOWNLOAD_COMPLETE

[*] Encrypted String: 9/jy5Pn/8rj/+OLz+OK49/Xi//n4uNLZwdja2dfSydjZwt/Q39XXwt/Z2MnV2t/V3dPS
=> Decrypted String: android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED

[*] Encrypted String: 9/jy5Pn/8rjl8+Li//jx5bjb19jX0dPJw9jd2NnB2MnXxsbJxdnDxNXTxQ
=> Decrypted String: android.settings.MANAGE_UNKNOWN_APP_SOURCES

[*] Encrypted String: //v38fM
=> Decrypted String: image

[*] Encrypted String: uPT/+A
=> Decrypted String: .bin

[*] Encrypted String: 8vPu
=> Decrypted String: dex

[*] Encrypted String: 8P/68+U
=> Decrypted String: files

[*] Encrypted String: +v/0
=> Decrypted String: lib

[*] Encrypted String: 5vPk+//l5f/5+Lo
=> Decrypted String: permission,

[*] Encrypted String: 9/jy5Pn/8rj35ua41/Xi/+D/4u/C/uTz9/I
=> Decrypted String: android.app.ActivityThread

[*] Encrypted String: 9ePk5PP44tf14v/g/+Lvwv7k8/fy
=> Decrypted String: currentActivityThread

[*] Encrypted String: +8b39f338fPl
=> Decrypted String: mPackages

[*] Encrypted String: 9/jy5Pn/8rj35ua42vn38vPy1+b9
=> Decrypted String: android.app.LoadedApk

[*] Encrypted String: +9X69+Xl2vn38vPk
=> Decrypted String: mClassLoader

[*] Encrypted String: 8vP68+Lzyfn0/PP14g
=> Decrypted String: delete_object

[*] Encrypted String: 5fPiyfn0/PP14g
=> Decrypted String: set_object

[*] Encrypted String: 5vfk8/ji
=> Decrypted String: parent

[*] Encrypted String: +fT8tvX3+Pj54rb087b44/r6
=> Decrypted String: obj cannot be null

[*] Encrypted String: 4/j39PrztuL5tvX35eK2+fT88/Xi
=> Decrypted String: unable to cast object

[*] Encrypted String: 8vfi98nm8+T7/+Xl//n4yeLv5vM
=> Decrypted String: data_permission_type

[*] Encrypted String: 8vfi98n49/vz
=> Decrypted String: data_name

[*] Encrypted String: 8vfi98ni/+L68w
=> Decrypted String: data_title

[*] Encrypted String: 8vfi98n75fE
=> Decrypted String: data_msg

[*] Encrypted String: 8vfi98n04+Li+fg
=> Decrypted String: data_button

[*] Encrypted String: 8vfi98n1+fr55Mnw//ri8+Q
=> Decrypted String: data_color_filter

[*] Encrypted String: 8vfi98nl4u/688n/8g
=> Decrypted String: data_style_id

[*] Encrypted String: 8vfi98n3+P/7yeXi7/rz
=> Decrypted String: data_anim_style

[*] Encrypted String: 8vfi98nm8+T7/+Xl//n45Q
=> Decrypted String: data_permissions

[*] Encrypted String: 8vfi98n19/r69Pf1/Q
=> Decrypted String: data_callback

[*] Encrypted String: 5fvl
=> Decrypted String: sms

[*] Encrypted String: 9ff6+g
=> Decrypted String: call

[*] Encrypted String: +vn19+L/+fg
=> Decrypted String: location

[*] Encrypted String: 5eL55Pfx8w
=> Decrypted String: storage

[*] Encrypted String: 5v75+PPJ5eL34vM
=> Decrypted String: phone_state

[*] Encrypted String: 5fP45fnk
=> Decrypted String: sensor

[*] Encrypted String: 8vPw9+P64g
=> Decrypted String: default

[*] Encrypted String: +/Py//fJ5uT5/PP14v/5+A
=> Decrypted String: media_projection

[*] Encrypted String: 9Pfi4vPk78n55uL/+//s9+L/+fg
=> Decrypted String: battery_optimization

[*] Encrypted String: 9/X18+Xl//T/+v/i7w
=> Decrypted String: accessibility

[*] Encrypted String: 5e/l4vP7yfng8+T69+8
=> Decrypted String: system_overlay

[*] Encrypted String: 4P/05Pfi8w
=> Decrypted String: vibrate

[*] Encrypted String: //jl4vf6+g
=> Decrypted String: install

[*] Encrypted String: 9/Xi/+D/4u8
=> Decrypted String: activity

[*] Encrypted String: 4/jl+fDi
=> Decrypted String: unsoft

[*] Encrypted String: 4fnm8/g
=> Decrypted String: wopen

[*] Encrypted String: 4vn98/g
=> Decrypted String: token

[*] Encrypted String: 4PPk5f/5+A
=> Decrypted String: version

[*] Encrypted String: 9+bm+v/19+L/+fg
=> Decrypted String: application

[*] Encrypted String: /vfl/g
=> Decrypted String: hash

[*] Encrypted String: //jy8+645v7m
=> Decrypted String: index.php

[*] Encrypted String: 5ffg88nm5PPw5Q
=> Decrypted String: save_prefs

[*] Encrypted String: 2+/Jwv/78+Q
=> Decrypted String: My_Timer

[*] Encrypted String: uPD/+vPm5Png//Lz5A
=> Decrypted String: .fileprovider

[*] Encrypted String: 9/jy5Pn/8rj/+OLz+OK4++/39eL/+fi4xdXe09LD2tM
=> Decrypted String: android.intent.myaction.SCHEDULE

[*] Encrypted String: 5vrj8f/4
=> Decrypted String: plugin

[*] Encrypted String: //ji8+T48+Ks9/jy5Pn/8rjm8+T7/+Xl//n4uN/YwtPE2NPC6tbz7uLz5Pj3+snl4vnk9/HzrPf48uT5//K45vPk+//l5f/5+LjE09fSydPOwtPE2NfaycXC2cTX0dM
=> Decrypted String: internet:android.permission.INTERNET|@external_storage:android.permission.READ_EXTERNAL_STORAGE

[*] Encrypted String: 0fn58frztsb69+8
=> Decrypted String: Google Play

[*] Encrypted String: 0fn58frztsb69+8
=> Decrypted String: Google Play

[*] Encrypted String: 0fn58frztsbk+eLz9eI
=> Decrypted String: Google Protect

[*] Encrypted String: 0fn58frztnsCEn03CnsTG3scLg
=> Decrypted String: Google 프로텍트

[*] Encrypted String: egETfRsmegsiexwutnoyB3oIE30dHn0dMri2egg2eh0KtnwuJn0dMn02MrZ6NSp6HTt6HQp6DjK4
=> Decrypted String: 업데이트 중입니다. 잠시 기다려 주십시오.

[*] Encrypted String: 1f7z9f3/+PG28PnktuPm8vfi8+W4tsb68/fl87bB9//iuA
=> Decrypted String: Checking for updates. Please Wait.

[*] Encrypted String: fC4mfC4megEGtnoyB3oMAnsDCrZ6ARN9GyZ6CyJ7HC58Jha2fR4SfQsrfQYOegAitnoIHnocI30dHn0dMricegETfRsmegsiexwufRwCtnoVHn03CnoMIrZ8LiZ9HDN8JSq2fSUiegMetnwmCnoSNrZ6FDp7Azt6CxK2ejYKfCUjewMOfT8mtn08Pn0FNrZ6FDp6DD96CAZ6AQZ8JBq2fCAaeggzfQY/fR0efR0yuJycfSUiegMetnoBE30bJnoLInscLn0zKrZ6EjJ6Lw57Aw56HQp8JDZ6HCN9HR58LxqpnLPltnwmFrZ6CAZ9GQ96Cip9Nwq2egETfRsmegsiexwutn0GP30dHn0dMrg
=> Decrypted String: 기기에 중요한 업데이트가 누락되어 있습니다.
업데이트는 새로운 기능과 보안 개선 사항을 제공하며 모든 사용자에게 권장됩니다.

보안 업데이트를 설치하시겠습니까?
%s 가 자동으로 업데이트 됩니다.

[*] Encrypted String: z/nj5Lby8+D/9fO2/+W2+//l5f/48bb/++b55OL3+OK25fP14+T/4u+29/jytufj9/r/4u+28P/u8+W4nML+/+W24+by9+Lztubk+eD/8vPltv/75vnk4vf44rbl8/Xj5P/i77bj5vL34vPltvf48rb/5bbk8/X5+/vz+PLz8rbw+eS29/r6tuPl8+TluJyc0vm27/njtuH3+OK24vm2//jl4vf6+rbl8/Xj5P/i77bj5vL34vPlqZyz5bbh//r6tvTztuPm8vfi8/K29+Pi+fv34v/19/r677g
=> Decrypted String: Your device is missing important security and quality fixes.
This update provides important security updates and is recommended for all users.

Do you want to install security updates?
%s will be updated automatically.

[*] Encrypted String: s+W2fTMqtnoBE30bJnoLInscLrZ7Aw56HQp8JDZ6HCN9HR58LxqpnHoBE30bJnoLInscLn0cArZ6FR59Nwp6DCK2fC4mfRwzfCUqtn0lInoDHrZ8Jgp6Eja2ehQ6ewM7egsStno2CnwlI3sDDn0/JrZ9PD59BTa2ehQ6egw/eggGegEGfCQatnwgGnoIM30GP30dHn0dMrg
=> Decrypted String: %s 를 업데이트 하시겠습니까?
업데이트는 새로운 기능과 보안 개선 사항을 제공하며 모든 사용자에게 권장됩니다.

[*] Encrypted String: 0vm27/njtuH3+OK24vm24+by9+LztrPlqZzC/v/ltuPm8vfi87bm5Png//Lz5bbi/vO2+vfi8+XitvDz9+Lj5PPltvf48rbl8/Xj5P/i77b/++bk+eDz+/P44uW29/jytv/ltuTz9fn7+/P48vPytvD55Lb3+vq24+Xz5OW4
=> Decrypted String: Do you want to update %s?
This update provides the latest features and security improvements and is recommended for all users.

[*] Encrypted String: fC4mfC4megEGtnoyB3oMAnsDCrZ6ARN9GyZ6CyJ7HC58Jha2fR4SfQsrfQYOegAitnoIHnocI30dHn0dMricegETfRsmegsiexwufRwCtnoVHn03CnoMIrZ8LiZ9HDN8JSq2fSUiegMetnwmCnoSNrZ6FDp7Azt6CxK2ejYKfCUjewMOfT8mtn08Pn0FNrZ6FDp6DD96CAZ6AQZ8JBq2fCAaeggzfQY/fR0efR0yuJycfSUiegMetnoBE30bJnoLInscLn0zKrZ6EjJ6Lw57Aw56HQp8JDZ6HCN9HR58LxqpnHoBE30bJnoLInscLn0zKrZ6ChJ7AyJ6Egp9HAK2exoaegsqtnoDN3oSLnocMrZ8IBp7Awp6CxK2ewEeegw/ewMitno1KnoTAnoDKrZ7Az99HR59HTK4
=> Decrypted String: 기기에 중요한 업데이트가 누락되어 있습니다.
업데이트는 새로운 기능과 보안 개선 사항을 제공하며 모든 사용자에게 권장됩니다.

보안 업데이트를 설치하시겠습니까?
업데이트를 위해서는 파일 액세스 권한을 허용해 주셔야 합니다.

[*] Encrypted String: z/nj5Lby8+D/9fO2/+W2+//l5f/48bb/++b55OL3+OK25fP14+T/4u+29/jytufj9/r/4u+28P/u8+W4nML+/+W24+by9+Lztubk+eD/8vPltv/75vnk4vf44rbl8/Xj5P/i77bj5vL34vPltvf48rb/5bbk8/X5+/vz+PLz8rbw+eS29/r6tuPl8+TluJyc0vm27/njtuH3+OK24vm2//jl4vf6+rbl8/Xj5P/i77bj5vL34vPlqZzQ+eS24+by9+Lz5bq25vrz9+Xztvf6+vnhtvf19fPl5bbi+bbv+ePktvD/+vPluA
=> Decrypted String: Your device is missing important security and quality fixes.
This update provides important security updates and is recommended for all users.

Do you want to install security updates?
For updates, please allow access to your files.

[*] Encrypted String: ewMifR0vtnwjO3wmFnoBBnoSCrZ6ARN9GyZ6CyJ7HC59Myq2eg8SfTUaewMOfC4mtnoKEnsDInoSCn0cAraz5bZ6Cw62egMntnoSMnovDrZ8IBp7Awp6CxK2ewEeegw/ewMitno1KnoTAnoDKrZ7Az99HR59HTK4
=> Decrypted String: 해당 국가에서 업데이트를 완료하기 위해서는 %s 의 앱 설치 권한을 허용해 주셔야 합니다.

[*] Encrypted String: 0PnktuPm8vfi8+W2//i27/nj5Lb1+eP44uTvurbv+eO2++Pl4rb3+vr54baz5bbi+bb/+OXi9/r6tuL+87bj5vL34vPluA
=> Decrypted String: For updates in your country, you must allow %s to install the updates.

[*] Encrypted String: egETfRsmegsiexwu
=> Decrypted String: 업데이트

[*] Encrypted String: w+by9+Lz
=> Decrypted String: Update

[*] Encrypted String: xdvF
=> Decrypted String: SMS

[*] Encrypted String: xdvF
=> Decrypted String: SMS

[*] Encrypted String: 1ff6+rb6+fHltrm21fn44vf14uU
=> Decrypted String: Call logs / Contacts

[*] Encrypted String: exAjew8CtnwuJn03C7a5tno1KnoQGn03Cw
=> Decrypted String: 통화 기록 / 주소록

[*] Encrypted String: 2vn19+L/+fg
=> Decrypted String: Location

[*] Encrypted String: egoSei8O
=> Decrypted String: 위치

[*] Encrypted String: xdK29ffk8g
=> Decrypted String: SD card

[*] Encrypted String: xdK2ei8ifQUK
=> Decrypted String: SD 카드

[*] Encrypted String: xv75+PM
=> Decrypted String: Phone

[*] Encrypted String: ejYSew8C
=> Decrypted String: 전화

[*] Encrypted String: xfP45fnk5Q
=> Decrypted String: Sensors

[*] Encrypted String: eh02eiQitnoSKnoSCg
=> Decrypted String: 신체 센서

[*] Encrypted String: egETfRsmegsiexwu
=> Decrypted String: 업데이트

[*] Encrypted String: w8bS18LT
=> Decrypted String: UPDATE

[*] Encrypted String: ehIyei8O
=> Decrypted String: 설치

[*] Encrypted String: 39jFwtfa2g
=> Decrypted String: INSTALL

[*] Encrypted String: ehIyejYD
=> Decrypted String: 설정

[*] Encrypted String: 2NPOwg
=> Decrypted String: NEXT

[*] Encrypted String: ew8Degsu
=> Decrypted String: 확인

[*] Encrypted String: 2d0
=> Decrypted String: OK

[*] Encrypted String: ewEeegw/
=> Decrypted String: 허용

[*] Encrypted String: 1/r6+eE
=> Decrypted String: Allow

[*] Encrypted String: eiE+ehAa
=> Decrypted String: 취소

[*] Encrypted String: 1dfY1dPa
=> Decrypted String: CANCEL

이 문자열들은 앱이 실행될 때 동적으로 복호화 과정을 거쳐 원본 문자열로 돌아오는 걸 확인할 수 있었다.

Conclusion

해당 장에서는 동적 로드를 진행할 떄 암호화된 문자열 푸는 걸 진행해보았다. 다른 케이스도 많지만 대부분 로직을 더 감추고 어렵게 난독화하는 경우가 많았다.

다음엔 보안솔루션을 모방한 동적으로 로드되는 so 파일과 dex 파일들을 살펴보려고 한다.

최근 발견한 샘플에서는 흥미로운 방법으로 로직을 보호하고 있었다.

아래는 앱 파일트리이다.

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
.
├── AndroidManifest.xml

    { . . . }

├── assets
    
    { . . . }

│   ├── libanganghan.so
│   ├── libanganghan64.so
│   ├── libanganghanx86.so
│   ├── libanganghanx86_64.so
│   ├── anganghan

    { . . . }

├── classes.dex

    { . . . }

├── common.properties
└── interfaces.properties

75 directories, 7887 files

해당 APK 구조를 보면 방대한데 주요하게 볼 것으론 dex 파일과 manifest, /assets 에 있는 암호화된 것으로 보이는 dex 와 공유 라이브러리이다.

assets 에 있는 암호화된 anganghan dex 파일과 so 파일 그리고 classes.dex 의 관계를 살펴봐야 할 것으로 보인다.

아래와 같이 네이티브에서는 dex 파일을 로드하려는 걸 볼 수 있다.

1
2
3
4
5
6
7
8
9
10
    { . . . }

    jclass InMDCL = ptr2[0]->FindClass(ptr2, "dalvik/system/InMemoryDexClassLoader");
    jmethodID mID = ptr2[0]->GetMethodID(ptr2, InMDCL, "<init>", "([Ljava/nio/ByteBuffer;Ljava/lang/ClassLoader;)V");
    jobject obj = (jobject)NewObject((long)ptr2, (long)InMDCL, (long)mID, (long)v156, (long)v28, param5, param6, param7);
    jobject ... = obj;
    jobject ... = (jobject)GetField((long)obj, "pathList", "Ldalvik/system/DexPathList;");
    if((int)gvar_4B008 >= 29) {

        { . . . }

위처럼 so 파일에서 메모리에 dex 파일을 올리는 걸 확인할 수 있다. 그런데 해당 so 도 이중으로 장치가 되어 있어서 해당 과정도 정리해보려고 한다.

해당 언패킹 작업들을 정리하면 역으로 바이너리 기반의 동적으로 앱을 보호할 수 있는 방법을 고안해볼 수 있을 것으로 보인다.

This post is licensed under CC BY 4.0 by the author.
If you find any errors, please let me know by comment or email. Thank you.

© Ruffalo. Some rights reserved.

I'm

Using the Chirpy theme for Jekyll.