diff --git a/mfoc_fix_4k_and_mini.diff b/mfoc_fix_4k_and_mini.diff deleted file mode 100644 index c835ad2..0000000 --- a/mfoc_fix_4k_and_mini.diff +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/src/mfoc.c b/src/mfoc.c -index 32ef6f7..babbe15 100644 ---- a/src/mfoc.c -+++ b/src/mfoc.c -@@ -756,7 +756,7 @@ int main(int argc, char *const argv[]) - } - - // Finally save all keys + data to file -- uint16_t dump_size = (t.num_blocks + 1) * t.num_sectors; -+ uint16_t dump_size = (t.num_blocks + 1) * 16; - if (fwrite(&mtDump, 1, dump_size, pfDump) != dump_size) { - fprintf(stdout, "Error, cannot write dump\n"); - fclose(pfDump); diff --git a/mfoc_support_2k.diff b/mfoc_support_2k.diff deleted file mode 100644 index d41caac..0000000 --- a/mfoc_support_2k.diff +++ /dev/null @@ -1,153 +0,0 @@ -diff --git a/src/mfoc.c b/src/mfoc.c -index 469b138..ba11ce9 100644 ---- a/src/mfoc.c -+++ b/src/mfoc.c -@@ -56,6 +56,13 @@ - #include "slre.h" - #include "slre.c" - -+#define MAX_FRAME_LEN 264 -+ -+static const nfc_modulation nm = { -+.nmt = NMT_ISO14443A, -+.nbr = NBR_106, -+}; -+ - nfc_context *context; - - uint64_t knownKey = 0; -@@ -99,13 +106,8 @@ int32_t dist_nt(uint32_t nt1, uint32_t nt2) { - return(-99999); - } - -- - int main(int argc, char *const argv[]) - { -- const nfc_modulation nm = { -- .nmt = NMT_ISO14443A, -- .nbr = NBR_106, -- }; - - int ch, i, k, n, j, m; - int key, block; -@@ -321,9 +323,15 @@ int main(int argc, char *const argv[]) - case 0x01: - case 0x08: - case 0x88: -- printf("Found Mifare Classic 1k tag\n"); -- t.num_sectors = NR_TRAILERS_1k; -- t.num_blocks = NR_BLOCKS_1k; -+ if (get_rats_is_2k(t, r)) { -+ printf("Found Mifare Plus 2k tag\n"); -+ t.num_sectors = NR_TRAILERS_2k; -+ t.num_blocks = NR_BLOCKS_2k; -+ } else { -+ printf("Found Mifare Classic 1k tag\n"); -+ t.num_sectors = NR_TRAILERS_1k; -+ t.num_blocks = NR_BLOCKS_1k; -+ } - break; - case 0x09: - printf("Found Mifare Classic Mini tag\n"); -@@ -858,11 +866,6 @@ void mf_configure(nfc_device *pdi) - - void mf_select_tag(nfc_device *pdi, nfc_target *pnt) - { -- // Poll for a ISO14443A (MIFARE) tag -- const nfc_modulation nm = { -- .nmt = NMT_ISO14443A, -- .nbr = NBR_106, -- }; - if (nfc_initiator_select_passive_target(pdi, nm, NULL, 0, pnt) < 0) { - ERR("Unable to connect to the MIFARE Classic tag"); - nfc_close(pdi); -@@ -905,10 +908,6 @@ int find_exploit_sector(mftag t) - - void mf_anticollision(mftag t, mfreader r) - { -- const nfc_modulation nm = { -- .nmt = NMT_ISO14443A, -- .nbr = NBR_106, -- }; - if (nfc_initiator_select_passive_target(r.pdi, nm, NULL, 0, &t.nt) < 0) { - nfc_perror(r.pdi, "nfc_initiator_select_passive_target"); - ERR("Tag has been removed"); -@@ -916,6 +915,48 @@ void mf_anticollision(mftag t, mfreader r) - } - } - -+ -+bool -+get_rats_is_2k(mftag t, mfreader r) -+{ -+ int res; -+ uint8_t abtRx[MAX_FRAME_LEN]; -+ int szRxBits; -+ uint8_t abtRats[2] = { 0xe0, 0x50}; -+ // Use raw send/receive methods -+ if (nfc_device_set_property_bool(r.pdi, NP_EASY_FRAMING, false) < 0) { -+ nfc_perror(r.pdi, "nfc_configure"); -+ return false; -+ } -+ res = nfc_initiator_transceive_bytes(r.pdi, abtRats, sizeof(abtRats), abtRx, sizeof(abtRx), 0); -+ if (res > 0) { -+ // ISO14443-4 card, turn RF field off/on to access ISO14443-3 again -+ if (nfc_device_set_property_bool(r.pdi, NP_ACTIVATE_FIELD, false) < 0) { -+ nfc_perror(r.pdi, "nfc_configure"); -+ return false; -+ } -+ if (nfc_device_set_property_bool(r.pdi, NP_ACTIVATE_FIELD, true) < 0) { -+ nfc_perror(r.pdi, "nfc_configure"); -+ return false; -+ } -+ } -+ // Reselect tag -+ if (nfc_initiator_select_passive_target(r.pdi, nm, NULL, 0, &t.nt) <= 0) { -+ printf("Error: tag disappeared\n"); -+ nfc_close(r.pdi); -+ nfc_exit(context); -+ exit(EXIT_FAILURE); -+ } -+ if (res >= 10) { -+ printf("ATS %02X%02X%02X%02X%02X|%02X%02X%02X%02X\n", res, abtRx[0], abtRx[1], abtRx[2], abtRx[3], abtRx[4], abtRx[5], abtRx[6], abtRx[7], abtRx[8]); -+ return ((abtRx[5] == 0xc1) && (abtRx[6] == 0x05) -+ && (abtRx[7] == 0x2f) && (abtRx[8] == 0x2f) -+ && ((t.nt.nti.nai.abtAtqa[1] & 0x02) == 0x00)); -+ } else { -+ return false; -+ } -+} -+ - int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d, pKeys *pk, char mode, bool dumpKeysA) - { - struct Crypto1State *pcs; -diff --git a/src/mfoc.h b/src/mfoc.h -index 532e834..9ea7547 100644 ---- a/src/mfoc.h -+++ b/src/mfoc.h -@@ -8,6 +8,8 @@ - #define NR_TRAILERS_MINI (5) - // Mifare Classic 4k 32x64b + 8*256b = 40 - #define NR_TRAILERS_4k (40) -+// Mifare Classic 2k 32x64b -+#define NR_TRAILERS_2k (32) - - // Number of blocks - // Mifare Classic 1k -@@ -16,6 +18,8 @@ - #define NR_BLOCKS_MINI 0x13 - // Mifare Classic 4k - #define NR_BLOCKS_4k 0xff -+// Mifare Classic 2k -+#define NR_BLOCKS_2k 0x7f - - #define MAX_FRAME_LEN 264 - -@@ -85,6 +89,7 @@ void mf_select_tag(nfc_device *pdi, nfc_target *pnt); - int trailer_block(uint32_t block); - int find_exploit_sector(mftag t); - void mf_anticollision(mftag t, mfreader r); -+bool get_rats_is_2k(mftag t, mfreader r); - int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d, pKeys *pk, char mode, bool dumpKeysA); - uint32_t median(denonce d); - int compar_int(const void *a, const void *b); diff --git a/mfoc_support_tnp.diff b/mfoc_support_tnp.diff deleted file mode 100644 index f00bdf9..0000000 --- a/mfoc_support_tnp.diff +++ /dev/null @@ -1,21 +0,0 @@ -diff --git a/src/mfoc.c b/src/mfoc.c -index 2c06b16..469b138 100644 ---- a/src/mfoc.c -+++ b/src/mfoc.c -@@ -307,7 +307,7 @@ int main(int argc, char *const argv[]) - } - - // Test if a compatible MIFARE tag is used -- if ((t.nt.nti.nai.btSak & 0x08) == 0) { -+ if (((t.nt.nti.nai.btSak & 0x08) == 0) && (t.nt.nti.nai.btSak != 0x01)) { - ERR("only Mifare Classic is supported"); - goto error; - } -@@ -318,6 +318,7 @@ int main(int argc, char *const argv[]) - // see http://www.nxp.com/documents/application_note/AN10833.pdf Section 3.2 - switch (t.nt.nti.nai.btSak) - { -+ case 0x01: - case 0x08: - case 0x88: - printf("Found Mifare Classic 1k tag\n"); diff --git a/mfoc_test_prng.diff b/mfoc_test_prng.diff deleted file mode 100644 index 3a44c5e..0000000 --- a/mfoc_test_prng.diff +++ /dev/null @@ -1,160 +0,0 @@ -diff --git a/src/mfoc.c b/src/mfoc.c -index 32ef6f7..889669d 100644 ---- a/src/mfoc.c -+++ b/src/mfoc.c -@@ -58,6 +58,48 @@ - - nfc_context *context; - -+uint64_t knownKey = 0; -+char knownKeyLetter = 'A'; -+uint32_t knownSector = 0; -+uint32_t unknownSector = 0; -+char unknownKeyLetter = 'A'; -+uint32_t unexpected_random = 0; -+ -+// Determine the distance between two nonces. -+// Assume that the difference is small, but we don't know which is first. -+// Therefore try in alternating directions. -+int32_t dist_nt(uint32_t nt1, uint32_t nt2) { -+ -+ if (nt1 == nt2) return 0; -+ -+ uint16_t i; -+ uint32_t nttmp1 = nt1; -+ uint32_t nttmp2 = nt2; -+ -+ for (i = 1; i < (32768/8); ++i) { -+ nttmp1 = prng_successor(nttmp1, 1); if (nttmp1 == nt2) return i; -+ nttmp2 = prng_successor(nttmp2, 1); if (nttmp2 == nt1) return -i; -+ -+ nttmp1 = prng_successor(nttmp1, 1); if (nttmp1 == nt2) return i+1; -+ nttmp2 = prng_successor(nttmp2, 1); if (nttmp2 == nt1) return -(i+1); -+ nttmp1 = prng_successor(nttmp1, 1); if (nttmp1 == nt2) return i+2; -+ nttmp2 = prng_successor(nttmp2, 1); if (nttmp2 == nt1) return -(i+2); -+ nttmp1 = prng_successor(nttmp1, 1); if (nttmp1 == nt2) return i+3; -+ nttmp2 = prng_successor(nttmp2, 1); if (nttmp2 == nt1) return -(i+3); -+ nttmp1 = prng_successor(nttmp1, 1); if (nttmp1 == nt2) return i+4; -+ nttmp2 = prng_successor(nttmp2, 1); if (nttmp2 == nt1) return -(i+4); -+ nttmp1 = prng_successor(nttmp1, 1); if (nttmp1 == nt2) return i+5; -+ nttmp2 = prng_successor(nttmp2, 1); if (nttmp2 == nt1) return -(i+5); -+ nttmp1 = prng_successor(nttmp1, 1); if (nttmp1 == nt2) return i+6; -+ nttmp2 = prng_successor(nttmp2, 1); if (nttmp2 == nt1) return -(i+6); -+ nttmp1 = prng_successor(nttmp1, 1); if (nttmp1 == nt2) return i+7; -+ nttmp2 = prng_successor(nttmp2, 1); if (nttmp2 == nt1) return -(i+7); -+ } -+ // either nt1 or nt2 are invalid nonces -+ return(-99999); -+} -+ -+ - int main(int argc, char *const argv[]) - { - const nfc_modulation nm = { -@@ -117,6 +159,7 @@ int main(int argc, char *const argv[]) - - mifare_cmd mc; - FILE *pfDump = NULL; -+ FILE *pfKey = NULL; - - //File pointers for the keyfile - FILE * fp; -@@ -200,6 +243,14 @@ int main(int argc, char *const argv[]) - } - // fprintf(stdout, "Output file: %s\n", optarg); - break; -+ case 'D': -+ // Partial File output -+ if (!(pfKey = fopen(optarg, "w"))) { -+ fprintf(stderr, "Cannot open: %s, exiting\n", optarg); -+ exit(EXIT_FAILURE); -+ } -+ // fprintf(stdout, "Output file: %s\n", optarg); -+ break; - case 'h': - usage(stdout, 0); - break; -@@ -421,14 +472,28 @@ int main(int argc, char *const argv[]) - - fprintf(stdout, "\n"); - for (i = 0; i < (t.num_sectors); ++i) { -- if(t.sectors[i].foundKeyA) -+ if(t.sectors[i].foundKeyA){ - fprintf(stdout, "Sector %02d - Found Key A: %012llx ", i, bytes_to_num(t.sectors[i].KeyA, sizeof(t.sectors[i].KeyA))); -- else -+ memcpy(&knownKey, t.sectors[i].KeyA, 6); -+ knownKeyLetter = 'A'; -+ knownSector = i; -+ } -+ else{ - fprintf(stdout, "Sector %02d - Unknown Key A ", i); -- if(t.sectors[i].foundKeyB) -+ unknownSector = i; -+ unknownKeyLetter = 'A'; -+ } -+ if(t.sectors[i].foundKeyB){ - fprintf(stdout, "Found Key B: %012llx\n", bytes_to_num(t.sectors[i].KeyB, sizeof(t.sectors[i].KeyB))); -- else -+ knownKeyLetter = 'B'; -+ memcpy(&knownKey, t.sectors[i].KeyB, 6); -+ knownSector = i; -+ } -+ else{ - fprintf(stdout, "Unknown Key B\n"); -+ unknownSector = i; -+ unknownKeyLetter = 'B'; -+ } - } - fflush(stdout); - -@@ -504,7 +569,18 @@ int main(int argc, char *const argv[]) - // Max probes for auth for each sector - for (k = 0; k < probes; ++k) { - // Try to authenticate to exploit sector and determine distances (filling denonce.distances) -- mf_enhanced_auth(e_sector, 0, t, r, &d, pk, 'd', dumpKeysA); // AUTH + Get Distances mode -+ int authresult = mf_enhanced_auth(e_sector, 0, t, r, &d, pk, 'd', dumpKeysA); // AUTH + Get Distances mode -+ if(authresult == -99999){ -+ //for now we return the last sector that is unknown -+ nfc_close(r.pdi); -+ nfc_exit(context); -+ if(pfKey) { -+ fprintf(pfKey, "%012llx;%d;%c;%d;%c", knownKey, knownSector, knownKeyLetter, unknownSector, unknownKeyLetter); -+ fclose(pfKey); -+ } -+ return 9; -+ } -+ - printf("Sector: %d, type %c, probe %d, distance %d ", j, (dumpKeysA ? 'A' : 'B'), k, d.median); - // Configure device to the previous state - mf_configure(r.pdi); -@@ -720,6 +796,7 @@ void usage(FILE *stream, int errno) - fprintf(stream, " T nonce tolerance half-range, instead of default of 20\n (i.e., 40 for the total range, in both directions)\n"); - // fprintf(stream, " s specify the list of sectors to crack, for example -s 0,1,3,5\n"); - fprintf(stream, " O file in which the card contents will be written (REQUIRED)\n"); -+ fprintf(stream, " D file in which partial card info will be written in case PRNG is not vulnerable\n"); - fprintf(stream, "\n"); - fprintf(stream, "Example: mfoc -O mycard.mfd\n"); - fprintf(stream, "Example: mfoc -k ffffeeeedddd -O mycard.mfd\n"); -@@ -979,7 +1056,21 @@ int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d - - // Save the determined nonces distance - d->distances[m] = nonce_distance(Nt, NtLast); -- // fprintf(stdout, "distance: %05d\n", d->distances[m]); -+ int checkForValidPRNG = dist_nt(Nt, NtLast); -+ //printf("NT distance: %d\n", checkForValidPRNG); -+ -+ // if no distance between, then we are in sync. -+ if (checkForValidPRNG == 0) { -+ printf("NT Distance is zero..........\n"); -+ } else { -+ if (checkForValidPRNG == -99999) { // invalid nonce received -+ ++unexpected_random; -+ if (unexpected_random > 4) { -+ printf("PRNG is not vulnerable to nested attack\n"); -+ return -99999; -+ } -+ } -+ } - - // Again, prepare and send {At} - for (i = 0; i < 4; i++) { diff --git a/miLazyCrackerFreshInstall.sh b/miLazyCrackerFreshInstall.sh index e580cc5..54cc1f3 100755 --- a/miLazyCrackerFreshInstall.sh +++ b/miLazyCrackerFreshInstall.sh @@ -12,11 +12,7 @@ sudo apt-get install git libnfc-bin autoconf libnfc-dev cd mfoc || exit 1 git reset --hard git clean -dfx - # patch initially done against commit 48156f9b: - patch -p1 < ../mfoc_test_prng.diff - patch -p1 < ../mfoc_fix_4k_and_mini.diff - patch -p1 < ../mfoc_support_tnp.diff - patch -p1 < ../mfoc_support_2k.diff + # tested against commit 9d9f01fb autoreconf -vfi ./configure make