diff --git a/0001-Add-support-for-MFP-2k.patch b/0001-Add-support-for-MFP-2k.patch new file mode 100644 index 0000000..eed008f --- /dev/null +++ b/0001-Add-support-for-MFP-2k.patch @@ -0,0 +1,185 @@ +From 3d1b6407322ea29114cf15b243dd782bd5afec8a Mon Sep 17 00:00:00 2001 +From: Clark Kent +Date: Tue, 24 Jan 2017 08:51:52 +0100 +Subject: [PATCH 1/2] Add support for MFP 2k + +--- + mfoc_support_2k.diff | 153 +++++++++++++++++++++++++++++++++++++++++++ + miLazyCrackerFreshInstall.sh | 1 + + 2 files changed, 154 insertions(+) + create mode 100644 mfoc_support_2k.diff + +diff --git a/mfoc_support_2k.diff b/mfoc_support_2k.diff +new file mode 100644 +index 0000000..d41caac +--- /dev/null ++++ b/mfoc_support_2k.diff +@@ -0,0 +1,153 @@ ++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/miLazyCrackerFreshInstall.sh b/miLazyCrackerFreshInstall.sh +index 0b02392..b3ae19e 100755 +--- a/miLazyCrackerFreshInstall.sh ++++ b/miLazyCrackerFreshInstall.sh +@@ -15,6 +15,7 @@ git clean -dfx + 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 + autoreconf -vfi + ./configure + make +-- +2.11.0 + diff --git a/0002-shellcheck.patch b/0002-shellcheck.patch new file mode 100644 index 0000000..83d67ea --- /dev/null +++ b/0002-shellcheck.patch @@ -0,0 +1,117 @@ +From 4bda59ac314d216d134225d475ad241fc465c2a2 Mon Sep 17 00:00:00 2001 +From: Clark Kent +Date: Tue, 24 Jan 2017 09:05:02 +0100 +Subject: [PATCH 2/2] shellcheck + +--- + miLazyCracker.sh | 10 ++++----- + miLazyCrackerFreshInstall.sh | 51 ++++++++++++++++++++++---------------------- + 2 files changed, 31 insertions(+), 30 deletions(-) + +diff --git a/miLazyCracker.sh b/miLazyCracker.sh +index c0677a2..a284ac7 100755 +--- a/miLazyCracker.sh ++++ b/miLazyCracker.sh +@@ -21,12 +21,12 @@ while [ $keepTrying -eq 1 ]; do + echo "MFOC not possible, detected hardened Mifare Classic" + if [ "$mfocResult" -eq 9 ]; then + count=0 +- while read LINE; do ++ while read -r LINE; do + let count++ + #echo "$count $LINE" + done < "$TMPFILE_UNK" + +- arr=(`echo $LINE | tr ';' ' '`) ++ arr=($(echo "$LINE" | tr ';' ' ')) + #echo ${arr[0]} + #echo ${arr[1]} + #echo ${arr[2]} +@@ -38,8 +38,8 @@ while [ $keepTrying -eq 1 ]; do + knownKeyLetter=${arr[2]} + unknownSectorNum=${arr[3]} + unknownKeyLetter=${arr[4]} +- knownBlockNum=$(($knownSectorNum * 4)) +- unknownBlockNum=$(($unknownSectorNum * 4)) ++ knownBlockNum=$((knownSectorNum * 4)) ++ unknownBlockNum=$((unknownSectorNum * 4)) + echo "Trying HardNested Attack..." + mycmd=(libnfc_crypto1_crack "$knownKey" "$knownBlockNum" "$knownKeyLetter" "$unknownBlockNum" "$unknownKeyLetter" "$TMPFILE_FND") + echo "${mycmd[@]}" +@@ -51,7 +51,7 @@ while [ $keepTrying -eq 1 ]; do + + cryptoCrackResult=$? + if [ "$cryptoCrackResult" -eq 0 ];then +- while read LINE ++ while read -r LINE + do + echo "$LINE" + done < "$TMPFILE_FND" +diff --git a/miLazyCrackerFreshInstall.sh b/miLazyCrackerFreshInstall.sh +index b3ae19e..e580cc5 100755 +--- a/miLazyCrackerFreshInstall.sh ++++ b/miLazyCrackerFreshInstall.sh +@@ -8,34 +8,35 @@ sudo apt-get install git libnfc-bin autoconf libnfc-dev + + # install MFOC + [ -d mfoc ] || git clone https://github.com/nfc-tools/mfoc.git +-cd mfoc +-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 +-autoreconf -vfi +-./configure +-make +-sudo make install +- +-cd .. ++( ++ 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 ++ autoreconf -vfi ++ ./configure ++ make ++ sudo make install ++) + + # install Hardnested Attack Tool + [ -d crypto1_bs ] || git clone https://github.com/aczid/crypto1_bs +-cd crypto1_bs +-git reset --hard +-git clean -dfx +-# patch initially done against commit 957702be: +-patch -p1 < ../crypto1_bs.diff +-make get_craptev1 +-make get_crapto1 +-make +-sudo cp -a libnfc_crypto1_crack /usr/local/bin +- +-cd .. ++( ++ cd crypto1_bs || exit 1 ++ git reset --hard ++ git clean -dfx ++ # patch initially done against commit 957702be: ++ patch -p1 < ../crypto1_bs.diff ++ make get_craptev1 ++ make get_crapto1 ++ make ++ sudo cp -a libnfc_crypto1_crack /usr/local/bin ++) + + # install our script + sudo cp -a miLazyCracker.sh /usr/local/bin/miLazyCracker ++echo "Done." +-- +2.11.0 + diff --git a/miLazyCracker.sh b/miLazyCracker.sh index a284ac7..175a313 100755 --- a/miLazyCracker.sh +++ b/miLazyCracker.sh @@ -1,5 +1,46 @@ #!/bin/bash +# This is a general-purpose function to ask Yes/No questions in Bash, either +# with or without a default answer. It keeps repeating the question until it +# gets a valid answer. + +ask() { + # http://djm.me/ask + local prompt default REPLY + + while true; do + + if [ "${2:-}" = "Y" ]; then + prompt="Y/n" + default=Y + elif [ "${2:-}" = "N" ]; then + prompt="y/N" + default=N + else + prompt="y/n" + default= + fi + + # Ask the question (not using "read -p" as it uses stderr not stdout) + echo -n "$1 [$prompt] " + + # Read the answer (use /dev/tty in case stdin is redirected from somewhere else) + read REPLY