From f9848fd647ce3c708510d8ead6d1b56b26c57ad9 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 3 May 2015 23:17:11 -0400 Subject: [PATCH] MFU dump UL-C with key adding UL-C auth and keys to dump cmd swapped endian for input of hf mfu crdbl to match output of hf mfu info cmd and tag info app --- client/cmdhfmfu.c | 115 +++++++++++++++++++++++++++++++++------------- client/util.c | 14 ++++++ client/util.h | 1 + 3 files changed, 98 insertions(+), 32 deletions(-) diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 9825f928..620f1b0e 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -12,6 +12,7 @@ #include "cmdhfmf.h" #include "cmdhf14a.h" #include "mifare.h" +#include "util.h" #define MAX_UL_BLOCKS 0x0f #define MAX_ULC_BLOCKS 0x2f @@ -87,8 +88,8 @@ uint8_t GetHF14AMfU_Type(void){ // EV1 GetVersion if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { - uint8_t version[10] = {0,0,0,0,0,0,0,0}; - memcpy(&version, resp.d.asBytes, sizeof(version)); + uint8_t version[10] = {0,0,0,0,0,0,0,0,0,0}; + memcpy(version, resp.d.asBytes, resp.arg[0] < sizeof(version) ? resp.arg[0] : sizeof(version)); uint8_t len = resp.arg[0] & 0xff; if ( len == 0x0A && version[6] == 0x0B ) @@ -324,10 +325,9 @@ int usage_hf_mfu_dump(void) PrintAndLog("Reads all pages from Ultralight, Ultralight-C, Ultralight EV1"); PrintAndLog("and saves binary dump into the file `filename.bin` or `cardUID.bin`"); PrintAndLog("It autodetects card type.\n"); - PrintAndLog("Usage: hf mfu dump "); + PrintAndLog("Usage: hf mfu dump k n "); PrintAndLog(" sample : hf mfu dump"); - PrintAndLog(" : hf mfu dump myfile"); - PrintAndLog(" : hf mfu dump 1 myfile"); + PrintAndLog(" : hf mfu dump n myfile"); return 0; } // @@ -337,26 +337,66 @@ int usage_hf_mfu_dump(void) // TODO: take a password to read UL-C / UL-EV1 tags. int CmdHF14AMfUDump(const char *Cmd){ - char cmdp = param_getchar(Cmd, 0); - if (cmdp == 'h' || cmdp == 'H') - return usage_hf_mfu_dump(); - FILE *fout; char filename[FILE_PATH_SIZE] = {0x00}; char *fnameptr = filename; char *str = "Dumping Ultralight%s%s Card Data..."; - uint8_t *lockbytes_t = NULL; uint8_t lockbytes[2] = {0x00}; uint8_t *lockbytes_t2 = NULL; uint8_t lockbytes2[2] = {0x00}; bool bit[16] = {0x00}; bool bit2[16] = {0x00}; - uint8_t data[176] = {0x00}; - + uint8_t data[1024] = {0x00}; + bool hasPwd = false; int i = 0; int Pages = 16; bool tmplockbit = false; + uint8_t dataLen=0; + uint8_t cmdp =0; + uint8_t *key= NULL; + size_t fileNlen = 0; + bool errors = FALSE; + + while(param_getchar(Cmd, cmdp) != 0x00) + { + switch(param_getchar(Cmd, cmdp)) + { + case 'h': + case 'H': + return usage_hf_mfu_dump(); + case 'k': + case 'K': + dataLen = param_gethex(Cmd, cmdp+1, data, 32); + if (dataLen) { + errors = true; + } else { + key = SwapEndian64(data, 16); + PrintAndLog("3des key: %s",sprint_hex(key, 16)); + } + cmdp += 2; + hasPwd = true; + break; + case 'n': + case 'N': + fileNlen = param_getstr(Cmd, cmdp+1, filename); + if (!fileNlen) errors = true; + if (fileNlen > FILE_PATH_SIZE-5) fileNlen = FILE_PATH_SIZE-5; + cmdp += 2; + break; + default: + PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + if(errors) break; + } + + //Validations + if(errors) + { + return usage_hf_mfu_dump(); + } TagTypeUL_t tagtype = GetHF14AMfU_Type(); if (tagtype == UL_ERROR) return -1; @@ -381,20 +421,28 @@ int CmdHF14AMfUDump(const char *Cmd){ PrintAndLog("Dumping unknown Ultralight, using default values."); } - UsbCommand c = {CMD_MIFAREU_READCARD, {0,Pages}}; - SendCommand(&c); - UsbCommand resp; - - if (!WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - PrintAndLog("Command execute time-out"); - return 0; - } + for (uint8_t i = 0; i FILE_PATH_SIZE-5) - len = FILE_PATH_SIZE-5; - // user supplied filename? - if (len < 1) { + if (fileNlen < 1) { // UID = data 0-1-2 4-5-6-7 (skips a beat) sprintf(fnameptr,"%02X%02X%02X%02X%02X%02X%02X.bin", data[0],data[1], data[2], data[4],data[5],data[6], data[7]); } else { - sprintf(fnameptr + len," .bin"); + sprintf(fnameptr + fileNlen," .bin"); } if ((fout = fopen(filename,"wb")) == NULL) { @@ -707,6 +756,7 @@ int CmdTestDES(const char * cmd) return 0; } **/ + // // Ultralight C Read Single Block // @@ -715,7 +765,7 @@ int CmdHF14AMfUCRdBl(const char *Cmd) UsbCommand resp; bool hasPwd = FALSE; uint8_t blockNo = -1; - unsigned char key[16]; + uint8_t key[16]; char cmdp = param_getchar(Cmd, 0); if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') { @@ -746,12 +796,13 @@ int CmdHF14AMfUCRdBl(const char *Cmd) hasPwd = TRUE; } } + uint8_t *key2 = SwapEndian64(key, 16); //Read Block UsbCommand c = {CMD_MIFAREU_READBL, {blockNo}}; if ( hasPwd ) { c.arg[1] = 1; - memcpy(c.d.asBytes,key,16); + memcpy(c.d.asBytes,key2,16); } SendCommand(&c); diff --git a/client/util.c b/client/util.c index 709e2014..5bb98fd7 100644 --- a/client/util.c +++ b/client/util.c @@ -158,6 +158,20 @@ uint64_t bytes_to_num(uint8_t* src, size_t len) return num; } +// aa,bb,cc,dd,ee,ff,gg,hh, ii,jj,kk,ll,mm,nn,oo,pp +// to +// hh,gg,ff,ee,dd,cc,bb,aa, pp,oo,nn,mm,ll,kk,jj,ii +// up to 64 bytes or 512 bits +uint8_t *SwapEndian64(uint8_t *src, size_t len){ + static uint8_t temp[64]={0}; + for (uint8_t block=0; block < (uint8_t)len/8; block++){ + for (size_t i = 0; i < 8; i++){ + temp[i+(8*block)] = src[(7-i)+(8*block)]; + } + } + return temp; +} + //assumes little endian char * printBits(size_t const size, void const * const ptr) { diff --git a/client/util.h b/client/util.h index a6d0f49f..fb587da0 100644 --- a/client/util.h +++ b/client/util.h @@ -44,6 +44,7 @@ char * sprint_bin_break(const uint8_t *data, const size_t len, const uint8_t bre void num_to_bytes(uint64_t n, size_t len, uint8_t* dest); uint64_t bytes_to_num(uint8_t* src, size_t len); char * printBits(size_t const size, void const * const ptr); +uint8_t *SwapEndian64(uint8_t *src, size_t len); char param_getchar(const char *line, int paramnum); uint8_t param_get8(const char *line, int paramnum); -- 2.39.5