mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 13:53:55 -07:00
uniformize tools/mfc/card_reader
This commit is contained in:
parent
e6c29ce6e0
commit
5b6a898fe7
7 changed files with 60 additions and 54 deletions
|
@ -645,11 +645,11 @@ static void *brute_key_thread(void *arguments) {
|
|||
|
||||
static int usage(void) {
|
||||
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("how to convert trace data to needed input:\n");
|
||||
printf(" nt in trace = 8c! 42 e6! 4e!\n");
|
||||
printf(" nt = 8c42e64e\n");
|
||||
printf(" nt_par_err = 1011\n\n");
|
||||
printf(" {nt} in trace = 8c! 42 e6! 4e!\n");
|
||||
printf(" => {nt} = 8c42e64e\n");
|
||||
printf(" => nt_par_err = 1011\n\n");
|
||||
printf("samples:\n");
|
||||
printf("\n");
|
||||
printf(" ./mf_nonce_brute fa247164 fb47c594 0000 71909d28 0c254817 1000 0dc7cfbd 1110\n");
|
||||
|
|
|
@ -20,8 +20,8 @@ Sample trace:
|
|||
TAG 08 b6 dd // sak
|
||||
60 04 d1 3d // wanna auth block 0x04 with A key
|
||||
TAG ed 12 9c 74 // 1st auth clear text nt
|
||||
55 53 9f cc 41 8d e8 f3 // nr', ar' (nr^ks1, ar^ks2 )
|
||||
TAG 05 49 e1 65 // at' ( at^ks3 )
|
||||
55 53 9f cc 41 8d e8 f3 // {nr}, {ar} (nr^ks1, ar^ks2 )
|
||||
TAG 05 49 e1 65 // {at} ( at^ks3 )
|
||||
03 24 26 56 // wanna read block 0x04
|
||||
TAG ac 69 ef 58 45 e1 c2 1d a9 47 a5 94 54 ef 5d c7 1e a9 // block 0x04 content
|
||||
d4 3e a8 aa
|
||||
|
@ -35,8 +35,8 @@ TAG a3 76 dc df c1 42 e0 ee c6 75 a4 ca eb 0c da eb 46 a0 // 18 bytes = 16 byte
|
|||
-------Until this line we can recover key or decrypt communication with no troubles (see mfkey64 tool)--------------------------------
|
||||
|
||||
TAG 52 6e af 8b // nested auth encrypted tag nonce that we don't know
|
||||
8e 21 3a 29 a4 80 7e 02 // nr_enc = nr^ks1, ar_enc = ar^ks2
|
||||
TAG b9 43 74 8d // at_enc = at^ks3
|
||||
8e 21 3a 29 a4 80 7e 02 // {nr} = nr^ks1, {ar} = ar^ks2
|
||||
TAG b9 43 74 8d // {at} = at^ks3
|
||||
e2 25 f8 32 // probably next command (actually is read block cmd, but we don't know it yet)
|
||||
TAG 1f 26 82 8d 12 21 dd 42 c2 84 3e d0 26 7f 6b 2a 81 a9 // probably data
|
||||
ba 85 1d 36 // probably read cmd
|
||||
|
@ -54,7 +54,7 @@ Phase 1
|
|||
Syntax:
|
||||
`mf_nonce_brute <uid> <{nt}> <nt_par_err> <{nr}> <{ar}> <ar_par_err> <{at}> <at_par_err> [<{next_command}>]`
|
||||
|
||||
Example: if `nt` in trace is `8c! 42 e6! 4e!`, then `nt` is `8c42e64e` and `nt_par_err` is `1011`
|
||||
Example: if `{nt}` in trace is `8c! 42 e6! 4e!`, then `{nt}` is `8c42e64e` and `nt_par_err` is `1011`
|
||||
|
||||
Example with parity (from this trace http://www.proxmark.org/forum/viewtopic.php?pid=550#p550) :
|
||||
|
||||
|
@ -66,13 +66,13 @@ Example with parity (from this trace http://www.proxmark.org/forum/viewtopic.php
|
|||
+ 12313: 9 : 93 70 9c 59 9b 32 6c 6b 30
|
||||
+ 64: 3 : TAG 08 b6 dd
|
||||
+ 923318: 4 : 60 00 f5 7b AUTH Block 0
|
||||
+ 112: 4 : TAG 82 a4 16 6c Nonce Tag (NT)
|
||||
+ 6985: 8 : a1 e4! 58 ce! 6e ea! 41 e0! NR , AR
|
||||
+ 64: 4 : TAG 5c! ad f4 39! AT
|
||||
+ 112: 4 : TAG 82 a4 16 6c Nonce Tag (nt)
|
||||
+ 6985: 8 : a1 e4! 58 ce! 6e ea! 41 e0! {nr}, {ar}
|
||||
+ 64: 4 : TAG 5c! ad f4 39! {at}
|
||||
+ 811513: 4 : 8e 0e! 5d! b9 AUTH Block 0 (nested)
|
||||
+ 112: 4 : TAG 5a! 92 0d! 85! Nonce Tag (NT)
|
||||
+ 6946: 8 : 98! d7 6b! 77 d6 c6 e8 70 NR , AR
|
||||
+ 64: 4 : TAG ca 7e! 0b! 63! AT
|
||||
+ 112: 4 : TAG 5a! 92 0d! 85! Nonce Tag ({nt})
|
||||
+ 6946: 8 : 98! d7 6b! 77 d6 c6 e8 70 {nr}, {ar}
|
||||
+ 64: 4 : TAG ca 7e! 0b! 63! {at}
|
||||
+ 670868: 4 : 3e! 70 9c! 8a
|
||||
+ 112: 4 : TAG 36! 41 24! 79
|
||||
+ 9505: 8 : 1b! 8c 3a! 48! 83 5a 4a! 27
|
||||
|
@ -87,7 +87,7 @@ Example with parity (from this trace http://www.proxmark.org/forum/viewtopic.php
|
|||
```
|
||||
./mf_nonce_brute 9c599b32 82a4166c 0000 a1e458ce 6eea41e0 0101 5cadf439 1001 8e0e5db9
|
||||
| | | | | | | | |
|
||||
+UID +nt_enc | +nr_enc +ar_enc | +at_enc | +encrypted next cmd
|
||||
+UID +nt | +{nr} +{ar} | +{at} | +{next cmd}
|
||||
+nt_par_err +at_par_err +at_par_err
|
||||
```
|
||||
|
||||
|
@ -97,12 +97,12 @@ These two taken from above use the plaintext tagnonce `nt`=`82a4166c`, they sti
|
|||
./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.
|
||||
```
|
||||
./mf_nonce_brute 9c599b32 5a920d85 1011 98d76b77 d6c6e870 0000 ca7e0b63 0111
|
||||
```
|
||||
|
||||
This one uses the encrypted tagnonce `nt`=`5a920d85` and the encrypted cmd `3e709c8a` to validate , it finds a valid key.
|
||||
This one uses the encrypted tagnonce `{nt}`=`5a920d85` and the encrypted cmd `3e709c8a` to validate , it finds a valid key.
|
||||
```
|
||||
./mf_nonce_brute 9c599b32 5a920d85 1011 98d76b77 d6c6e870 0000 ca7e0b63 0111 3e709c8a
|
||||
```
|
||||
|
|
|
@ -243,7 +243,7 @@ static void *brute_thread(void *arguments) {
|
|||
}
|
||||
|
||||
static int usage(void) {
|
||||
printf(" syntax: mf_trace_brute <uid> <partial key> <nt enc> <nr enc> [<next_command + 18 bytes>]\n\n");
|
||||
printf(" syntax: mf_trace_brute <uid> <partial key> <{nt}> <{nr}> [<{next_command + 18 bytes}>]\n\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,13 +15,14 @@ int main(int argc, char *argv[]) {
|
|||
uint32_t ar0_enc; // first encrypted reader response
|
||||
uint32_t nr1_enc; // second encrypted reader challenge
|
||||
uint32_t ar1_enc; // second encrypted reader response
|
||||
uint32_t ks2; // keystream used to encrypt reader response
|
||||
uint32_t ks2_0; // first keystream used to encrypt reader response
|
||||
uint32_t ks2_1; // second keystream used to encrypt reader response
|
||||
|
||||
printf("MIFARE Classic key recovery - based on 32 bits of keystream\n");
|
||||
printf("Recover key from two 32-bit reader authentication answers only!\n\n");
|
||||
|
||||
if (argc < 7) {
|
||||
printf(" syntax: %s <uid> <nt> <nr_0> <ar_0> <nr_1> <ar_1>\n\n", argv[0]);
|
||||
printf(" syntax: %s <uid> <nt> <{nr_0}> <{ar}_0> <{nr_1}> <{ar}_0>\n\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -36,22 +37,23 @@ int main(int argc, char *argv[]) {
|
|||
printf(" uid: %08x\n", uid);
|
||||
printf(" nt: %08x\n", nt);
|
||||
printf(" {nr_0}: %08x\n", nr0_enc);
|
||||
printf(" {ar_0}: %08x\n", ar0_enc);
|
||||
printf(" {ar}_0: %08x\n", ar0_enc);
|
||||
printf(" {nr_1}: %08x\n", nr1_enc);
|
||||
printf(" {ar_1}: %08x\n", ar1_enc);
|
||||
printf(" {ar}_1: %08x\n", ar1_enc);
|
||||
|
||||
// Generate lfsr successors of the tag challenge
|
||||
printf("\nLFSR successors of the tag challenge:\n");
|
||||
uint32_t p64 = prng_successor(nt, 64);
|
||||
printf(" nt': %08x\n", p64);
|
||||
printf(" nt'': %08x\n", prng_successor(p64, 32));
|
||||
printf("\nLFSR successor of the tag challenge:\n");
|
||||
uint32_t ar = prng_successor(nt, 64);
|
||||
printf(" ar: %08x\n", ar);
|
||||
|
||||
// Extract the keystream from the messages
|
||||
printf("\nKeystream used to generate {ar} and {at}:\n");
|
||||
ks2 = ar0_enc ^ p64;
|
||||
printf(" ks2: %08x\n", ks2);
|
||||
printf("\nKeystreams used to generate {ar}_0 and {ar}_1:\n");
|
||||
ks2_0 = ar0_enc ^ ar;
|
||||
printf(" ks2_0: %08x\n", ks2_0);
|
||||
ks2_1 = ar1_enc ^ ar;
|
||||
printf(" ks2_1: %08x\n", ks2_1);
|
||||
|
||||
s = lfsr_recovery32(ar0_enc ^ p64, 0);
|
||||
s = lfsr_recovery32(ks2_0, 0);
|
||||
|
||||
for (t = s; t->odd | t->even; ++t) {
|
||||
lfsr_rollback_word(t, 0, 0);
|
||||
|
@ -60,7 +62,7 @@ int main(int argc, char *argv[]) {
|
|||
crypto1_get_lfsr(t, &key);
|
||||
crypto1_word(t, uid ^ nt, 0);
|
||||
crypto1_word(t, nr1_enc, 1);
|
||||
if (ar1_enc == (crypto1_word(t, 0, 0) ^ p64)) {
|
||||
if (ks2_1 == crypto1_word(t, 0, 0)) {
|
||||
printf("\nFound Key: [%012" PRIx64 "]\n\n", key);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -16,14 +16,15 @@ int main(int argc, char *argv[]) {
|
|||
uint32_t ar0_enc; // first encrypted reader response
|
||||
uint32_t nr1_enc; // second encrypted reader challenge
|
||||
uint32_t ar1_enc; // second encrypted reader response
|
||||
uint32_t ks2; // keystream used to encrypt reader response
|
||||
uint32_t ks2_0; // first keystream used to encrypt reader response
|
||||
uint32_t ks2_1; // second keystream used to encrypt reader response
|
||||
|
||||
printf("MIFARE Classic key recovery - based 32 bits of keystream VERSION2\n");
|
||||
printf("Recover key from two 32-bit reader authentication answers only\n");
|
||||
printf("This version implements Moebius two different nonce solution (like the supercard)\n\n");
|
||||
|
||||
if (argc < 8) {
|
||||
printf("syntax: %s <uid> <nt> <nr_0> <ar_0> <nt1> <nr_1> <ar_1>\n\n", argv[0]);
|
||||
printf("syntax: %s <uid> <{nt_0}> <{nr_0}> <{ar_0}> <{nt_1}> <{nr_1}> <{ar_1}>\n\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -45,19 +46,21 @@ int main(int argc, char *argv[]) {
|
|||
printf(" {ar_1}: %08x\n", ar1_enc);
|
||||
|
||||
// Generate lfsr successors of the tag challenge
|
||||
printf("\nLFSR successors of the tag challenge:\n");
|
||||
uint32_t p64 = prng_successor(nt0, 64);
|
||||
uint32_t p64b = prng_successor(nt1, 64);
|
||||
printf("\nLFSR successors of the tag challenges:\n");
|
||||
uint32_t ar0 = prng_successor(nt0, 64);
|
||||
uint32_t ar1 = prng_successor(nt1, 64);
|
||||
|
||||
printf(" nt': %08x\n", p64);
|
||||
printf(" nt'': %08x\n", prng_successor(p64, 32));
|
||||
printf(" ar_0: %08x\n", ar0);
|
||||
printf(" ar_1: %08x\n", ar1);
|
||||
|
||||
// Extract the keystream from the messages
|
||||
printf("\nKeystream used to generate {ar} and {at}:\n");
|
||||
ks2 = ar0_enc ^ p64;
|
||||
printf(" ks2: %08x\n", ks2);
|
||||
printf("\nKeystreams used to generate {ar_0} and {ar_1}:\n");
|
||||
ks2_0 = ar0_enc ^ ar0;
|
||||
printf(" ks2_0: %08x\n", ks2_0);
|
||||
ks2_1 = ar1_enc ^ ar1;
|
||||
printf(" ks2_1: %08x\n", ks2_1);
|
||||
|
||||
s = lfsr_recovery32(ar0_enc ^ p64, 0);
|
||||
s = lfsr_recovery32(ks2_0, 0);
|
||||
|
||||
for (t = s; t->odd | t->even; ++t) {
|
||||
lfsr_rollback_word(t, 0, 0);
|
||||
|
@ -67,7 +70,7 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
crypto1_word(t, uid ^ nt1, 0);
|
||||
crypto1_word(t, nr1_enc, 1);
|
||||
if (ar1_enc == (crypto1_word(t, 0, 0) ^ p64b)) {
|
||||
if (ks2_1 == crypto1_word(t, 0, 0)) {
|
||||
printf("\nFound Key: [%012" PRIx64 "]\n\n", key);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -60,14 +60,15 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
// Generate lfsr successors of the tag challenge
|
||||
printf("\nLFSR successors of the tag challenge:\n");
|
||||
uint32_t p64 = prng_successor(nt, 64);
|
||||
printf(" nt': %08x\n", p64);
|
||||
printf(" nt'': %08x\n", prng_successor(p64, 32));
|
||||
uint32_t ar = prng_successor(nt, 64);
|
||||
uint32_t at = prng_successor(ar, 32);
|
||||
printf(" ar: %08x\n", ar);
|
||||
printf(" at: %08x\n", at);
|
||||
|
||||
// Extract the keystream from the messages
|
||||
printf("\nKeystream used to generate {ar} and {at}:\n");
|
||||
ks2 = ar_enc ^ p64;
|
||||
ks3 = at_enc ^ prng_successor(p64, 32);
|
||||
printf("\nKeystreams used to generate {ar} and {at}:\n");
|
||||
ks2 = ar_enc ^ ar;
|
||||
ks3 = at_enc ^ at;
|
||||
printf(" ks2: %08x\n", ks2);
|
||||
printf(" ks3: %08x\n", ks3);
|
||||
|
||||
|
|
|
@ -19,8 +19,8 @@ Usage with sample trace:
|
|||
For mfkey32, you want to get two different NR_0/NR_1 values.
|
||||
|
||||
```
|
||||
# <uid> <nt> <nr_0> <ar_0> <nr_1> <ar_1>
|
||||
./mfkey32 52B0F519 5417D1F8 4D545EA7 E15AC8C2 DAC1A7F4 5AE5C37F
|
||||
# <uid> <nt> <{nr_0}> <{ar}_0> <{nr_1}> <{ar}_1>
|
||||
./mfkey32 57DA41DA 01200145 7B70C62C 909121F2 F9206A8B 908B8981
|
||||
```
|
||||
|
||||
For mfkey32v2 (moebius), you want to get two different NT/NT1 values. (like in the SIM commands)
|
||||
|
@ -83,8 +83,8 @@ Recovering key for:
|
|||
{enc8}: 9f9149ea
|
||||
|
||||
LFSR successors of the tag challenge:
|
||||
nt': 76d4468d
|
||||
nt'': d5f3c476
|
||||
ar: 76d4468d
|
||||
at: d5f3c476
|
||||
|
||||
Keystream used to generate {ar} and {at}:
|
||||
ks2: 73f18ec2
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue