CryptoHorrific
CryptoHorrific
Files
We get the following files after extraction:
1
2
3
4
5
6
7
8
9
10
11
ls -la
total 72
drwxrwxr-x 4 kali kali 4096 May 3 2018 .
drwxrwxr-x 4 kali kali 4096 Aug 30 16:54 ..
drwxrwxr-x 4 kali kali 4096 May 3 2018 Base.lproj
-rw-rw-r-- 1 kali kali 185 May 3 2018 challenge.plist
drwxrwxr-x 2 kali kali 4096 May 3 2018 _CodeSignature
-rw-rw-r-- 1 kali kali 32352 May 3 2018 hackthebox
-rw-rw-r-- 1 kali kali 9793 May 3 2018 htb-company.png
-rw-rw-r-- 1 kali kali 1132 May 3 2018 Info.plist
-rw-rw-r-- 1 kali kali 8 May 3 2018 PkgInfo
The files are:
Directories:
- Base.lproj - Contains localized resources (strings, interface files) for the base language
- _CodeSignature - Contains digital signature files that verify the app’s authenticity and integrity
Files:
- challenge.plist - A property list file, likely containing app-specific configuration or challenge data
- hackthebox - The main executable binary of the application
- htb-company.png - An image file
- Info.plist - The app’s information property list containing metadata like bundle identifier, version, supported devices, etc.
- PkgInfo - A legacy file containing basic package type and creator information
Content of challenge.plist
1
2
3
cat challenge.plist
bplist00��TflagRidUtitle_XTq+CWzQS0wYzs2rJ+GNrPLP6qekDbwze6fIeRRwBK2WXHOhba7WR2OGNUFKoAvyW7njTCMlQzlwIRdJvaP2iYQ==S123_HackTheBoxIsCool
z�
This looks like an encrypted string.
Inspecting the binary
Let’s check our binary.
1
2
file hackthebox
hackthebox: Mach-O 64-bit x86_64 executable, flags:<NOUNDEFS|DYLDLINK|TWOLEVEL|PIE>
Let’s throw it on ghidra.
Ghidra
Going through the disassembled binary, entry() and CCCrypt() were the first few functions that I took a look at. Afterwards I immediately went through the defined strings. Near challenge plist I saw some interesting strings:
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
//
// __cstring
// __TEXT
// ram:1000024cb-ram:10000257b
//
s_!A%D*G-KaPdSgVkY_1000024cb XREF[1]: 1000030a8(*)
1000024cb 21 41 25 ds "!A%D*G-KaPdSgVkY"
44 2a 47
2d 4b 61
s_QfTjWnZq4t7w!z%C_1000024dc XREF[1]: 1000030c8(*)
1000024dc 51 66 54 ds "QfTjWnZq4t7w!z%C"
6a 57 6e
5a 71 34
s_challenge_1000024ed XREF[1]: 1000030e8(*)
1000024ed 63 68 61 ds "challenge"
6c 6c 65
6e 67 65 00
s_plist_1000024f7 XREF[1]: 100003108(*)
1000024f7 70 6c 69 ds "plist"
73 74 00
s_flag_1000024fd XREF[1]: 100003128(*)
1000024fd 66 6c 61 ds "flag"
67 00
s_hash_100002502 XREF[2]: 100003478(*), 100003d30(*)
100002502 68 61 73 ds "hash"
68 00
Clicking on the XREF took us to a refernce of the function ` XREF[1]: viewDidLoad:1000010b2() `.
Clicking on the above XREF again took us to this code:
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
/* Function Stack Size: 0x10 bytes */
void ViewController::viewDidLoad(ID param_1,SEL param_2)
{
undefined8 uVar1;
undefined8 uVar2;
undefined8 uVar3;
undefined8 uVar4;
undefined8 uVar5;
undefined8 uVar6;
undefined8 uVar7;
undefined8 uVar8;
ID IVar9;
ID IVar10;
ID local_28;
class_t *local_20;
SEL local_18;
ID local_10;
local_20 = &objc::class_t::ViewController;
local_28 = param_1;
local_18 = param_2;
local_10 = param_1;
_objc_msgSendSuper2(&local_28,"viewDidLoad");
uVar1 = *(undefined8 *)(local_10 + l);
uVar2 = _objc_msgSend(&_OBJC_CLASS_$_NSString,"alloc");
IVar10 = local_10;
uVar3 = _objc_msgSend(&_OBJC_CLASS_$_NSData,"alloc");
uVar4 = _objc_msgSend(&_OBJC_CLASS_$_NSArray,"alloc");
uVar5 = _objc_msgSend(&_OBJC_CLASS_$_NSBundle,"mainBundle");
uVar5 = _objc_retainAutoreleasedReturnValue(uVar5);
uVar6 = _objc_msgSend(uVar5,"pathForResource:ofType:",&cf_challenge,&cf_plist);
uVar6 = _objc_retainAutoreleasedReturnValue(uVar6);
uVar4 = _objc_msgSend(uVar4,"initWithContentsOfFile:",uVar6);
uVar7 = _objc_msgSend(uVar4,"objectAtIndex:",0);
uVar7 = _objc_retainAutoreleasedReturnValue(uVar7);
uVar8 = _objc_msgSend(uVar7,"objectForKey:",&cf_flag);
uVar8 = _objc_retainAutoreleasedReturnValue(uVar8);
IVar9 = _objc_msgSend(uVar3,"initWithBase64EncodedString:options:",uVar8,0);
IVar10 = SecretManager:key:iv:data:
(IVar10,(SEL)"SecretManager:key:iv:data:",1,0x100003098,0x1000030b8,IVar9);
uVar3 = _objc_retainAutoreleasedReturnValue(IVar10);
uVar2 = _objc_msgSend(uVar2,"initWithData:encoding:",uVar3,4);
_objc_msgSend(uVar1,"setText:",uVar2);
_objc_release(uVar2);
_objc_release(uVar3);
_objc_release(IVar9);
_objc_release(uVar8);
_objc_release(uVar7);
_objc_release(uVar4);
_objc_release(uVar6);
_objc_release(uVar5);
return;
}
The algorithm:
- Read plist: Loads
challenge.plistand extracts the flag value - Base64 decode: Converts the flag string to binary data
- Decrypt: Calls
SecretManager:key:iv:data:with:- key:
0x100003098(which points to “!A%D*G-KaPdSgVkY”) - iv:
0x1000030b8(which points to “QfTjWnZq4t7w!z%C”) - data: The Base64-decoded flag
- key:
- Convert result: Turns decrypted data back into a string
The encrypted data:
1
Tq+CWzQS0wYzs2rJ+GNrPLP6qekDbwze6fIeRRwBK2WXHOhba7WR2OGNUFKoAvyW7njTCMlQzlwIRdJvaP2iYQ==
To confirm which encryption is being used we can go through the classes, ViewController:
We can confirm the algorithm is: AES-128-ECB. From CyberChef:
Output:
1
HTB{*SoC00l_H4ckTh3****
This post is licensed under CC BY 4.0 by the author.

