This commit is contained in:
iceman1001 2024-07-21 16:19:21 +02:00
commit 4de7b7d6b9
10 changed files with 103 additions and 66 deletions

View file

@ -2242,17 +2242,17 @@ void iClass_Recover(iclass_recover_req_t *msg) {
//Viewing the weak macs table card 24 bits (3x8) in the form of a 24 bit decimal number //Viewing the weak macs table card 24 bits (3x8) in the form of a 24 bit decimal number
static uint32_t iclass_mac_table_bit_values[8] = {0, 2396745, 4793490, 7190235, 9586980, 11983725, 14380470, 16777215}; static uint32_t iclass_mac_table_bit_values[8] = {0, 2396745, 4793490, 7190235, 9586980, 11983725, 14380470, 16777215};
/* iclass_mac_table is a series of weak macs, those weak macs correspond to the different combinations of the last 3 bits of each key byte. /* iclass_mac_table is a series of weak macs, those weak macs correspond to the different combinations of the last 3 bits of each key byte.
If we concatenate the last three bits of each key byte, we have a 24 bits long binary string. If we concatenate the last three bits of each key byte, we have a 24 bits long binary string.
If we convert that string to decimal we obtain the decimal numbers in iclass_mac_table_bit_values If we convert that string to decimal we obtain the decimal numbers in iclass_mac_table_bit_values
Xorring the index of iterations against those decimal numbers allows us to retrieve the what was the corresponding sequence of bits of the original key in decimal format. */ Xorring the index of iterations against those decimal numbers allows us to retrieve the what was the corresponding sequence of bits of the original key in decimal format. */
uint8_t zero_key[PICOPASS_BLOCK_SIZE] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t zero_key[PICOPASS_BLOCK_SIZE] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint32_t index = 1; uint32_t index = 1;
int bits_found = -1; int bits_found = -1;
//START LOOP //START LOOP
while (bits_found == -1){ while (bits_found == -1) {
//Step3 Calculate New Key //Step3 Calculate New Key
uint8_t genkeyblock[PICOPASS_BLOCK_SIZE]; uint8_t genkeyblock[PICOPASS_BLOCK_SIZE];
@ -2262,12 +2262,12 @@ Xorring the index of iterations against those decimal numbers allows us to retri
//NOTE BEFORE UPDATING THE KEY WE NEED TO KEEP IN MIND KEYS ARE XORRED //NOTE BEFORE UPDATING THE KEY WE NEED TO KEEP IN MIND KEYS ARE XORRED
//xor the new key against the previously generated key so that we only update the difference //xor the new key against the previously generated key so that we only update the difference
if(index != 0){ if (index != 0) {
generate_single_key_block_inverted(zero_key, index - 1, genkeyblock_old); generate_single_key_block_inverted(zero_key, index - 1, genkeyblock_old);
for (int i = 0; i < 8 ; i++) { for (int i = 0; i < 8 ; i++) {
xorkeyblock[i] = genkeyblock[i] ^ genkeyblock_old[i]; xorkeyblock[i] = genkeyblock[i] ^ genkeyblock_old[i];
} }
}else{ } else {
memcpy(xorkeyblock, genkeyblock, PICOPASS_BLOCK_SIZE); memcpy(xorkeyblock, genkeyblock, PICOPASS_BLOCK_SIZE);
} }
@ -2289,7 +2289,7 @@ Xorring the index of iterations against those decimal numbers allows us to retri
Dbprintf("Write block [%3d/0x%02X] " _GREEN_("successful"), blockno, blockno); Dbprintf("Write block [%3d/0x%02X] " _GREEN_("successful"), blockno, blockno);
} else { } else {
Dbprintf("Write block [%3d/0x%02X] " _RED_("failed"), blockno, blockno); Dbprintf("Write block [%3d/0x%02X] " _RED_("failed"), blockno, blockno);
if (index > 1){ if (index > 1) {
Dbprintf(_RED_("Card is likely to be unusable!")); Dbprintf(_RED_("Card is likely to be unusable!"));
} }
goto out; goto out;

View file

@ -3601,9 +3601,9 @@ static int CmdHFiClassCheckKeys(const char *Cmd) {
bool use_vb6kdf = arg_get_lit(ctx, 6); bool use_vb6kdf = arg_get_lit(ctx, 6);
bool use_elite = arg_get_lit(ctx, 3); bool use_elite = arg_get_lit(ctx, 3);
bool use_raw = arg_get_lit(ctx, 4); bool use_raw = arg_get_lit(ctx, 4);
if(use_vb6kdf){ if (use_vb6kdf) {
use_elite = true; use_elite = true;
}else{ } else {
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
} }
@ -3827,14 +3827,14 @@ uint8_t picopass_elite_nextByte(void) {
return (picopass_elite_rng() >> 16) & 0xFF; return (picopass_elite_rng() >> 16) & 0xFF;
} }
void picopass_elite_nextKey(uint8_t* key) { void picopass_elite_nextKey(uint8_t *key) {
if(prepared) { if (prepared) {
for(size_t i = 0; i < 7; i++) { for (size_t i = 0; i < 7; i++) {
key_state[i] = key_state[i + 1]; key_state[i] = key_state[i + 1];
} }
key_state[7] = picopass_elite_nextByte(); key_state[7] = picopass_elite_nextByte();
} else { } else {
for(size_t i = 0; i < 8; i++) { for (size_t i = 0; i < 8; i++) {
key_state[i] = picopass_elite_nextByte(); key_state[i] = picopass_elite_nextByte();
} }
prepared = true; prepared = true;
@ -4086,14 +4086,14 @@ static int CmdHFiClassLegacyRecover(const char *Cmd) {
CLIParserContext *ctx; CLIParserContext *ctx;
CLIParserInit(&ctx, "hf iclass legrec", CLIParserInit(&ctx, "hf iclass legrec",
"Attempts to recover the diversified key of a specific iClass card. This may take a long time. The Card must remain be on the PM3 antenna during the whole process! This process may brick the card!", "Attempts to recover the diversified key of a specific iClass card. This may take a long time. The Card must remain be on the PM3 antenna during the whole process! This process may brick the card!",
"hf iclass legrec --macs 0000000089cb984b" "hf iclass legrec --macs 0000000089cb984b"
); );
void *argtable[] = { void *argtable[] = {
arg_param_begin, arg_param_begin,
arg_str1(NULL, "macs", "<hex>", "MACs"), arg_str1(NULL, "macs", "<hex>", "MACs"),
arg_param_end arg_param_end
}; };
CLIExecWithReturn(ctx, Cmd, argtable, false); CLIExecWithReturn(ctx, Cmd, argtable, false);
@ -4148,9 +4148,9 @@ static int CmdHFiClassLookUp(const char *Cmd) {
bool use_elite = arg_get_lit(ctx, 5); bool use_elite = arg_get_lit(ctx, 5);
bool use_raw = arg_get_lit(ctx, 6); bool use_raw = arg_get_lit(ctx, 6);
if(use_vb6kdf){ if (use_vb6kdf) {
use_elite = true; use_elite = true;
}else{ } else {
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
} }

View file

@ -37,7 +37,7 @@ void PrintPreCalc(iclass_prekey_t *list, uint32_t itemcnt);
uint8_t get_pagemap(const picopass_hdr_t *hdr); uint8_t get_pagemap(const picopass_hdr_t *hdr);
bool check_known_default(uint8_t *csn, uint8_t *epurse, uint8_t *rmac, uint8_t *tmac, uint8_t *key); bool check_known_default(uint8_t *csn, uint8_t *epurse, uint8_t *rmac, uint8_t *tmac, uint8_t *key);
void picopass_elite_nextKey(uint8_t* key); void picopass_elite_nextKey(uint8_t *key);
void picopass_elite_reset(void); void picopass_elite_reset(void);
uint32_t picopass_elite_rng(void); uint32_t picopass_elite_rng(void);
uint32_t picopass_elite_lcg(void); uint32_t picopass_elite_lcg(void);

View file

@ -279,6 +279,8 @@ const static vocabulary_t vocabulary[] = {
{ 0, "hf iclass chk" }, { 0, "hf iclass chk" },
{ 1, "hf iclass loclass" }, { 1, "hf iclass loclass" },
{ 1, "hf iclass lookup" }, { 1, "hf iclass lookup" },
{ 0, "hf iclass legrec" },
{ 1, "hf iclass legbrute" },
{ 0, "hf iclass sim" }, { 0, "hf iclass sim" },
{ 0, "hf iclass eload" }, { 0, "hf iclass eload" },
{ 0, "hf iclass esave" }, { 0, "hf iclass esave" },

View file

@ -189,9 +189,9 @@
"options": [ "options": [
"-h, --help This help", "-h, --help This help",
"-d <hex> ASN1 encoded byte array", "-d <hex> ASN1 encoded byte array",
"-t, --test perform self test" "--test perform self tests"
], ],
"usage": "data asn1 [-ht] [-d <hex>]" "usage": "data asn1 [-h] [-d <hex>] [--test]"
}, },
"data atr": { "data atr": {
"command": "data atr", "command": "data atr",
@ -3163,7 +3163,8 @@
"description": "Checkkeys loads a dictionary text file with 8byte hex keys to test authenticating against a iClass tag", "description": "Checkkeys loads a dictionary text file with 8byte hex keys to test authenticating against a iClass tag",
"notes": [ "notes": [
"hf iclass chk -f iclass_default_keys.dic", "hf iclass chk -f iclass_default_keys.dic",
"hf iclass chk -f iclass_elite_keys.dic --elite" "hf iclass chk -f iclass_elite_keys.dic --elite",
"hf iclass chk --vb6kdf"
], ],
"offline": false, "offline": false,
"options": [ "options": [
@ -3172,9 +3173,10 @@
"--credit key is assumed to be the credit key", "--credit key is assumed to be the credit key",
"--elite elite computations applied to key", "--elite elite computations applied to key",
"--raw no computations applied to key (raw)", "--raw no computations applied to key (raw)",
"--shallow use shallow (ASK) reader modulation instead of OOK" "--shallow use shallow (ASK) reader modulation instead of OOK",
"--vb6kdf use the VB6 elite KDF instead of a file"
], ],
"usage": "hf iclass chk [-h] -f <fn> [--credit] [--elite] [--raw] [--shallow]" "usage": "hf iclass chk [-h] [-f <fn>] [--credit] [--elite] [--raw] [--shallow] [--vb6kdf]"
}, },
"hf iclass configcard": { "hf iclass configcard": {
"command": "hf iclass configcard", "command": "hf iclass configcard",
@ -3370,7 +3372,7 @@
}, },
"hf iclass help": { "hf iclass help": {
"command": "hf iclass help", "command": "hf iclass help",
"description": "help This help list List iclass history view Display content from tag dump file ----------- --------------------- Recovery -------------------- loclass Use loclass to perform bruteforce reader attack lookup Uses authentication trace to check for key in dictionary file ----------- ---------------------- Utils ---------------------- calcnewkey Calc diversified keys (blocks 3 & 4) to write new keys encode Encode binary wiegand to block 7 encrypt Encrypt given block data decrypt Decrypt given block data or tag dump file managekeys Manage keys to use with iclass commands permutekey Permute function from 'heart of darkness' paper --------------------------------------------------------------------------------------- hf iclass list available offline: yes Alias of `trace list -t iclass -c` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "description": "help This help list List iclass history view Display content from tag dump file ----------- --------------------- Recovery -------------------- loclass Use loclass to perform bruteforce reader attack lookup Uses authentication trace to check for key in dictionary file legbrute Bruteforces 40 bits of a partial raw key ----------- ---------------------- Utils ---------------------- calcnewkey Calc diversified keys (blocks 3 & 4) to write new keys encode Encode binary wiegand to block 7 encrypt Encrypt given block data decrypt Decrypt given block data or tag dump file managekeys Manage keys to use with iclass commands permutekey Permute function from 'heart of darkness' paper --------------------------------------------------------------------------------------- hf iclass list available offline: yes Alias of `trace list -t iclass -c` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol",
"notes": [ "notes": [
"hf iclass list --frame -> show frame delay times", "hf iclass list --frame -> show frame delay times",
"hf iclass list -1 -> use trace buffer" "hf iclass list -1 -> use trace buffer"
@ -3402,6 +3404,35 @@
], ],
"usage": "hf iclass info [-h] [--shallow]" "usage": "hf iclass info [-h] [--shallow]"
}, },
"hf iclass legbrute": {
"command": "hf iclass legbrute",
"description": "This command take sniffed trace data and partial raw key and bruteforces the remaining 40 bits of the raw key.",
"notes": [
"hf iclass legbrute --csn 8D7BD711FEFF12E0 --epurse feffffffffffffff --macs 00000000BD478F76 --pk B4F12AADC5301225"
],
"offline": true,
"options": [
"-h, --help This help",
"--csn <hex> Specify CSN as 8 hex bytes",
"--epurse <hex> Specify ePurse as 8 hex bytes",
"--macs <hex> MACs",
"--pk <hex> Partial Key"
],
"usage": "hf iclass legbrute [-h] --csn <hex> --epurse <hex> --macs <hex> --pk <hex>"
},
"hf iclass legrec": {
"command": "hf iclass legrec",
"description": "Attempts to recover the diversified key of a specific iClass card. This may take a long time. The Card must remain be on the PM3 antenna during the whole process! This process may brick the card!",
"notes": [
"hf iclass legrec --macs 0000000089cb984b"
],
"offline": false,
"options": [
"-h, --help This help",
"--macs <hex> MACs"
],
"usage": "hf iclass legrec [-h] --macs <hex>"
},
"hf iclass loclass": { "hf iclass loclass": {
"command": "hf iclass loclass", "command": "hf iclass loclass",
"description": "Execute the offline part of loclass attack An iclass dumpfile is assumed to consist of an arbitrary number of malicious CSNs, and their protocol responses The binary format of the file is expected to be as follows: <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC> <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC> <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC> ... totalling N*24 bytes", "description": "Execute the offline part of loclass attack An iclass dumpfile is assumed to consist of an arbitrary number of malicious CSNs, and their protocol responses The binary format of the file is expected to be as follows: <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC> <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC> <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC> ... totalling N*24 bytes",
@ -3423,7 +3454,8 @@
"description": "This command take sniffed trace data and try to recovery a iCLASS Standard or iCLASS Elite key.", "description": "This command take sniffed trace data and try to recovery a iCLASS Standard or iCLASS Elite key.",
"notes": [ "notes": [
"hf iclass lookup --csn 9655a400f8ff12e0 --epurse f0ffffffffffffff --macs 0000000089cb984b -f iclass_default_keys.dic", "hf iclass lookup --csn 9655a400f8ff12e0 --epurse f0ffffffffffffff --macs 0000000089cb984b -f iclass_default_keys.dic",
"hf iclass lookup --csn 9655a400f8ff12e0 --epurse f0ffffffffffffff --macs 0000000089cb984b -f iclass_default_keys.dic --elite" "hf iclass lookup --csn 9655a400f8ff12e0 --epurse f0ffffffffffffff --macs 0000000089cb984b -f iclass_default_keys.dic --elite",
"hf iclass lookup --csn 9655a400f8ff12e0 --epurse f0ffffffffffffff --macs 0000000089cb984b --vb6rng"
], ],
"offline": true, "offline": true,
"options": [ "options": [
@ -3433,9 +3465,10 @@
"--epurse <hex> Specify ePurse as 8 hex bytes", "--epurse <hex> Specify ePurse as 8 hex bytes",
"--macs <hex> MACs", "--macs <hex> MACs",
"--elite Elite computations applied to key", "--elite Elite computations applied to key",
"--raw no computations applied to key" "--raw no computations applied to key",
"--vb6rng use the VB6 rng for elite keys instead of a dictionary file"
], ],
"usage": "hf iclass lookup [-h] -f <fn> --csn <hex> --epurse <hex> --macs <hex> [--elite] [--raw]" "usage": "hf iclass lookup [-h] [-f <fn>] --csn <hex> --epurse <hex> --macs <hex> [--elite] [--raw] [--vb6rng]"
}, },
"hf iclass managekeys": { "hf iclass managekeys": {
"command": "hf iclass managekeys", "command": "hf iclass managekeys",
@ -12732,8 +12765,8 @@
} }
}, },
"metadata": { "metadata": {
"commands_extracted": 737, "commands_extracted": 739,
"extracted_by": "PM3Help2JSON v1.00", "extracted_by": "PM3Help2JSON v1.00",
"extracted_on": "2024-05-27T13:38:05" "extracted_on": "2024-07-21T14:16:40"
} }
} }

View file

@ -402,6 +402,8 @@ Check column "offline" for their availability.
|`hf iclass chk `|N |`Check keys` |`hf iclass chk `|N |`Check keys`
|`hf iclass loclass `|Y |`Use loclass to perform bruteforce reader attack` |`hf iclass loclass `|Y |`Use loclass to perform bruteforce reader attack`
|`hf iclass lookup `|Y |`Uses authentication trace to check for key in dictionary file` |`hf iclass lookup `|Y |`Uses authentication trace to check for key in dictionary file`
|`hf iclass legrec `|N |`Attempts to recover the standard key of a legacy card`
|`hf iclass legbrute `|Y |`Bruteforces 40 bits of a partial raw key`
|`hf iclass sim `|N |`Simulate iCLASS tag` |`hf iclass sim `|N |`Simulate iCLASS tag`
|`hf iclass eload `|N |`Upload file into emulator memory` |`hf iclass eload `|N |`Upload file into emulator memory`
|`hf iclass esave `|N |`Save emulator memory to file` |`hf iclass esave `|N |`Save emulator memory to file`