diff --git a/tools/mfc/card_reader/mf_nonce_brute.c b/tools/mfc/card_reader/mf_nonce_brute.c index 8f812960d..b99486dd9 100644 --- a/tools/mfc/card_reader/mf_nonce_brute.c +++ b/tools/mfc/card_reader/mf_nonce_brute.c @@ -32,6 +32,7 @@ uint32_t nr_enc = 0; // encrypted reader challenge uint32_t ar_enc = 0; // encrypted reader response uint32_t at_enc = 0; // encrypted tag response uint32_t cmd_enc = 0; // next encrypted command to sector +bool is_nt_encrypted = 1; uint32_t nt_par_err = 0; uint32_t ar_par_err = 0; @@ -54,6 +55,7 @@ typedef struct thread_key_args { uint32_t nr_enc; uint16_t enc_len; uint8_t enc[ENC_LEN]; // next encrypted command + a full read/write + bool is_nt_encrypted; } targs_key; //------------------------------------------------------------------ @@ -452,7 +454,7 @@ static void *check_default_keys(void *arguments) { struct Crypto1State *pcs = crypto1_create(key); // NESTED decrypt nt with help of new key - crypto1_word(pcs, args->nt_enc ^ args->uid, 1); + crypto1_word(pcs, args->nt_enc ^ args->uid, args->is_nt_encrypted); crypto1_word(pcs, args->nr_enc, 1); crypto1_word(pcs, 0, 0); crypto1_word(pcs, 0, 0); @@ -606,7 +608,7 @@ static void *brute_key_thread(void *arguments) { struct Crypto1State *pcs = crypto1_create(key); // NESTED decrypt nt with help of new key - crypto1_word(pcs, args->nt_enc ^ args->uid, 1); + crypto1_word(pcs, args->nt_enc ^ args->uid, args->is_nt_encrypted); crypto1_word(pcs, args->nr_enc, 1); crypto1_word(pcs, 0, 0); crypto1_word(pcs, 0, 0); @@ -646,6 +648,8 @@ static void *brute_key_thread(void *arguments) { static int usage(void) { printf("\n"); printf("syntax: mf_nonce_brute <{nt}> <{nr}> <{ar}> <{at}> [<{next_command}>]\n\n"); + printf("alternatively, you can provide a clear nt:\n"); + printf("syntax: mf_nonce_brute clear <{nr}> <{ar}> <{at}> [<{next_command}>]\n\n"); printf("how to convert trace data to needed input:\n"); printf(" {nt} in trace = 8c! 42 e6! 4e!\n"); printf(" => {nt} = 8c42e64e\n"); @@ -673,7 +677,12 @@ int main(int argc, const char *argv[]) { sscanf(argv[1], "%x", &uid); sscanf(argv[2], "%x", &nt_enc); - sscanf(argv[3], "%x", &nt_par_err); + if (strncmp(argv[3], "clear", 5) == 0) { + nt_par_err = 0; + is_nt_encrypted = 0; + } else { + sscanf(argv[3], "%x", &nt_par_err); + } sscanf(argv[4], "%x", &nr_enc); sscanf(argv[5], "%x", &ar_enc); sscanf(argv[6], "%x", &ar_par_err); @@ -734,6 +743,7 @@ int main(int argc, const char *argv[]) { def->nt_enc = nt_enc; def->nr_enc = nr_enc; def->enc_len = enc_len; + def->is_nt_encrypted = is_nt_encrypted; memcpy(def->enc, enc, enc_len); pthread_create(&threads[0], NULL, check_default_keys, (void *)def); pthread_join(threads[0], NULL); @@ -820,6 +830,7 @@ int main(int argc, const char *argv[]) { b->nt_enc = nt_enc; b->nr_enc = nr_enc; b->enc_len = enc_len; + b->is_nt_encrypted = is_nt_encrypted; memcpy(b->enc, enc, enc_len); pthread_create(&threads[i], NULL, brute_key_thread, (void *)b); } diff --git a/tools/mfc/card_reader/mf_nonce_brute_examples.md b/tools/mfc/card_reader/mf_nonce_brute_examples.md index a13ade916..03e7e24c4 100644 --- a/tools/mfc/card_reader/mf_nonce_brute_examples.md +++ b/tools/mfc/card_reader/mf_nonce_brute_examples.md @@ -83,18 +83,17 @@ Example with parity (from this trace http://www.proxmark.org/forum/viewtopic.php + 64: 4 : TAG bf dd 01 be! + 987853: 4 : 56 98 49 d6! !crc ``` -=> +=> Using the plaintext tagnonce `nt`=`82a4166c` ``` -./mf_nonce_brute 9c599b32 82a4166c 0000 a1e458ce 6eea41e0 0101 5cadf439 1001 8e0e5db9 - | | | | | | | | | - +UID +nt | +{nr} +{ar} | +{at} | +{next cmd} - +nt_par_err +at_par_err +at_par_err +./mf_nonce_brute 9c599b32 82a4166c clear a1e458ce 6eea41e0 0101 5cadf439 1001 8e0e5db9 + | | | | | | | | | + +UID +nt | +{nr} +{ar} | +{at} | +{next cmd} + + nt is clear +ar_par_err +at_par_err ``` -These two taken from above use the plaintext tagnonce `nt`=`82a4166c`, they still find a possible key candidate. +Without a next command, it still finds a possible key candidate. ``` -./mf_nonce_brute 9c599b32 82a4166c 0000 a1e458ce 6eea41e0 0101 5cadf439 1001 -./mf_nonce_brute 9c599b32 82a4166c 0000 98d76b77 d6c6e870 0000 ca7e0b63 0111 +./mf_nonce_brute 9c599b32 82a4166c clear a1e458ce 6eea41e0 0101 5cadf439 1001 ``` This one uses the encrypted tagnonce `{nt}`=`5a920d85`, it finds a valid key.