mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 13:00:42 -07:00
mf_nonce_brute: allow clear nt. Fix the weird example half working with a clear nt provided as encrypted nt...
This commit is contained in:
parent
5b6a898fe7
commit
cce2c8e7ee
2 changed files with 21 additions and 11 deletions
|
@ -32,6 +32,7 @@ uint32_t nr_enc = 0; // encrypted reader challenge
|
||||||
uint32_t ar_enc = 0; // encrypted reader response
|
uint32_t ar_enc = 0; // encrypted reader response
|
||||||
uint32_t at_enc = 0; // encrypted tag response
|
uint32_t at_enc = 0; // encrypted tag response
|
||||||
uint32_t cmd_enc = 0; // next encrypted command to sector
|
uint32_t cmd_enc = 0; // next encrypted command to sector
|
||||||
|
bool is_nt_encrypted = 1;
|
||||||
|
|
||||||
uint32_t nt_par_err = 0;
|
uint32_t nt_par_err = 0;
|
||||||
uint32_t ar_par_err = 0;
|
uint32_t ar_par_err = 0;
|
||||||
|
@ -54,6 +55,7 @@ typedef struct thread_key_args {
|
||||||
uint32_t nr_enc;
|
uint32_t nr_enc;
|
||||||
uint16_t enc_len;
|
uint16_t enc_len;
|
||||||
uint8_t enc[ENC_LEN]; // next encrypted command + a full read/write
|
uint8_t enc[ENC_LEN]; // next encrypted command + a full read/write
|
||||||
|
bool is_nt_encrypted;
|
||||||
} targs_key;
|
} targs_key;
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
@ -452,7 +454,7 @@ static void *check_default_keys(void *arguments) {
|
||||||
struct Crypto1State *pcs = crypto1_create(key);
|
struct Crypto1State *pcs = crypto1_create(key);
|
||||||
|
|
||||||
// NESTED decrypt nt with help of new 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, args->nr_enc, 1);
|
||||||
crypto1_word(pcs, 0, 0);
|
crypto1_word(pcs, 0, 0);
|
||||||
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);
|
struct Crypto1State *pcs = crypto1_create(key);
|
||||||
|
|
||||||
// NESTED decrypt nt with help of new 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, args->nr_enc, 1);
|
||||||
crypto1_word(pcs, 0, 0);
|
crypto1_word(pcs, 0, 0);
|
||||||
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) {
|
static int usage(void) {
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("syntax: mf_nonce_brute <uid> <{nt}> <nt_par_err> <{nr}> <{ar}> <ar_par_err> <{at}> <at_par_err> [<{next_command}>]\n\n");
|
printf("syntax: mf_nonce_brute <uid> <{nt}> <nt_par_err> <{nr}> <{ar}> <ar_par_err> <{at}> <at_par_err> [<{next_command}>]\n\n");
|
||||||
|
printf("alternatively, you can provide a clear nt:\n");
|
||||||
|
printf("syntax: mf_nonce_brute <uid> <nt> clear <{nr}> <{ar}> <ar_par_err> <{at}> <at_par_err> [<{next_command}>]\n\n");
|
||||||
printf("how to convert trace data to needed input:\n");
|
printf("how to convert trace data to needed input:\n");
|
||||||
printf(" {nt} in trace = 8c! 42 e6! 4e!\n");
|
printf(" {nt} in trace = 8c! 42 e6! 4e!\n");
|
||||||
printf(" => {nt} = 8c42e64e\n");
|
printf(" => {nt} = 8c42e64e\n");
|
||||||
|
@ -673,7 +677,12 @@ int main(int argc, const char *argv[]) {
|
||||||
|
|
||||||
sscanf(argv[1], "%x", &uid);
|
sscanf(argv[1], "%x", &uid);
|
||||||
sscanf(argv[2], "%x", &nt_enc);
|
sscanf(argv[2], "%x", &nt_enc);
|
||||||
|
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[3], "%x", &nt_par_err);
|
||||||
|
}
|
||||||
sscanf(argv[4], "%x", &nr_enc);
|
sscanf(argv[4], "%x", &nr_enc);
|
||||||
sscanf(argv[5], "%x", &ar_enc);
|
sscanf(argv[5], "%x", &ar_enc);
|
||||||
sscanf(argv[6], "%x", &ar_par_err);
|
sscanf(argv[6], "%x", &ar_par_err);
|
||||||
|
@ -734,6 +743,7 @@ int main(int argc, const char *argv[]) {
|
||||||
def->nt_enc = nt_enc;
|
def->nt_enc = nt_enc;
|
||||||
def->nr_enc = nr_enc;
|
def->nr_enc = nr_enc;
|
||||||
def->enc_len = enc_len;
|
def->enc_len = enc_len;
|
||||||
|
def->is_nt_encrypted = is_nt_encrypted;
|
||||||
memcpy(def->enc, enc, enc_len);
|
memcpy(def->enc, enc, enc_len);
|
||||||
pthread_create(&threads[0], NULL, check_default_keys, (void *)def);
|
pthread_create(&threads[0], NULL, check_default_keys, (void *)def);
|
||||||
pthread_join(threads[0], NULL);
|
pthread_join(threads[0], NULL);
|
||||||
|
@ -820,6 +830,7 @@ int main(int argc, const char *argv[]) {
|
||||||
b->nt_enc = nt_enc;
|
b->nt_enc = nt_enc;
|
||||||
b->nr_enc = nr_enc;
|
b->nr_enc = nr_enc;
|
||||||
b->enc_len = enc_len;
|
b->enc_len = enc_len;
|
||||||
|
b->is_nt_encrypted = is_nt_encrypted;
|
||||||
memcpy(b->enc, enc, enc_len);
|
memcpy(b->enc, enc, enc_len);
|
||||||
pthread_create(&threads[i], NULL, brute_key_thread, (void *)b);
|
pthread_create(&threads[i], NULL, brute_key_thread, (void *)b);
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,18 +83,17 @@ Example with parity (from this trace http://www.proxmark.org/forum/viewtopic.php
|
||||||
+ 64: 4 : TAG bf dd 01 be!
|
+ 64: 4 : TAG bf dd 01 be!
|
||||||
+ 987853: 4 : 56 98 49 d6! !crc
|
+ 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
|
./mf_nonce_brute 9c599b32 82a4166c clear a1e458ce 6eea41e0 0101 5cadf439 1001 8e0e5db9
|
||||||
| | | | | | | | |
|
| | | | | | | | |
|
||||||
+UID +nt | +{nr} +{ar} | +{at} | +{next cmd}
|
+UID +nt | +{nr} +{ar} | +{at} | +{next cmd}
|
||||||
+nt_par_err +at_par_err +at_par_err
|
+ 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 clear a1e458ce 6eea41e0 0101 5cadf439 1001
|
||||||
./mf_nonce_brute 9c599b32 82a4166c 0000 98d76b77 d6c6e870 0000 ca7e0b63 0111
|
|
||||||
```
|
```
|
||||||
|
|
||||||
This one uses the encrypted tagnonce `{nt}`=`5a920d85`, it finds a valid key.
|
This one uses the encrypted tagnonce `{nt}`=`5a920d85`, it finds a valid key.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue