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.
* 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_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)
*/
*@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)
*/
uint8_t mM = 0; //moebius_modifier for collection storage
// Authenticate response - nonce
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
//-- Determine the UID
// Can be set from emulator memory, incoming data
LED_C_OFF();
crypto1_destroy(pcs);
cardAUTHKEY = 0xff;
LED_C_OFF();
crypto1_destroy(pcs);
cardAUTHKEY = 0xff;
+ if (flags & FLAG_RANDOM_NONCE) {
+ nonce = prand();
+ } else {
+ nonce++;
+ }
// switch to moebius collection
gettingMoebius = true;
mM = ATTACK_KEY_COUNT;
// switch to moebius collection
gettingMoebius = true;
mM = ATTACK_KEY_COUNT;
+ if (flags & FLAG_RANDOM_NONCE) {
+ nonce = prand();
+ } else {
+ nonce = nonce*7;
+ }
+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;
+}
+
void StartCountSspClk();
uint32_t RAMFUNC GetCountSspClk();
void StartCountSspClk();
uint32_t RAMFUNC GetCountSspClk();
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(" 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
PrintAndLog("samples:");\r
PrintAndLog(" hf mf sim u 0a0a0a0a");\r
PrintAndLog(" hf mf sim u 11223344556677");\r
exitAfterNReads = param_get8(Cmd, pnr+1);\r
cmdp += 2;\r
break;\r
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
case 'u':\r
case 'U':\r
param_gethex_ex(Cmd, cmdp+1, uid, &uidlen);\r
#define FLAG_7B_UID_IN_DATA 0x04
#define FLAG_10B_UID_IN_DATA 0x08
#define FLAG_NR_AR_ATTACK 0x10
#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