From 2491a25235fc97c043f81399d9d2f06fc50d886e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 21 May 2015 23:17:01 +0200 Subject: [PATCH] FIX; the "L" optional parameter for swapping endianess on used authentication key. It is now implemented for following commands. "HF MFU INFO" "HF MFU DUMP" "HF MFU RDBL" "HF MFU WRBL" CHG; I commented away the option to add the key to the dump, since it is not written in big-endian, like the data is on ULC. This needs to be addressed before it comes back. I like the idea of having keys inside the dumps on the correct places. --- client/cmdhfmfu.c | 140 +++++++++++++++++++++++++--------------------- 1 file changed, 77 insertions(+), 63 deletions(-) diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 147bbb92..1192ae70 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -576,7 +576,7 @@ uint32_t GetHF14AMfU_Type(void){ } case 0x01: tagtype = UL_C; break; case 0x00: tagtype = UL; break; - case -1 : tagtype = (UL | UL_C | NTAG_203); break; //when does this happen? -- if getversion fails, it assumes it is either UL/ULC -- but why? magic tags? + case -1 : tagtype = (UL | UL_C | NTAG_203); break; // could be UL | UL_C magic tags default : tagtype = UNKNOWN; break; } // UL vs UL-C vs ntag203 test @@ -600,7 +600,7 @@ uint32_t GetHF14AMfU_Type(void){ tagtype = UL; } else { // read page 0x30 (should error if it is a ntag203) - status = ul_read(30, data, sizeof(data)); + status = ul_read(0x30, data, sizeof(data)); if ( status <= 1 ){ tagtype = NTAG_203; } else { @@ -631,14 +631,16 @@ int CmdHF14AMfUInfo(const char *Cmd){ uint8_t authlim = 0xff; uint8_t data[16] = {0x00}; iso14a_card_select_t card; - uint8_t *key; int status; bool errors = false; bool hasAuthKey = false; bool locked = false; + bool swapEndian = false; uint8_t cmdp = 0; uint8_t datalen = 0; - uint8_t authenticationkey[16] = {0x00}; + uint8_t authenticationkey[16] = {0x00}; + uint8_t *authkeyptr = authenticationkey; + uint8_t *key; uint8_t pack[4] = {0,0,0,0}; int len = 0; @@ -657,6 +659,7 @@ int CmdHF14AMfUInfo(const char *Cmd){ memcpy(authenticationkey, data, 4); cmdp += 2; hasAuthKey = true; + datalen = 4; break; } // UL-C size key @@ -665,10 +668,16 @@ int CmdHF14AMfUInfo(const char *Cmd){ memcpy(authenticationkey, data, 16); cmdp += 2; hasAuthKey = true; + datalen = 16; break; } errors = true; break; + case 'l': + case 'L': + swapEndian = true; + cmdp++; + break; default: PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; @@ -687,7 +696,10 @@ int CmdHF14AMfUInfo(const char *Cmd){ PrintAndLog("-------------------------------------------------------------"); ul_print_type(tagtype, 6); - if (!ul_auth_select( &card, tagtype, hasAuthKey, authenticationkey, pack, sizeof(pack))) return -1; + // Swap endianness + if (swapEndian && hasAuthKey) authkeyptr = SwapEndian64(authenticationkey, datalen, (datalen == 16) ? 8 : 4 ); + + if (!ul_auth_select( &card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1; // read pages 0,1,2,3 (should read 4pages) status = ul_read(0, data, sizeof(data)); @@ -741,11 +753,10 @@ int CmdHF14AMfUInfo(const char *Cmd){ uint8_t keySwap[16]; memcpy(keySwap, SwapEndian64(key,16,8), 16); ulc_print_3deskey(keySwap); - break; + return 1; } } - // reselect for future tests (ntag test) - if (!ul_auth_select( &card, tagtype, hasAuthKey, authenticationkey, pack, sizeof(pack))) return -1; + return 1; } } @@ -755,7 +766,7 @@ int CmdHF14AMfUInfo(const char *Cmd){ if ((tagtype & (UL_EV1_48 | UL_EV1_128))) { if (ulev1_print_counters() != 3) { // failed - re-select - if (!ul_auth_select( &card, tagtype, hasAuthKey, authenticationkey, pack, sizeof(pack))) return -1; + if (!ul_auth_select( &card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1; } } @@ -770,7 +781,7 @@ int CmdHF14AMfUInfo(const char *Cmd){ if (status == 32) ulev1_print_signature( ulev1_signature, sizeof(ulev1_signature)); else { // re-select - if (!ul_auth_select( &card, tagtype, hasAuthKey, authenticationkey, pack, sizeof(pack))) return -1; + if (!ul_auth_select( &card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1; } } @@ -785,7 +796,7 @@ int CmdHF14AMfUInfo(const char *Cmd){ ulev1_print_version(version); } else { locked = true; - if (!ul_auth_select( &card, tagtype, hasAuthKey, authenticationkey, pack, sizeof(pack))) return -1; + if (!ul_auth_select( &card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1; } uint8_t startconfigblock = 0; @@ -822,7 +833,7 @@ int CmdHF14AMfUInfo(const char *Cmd){ PrintAndLog("Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]); break; } else { - if (!ul_auth_select( &card, tagtype, hasAuthKey, authenticationkey, pack, sizeof(pack))) return -1; + if (!ul_auth_select( &card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1; } } if (len < 1) PrintAndLog("password not known"); @@ -851,7 +862,7 @@ int CmdHF14AMfUWrBl(const char *Cmd){ uint8_t blockdata[20] = {0x00}; uint8_t data[16] = {0x00}; uint8_t authenticationkey[16] = {0x00}; - uint8_t *keyPtr = authenticationkey; + uint8_t *authkeyptr = authenticationkey; // starting with getting tagtype TagTypeUL_t tagtype = GetHF14AMfU_Type(); @@ -931,8 +942,9 @@ int CmdHF14AMfUWrBl(const char *Cmd){ if ( blockNo == -1 ) return usage_hf_mfu_wrbl(); // Swap endianness - if (swapEndian && hasAuthKey) keyPtr = SwapEndian64(authenticationkey, 16, 8); - if (swapEndian && hasPwdKey) keyPtr = SwapEndian64(authenticationkey, 4, 4); + if (swapEndian && hasAuthKey) authkeyptr = SwapEndian64(authenticationkey, 16, 8); + if (swapEndian && hasPwdKey) authkeyptr = SwapEndian64(authenticationkey, 4, 4); + if ( blockNo <= 3) PrintAndLog("Special Block: %0d (0x%02X) [ %s]", blockNo, blockNo, sprint_hex(blockdata, 4)); @@ -947,11 +959,11 @@ int CmdHF14AMfUWrBl(const char *Cmd){ if ( hasAuthKey ){ c.arg[1] = 1; - memcpy(c.d.asBytes+4,authenticationkey,16); + memcpy(c.d.asBytes+4,authkeyptr,16); } else if ( hasPwdKey ) { c.arg[1] = 2; - memcpy(c.d.asBytes+4,authenticationkey,4); + memcpy(c.d.asBytes+4,authkeyptr,4); } SendCommand(&c); @@ -979,8 +991,8 @@ int CmdHF14AMfURdBl(const char *Cmd){ uint8_t keylen = 0; uint8_t data[16] = {0x00}; uint8_t authenticationkey[16] = {0x00}; - uint8_t *keyPtr = authenticationkey; - + uint8_t *authkeyptr = authenticationkey; + // starting with getting tagtype TagTypeUL_t tagtype = GetHF14AMfU_Type(); if (tagtype == UL_ERROR) return -1; @@ -1050,18 +1062,18 @@ int CmdHF14AMfURdBl(const char *Cmd){ if ( blockNo == -1 ) return usage_hf_mfu_rdbl(); // Swap endianness - if (swapEndian && hasAuthKey) keyPtr = SwapEndian64(authenticationkey, 16, 8); - if (swapEndian && hasPwdKey) keyPtr = SwapEndian64(authenticationkey, 4, 4); + if (swapEndian && hasAuthKey) authkeyptr = SwapEndian64(authenticationkey, 16, 8); + if (swapEndian && hasPwdKey) authkeyptr = SwapEndian64(authenticationkey, 4, 4); //Read Block UsbCommand c = {CMD_MIFAREU_READBL, {blockNo}}; if ( hasAuthKey ){ c.arg[1] = 1; - memcpy(c.d.asBytes,authenticationkey,16); + memcpy(c.d.asBytes,authkeyptr,16); } else if ( hasPwdKey ) { c.arg[1] = 2; - memcpy(c.d.asBytes,authenticationkey,4); + memcpy(c.d.asBytes,authkeyptr,4); } SendCommand(&c); @@ -1085,28 +1097,29 @@ int usage_hf_mfu_info(void) { PrintAndLog("It gathers information about the tag and tries to detect what kind it is."); PrintAndLog("Sometimes the tags are locked down, and you may need a key to be able to read the information"); PrintAndLog("The following tags can be identified:\n"); - PrintAndLog("Ultralight, Ultralight-C, Ultralight EV1"); - PrintAndLog("NTAG 213, NTAG 215, NTAG 216"); + PrintAndLog("Ultralight, Ultralight-C, Ultralight EV1, NTAG 203, NTAG 210,"); + PrintAndLog("NTAG 212, NTAG 213, NTAG 215, NTAG 216, NTAG I2C 1K & 2K"); PrintAndLog("my-d, my-d NFC, my-d move, my-d move NFC\n"); - PrintAndLog("Usage: hf mfu info h k "); + PrintAndLog("Usage: hf mfu info k l"); PrintAndLog(" Options : "); - PrintAndLog(" h : this help"); - PrintAndLog(" k : key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]"); + PrintAndLog(" k : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]"); + PrintAndLog(" l : (optional) swap entered key's endianness"); PrintAndLog(""); PrintAndLog(" sample : hf mfu info"); - PrintAndLog(" : hf mfu info k 11223344"); + PrintAndLog(" : hf mfu info k 00112233445566778899AABBCCDDEEFF"); + PrintAndLog(" : hf mfu info k AABBCCDDD"); return 0; } int usage_hf_mfu_dump(void) { PrintAndLog("Reads all pages from Ultralight, Ultralight-C, Ultralight EV1"); + PrintAndLog("NTAG 203, NTAG 210, NTAG 212, NTAG 213, NTAG 215, NTAG 216"); PrintAndLog("and saves binary dump into the file `filename.bin` or `cardUID.bin`"); PrintAndLog("It autodetects card type.\n"); - PrintAndLog("Usage: hf mfu dump l k n p <> q <>"); + PrintAndLog("Usage: hf mfu dump k l n "); PrintAndLog(" Options : "); - PrintAndLog(" h : this help"); - PrintAndLog(" k : key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]"); - PrintAndLog(" l : swap entered key's endianness for auth"); + PrintAndLog(" k : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]"); + PrintAndLog(" l : (optional) swap entered key's endianness"); PrintAndLog(" n : filename w/o .bin to save the dump as"); PrintAndLog(" p : starting Page number to manually set a page to start the dump at"); PrintAndLog(" q : number of Pages to manually set how many pages to dump"); @@ -1115,36 +1128,35 @@ int usage_hf_mfu_dump(void) { PrintAndLog(" sample : hf mfu dump"); PrintAndLog(" : hf mfu dump n myfile"); PrintAndLog(" : hf mfu dump k 00112233445566778899AABBCCDDEEFF"); + PrintAndLog(" : hf mfu dump k AABBCCDDD\n"); return 0; } int usage_hf_mfu_rdbl(void) { PrintAndLog("Read a block and print. It autodetects card type.\n"); - PrintAndLog("Usage: hf mfu rdbl h l b k \n"); + PrintAndLog("Usage: hf mfu rdbl b k l\n"); PrintAndLog(" Options:"); - PrintAndLog(" h : this help"); PrintAndLog(" b : block to read"); - PrintAndLog(" k : key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]"); - PrintAndLog(" l : swap entered key's endianness"); + PrintAndLog(" k : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]"); + PrintAndLog(" l : (optional) swap entered key's endianness"); PrintAndLog(""); - PrintAndLog(" sample : hf mfu rdbl b 0"); + PrintAndLog(" sample : hf mfu rdbl b 0"); PrintAndLog(" : hf mfu rdbl b 0 k 00112233445566778899AABBCCDDEEFF"); - PrintAndLog(" : hf mfu rdbl b 0 k 11223344\n"); + PrintAndLog(" : hf mfu rdbl b 0 k AABBCCDDD\n"); return 0; } int usage_hf_mfu_wrbl(void) { PrintAndLog("Write a block. It autodetects card type.\n"); PrintAndLog("Usage: hf mfu wrbl b d k l\n"); - PrintAndLog(" Options:"); - PrintAndLog(" h : this help"); + PrintAndLog(" Options:"); PrintAndLog(" b : block to write"); - PrintAndLog(" d : [block data] - (8 hex symbols)"); - PrintAndLog(" k : key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]"); - PrintAndLog(" l : swap entered key's endianness"); + PrintAndLog(" d : block data - (8 hex symbols)"); + PrintAndLog(" k : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]"); + PrintAndLog(" l : (optional) swap entered key's endianness"); PrintAndLog(""); - PrintAndLog(" sample : hf mfu wrbl b 0 d 01020304"); - PrintAndLog(" : hf mfu wrbl b 0 d 01020304 k 11223344\n"); + PrintAndLog(" sample : hf mfu wrbl b 0 d 01234567"); + PrintAndLog(" : hf mfu wrbl b 0 d 01234567 k AABBCCDDD\n"); return 0; } @@ -1165,14 +1177,14 @@ int CmdHF14AMfUDump(const char *Cmd){ bool bit[16] = {0x00}; bool bit2[16] = {0x00}; uint8_t data[1024] = {0x00}; - bool hasPwd = false; + bool hasAuthKey = false; int i = 0; int Pages = 16; bool tmplockbit = false; uint8_t dataLen=0; uint8_t cmdp =0; - uint8_t key[16] = {0x00}; - uint8_t *keyPtr = key; + uint8_t authenticationkey[16] = {0x00}; + uint8_t *authkeyptr = authenticationkey; size_t fileNlen = 0; bool errors = false; bool swapEndian = false; @@ -1191,16 +1203,16 @@ int CmdHF14AMfUDump(const char *Cmd){ case 'K': dataLen = param_getstr(Cmd, cmdp+1, tempStr); if (dataLen == 32) //ul-c - errors = param_gethex(tempStr, 0, key, dataLen); + errors = param_gethex(tempStr, 0, authenticationkey, dataLen); else if (dataLen == 8) //ev1/ntag - errors = param_gethex(tempStr, 0, key, dataLen); + errors = param_gethex(tempStr, 0, authenticationkey, dataLen); else{ PrintAndLog("\nERROR: Key is incorrect length\n"); errors = true; } cmdp += 2; - hasPwd = true; + hasAuthKey = true; break; case 'l': case 'L': @@ -1237,8 +1249,7 @@ int CmdHF14AMfUDump(const char *Cmd){ //Validations if(errors) return usage_hf_mfu_dump(); - if (swapEndian && dataLen == 32) - keyPtr = SwapEndian64(data, 16, 8); + if (swapEndian && hasAuthKey) authkeyptr = SwapEndian64(authenticationkey, dataLen/2, (dataLen == 32) ? 8 : 4); TagTypeUL_t tagtype = GetHF14AMfU_Type(); if (tagtype == UL_ERROR) return -1; @@ -1251,13 +1262,13 @@ int CmdHF14AMfUDump(const char *Cmd){ ul_print_type(tagtype, 0); PrintAndLog("Reading tag memory..."); UsbCommand c = {CMD_MIFAREU_READCARD, {startPage,Pages}}; - if ( hasPwd ) { + if ( hasAuthKey ) { if (tagtype & UL_C) c.arg[2] = 1; //UL_C auth else c.arg[2] = 2; //UL_EV1/NTAG auth - memcpy(c.d.asBytes, key, dataLen/2); + memcpy(c.d.asBytes, authkeyptr, dataLen/2); } SendCommand(&c); UsbCommand resp; @@ -1301,13 +1312,16 @@ int CmdHF14AMfUDump(const char *Cmd){ } // add keys to block dump - if (hasPwd && (tagtype & UL_C)){ //UL_C - memcpy(data + Pages*4, key, dataLen/2); - Pages += 4; - } else if (hasPwd) { //not sure output is in correct location. - memcpy(data + Pages*4, key, dataLen/2); - Pages += 1; - } + // cant add swapped bytes-- ULC saves it as big endian in user memory. + //if (swapEndian) authkeyptr = SwapEndian64(authenticationkey, dataLen/2, (dataLen == 32) ? 8 : 4); + + // if (hasAuthKey && (tagtype & UL_C)){ //UL_C + // memcpy(data + Pages*4, authkeyptr, dataLen/2); + // Pages += 4; + // } else if (hasAuthKey) { //not sure output is in correct location. + // memcpy(data + Pages*4, authkeyptr, dataLen/2); + // Pages += 1; + // } for (i = 0; i < Pages; ++i) { if ( i < 3 ) { -- 2.39.2