MASTG-DEMO-0080: Uses of Broken Encryption Modes in CommonCrypto with r2
Download MASTG-DEMO-0080 IPA Open MASTG-DEMO-0080 Folder Build MASTG-DEMO-0080 IPA
Sample¶
The snippet below shows sample code that uses the insecure ECB (Electronic Codebook) mode when encrypting data with CommonCrypto's CCCrypt function. ECB mode is vulnerable because it encrypts identical plaintext blocks to identical ciphertext blocks, revealing patterns in the data.
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 | |
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 | |
Steps¶
- Unzip the app package and locate the main binary file ( Exploring the App Package), which in this case is
./Payload/MASTestApp.app/MASTestApp. - Open the app binary with radare2 for iOS with the
-ioption to run this script.
| cccrypt-ecb.r2 | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
| run.sh | |
|---|---|
1 2 | |
Observation¶
The output contains the disassembled code for the CCCrypt function in ECB mode.
| output.asm | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | |
Evaluation¶
Inspect the disassembled code to identify the use of insecure encryption modes.
In CommonCryptor.h, you can find the definition of the CCCrypt function:
CCCryptorStatus CCCrypt(
CCOperation op, /* kCCEncrypt, etc. */
CCAlgorithm alg, /* kCCAlgorithmAES128, etc. */
CCOptions options, /* kCCOptionPKCS7Padding, kCCOptionECBMode, etc. */
const void *key,
size_t keyLength,
const void *iv, /* optional initialization vector */
const void *dataIn, /* optional per op and alg */
size_t dataInLength,
void *dataOut, /* data RETURNED here */
size_t dataOutAvailable,
size_t *dataOutMoved);
There you will also find the options parameter, which can include kCCOptionECBMode:
/*!
@enum CCOptions
@abstract Options flags, passed to CCCryptorCreate().
@constant kCCOptionPKCS7Padding Perform PKCS7 padding.
@constant kCCOptionECBMode Electronic Code Book Mode.
Default is CBC.
*/
enum {
kCCOptionPKCS7Padding = 0x0001,
kCCOptionECBMode = 0x0002,
};
typedef uint32_t CCOptions;
In the disassembly, the third argument to CCCrypt is passed in w2 and is set to the constant value 3. This argument corresponds to the CCOptions parameter, which is defined as a bitmask rather than a single enumerated value. That distinction is important because it means individual options are combined by setting bits, not by selecting one value from a list.
When analyzing a bitmask, the numeric value must be decomposed into its constituent flags. The value 3 in binary is 0b11. The least significant bit, 0b01, corresponds to kCCOptionPKCS7Padding, which has a value of 1. The next bit, 0b10, corresponds to kCCOptionECBMode, which has a value of 2. Since both of these bits are set in 3, both options are enabled at the same time.
Looking at the rest of the arguments confirms the interpretation. w0 is 0, mapping to kCCEncrypt, and w1 is 0, mapping to kCCAlgorithmAES128. The key length passed in w4 is 0x10, indicating a 16-byte key, which is appropriate for AES 128. The IV argument is passed as a null pointer, which is consistent with ECB mode, since ECB does not use an initialization vector.
Taken together, we can conclude that the test fails because the app is performing AES-128 encryption with PKCS7 padding enabled and in ECB mode.