X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/f4217d58b68ef3e7828892d8401ea1eb3da4696d..refs/pull/466/head:/client/cmdhfmfu.c?ds=sidebyside diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index a631b6b1..c95fa20b 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -7,8 +7,16 @@ //----------------------------------------------------------------------------- // High frequency MIFARE ULTRALIGHT (C) commands //----------------------------------------------------------------------------- -#include "loclass/des.h" + #include "cmdhfmfu.h" + +#include +#include +#include "proxmark3.h" +#include "usb_cmd.h" +#include "cmdmain.h" +#include "ui.h" +#include "polarssl/des.h" #include "cmdhfmf.h" #include "cmdhf14a.h" #include "mifare.h" @@ -41,7 +49,7 @@ uint8_t default_3des_keys[KEYS_3DES_COUNT][16] = { { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF } // 11 22 33 }; -#define KEYS_PWD_COUNT 10 +#define KEYS_PWD_COUNT 6 uint8_t default_pwd_pack[KEYS_PWD_COUNT][4] = { {0xFF,0xFF,0xFF,0xFF}, // PACK 0x00,0x00 -- factory default @@ -50,11 +58,6 @@ uint8_t default_pwd_pack[KEYS_PWD_COUNT][4] = { {0xFF,0x90,0x6C,0xB2}, // PACK 0x12,0x9e -- italian bus (sniffed) {0x46,0x1c,0xA3,0x19}, // PACK 0xE9,0x5A -- italian bus (sniffed) {0x35,0x1C,0xD0,0x19}, // PACK 0x9A,0x5a -- italian bus (sniffed) - - {0x05,0x22,0xE6,0xB4}, // PACK 0x80,0x80 -- Amiiboo (sniffed) pikachu-b UID: - {0x7E,0x22,0xE6,0xB4}, // PACK 0x80,0x80 -- AMiiboo (sniffed) - {0x02,0xE1,0xEE,0x36}, // PACK 0x80,0x80 -- AMiiboo (sniffed) sonic UID: 04d257 7ae33e8027 - {0x32,0x0C,0x16,0x17}, // PACK 0x80,0x80 -- AMiiboo (sniffed) }; #define MAX_UL_TYPES 18 @@ -105,13 +108,7 @@ char *getUlev1CardSizeStr( uint8_t fsize ){ } static void ul_switch_on_field(void) { - UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}}; - clearCommandBuffer(); - SendCommand(&c); -} - -void ul_switch_off_field(void) { - UsbCommand c = {CMD_READER_ISO_14443a, {0, 0, 0}}; + UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT | ISO14A_NO_RATS, 0, 0}}; clearCommandBuffer(); SendCommand(&c); } @@ -276,7 +273,20 @@ static int ulev1_readSignature( uint8_t *response, uint16_t responseLength ){ return len; } -//make sure field is off before calling this function + +// Fudan check checks for which error is given for a command with incorrect crc +// NXP UL chip responds with 01, fudan 00. +// other possible checks: +// send a0 + crc +// UL responds with 00, fudan doesn't respond +// or +// send a200 + crc +// UL doesn't respond, fudan responds with 00 +// or +// send 300000 + crc (read with extra byte(s)) +// UL responds with read of page 0, fudan doesn't respond. +// +// make sure field is off before calling this function static int ul_fudan_check( void ){ iso14a_card_select_t card; if ( !ul_select(&card) ) @@ -895,10 +905,6 @@ int CmdHF14AMfUWrBl(const char *Cmd){ uint8_t authenticationkey[16] = {0x00}; uint8_t *authKeyPtr = authenticationkey; - // starting with getting tagtype - TagTypeUL_t tagtype = GetHF14AMfU_Type(); - if (tagtype == UL_ERROR) return -1; - while(param_getchar(Cmd, cmdp) != 0x00) { switch(param_getchar(Cmd, cmdp)) @@ -930,21 +936,10 @@ int CmdHF14AMfUWrBl(const char *Cmd){ case 'b': case 'B': blockNo = param_get8(Cmd, cmdp+1); - - uint8_t maxblockno = 0; - for (uint8_t idx = 0; idx < MAX_UL_TYPES; idx++){ - if (tagtype & UL_TYPES_ARRAY[idx]) - maxblockno = UL_MEMORY_ARRAY[idx]; - } - if (blockNo < 0) { PrintAndLog("Wrong block number"); errors = true; } - if (blockNo > maxblockno){ - PrintAndLog("block number too large. Max block is %u/0x%02X \n", maxblockno,maxblockno); - errors = true; - } cmdp += 2; break; case 'l': @@ -971,6 +966,19 @@ int CmdHF14AMfUWrBl(const char *Cmd){ } if ( blockNo == -1 ) return usage_hf_mfu_wrbl(); + // starting with getting tagtype + TagTypeUL_t tagtype = GetHF14AMfU_Type(); + if (tagtype == UL_ERROR) return -1; + + uint8_t maxblockno = 0; + for (uint8_t idx = 0; idx < MAX_UL_TYPES; idx++){ + if (tagtype & UL_TYPES_ARRAY[idx]) + maxblockno = UL_MEMORY_ARRAY[idx]; + } + if (blockNo > maxblockno){ + PrintAndLog("block number too large. Max block is %u/0x%02X \n", maxblockno,maxblockno); + return usage_hf_mfu_wrbl(); + } // Swap endianness if (swapEndian && hasAuthKey) authKeyPtr = SwapEndian64(authenticationkey, 16, 8); @@ -1022,10 +1030,6 @@ int CmdHF14AMfURdBl(const char *Cmd){ uint8_t authenticationkey[16] = {0x00}; uint8_t *authKeyPtr = authenticationkey; - // starting with getting tagtype - TagTypeUL_t tagtype = GetHF14AMfU_Type(); - if (tagtype == UL_ERROR) return -1; - while(param_getchar(Cmd, cmdp) != 0x00) { switch(param_getchar(Cmd, cmdp)) @@ -1057,21 +1061,10 @@ int CmdHF14AMfURdBl(const char *Cmd){ case 'b': case 'B': blockNo = param_get8(Cmd, cmdp+1); - - uint8_t maxblockno = 0; - for (uint8_t idx = 0; idx < MAX_UL_TYPES; idx++){ - if (tagtype & UL_TYPES_ARRAY[idx]) - maxblockno = UL_MEMORY_ARRAY[idx]; - } - if (blockNo < 0) { PrintAndLog("Wrong block number"); errors = true; } - if (blockNo > maxblockno){ - PrintAndLog("block number to large. Max block is %u/0x%02X \n", maxblockno,maxblockno); - errors = true; - } cmdp += 2; break; case 'l': @@ -1089,6 +1082,19 @@ int CmdHF14AMfURdBl(const char *Cmd){ } if ( blockNo == -1 ) return usage_hf_mfu_rdbl(); + // start with getting tagtype + TagTypeUL_t tagtype = GetHF14AMfU_Type(); + if (tagtype == UL_ERROR) return -1; + + uint8_t maxblockno = 0; + for (uint8_t idx = 0; idx < MAX_UL_TYPES; idx++){ + if (tagtype & UL_TYPES_ARRAY[idx]) + maxblockno = UL_MEMORY_ARRAY[idx]; + } + if (blockNo > maxblockno){ + PrintAndLog("block number to large. Max block is %u/0x%02X \n", maxblockno,maxblockno); + return usage_hf_mfu_rdbl(); + } // Swap endianness if (swapEndian && hasAuthKey) authKeyPtr = SwapEndian64(authenticationkey, 16, 8); @@ -1112,9 +1118,9 @@ int CmdHF14AMfURdBl(const char *Cmd){ uint8_t isOK = resp.arg[0] & 0xff; if (isOK) { uint8_t *data = resp.d.asBytes; - PrintAndLog("\nBlock# | Data | Ascii"); - PrintAndLog("-----------------------------"); - PrintAndLog("%02d/0x%02X | %s| %.4s\n", blockNo, blockNo, sprint_hex(data, 4), data); + PrintAndLog("\n Block# | Data | Ascii"); + PrintAndLog("---------+-------------+------"); + PrintAndLog(" %02d/0x%02X | %s| %.4s\n", blockNo, blockNo, sprint_hex(data, 4), data); } else { PrintAndLog("Failed reading block: (%02x)", isOK); @@ -1221,6 +1227,7 @@ int CmdHF14AMfUDump(const char *Cmd){ bool manualPages = false; uint8_t startPage = 0; char tempStr[50]; + unsigned char cleanASCII[4]; while(param_getchar(Cmd, cmdp) != 0x00) { @@ -1359,11 +1366,11 @@ int CmdHF14AMfUDump(const char *Cmd){ } } - PrintAndLog("\nBlock# | Data |lck| Ascii"); - PrintAndLog("---------------------------------"); + PrintAndLog("\n Block# | Data |lck| Ascii"); + PrintAndLog("---------+-------------+---+------"); for (i = 0; i < Pages; ++i) { if ( i < 3 ) { - PrintAndLog("%02d/0x%02X | %s| | ", i+startPage, i+startPage, sprint_hex(data + i * 4, 4)); + PrintAndLog("%3d/0x%02X | %s| | ", i+startPage, i+startPage, sprint_hex(data + i * 4, 4)); continue; } switch(i){ @@ -1410,7 +1417,12 @@ int CmdHF14AMfUDump(const char *Cmd){ case 43: tmplockbit = bit2[9]; break; //auth1 default: break; } - PrintAndLog("%02d/0x%02X | %s| %d | %.4s", i+startPage, i+startPage, sprint_hex(data + i * 4, 4), tmplockbit, data+i*4); + + // convert unprintable characters and line breaks to dots + memcpy(cleanASCII, data+i*4, 4); + clean_ascii(cleanASCII, 4); + + PrintAndLog("%3d/0x%02X | %s| %d | %.4s", i+startPage, i+startPage, sprint_hex(data + i * 4, 4), tmplockbit, cleanASCII); } PrintAndLog("---------------------------------"); @@ -1451,7 +1463,7 @@ int CmdHF14AMfucAuth(const char *Cmd){ //Change key to user defined one if (cmdp == 'k' || cmdp == 'K'){ keyNo = param_get8(Cmd, 1); - if(keyNo > KEYS_3DES_COUNT) + if(keyNo > KEYS_3DES_COUNT-1) errors = true; }