diff --git a/configure.ac b/configure.ac index dd3d60f..8baa292 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([mfcuk], [0.3.1], [zveriu@gmail.com]) +AC_INIT([mfcuk], [0.3.2], [zveriu@gmail.com]) AC_CONFIG_MACRO_DIR([m4]) @@ -29,7 +29,7 @@ fi AC_PATH_PROG(PKG_CONFIG, pkg-config, [AC_MSG_WARN([pkg-config not found.])]) if test x"$WITH_NFC" = "x0"; then if test x"$PKG_CONFIG" != "x"; then - LIBNFC_REQUIRED_VERSION=1.3.9 + LIBNFC_REQUIRED_VERSION=1.4.2 PKG_CHECK_MODULES([LIBNFC], [libnfc >= $LIBNFC_REQUIRED_VERSION], [WITH_NFC=1], [WITH_NFC=0]) fi fi diff --git a/src/mfcuk_keyrecovery_darkside.c b/src/mfcuk_keyrecovery_darkside.c index 0316c71..aebf1e9 100644 --- a/src/mfcuk_keyrecovery_darkside.c +++ b/src/mfcuk_keyrecovery_darkside.c @@ -139,6 +139,7 @@ #include #include #include +#include #ifdef WIN32 #define NOMINMAX @@ -192,6 +193,11 @@ uint32_t numAuthAttempts = 0; // Number of authentication attempts for Recovery bool bfOpts[256] = {false}; // Command line options, indicates their presence, initialize with false byte_t verboseLevel = 0; // No verbose level by default +static const nfc_modulation_t nmMifare = { + .nmt = NMT_ISO14443A, + .nbr = NBR_106, +}; + int compareTagNonces (const void * a, const void * b) { // TODO: test the improvement (especially corner cases, over/under-flows) "return ( (*(uint32_t*)a) - (*(uint32_t*)b) ); @@ -243,7 +249,7 @@ uint32_t mfcuk_verify_key_block(nfc_device_t* pnd, uint32_t uiUID, uint64_t ui64 // Configure the authentication frame using the supplied block abtAuth[0] = bKeyType; abtAuth[1] = uiBlock; - append_iso14443a_crc(abtAuth,2); + iso14443a_crc_append(abtAuth,2); // Now we take over, first we need full control over the CRC if ( !nfc_configure(pnd,NDO_HANDLE_CRC,false) ) @@ -397,7 +403,7 @@ uint32_t mfcuk_key_recovery_block(nfc_device_t* pnd, uint32_t uiUID, uint64_t ui // Configure the authentication frame using the supplied block abtAuth[0] = bKeyType; abtAuth[1] = uiBlock; - append_iso14443a_crc(abtAuth,2); + iso14443a_crc_append(abtAuth,2); // Now we take over, first we need full control over the CRC nfc_configure(pnd,NDO_HANDLE_CRC,false); @@ -659,7 +665,7 @@ uint32_t mfcuk_key_recovery_block(nfc_device_t* pnd, uint32_t uiUID, uint64_t ui if ( bfOpts['v'] && (verboseLevel > 1) ) { - printf("\nINFO: block %d recovered KEY: %012llx\n", uiBlock, key_recovered); + printf("\nINFO: block %d recovered KEY: %012"PRIx64"\n", uiBlock, key_recovered); } flag_key_recovered = 1; @@ -842,7 +848,7 @@ bool mfcuk_darkside_reset_advanced(nfc_device_t* pnd) bool mfcuk_darkside_select_tag(nfc_device_t* pnd, int iSleepAtFieldOFF, int iSleepAfterFieldON, nfc_target_info_t* ti) { - nfc_target_info_t ti_tmp; + nfc_target_t ti_tmp; if ( !pnd || !ti ) { @@ -891,7 +897,7 @@ bool mfcuk_darkside_select_tag(nfc_device_t* pnd, int iSleepAtFieldOFF, int iSle sleep(iSleepAfterFieldON); // Poll for a ISO14443A (MIFARE) tag - if (!nfc_initiator_select_passive_target(pnd,NM_ISO14443A_106,NULL,0,&ti_tmp)) + if (!nfc_initiator_select_passive_target(pnd, nmMifare,NULL,0,&ti_tmp)) { ERR("connecting to MIFARE Classic tag"); //nfc_disconnect(pnd); @@ -929,7 +935,7 @@ int main(int argc, char* argv[]) // libnfc related nfc_device_t* pnd; - nfc_target_info_t ti; + nfc_target_t ti; // mifare and crapto related uint32_t uiErrCode = MFCUK_SUCCESS; @@ -1511,7 +1517,7 @@ int main(int argc, char* argv[]) printf("\nINFO: Connected to NFC reader: %s\n\n", pnd->acName); // Select tag and get tag info - if ( !mfcuk_darkside_select_tag(pnd, iSleepAtFieldOFF, iSleepAfterFieldON, &ti) ) + if ( !mfcuk_darkside_select_tag(pnd, iSleepAtFieldOFF, iSleepAfterFieldON, &ti.nti) ) { ERR("selecting tag on the reader %s", pnd->acName); nfc_disconnect(pnd); @@ -1521,25 +1527,25 @@ int main(int argc, char* argv[]) mfcuk_darkside_reset_advanced(pnd); // Tag on the reader type - tag_on_reader.type = ti.nai.btSak; - tag_on_reader.tag_basic.amb[0].mbm.btUnknown = ti.nai.btSak; + tag_on_reader.type = ti.nti.nai.btSak; + tag_on_reader.tag_basic.amb[0].mbm.btUnknown = ti.nti.nai.btSak; // No command line tag type specified, take it from the tag on the reader if ( !bfOpts['M'] ) { - tag_recover_verify.type = ti.nai.btSak; - tag_recover_verify.tag_basic.amb[0].mbm.btUnknown = ti.nai.btSak; + tag_recover_verify.type = ti.nti.nai.btSak; + tag_recover_verify.tag_basic.amb[0].mbm.btUnknown = ti.nti.nai.btSak; } // Tag on the reader UID - tag_on_reader.uid = bswap_32(*((uint32_t *) &(ti.nai.abtUid))); - memcpy( tag_on_reader.tag_basic.amb[0].mbm.abtUID, ti.nai.abtUid, MIFARE_CLASSIC_UID_BYTELENGTH); + tag_on_reader.uid = bswap_32(*((uint32_t *) &(ti.nti.nai.abtUid))); + memcpy( tag_on_reader.tag_basic.amb[0].mbm.abtUID, ti.nti.nai.abtUid, MIFARE_CLASSIC_UID_BYTELENGTH); // No command line tag UID specified, take it from the tag on the reader if ( !bfOpts['U'] ) { - tag_recover_verify.uid = bswap_32(*((uint32_t *) &(ti.nai.abtUid))); - memcpy( tag_recover_verify.tag_basic.amb[0].mbm.abtUID, ti.nai.abtUid, MIFARE_CLASSIC_UID_BYTELENGTH); + tag_recover_verify.uid = bswap_32(*((uint32_t *) &(ti.nti.nai.abtUid))); + memcpy( tag_recover_verify.tag_basic.amb[0].mbm.abtUID, ti.nti.nai.abtUid, MIFARE_CLASSIC_UID_BYTELENGTH); } if (bfOpts['v'] && (verboseLevel > 0)) @@ -1636,7 +1642,7 @@ int main(int argc, char* argv[]) memcpy(mp.mpa.abtUid, tag_recover_verify.tag_basic.amb[0].mbm.abtUID, MIFARE_CLASSIC_UID_BYTELENGTH); memcpy(mp.mpa.abtKey, &(current_default_keys[j][0]), MIFARE_CLASSIC_KEY_BYTELENGTH); - if ( !nfc_initiator_select_passive_target(pnd, NM_ISO14443A_106, NULL, 0, &ti) ) + if ( !nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &ti) ) { ERR("tag was removed or cannot be selected"); } @@ -1721,7 +1727,7 @@ int main(int argc, char* argv[]) // Recovery loop for current key-type of current sector do { - mfcuk_darkside_select_tag(pnd, iSleepAtFieldOFF, iSleepAfterFieldON, &ti); + mfcuk_darkside_select_tag(pnd, iSleepAtFieldOFF, iSleepAfterFieldON, &ti.nti); // Print usefull/useless info (sort-of "Let me entertain you!") if ( bfOpts['v'] && (verboseLevel > 2) ) @@ -1730,7 +1736,7 @@ int main(int argc, char* argv[]) printf("Let me entertain you!\n"); printf(" uid: %08x\n", tag_recover_verify.uid); printf(" type: %02x\n", tag_recover_verify.type); - printf(" key: %012llx\n", crntRecovKey); + printf(" key: %012"PRIx64"\n", crntRecovKey); printf(" block: %02x\n", block); printf("diff Nt: %d\n", numSpoofEntries); printf(" auths: %d\n", numAuthAttempts); diff --git a/src/mifare.c b/src/mifare.c index 28db72c..9afb082 100644 --- a/src/mifare.c +++ b/src/mifare.c @@ -25,7 +25,7 @@ bool nfc_initiator_mifare_cmd(nfc_device_t* pnd, const mifare_cmd mc, const uint byte_t abtCmd[265]; // Make sure we are dealing with a active device - if (!pnd->bActive) return false; + if (pnd == NULL) return false; abtCmd[0] = mc; // The MIFARE Classic command abtCmd[1] = ui8Block; // The block address (1K=0x00..0x39, 4K=0x00..0xff) diff --git a/src/nfc-utils.c b/src/nfc-utils.c index 33063c8..c24ed4b 100644 --- a/src/nfc-utils.c +++ b/src/nfc-utils.c @@ -126,13 +126,61 @@ void print_nfc_felica_info(const nfc_felica_info_t nfi) void print_nfc_iso14443b_info(const nfc_iso14443b_info_t nbi) { - printf(" ATQB: "); print_hex(nbi.abtAtqb,12); - printf(" ID: "); print_hex(nbi.abtId,4); - printf(" CID: %02x\n",nbi.btCid); - if (nbi.szInfLen>0) { - printf(" INF: "); print_hex(nbi.abtInf,nbi.szInfLen); +#define PI_ISO14443_4_SUPPORTED 0x01 +#define PI_NAD_SUPPORTED 0x01 +#define PI_CID_SUPPORTED 0x02 + //copied from libnfc r963 + bool verbose = true; + const int iMaxFrameSizes[] = { 16, 24, 32, 40, 48, 64, 96, 128, 256 }; + printf (" PUPI: "); + print_hex (nbi.abtPupi, 4); + printf (" Application Data: "); + print_hex (nbi.abtApplicationData, 4); + printf (" Protocol Info: "); + print_hex (nbi.abtProtocolInfo, 3); + if (verbose) { + printf ("* Bit Rate Capability:\n"); + if (nbi.abtProtocolInfo[0] == 0) { + printf (" * PICC supports only 106 kbits/s in both directions\n"); + } + if (nbi.abtProtocolInfo[0] & 1<<7) { + printf (" * Same bitrate in both directions mandatory\n"); + } + if (nbi.abtProtocolInfo[0] & 1<<4) { + printf (" * PICC to PCD, 1etu=64/fc, bitrate 212 kbits/s supported\n"); + } + if (nbi.abtProtocolInfo[0] & 1<<5) { + printf (" * PICC to PCD, 1etu=32/fc, bitrate 424 kbits/s supported\n"); + } + if (nbi.abtProtocolInfo[0] & 1<<6) { + printf (" * PICC to PCD, 1etu=16/fc, bitrate 847 kbits/s supported\n"); + } + if (nbi.abtProtocolInfo[0] & 1<<0) { + printf (" * PCD to PICC, 1etu=64/fc, bitrate 212 kbits/s supported\n"); + } + if (nbi.abtProtocolInfo[0] & 1<<1) { + printf (" * PCD to PICC, 1etu=32/fc, bitrate 424 kbits/s supported\n"); + } + if (nbi.abtProtocolInfo[0] & 1<<2) { + printf (" * PCD to PICC, 1etu=16/fc, bitrate 847 kbits/s supported\n"); + } + if (nbi.abtProtocolInfo[0] & 1<<3) { + printf (" * ERROR unknown value\n"); + } + if( (nbi.abtProtocolInfo[1] & 0xf0) <= 0x80 ) { + printf ("* Maximum frame sizes: %d bytes\n", iMaxFrameSizes[((nbi.abtProtocolInfo[1] & 0xf0) >> 4)]); + } + if((nbi.abtProtocolInfo[1] & 0x0f) == PI_ISO14443_4_SUPPORTED) { + printf ("* Protocol types supported: ISO/IEC 14443-4\n"); + } + printf ("* Frame Waiting Time: %.4g ms\n",256.0*16.0*(1<<((nbi.abtProtocolInfo[2] & 0xf0) >> 4))/13560.0); + if((nbi.abtProtocolInfo[2] & (PI_NAD_SUPPORTED|PI_CID_SUPPORTED)) != 0) { + printf ("* Frame options supported: "); + if ((nbi.abtProtocolInfo[2] & PI_NAD_SUPPORTED) != 0) printf ("NAD "); + if ((nbi.abtProtocolInfo[2] & PI_CID_SUPPORTED) != 0) printf ("CID "); + printf("\n"); + } } - printf(" PARAMS: %02x %02x %02x %02x\n",nbi.btParam1,nbi.btParam2,nbi.btParam3,nbi.btParam4); } /**