]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
Adds random nonce (r) option to `hf mf sim`.
authorMichael Farrell <micolous+git@gmail.com>
Thu, 26 Jan 2017 07:16:10 +0000 (18:16 +1100)
committerMichael Farrell <micolous+git@gmail.com>
Thu, 26 Jan 2017 07:32:25 +0000 (18:32 +1100)
This makes the PM3 generate pseudo-random nonces rather than sequential
nonces, to make it act a bit more like a "real" MFC card.  A reader would
otherwise be able to detect the PM3 probing based on the predictable nonces
and throw different authentication challenges (or refuse to authenticate at
all).

The code includes an implementation of a rand-like function (prand), similar
to the one from libc, which is seeded automatically based on the time it
takes between the PM3 starting up and the first call to the RNG.

This isn't cryptographically random, but should be "good enough" to be able
to evade basic detection.

armsrc/iso14443a.c
armsrc/util.c
armsrc/util.h
client/cmdhfmf.c
include/usb_cmd.h

index 70dc54f17a39495cb8e374807015c3f2ce53aa63..07bbd37d3c8406c84e4fbb49fc7416e10c494563 100644 (file)
@@ -2329,6 +2329,7 @@ typedef struct {
   * FLAG_7B_UID_IN_DATA - means that there is a 7-byte UID in the data-section, we're expected to use that
   * FLAG_10B_UID_IN_DATA       - use 10-byte UID in the data-section not finished
   *    FLAG_NR_AR_ATTACK  - means we should collect NR_AR responses for bruteforcing later
+  * FLAG_RANDOM_NONCE - means we should generate some pseudo-random nonce data
   *@param exitAfterNReads, exit simulation after n blocks have been read, 0 is infinite ...
   * (unless reader attack mode enabled then it runs util it gets enough nonces to recover all keys attmpted)
   */
@@ -2387,7 +2388,12 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
        uint8_t mM = 0; //moebius_modifier for collection storage
 
        // Authenticate response - nonce
-       uint32_t nonce = bytes_to_num(rAUTH_NT, 4);
+       uint32_t nonce;
+       if (flags & FLAG_RANDOM_NONCE) {
+               nonce = prand();
+       } else {
+               nonce = bytes_to_num(rAUTH_NT, 4);
+       }
        
        //-- Determine the UID
        // Can be set from emulator memory, incoming data
@@ -2535,6 +2541,11 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                        LED_C_OFF();
                        crypto1_destroy(pcs);
                        cardAUTHKEY = 0xff;
+                       if (flags & FLAG_RANDOM_NONCE) {
+                               nonce = prand();
+                       } else {
+                               nonce++;
+                       }
                        continue;
                }
                
@@ -2656,7 +2667,11 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
                                                                                                // switch to moebius collection
                                                                                                gettingMoebius = true;
                                                                                                mM = ATTACK_KEY_COUNT;
-                                                                                               nonce = nonce*7;
+                                                                                               if (flags & FLAG_RANDOM_NONCE) {
+                                                                                                       nonce = prand();
+                                                                                               } else {
+                                                                                                       nonce = nonce*7;
+                                                                                               }
                                                                                                break;
                                                                                        }
                                                                                } else {
index 1dd8dc7544fe1cb2989548692f8449f19b6ca621..be41bad8aa2a351a8d9ef059aecc1e6104921c2a 100644 (file)
@@ -431,3 +431,19 @@ uint32_t RAMFUNC GetCountSspClk(){
        }
 }
 
+static uint64_t next_random = 1;
+
+/* Generates a (non-cryptographically secure) 32-bit random number.
+ *
+ * We don't have an implementation of the "rand" function or a clock to seed it
+ * with, so we just call GetTickCount the first time to seed ourselves.
+ */
+uint32_t prand() {
+       if (next_random == 1) {
+               next_random = GetTickCount();
+       }
+
+       next_random = next_random * 6364136223846793005 + 1;
+       return (uint32_t)(next_random >> 32) % 0xffffffff;
+}
+
index bf5d0cc81fc01477ea2526379948a71b5ce470dd..e919764bcc5a4cbac14081ae233557cd93fb46ea 100644 (file)
@@ -54,4 +54,6 @@ uint32_t RAMFUNC GetDeltaCountUS();
 void StartCountSspClk();
 uint32_t RAMFUNC GetCountSspClk();
 
+uint32_t prand();
+
 #endif
index 36c8e6c370eb121fab1ecb8c0b6027b210b640ad..2b14c763131cabba96e5ba5a03db3b35df6e1013 100644 (file)
@@ -1100,6 +1100,7 @@ int usage_hf14_mf1ksim(void) {
        PrintAndLog("      x    (Optional) Crack, performs the 'reader attack', nr/ar attack against a legitimate reader, fishes out the key(s)");\r
        PrintAndLog("      e    (Optional) set keys found from 'reader attack' to emulator memory (implies x and i)");\r
        PrintAndLog("      f    (Optional) get UIDs to use for 'reader attack' from file 'f <filename.txt>' (implies x and i)");\r
+       PrintAndLog("      r    (Optional) Generate random nonces instead of sequential nonces.");\r
        PrintAndLog("samples:");\r
        PrintAndLog("           hf mf sim u 0a0a0a0a");\r
        PrintAndLog("           hf mf sim u 11223344556677");\r
@@ -1164,6 +1165,11 @@ int CmdHF14AMf1kSim(const char *Cmd) {
                        exitAfterNReads = param_get8(Cmd, pnr+1);\r
                        cmdp += 2;\r
                        break;\r
+               case 'r':\r
+               case 'R':\r
+                       flags |= FLAG_RANDOM_NONCE;\r
+                       cmdp++;\r
+                       break;\r
                case 'u':\r
                case 'U':\r
                        param_gethex_ex(Cmd, cmdp+1, uid, &uidlen);\r
index 66e6cf91cea3529422532a746d8ac2185eee993d..16d1c5ddeb2aea165197b993d7b66870b443a4a3 100644 (file)
@@ -217,6 +217,7 @@ typedef struct{
 #define FLAG_7B_UID_IN_DATA   0x04
 #define FLAG_10B_UID_IN_DATA  0x08
 #define FLAG_NR_AR_ATTACK     0x10
+#define FLAG_RANDOM_NONCE     0x20
 
 
 //Iclass reader flags
Impressum, Datenschutz