The iPhone Wiki is no longer updated. Visit this article on The Apple Wiki for current information. |
Difference between revisions of "KBAG"
(fixing formatting) |
m (dd skips and counts vary depending on the file; next paragraph explains how also) |
||
(5 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
− | + | Apple's [[IMG3 File Format|IMG3]] and [[IMG4 File Format|IMG4]] security scheme uses a data format called a '''KBAG'''. At the bottom of a firmware file, you will see something that will, on the ASCII side of your hex editor, say "GABK", which, as ARM is [[wikipedia:little-endian|little-endian]] based, is "KBAG" flipped. Look on the hex side and you will see the KBAG according to this format: |
|
== How it works == |
== How it works == |
||
Line 6: | Line 6: | ||
Because of the circumstances with the [[IMG3 File Format]], the kernel never needs to even touch the [[GID Key]] anymore, as its job is to just flash the image to the [[NOR]] as is, with container and all. |
Because of the circumstances with the [[IMG3 File Format]], the kernel never needs to even touch the [[GID Key]] anymore, as its job is to just flash the image to the [[NOR]] as is, with container and all. |
||
+ | To grab the KBAG for img3 files, you'd run <code>xpwntool /path/to/img3/ /dev/null</code>. |
||
− | In order to decrypt the KBAG, you need to remove them from [[IMG3 File Format|IMG3]] using this command <code>dd if=IMG3_FILE bs=1 skip=4741424B count=0x70</code> |
||
+ | |||
+ | This is different with img4 files. For these, you can use [https://github.com/xerub/img4lib img4lib] and run the following command: <code>img4 -i /path/to/image.im4p -b</code>. |
||
==KBAG Format== |
==KBAG Format== |
||
===KBAG128=== |
===KBAG128=== |
||
− | typedef struct { |
+ | typedef struct Unparsed_KBAG_AES128 { |
uint32_t magic; // string with bytes flipped ("KBAG" in little endian) |
uint32_t magic; // string with bytes flipped ("KBAG" in little endian) |
||
uint32_t fullSize; // size of KBAG from beyond that point to the end of it |
uint32_t fullSize; // size of KBAG from beyond that point to the end of it |
||
uint32_t tagDataSize; // size of KBAG without this 0xC header |
uint32_t tagDataSize; // size of KBAG without this 0xC header |
||
uint32_t cryptState; // 1 if the key and IV in the KBAG are encrypted with the [[GID Key]] |
uint32_t cryptState; // 1 if the key and IV in the KBAG are encrypted with the [[GID Key]] |
||
− | // 2 |
+ | // 2 if the key and IV are encrypted with the Development [[GID Key]], used when the [[Security Fusings|processor is demoted.]] |
uint32_t aesType; // 0x80 = aes128 / 0xc0 = aes192 / 0x100 = aes256 |
uint32_t aesType; // 0x80 = aes128 / 0xc0 = aes192 / 0x100 = aes256 |
||
uint8_t encIV[16]; // IV for the firmware file, encrypted with the [[GID Key]] |
uint8_t encIV[16]; // IV for the firmware file, encrypted with the [[GID Key]] |
||
Line 27: | Line 29: | ||
uint32_t tagDataSize; // size of KBAG without this 0xC header |
uint32_t tagDataSize; // size of KBAG without this 0xC header |
||
uint32_t cryptState; // 1 if the key and IV in the KBAG are encrypted with the [[GID Key]] |
uint32_t cryptState; // 1 if the key and IV in the KBAG are encrypted with the [[GID Key]] |
||
− | // 2 |
+ | // 2 if the key and IV are encrypted with the Development [[GID Key]], used when the [[Security Fusings|processor is demoted.]] |
uint32_t aesType; // 0x80 = aes128 / 0xc0 = aes192 / 0x100 = aes256 |
uint32_t aesType; // 0x80 = aes128 / 0xc0 = aes192 / 0x100 = aes256 |
||
uint8_t encIV[16]; // IV for the firmware file, encrypted with the [[GID Key]] |
uint8_t encIV[16]; // IV for the firmware file, encrypted with the [[GID Key]] |
||
uint8_t encKey[24]; // Key for the firmware file, encrypted with the [[GID Key]] |
uint8_t encKey[24]; // Key for the firmware file, encrypted with the [[GID Key]] |
||
+ | } UnparsedKbagAes192_t; |
||
− | } UparsedKbagAes192_t; |
||
===KBAG256=== |
===KBAG256=== |
||
Line 39: | Line 41: | ||
uint32_t tagDataSize; // size of KBAG without this 0xC header |
uint32_t tagDataSize; // size of KBAG without this 0xC header |
||
uint32_t cryptState; // 1 if the key and IV in the KBAG are encrypted with the [[GID Key]] |
uint32_t cryptState; // 1 if the key and IV in the KBAG are encrypted with the [[GID Key]] |
||
− | // 2 |
+ | // 2 if the key and IV are encrypted with the Development [[GID Key]], used when the [[Security Fusings|processor is demoted.]] |
uint32_t aesType; // 0x80 = aes128 / 0xc0 = aes192 / 0x100 = aes256 |
uint32_t aesType; // 0x80 = aes128 / 0xc0 = aes192 / 0x100 = aes256 |
||
uint8_t encIV[16]; // IV for the firmware file, encrypted with the [[GID Key]] |
uint8_t encIV[16]; // IV for the firmware file, encrypted with the [[GID Key]] |
||
uint8_t encKey[32]; // Key for the firmware file, encrypted with the [[GID Key]] |
uint8_t encKey[32]; // Key for the firmware file, encrypted with the [[GID Key]] |
||
+ | } UnparsedKbagAes256_t; |
||
− | } UparsedKbagAes256_t; |
||
Latest revision as of 18:55, 29 March 2022
Apple's IMG3 and IMG4 security scheme uses a data format called a KBAG. At the bottom of a firmware file, you will see something that will, on the ASCII side of your hex editor, say "GABK", which, as ARM is little-endian based, is "KBAG" flipped. Look on the hex side and you will see the KBAG according to this format:
How it works
It boils down to using the GID Key to decrypt encIV
and encKey
, then using that key and IV to decrypt the DATA section of the file (the code itself).
Because of the circumstances with the IMG3 File Format, the kernel never needs to even touch the GID Key anymore, as its job is to just flash the image to the NOR as is, with container and all.
To grab the KBAG for img3 files, you'd run xpwntool /path/to/img3/ /dev/null
.
This is different with img4 files. For these, you can use img4lib and run the following command: img4 -i /path/to/image.im4p -b
.
KBAG Format
KBAG128
typedef struct Unparsed_KBAG_AES128 { uint32_t magic; // string with bytes flipped ("KBAG" in little endian) uint32_t fullSize; // size of KBAG from beyond that point to the end of it uint32_t tagDataSize; // size of KBAG without this 0xC header uint32_t cryptState; // 1 if the key and IV in the KBAG are encrypted with the GID Key // 2 if the key and IV are encrypted with the Development GID Key, used when the processor is demoted. uint32_t aesType; // 0x80 = aes128 / 0xc0 = aes192 / 0x100 = aes256 uint8_t encIV[16]; // IV for the firmware file, encrypted with the GID Key uint8_t encKey[16]; // Key for the firmware file, encrypted with the GID Key } UnparsedKbagAes128_t;
KBAG192
typedef struct Unparsed_KBAG_AES192 { uint32_t magic; // string with bytes flipped ("KBAG" in little endian) uint32_t fullSize; // size of KBAG from beyond that point to the end of it uint32_t tagDataSize; // size of KBAG without this 0xC header uint32_t cryptState; // 1 if the key and IV in the KBAG are encrypted with the GID Key // 2 if the key and IV are encrypted with the Development GID Key, used when the processor is demoted. uint32_t aesType; // 0x80 = aes128 / 0xc0 = aes192 / 0x100 = aes256 uint8_t encIV[16]; // IV for the firmware file, encrypted with the GID Key uint8_t encKey[24]; // Key for the firmware file, encrypted with the GID Key } UnparsedKbagAes192_t;
KBAG256
typedef struct Unparsed_KBAG_256 { uint32_t magic; // string with bytes flipped ("KBAG" in little endian) uint32_t fullSize; // size of KBAG from beyond that point to the end of it uint32_t tagDataSize; // size of KBAG without this 0xC header uint32_t cryptState; // 1 if the key and IV in the KBAG are encrypted with the GID Key // 2 if the key and IV are encrypted with the Development GID Key, used when the processor is demoted. uint32_t aesType; // 0x80 = aes128 / 0xc0 = aes192 / 0x100 = aes256 uint8_t encIV[16]; // IV for the firmware file, encrypted with the GID Key uint8_t encKey[32]; // Key for the firmware file, encrypted with the GID Key } UnparsedKbagAes256_t;