mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 13:53:55 -07:00
adapted hardnested and autopwn to detect MFC Ev1 cards and use the known sector key in the key recovery vectors
This commit is contained in:
parent
bde4e8d754
commit
c393b0caca
6 changed files with 82 additions and 26 deletions
|
@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file.
|
||||||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||||
|
|
||||||
## [unreleased][unreleased]
|
## [unreleased][unreleased]
|
||||||
|
- Changed `hf mf hardnested` - now can detect and use MFC EV1 signature sector key (@iceman1001)
|
||||||
|
- Changed `hf mf autopwn` - now can detect and use MFC EV1 signature sector key (@iceman1001)
|
||||||
- Fixed `pm3` shell script now automatically detects WSL2 with USBIPD serial ports (@iceman1001)
|
- Fixed `pm3` shell script now automatically detects WSL2 with USBIPD serial ports (@iceman1001)
|
||||||
- Fixed `trace list -c` - annotation of CRC bytes now is colored or squared if no ansi colors is supported (@iceman1001)
|
- Fixed `trace list -c` - annotation of CRC bytes now is colored or squared if no ansi colors is supported (@iceman1001)
|
||||||
- Fixed `trace list -t mf` - now also finds UID if anticollision is partial captured, to be used for mfkey (@iceman1001)
|
- Fixed `trace list -t mf` - now also finds UID if anticollision is partial captured, to be used for mfkey (@iceman1001)
|
||||||
|
|
|
@ -2318,7 +2318,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t signature[32] = {0};
|
uint8_t signature[32] = {0};
|
||||||
res = detect_mfc_ev1_signature(signature);
|
res = read_mfc_ev1_signature(signature);
|
||||||
if (res == PM3_SUCCESS) {
|
if (res == PM3_SUCCESS) {
|
||||||
mfc_ev1_print_signature(card.uid, card.uidlen, signature, sizeof(signature));
|
mfc_ev1_print_signature(card.uid, card.uidlen, signature, sizeof(signature));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1841,19 +1841,22 @@ static int CmdHF14AMfNestedHard(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "hf mf hardnested",
|
CLIParserInit(&ctx, "hf mf hardnested",
|
||||||
"Nested attack for hardened MIFARE Classic cards.\n"
|
"Nested attack for hardened MIFARE Classic cards.\n"
|
||||||
|
"if card is EV1, command can detect and use known key see example below\n"
|
||||||
|
"\n"
|
||||||
"`--i<X>` set type of SIMD instructions. Without this flag programs autodetect it.\n"
|
"`--i<X>` set type of SIMD instructions. Without this flag programs autodetect it.\n"
|
||||||
" or \n"
|
" or \n"
|
||||||
" hf mf hardnested -r --tk [known target key]\n"
|
" hf mf hardnested -r --tk [known target key]\n"
|
||||||
"Add the known target key to check if it is present in the remaining key space\n"
|
"Add the known target key to check if it is present in the remaining key space\n"
|
||||||
" hf mf hardnested --blk 0 -a -k A0A1A2A3A4A5 --tblk 4 --ta --tk FFFFFFFFFFFF\n"
|
" hf mf hardnested --blk 0 -a -k A0A1A2A3A4A5 --tblk 4 --ta --tk FFFFFFFFFFFF\n"
|
||||||
,
|
,
|
||||||
|
"hf mf hardnested --tblk 4 --ta --> works for MFC EV1\n"
|
||||||
"hf mf hardnested --blk 0 -a -k FFFFFFFFFFFF --tblk 4 --ta\n"
|
"hf mf hardnested --blk 0 -a -k FFFFFFFFFFFF --tblk 4 --ta\n"
|
||||||
"hf mf hardnested --blk 0 -a -k FFFFFFFFFFFF --tblk 4 --ta -w\n"
|
"hf mf hardnested --blk 0 -a -k FFFFFFFFFFFF --tblk 4 --ta -w\n"
|
||||||
"hf mf hardnested --blk 0 -a -k FFFFFFFFFFFF --tblk 4 --ta -f nonces.bin -w -s\n"
|
"hf mf hardnested --blk 0 -a -k FFFFFFFFFFFF --tblk 4 --ta -f nonces.bin -w -s\n"
|
||||||
"hf mf hardnested -r\n"
|
"hf mf hardnested -r\n"
|
||||||
"hf mf hardnested -r --tk a0a1a2a3a4a5\n"
|
"hf mf hardnested -r --tk a0a1a2a3a4a5\n"
|
||||||
"hf mf hardnested -t --tk a0a1a2a3a4a5\n"
|
"hf mf hardnested -t --tk a0a1a2a3a4a5\n"
|
||||||
"hf mf hardnested --blk 0 -a -k a0a1a2a3a4a5 --tblk 4 --ta --tk FFFFFFFFFFFF"
|
"hf mf hardnested --blk 0 -a -k a0a1a2a3a4a5 --tblk 4 --ta --tk FFFFFFFFFFFF\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
|
@ -1976,7 +1979,7 @@ static int CmdHF14AMfNestedHard(const char *Cmd) {
|
||||||
SetSIMDInstr(SIMD_NONE);
|
SetSIMDInstr(SIMD_NONE);
|
||||||
|
|
||||||
|
|
||||||
bool know_target_key = (trg_keylen);
|
bool known_target_key = (trg_keylen);
|
||||||
|
|
||||||
if (nonce_file_read) {
|
if (nonce_file_read) {
|
||||||
char *fptr = GenerateFilename("hf-mf-", "-nonces.bin");
|
char *fptr = GenerateFilename("hf-mf-", "-nonces.bin");
|
||||||
|
@ -2000,7 +2003,15 @@ static int CmdHF14AMfNestedHard(const char *Cmd) {
|
||||||
snprintf(filename, FILE_PATH_SIZE, "hf-mf-%s-nonces.bin", uid);
|
snprintf(filename, FILE_PATH_SIZE, "hf-mf-%s-nonces.bin", uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (know_target_key == false && nonce_file_read == false) {
|
// detect MFC EV1 Signature
|
||||||
|
if (detect_mfc_ev1_signature() && keylen == 0) {
|
||||||
|
PrintAndLogEx(INFO, "MIFARE Classic EV1 card detected");
|
||||||
|
blockno = 69;
|
||||||
|
keytype = MF_KEY_B;
|
||||||
|
memcpy(key, g_mifare_signature_key_b, sizeof(g_mifare_signature_key_b));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (known_target_key == false && nonce_file_read == false) {
|
||||||
|
|
||||||
// check if tag doesn't have static nonce
|
// check if tag doesn't have static nonce
|
||||||
if (detect_classic_static_nonce() == NONCE_STATIC) {
|
if (detect_classic_static_nonce() == NONCE_STATIC) {
|
||||||
|
@ -2021,7 +2032,7 @@ static int CmdHF14AMfNestedHard(const char *Cmd) {
|
||||||
trg_blockno,
|
trg_blockno,
|
||||||
(trg_keytype == MF_KEY_B) ? 'B' : 'A',
|
(trg_keytype == MF_KEY_B) ? 'B' : 'A',
|
||||||
trg_key[0], trg_key[1], trg_key[2], trg_key[3], trg_key[4], trg_key[5],
|
trg_key[0], trg_key[1], trg_key[2], trg_key[3], trg_key[4], trg_key[5],
|
||||||
know_target_key ? "" : " (not set)"
|
known_target_key ? "" : " (not set)"
|
||||||
);
|
);
|
||||||
PrintAndLogEx(INFO, "File action: " _YELLOW_("%s") ", Slow: " _YELLOW_("%s") ", Tests: " _YELLOW_("%d"),
|
PrintAndLogEx(INFO, "File action: " _YELLOW_("%s") ", Slow: " _YELLOW_("%s") ", Tests: " _YELLOW_("%d"),
|
||||||
nonce_file_write ? "write" : nonce_file_read ? "read" : "none",
|
nonce_file_write ? "write" : nonce_file_read ? "read" : "none",
|
||||||
|
@ -2029,7 +2040,7 @@ static int CmdHF14AMfNestedHard(const char *Cmd) {
|
||||||
tests);
|
tests);
|
||||||
|
|
||||||
uint64_t foundkey = 0;
|
uint64_t foundkey = 0;
|
||||||
int16_t isOK = mfnestedhard(blockno, keytype, key, trg_blockno, trg_keytype, know_target_key ? trg_key : NULL, nonce_file_read, nonce_file_write, slow, tests, &foundkey, filename);
|
int16_t isOK = mfnestedhard(blockno, keytype, key, trg_blockno, trg_keytype, known_target_key ? trg_key : NULL, nonce_file_read, nonce_file_write, slow, tests, &foundkey, filename);
|
||||||
|
|
||||||
if ((tests == 0) && IfPm3Iso14443a()) {
|
if ((tests == 0) && IfPm3Iso14443a()) {
|
||||||
DropField();
|
DropField();
|
||||||
|
@ -2105,7 +2116,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool know_target_key = (keylen == 6);
|
bool known_key = (keylen == 6);
|
||||||
|
|
||||||
uint8_t sectorno = arg_get_u32_def(ctx, 2, 0);
|
uint8_t sectorno = arg_get_u32_def(ctx, 2, 0);
|
||||||
|
|
||||||
|
@ -2223,7 +2234,6 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||||
int bytes;
|
int bytes;
|
||||||
// Settings
|
// Settings
|
||||||
int prng_type = PM3_EUNDEF;
|
int prng_type = PM3_EUNDEF;
|
||||||
int has_staticnonce;
|
|
||||||
uint8_t num_found_keys = 0;
|
uint8_t num_found_keys = 0;
|
||||||
|
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
|
@ -2247,6 +2257,14 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||||
iso14a_card_select_t card;
|
iso14a_card_select_t card;
|
||||||
memcpy(&card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t));
|
memcpy(&card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t));
|
||||||
|
|
||||||
|
|
||||||
|
// detect MFC EV1 Signature
|
||||||
|
bool is_ev1 = detect_mfc_ev1_signature();
|
||||||
|
if (is_ev1) {
|
||||||
|
// hidden sectors on MFC EV1
|
||||||
|
sector_cnt += 2;
|
||||||
|
}
|
||||||
|
|
||||||
// create/initialize key storage structure
|
// create/initialize key storage structure
|
||||||
uint32_t e_sector_size = sector_cnt > sectorno ? sector_cnt : sectorno + 1;
|
uint32_t e_sector_size = sector_cnt > sectorno ? sector_cnt : sectorno + 1;
|
||||||
res = initSectorTable(&e_sector, e_sector_size);
|
res = initSectorTable(&e_sector, e_sector_size);
|
||||||
|
@ -2255,11 +2273,31 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||||
return PM3_EMALLOC;
|
return PM3_EMALLOC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_ev1) {
|
||||||
|
PrintAndLogEx(INFO, "MIFARE Classic EV1 card detected");
|
||||||
|
// Store the keys
|
||||||
|
e_sector[16].Key[MF_KEY_A] = bytes_to_num((uint8_t *)g_mifare_signature_key_a, sizeof(g_mifare_signature_key_a));
|
||||||
|
e_sector[16].foundKey[MF_KEY_A] = 'D';
|
||||||
|
|
||||||
|
e_sector[17].Key[MF_KEY_A] = bytes_to_num((uint8_t *)g_mifare_signature_key_a, sizeof(g_mifare_signature_key_a));
|
||||||
|
e_sector[17].foundKey[MF_KEY_A] = 'D';
|
||||||
|
e_sector[17].Key[MF_KEY_B] = bytes_to_num((uint8_t *)g_mifare_signature_key_b, sizeof(g_mifare_signature_key_b));
|
||||||
|
e_sector[17].foundKey[MF_KEY_B] = 'D';
|
||||||
|
|
||||||
|
// use found key if not supplied
|
||||||
|
if (known_key == false) {
|
||||||
|
known_key = true;
|
||||||
|
sectorno = 17;
|
||||||
|
keytype = MF_KEY_B;
|
||||||
|
memcpy(key, g_mifare_signature_key_b, sizeof(g_mifare_signature_key_b));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// read uid to generate a filename for the key file
|
// read uid to generate a filename for the key file
|
||||||
char *fptr = GenerateFilename("hf-mf-", "-key.bin");
|
char *fptr = GenerateFilename("hf-mf-", "-key.bin");
|
||||||
|
|
||||||
// check if tag doesn't have static nonce
|
// check if tag doesn't have static nonce
|
||||||
has_staticnonce = detect_classic_static_nonce();
|
int has_staticnonce = detect_classic_static_nonce();
|
||||||
|
|
||||||
// card prng type (weak=1 / hard=0 / select/card comm error = negative value)
|
// card prng type (weak=1 / hard=0 / select/card comm error = negative value)
|
||||||
if (has_staticnonce == NONCE_NORMAL) {
|
if (has_staticnonce == NONCE_NORMAL) {
|
||||||
|
@ -2276,7 +2314,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
PrintAndLogEx(INFO, "======================= " _YELLOW_("SETTINGS") " =======================");
|
PrintAndLogEx(INFO, "======================= " _YELLOW_("SETTINGS") " =======================");
|
||||||
PrintAndLogEx(INFO, " card sectors .. " _YELLOW_("%d"), sector_cnt);
|
PrintAndLogEx(INFO, " card sectors .. " _YELLOW_("%d"), sector_cnt);
|
||||||
PrintAndLogEx(INFO, " key supplied .. " _YELLOW_("%s"), know_target_key ? "True" : "False");
|
PrintAndLogEx(INFO, " key supplied .. " _YELLOW_("%s"), known_key ? "True" : "False");
|
||||||
PrintAndLogEx(INFO, " known sector .. " _YELLOW_("%d"), sectorno);
|
PrintAndLogEx(INFO, " known sector .. " _YELLOW_("%d"), sectorno);
|
||||||
PrintAndLogEx(INFO, " keytype ....... " _YELLOW_("%c"), (keytype == MF_KEY_B) ? 'B' : 'A');
|
PrintAndLogEx(INFO, " keytype ....... " _YELLOW_("%c"), (keytype == MF_KEY_B) ? 'B' : 'A');
|
||||||
PrintAndLogEx(INFO, " known key ..... " _YELLOW_("%s"), sprint_hex(key, sizeof(key)));
|
PrintAndLogEx(INFO, " known key ..... " _YELLOW_("%s"), sprint_hex(key, sizeof(key)));
|
||||||
|
@ -2298,7 +2336,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||||
uint64_t t1 = msclock();
|
uint64_t t1 = msclock();
|
||||||
|
|
||||||
// check the user supplied key
|
// check the user supplied key
|
||||||
if (know_target_key == false) {
|
if (known_key == false) {
|
||||||
PrintAndLogEx(WARNING, "no known key was supplied, key recovery might fail");
|
PrintAndLogEx(WARNING, "no known key was supplied, key recovery might fail");
|
||||||
} else {
|
} else {
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
|
@ -2318,7 +2356,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||||
|
|
||||||
++num_found_keys;
|
++num_found_keys;
|
||||||
} else {
|
} else {
|
||||||
know_target_key = false;
|
known_key = false;
|
||||||
PrintAndLogEx(FAILED, "Key is wrong. Can't authenticate to sector"_RED_("%3d") " key type "_RED_("%c") " key " _RED_("%s"),
|
PrintAndLogEx(FAILED, "Key is wrong. Can't authenticate to sector"_RED_("%3d") " key type "_RED_("%c") " key " _RED_("%s"),
|
||||||
sectorno,
|
sectorno,
|
||||||
(keytype == MF_KEY_B) ? 'B' : 'A',
|
(keytype == MF_KEY_B) ? 'B' : 'A',
|
||||||
|
@ -2336,9 +2374,9 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||||
e_sector[i].foundKey[j] = 'U';
|
e_sector[i].foundKey[j] = 'U';
|
||||||
|
|
||||||
// If the user supplied secctor / keytype was wrong --> just be nice and correct it ;)
|
// If the user supplied secctor / keytype was wrong --> just be nice and correct it ;)
|
||||||
if (know_target_key == false) {
|
if (known_key == false) {
|
||||||
num_to_bytes(e_sector[i].Key[j], 6, key);
|
num_to_bytes(e_sector[i].Key[j], 6, key);
|
||||||
know_target_key = true;
|
known_key = true;
|
||||||
sectorno = i;
|
sectorno = i;
|
||||||
keytype = j;
|
keytype = j;
|
||||||
PrintAndLogEx(SUCCESS, "target sector %3u key type %c -- found valid key [ " _GREEN_("%s") " ] (used for nested / hardnested attack)",
|
PrintAndLogEx(SUCCESS, "target sector %3u key type %c -- found valid key [ " _GREEN_("%s") " ] (used for nested / hardnested attack)",
|
||||||
|
@ -2461,9 +2499,9 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||||
num_to_bytes(e_sector[i].Key[j], 6, tmp_key);
|
num_to_bytes(e_sector[i].Key[j], 6, tmp_key);
|
||||||
|
|
||||||
// Store valid credentials for the nested / hardnested attack if none exist
|
// Store valid credentials for the nested / hardnested attack if none exist
|
||||||
if (know_target_key == false) {
|
if (known_key == false) {
|
||||||
num_to_bytes(e_sector[i].Key[j], 6, key);
|
num_to_bytes(e_sector[i].Key[j], 6, key);
|
||||||
know_target_key = true;
|
known_key = true;
|
||||||
sectorno = i;
|
sectorno = i;
|
||||||
keytype = j;
|
keytype = j;
|
||||||
PrintAndLogEx(SUCCESS, "target sector %3u key type %c -- found valid key [ " _GREEN_("%s") " ] (used for nested / hardnested attack)",
|
PrintAndLogEx(SUCCESS, "target sector %3u key type %c -- found valid key [ " _GREEN_("%s") " ] (used for nested / hardnested attack)",
|
||||||
|
@ -2483,7 +2521,8 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if at least one sector key was found
|
// Check if at least one sector key was found
|
||||||
if (know_target_key == false) {
|
if (known_key == false) {
|
||||||
|
|
||||||
// Check if the darkside attack can be used
|
// Check if the darkside attack can be used
|
||||||
if (prng_type && has_staticnonce != NONCE_STATIC) {
|
if (prng_type && has_staticnonce != NONCE_STATIC) {
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
|
@ -2520,6 +2559,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||||
key64
|
key64
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
noValidKeyFound:
|
noValidKeyFound:
|
||||||
PrintAndLogEx(FAILED, "No usable key was found!");
|
PrintAndLogEx(FAILED, "No usable key was found!");
|
||||||
free(keyBlock);
|
free(keyBlock);
|
||||||
|
|
|
@ -29,6 +29,7 @@ static const uint64_t g_mifare_default_keys[] = {
|
||||||
0x000000000000, // Blank key
|
0x000000000000, // Blank key
|
||||||
0xa0a1a2a3a4a5, // NFCForum MAD key
|
0xa0a1a2a3a4a5, // NFCForum MAD key
|
||||||
0xd3f7d3f7d3f7, // NDEF public key
|
0xd3f7d3f7d3f7, // NDEF public key
|
||||||
|
0x4b791bea7bcc, // MFC EV1 Signature B
|
||||||
0xb0b1b2b3b4b5,
|
0xb0b1b2b3b4b5,
|
||||||
0xaabbccddeeff,
|
0xaabbccddeeff,
|
||||||
0x1a2b3c4d5e6f,
|
0x1a2b3c4d5e6f,
|
||||||
|
@ -75,6 +76,10 @@ static const uint8_t g_mifare_default_key[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0x
|
||||||
static const uint8_t g_mifare_mad_key[] = {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5};
|
static const uint8_t g_mifare_mad_key[] = {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5};
|
||||||
static const uint8_t g_mifare_mad_key_b[] = {0x89, 0xEC, 0xA9, 0x7F, 0x8C, 0x2A};
|
static const uint8_t g_mifare_mad_key_b[] = {0x89, 0xEC, 0xA9, 0x7F, 0x8C, 0x2A};
|
||||||
|
|
||||||
|
// 16 key B D01AFEEB890A
|
||||||
|
static const uint8_t g_mifare_signature_key_a[] = {0x5C, 0x8F, 0xF9, 0x99, 0x0D, 0xA2};
|
||||||
|
static const uint8_t g_mifare_signature_key_b[] = {0x4b, 0x79, 0x1b, 0xea, 0x7b, 0xcc};
|
||||||
|
|
||||||
static const uint8_t g_mifare_ndef_key[] = {0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7};
|
static const uint8_t g_mifare_ndef_key[] = {0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7};
|
||||||
static const uint8_t g_mifarep_mad_key[] = {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7};
|
static const uint8_t g_mifarep_mad_key[] = {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7};
|
||||||
static const uint8_t g_mifarep_ndef_key[] = {0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7};
|
static const uint8_t g_mifarep_ndef_key[] = {0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7};
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
#include "util_posix.h" // msclock
|
#include "util_posix.h" // msclock
|
||||||
#include "cmdparser.h" // detection of flash capabilities
|
#include "cmdparser.h" // detection of flash capabilities
|
||||||
#include "cmdflashmemspiffs.h" // upload to flash mem
|
#include "cmdflashmemspiffs.h" // upload to flash mem
|
||||||
|
#include "mifaredefault.h" // default keys
|
||||||
|
|
||||||
|
|
||||||
int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
|
int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
|
||||||
uint32_t uid = 0;
|
uint32_t uid = 0;
|
||||||
|
@ -880,7 +882,7 @@ int mfReadSector(uint8_t sectorNo, uint8_t keyType, const uint8_t *key, uint8_t
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mfReadBlock(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t *data) {
|
int mfReadBlock(uint8_t blockNo, uint8_t keyType, const uint8_t *key, uint8_t *data) {
|
||||||
mf_readblock_t payload = {
|
mf_readblock_t payload = {
|
||||||
.blockno = blockNo,
|
.blockno = blockNo,
|
||||||
.keytype = keyType
|
.keytype = keyType
|
||||||
|
@ -1417,15 +1419,20 @@ int detect_mf_magic(bool is_mfc) {
|
||||||
return isGeneration;
|
return isGeneration;
|
||||||
}
|
}
|
||||||
|
|
||||||
int detect_mfc_ev1_signature(uint8_t *signature) {
|
bool detect_mfc_ev1_signature(void) {
|
||||||
|
uint64_t key = 0;
|
||||||
|
int res = mfCheckKeys(69, MF_KEY_B, false, 1, (uint8_t*)g_mifare_signature_key_b, &key);
|
||||||
|
return (res == PM3_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
int read_mfc_ev1_signature(uint8_t *signature) {
|
||||||
if (signature == NULL) {
|
if (signature == NULL) {
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
uint8_t sign[32] = {0};
|
uint8_t sign[32] = {0};
|
||||||
uint8_t key[] = {0x4b, 0x79, 0x1b, 0xea, 0x7b, 0xcc};
|
int res = mfReadBlock(69, MF_KEY_B, g_mifare_signature_key_b, sign);
|
||||||
int res = mfReadBlock(69, 1, key, sign);
|
|
||||||
if (res == PM3_SUCCESS) {
|
if (res == PM3_SUCCESS) {
|
||||||
res = mfReadBlock(70, 1, key, sign + 16);
|
res = mfReadBlock(70, MF_KEY_B, g_mifare_signature_key_b, sign + 16);
|
||||||
if (res == PM3_SUCCESS) {
|
if (res == PM3_SUCCESS) {
|
||||||
memcpy(signature, sign, sizeof(sign));
|
memcpy(signature, sign, sizeof(sign));
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ int mfCheckKeys_file(uint8_t *destfn, uint64_t *key);
|
||||||
int mfKeyBrute(uint8_t blockNo, uint8_t keyType, const uint8_t *key, uint64_t *resultkey);
|
int mfKeyBrute(uint8_t blockNo, uint8_t keyType, const uint8_t *key, uint64_t *resultkey);
|
||||||
|
|
||||||
int mfReadSector(uint8_t sectorNo, uint8_t keyType, const uint8_t *key, uint8_t *data);
|
int mfReadSector(uint8_t sectorNo, uint8_t keyType, const uint8_t *key, uint8_t *data);
|
||||||
int mfReadBlock(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t *data);
|
int mfReadBlock(uint8_t blockNo, uint8_t keyType, const uint8_t *key, uint8_t *data);
|
||||||
|
|
||||||
int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount);
|
int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount);
|
||||||
int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount);
|
int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount);
|
||||||
|
@ -104,7 +104,9 @@ int detect_classic_prng(void);
|
||||||
int detect_classic_nackbug(bool verbose);
|
int detect_classic_nackbug(bool verbose);
|
||||||
int detect_mf_magic(bool is_mfc);
|
int detect_mf_magic(bool is_mfc);
|
||||||
int detect_classic_static_nonce(void);
|
int detect_classic_static_nonce(void);
|
||||||
int detect_mfc_ev1_signature(uint8_t *signature);
|
bool detect_mfc_ev1_signature(void);
|
||||||
|
int read_mfc_ev1_signature(uint8_t *signature);
|
||||||
|
|
||||||
|
|
||||||
void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len, bool isEncrypted);
|
void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len, bool isEncrypted);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue