From 6ca1477c746fbf310e7c246ac18d6d4c46f026f8 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Mon, 14 Dec 2015 16:51:11 -0500 Subject: [PATCH 01/16] fix occasional strange printed clock value with... ...fskdemod Fix Q5 tag detection in lf t55xx detect Fix param_get8 reversed parameters --- client/cmddata.c | 29 +++++++++++++---------------- client/cmdlft55xx.c | 8 ++++---- client/util.c | 4 ++-- 3 files changed, 19 insertions(+), 22 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index e8b77d1d..05c495d9 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -944,35 +944,32 @@ int FSKrawDemod(const char *Cmd, bool verbose) { //raw fsk demod no manchester decoding no start bit finding just get binary from wave uint8_t rfLen, invert, fchigh, fclow; - //set defaults //set options from parameters entered with the command - rfLen = param_get8ex(Cmd, 0, 0, 10); - invert = param_get8ex(Cmd, 1, 0, 10); - fchigh = param_get8ex(Cmd, 2, 0, 10); - fclow = param_get8ex(Cmd, 3, 0, 10); - + rfLen = param_get8(Cmd, 0); + invert = param_get8(Cmd, 1); + fchigh = param_get8(Cmd, 2); + fclow = param_get8(Cmd, 3); if (strlen(Cmd)>0 && strlen(Cmd)<=2) { if (rfLen==1){ invert = 1; //if invert option only is used rfLen = 0; } } - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; size_t BitLen = getFromGraphBuf(BitStream); if (BitLen==0) return 0; //get field clock lengths - uint16_t fcs=0; + uint8_t fc1=0, fc2=0, rf1=0; if (!fchigh || !fclow) { - fcs = countFC(BitStream, BitLen, 1); - if (!fcs) { - fchigh = 10; - fclow = 8; - } else { - fchigh = (fcs >> 8) & 0x00FF; - fclow = fcs & 0x00FF; + uint8_t ans = fskClocks(&fc1, &fc2, &rf1, false); + if (ans == 0) { + if (g_debugMode) PrintAndLog("\nError: cannot detect valid fsk field clocks"); + return 0; // can't detect field clock } + fchigh = fc1; + fclow = fc2; + if (rfLen == 0) rfLen = rf1; } //get bit clock length if (!rfLen){ @@ -985,7 +982,7 @@ int FSKrawDemod(const char *Cmd, bool verbose) // Now output the bitstream to the scrollback by line of 16 bits if (verbose || g_debugMode) { - PrintAndLog("\nUsing Clock:%u, invert:%u, fchigh:%u, fclow:%u", rfLen, invert, fchigh, fclow); + PrintAndLog("\nUsing Clock:%d, invert:%d, fchigh:%d, fclow:%d", rfLen, invert, fchigh, fclow); PrintAndLog("%s decoded bitstream:",GetFSKType(fchigh,fclow,invert)); printDemodBuff(); } diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 868126c9..8b23c175 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -469,7 +469,7 @@ bool tryDetectModulation(){ if (GetFskClock("", FALSE, FALSE)){ fskClocks(&fc1, &fc2, &clk, FALSE); - if ( FSKrawDemod("0 0", FALSE) && test(DEMOD_FSK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)){ + if ( FSKrawDemod("0 0", FALSE) && test(DEMOD_FSK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) { tests[hits].modulation = DEMOD_FSK; if (fc1==8 && fc2 == 5) tests[hits].modulation = DEMOD_FSK1a; @@ -486,7 +486,6 @@ bool tryDetectModulation(){ tests[hits].modulation = DEMOD_FSK1; else if (fc1 == 10 && fc2 == 8) tests[hits].modulation = DEMOD_FSK2a; - tests[hits].bitrate = bitRate; tests[hits].inverted = TRUE; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); @@ -597,6 +596,7 @@ bool tryDetectModulation(){ config.inverted = tests[0].inverted; config.offset = tests[0].offset; config.block0 = tests[0].block0; + config.Q5 = tests[0].Q5; printConfiguration( config ); return TRUE; } @@ -683,12 +683,12 @@ bool testQ5(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk){ uint8_t safer = PackBits(si, 4, DemodBuffer); si += 4; //master key uint8_t resv = PackBits(si, 8, DemodBuffer); si += 8; // 2nibble must be zeroed. - if (safer != 0x6) continue; + if (safer != 0x6 && safer != 0x9) continue; if ( resv > 0x00) continue; //uint8_t pageSel = PackBits(si, 1, DemodBuffer); si += 1; //uint8_t fastWrite = PackBits(si, 1, DemodBuffer); si += 1; si += 1+1; - int bitRate = PackBits(si, 5, DemodBuffer)*2 + 2; si += 5; //bit rate + int bitRate = PackBits(si, 6, DemodBuffer)*2 + 2; si += 6; //bit rate if (bitRate > 128 || bitRate < 8) continue; //uint8_t AOR = PackBits(si, 1, DemodBuffer); si += 1; diff --git a/client/util.c b/client/util.c index e8b72e81..32c06e91 100644 --- a/client/util.c +++ b/client/util.c @@ -142,7 +142,7 @@ char *sprint_bin_break(const uint8_t *data, const size_t len, const uint8_t brea for (size_t out_index=0; out_index < max_len; out_index++) { // set character sprintf(tmp++, "%u", data[in_index]); - // check if a line break is needed + // check if a line break is needed and we have room to print it in our array if ( (breaks > 0) && !((in_index+1) % breaks) && (out_index+1 != max_len) ) { // increment and print line break out_index++; @@ -271,7 +271,7 @@ char param_getchar(const char *line, int paramnum) uint8_t param_get8(const char *line, int paramnum) { - return param_get8ex(line, paramnum, 10, 0); + return param_get8ex(line, paramnum, 0, 10); } /** -- 2.39.5 From af5384bc906666b4f3097111f2b3566b64e23a4e Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Mon, 14 Dec 2015 17:36:08 -0500 Subject: [PATCH 02/16] additional Q5 `lf t55xx` fixes --- client/cmdlft55xx.c | 60 +++++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 35 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 8b23c175..0d277d06 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -183,7 +183,6 @@ int CmdT55xxSetConfig(const char *Cmd) { uint8_t bitRate = 0; uint8_t rates[9] = {8,16,32,40,50,64,100,128,0}; uint8_t cmdp = 0; - config.Q5 = FALSE; bool errors = FALSE; while(param_getchar(Cmd, cmdp) != 0x00 && !errors) { @@ -672,6 +671,15 @@ bool testQ5Modulation(uint8_t mode, uint8_t modread){ return FALSE; } +int convertQ5bitRate(uint8_t bitRateRead) { + uint8_t expected[] = {8, 16, 32, 40, 50, 64, 100, 128}; + for (int i=0; i<8; i++) + if (expected[i] == bitRateRead) + return i; + + return -1; +} + bool testQ5(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk){ if ( DemodBufferLen < 64 ) return FALSE; @@ -703,7 +711,8 @@ bool testQ5(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk){ //test modulation if (!testQ5Modulation(mode, modread)) continue; if (bitRate != clk) continue; - *fndBitRate = bitRate; + *fndBitRate = convertQ5bitRate(bitRate); + if (*fndBitRate < 0) continue; *offset = idx; return TRUE; @@ -1109,44 +1118,25 @@ int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password ){ return 1; } -char * GetBitRateStr(uint32_t id){ - static char buf[25]; +char * GetBitRateStr(uint32_t id) { + static char buf[25]; char *retStr = buf; - switch (id){ - case 0: - snprintf(retStr,sizeof(buf),"%d - RF/8",id); - break; - case 1: - snprintf(retStr,sizeof(buf),"%d - RF/16",id); - break; - case 2: - snprintf(retStr,sizeof(buf),"%d - RF/32",id); - break; - case 3: - snprintf(retStr,sizeof(buf),"%d - RF/40",id); - break; - case 4: - snprintf(retStr,sizeof(buf),"%d - RF/50",id); - break; - case 5: - snprintf(retStr,sizeof(buf),"%d - RF/64",id); - break; - case 6: - snprintf(retStr,sizeof(buf),"%d - RF/100",id); - break; - case 7: - snprintf(retStr,sizeof(buf),"%d - RF/128",id); - break; - default: - snprintf(retStr,sizeof(buf),"%d - (Unknown)",id); - break; - } - + switch (id) { + case 0: snprintf(retStr,sizeof(buf),"%d - RF/8",id); break; + case 1: snprintf(retStr,sizeof(buf),"%d - RF/16",id); break; + case 2: snprintf(retStr,sizeof(buf),"%d - RF/32",id); break; + case 3: snprintf(retStr,sizeof(buf),"%d - RF/40",id); break; + case 4: snprintf(retStr,sizeof(buf),"%d - RF/50",id); break; + case 5: snprintf(retStr,sizeof(buf),"%d - RF/64",id); break; + case 6: snprintf(retStr,sizeof(buf),"%d - RF/100",id); break; + case 7: snprintf(retStr,sizeof(buf),"%d - RF/128",id); break; + default: snprintf(retStr,sizeof(buf),"%d - (Unknown)",id); break; + } return buf; } -char * GetSaferStr(uint32_t id){ +char * GetSaferStr(uint32_t id) { static char buf[40]; char *retStr = buf; -- 2.39.5 From bc37cfb3ebccc95c6e75565e2484f79be7e97c4f Mon Sep 17 00:00:00 2001 From: Adam Laurie Date: Sat, 19 Dec 2015 16:37:32 +0000 Subject: [PATCH 03/16] add support for raw block 3/4 iclass keys --- client/cmdhficlass.c | 64 +++++++++++++++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 16 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index aca8ff50..99070e18 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -500,7 +500,7 @@ static bool select_only(uint8_t *CSN, uint8_t *CCNR, bool use_credit_key, bool v return true; } -static bool select_and_auth(uint8_t *KEY, uint8_t *MAC, uint8_t *div_key, bool use_credit_key, bool elite, bool verbose) { +static bool select_and_auth(uint8_t *KEY, uint8_t *MAC, uint8_t *div_key, bool use_credit_key, bool elite, bool rawkey, bool verbose) { uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; @@ -508,7 +508,11 @@ static bool select_and_auth(uint8_t *KEY, uint8_t *MAC, uint8_t *div_key, bool u return false; //get div_key - HFiClassCalcDivKey(CSN, KEY, div_key, elite); + if(rawkey) + memcpy(div_key, KEY, 8); + else + HFiClassCalcDivKey(CSN, KEY, div_key, elite); + PrintAndLog("Authing with %s: %02x%02x%02x%02x%02x%02x%02x%02x", rawkey ? "raw key" : "diversified key", div_key[0],div_key[1],div_key[2],div_key[3],div_key[4],div_key[5],div_key[6],div_key[7]); doMAC(CCNR, div_key, MAC); UsbCommand resp; @@ -530,7 +534,7 @@ static bool select_and_auth(uint8_t *KEY, uint8_t *MAC, uint8_t *div_key, bool u } int usage_hf_iclass_dump(void) { - PrintAndLog("Usage: hf iclass dump f k c e\n"); + PrintAndLog("Usage: hf iclass dump f k c e|r\n"); PrintAndLog("Options:"); PrintAndLog(" f : specify a filename to save dump to"); PrintAndLog(" k : *Access Key as 16 hex symbols or 1 hex to select key from memory"); @@ -538,6 +542,7 @@ int usage_hf_iclass_dump(void) { PrintAndLog(" e : If 'e' is specified, the key is interpreted as the 16 byte"); PrintAndLog(" Custom Key (KCus), which can be obtained via reader-attack"); PrintAndLog(" See 'hf iclass sim 2'. This key should be on iclass-format"); + PrintAndLog(" r : If 'r' is specified, the key is interpreted as raw block 3/4"); PrintAndLog(" NOTE: * = required"); PrintAndLog("Samples:"); PrintAndLog(" hf iclass dump k 001122334455667B"); @@ -567,6 +572,7 @@ int CmdHFiClassReader_Dump(const char *Cmd) { bool have_credit_key = false; bool use_credit_key = false; bool elite = false; + bool rawkey = false; bool errors = false; uint8_t cmdp = 0; @@ -631,6 +637,11 @@ int CmdHFiClassReader_Dump(const char *Cmd) { } cmdp += 2; break; + case 'r': + case 'R': + rawkey = true; + cmdp++; + break; default: PrintAndLog("Unknown parameter '%c'\n", param_getchar(Cmd, cmdp)); errors = true; @@ -674,9 +685,9 @@ int CmdHFiClassReader_Dump(const char *Cmd) { } ul_switch_off_field(); // authenticate debit key and get div_key - later store in dump block 3 - if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, false)){ + if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, false)){ //try twice - for some reason it sometimes fails the first time... - if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, false)){ + if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, false)){ ul_switch_off_field(); return 0; } @@ -714,9 +725,9 @@ int CmdHFiClassReader_Dump(const char *Cmd) { ul_switch_off_field(); memset(MAC,0,4); // AA2 authenticate credit key and git c_div_key - later store in dump block 4 - if (!select_and_auth(CreditKEY, MAC, c_div_key, true, false, false)){ + if (!select_and_auth(CreditKEY, MAC, c_div_key, true, false, false, false)){ //try twice - for some reason it sometimes fails the first time... - if (!select_and_auth(CreditKEY, MAC, c_div_key, true, false, false)){ + if (!select_and_auth(CreditKEY, MAC, c_div_key, true, false, false, false)){ ul_switch_off_field(); return 0; } @@ -776,10 +787,10 @@ int CmdHFiClassReader_Dump(const char *Cmd) { return 1; } -static int WriteBlock(uint8_t blockno, uint8_t *bldata, uint8_t *KEY, bool use_credit_key, bool elite, bool verbose) { +static int WriteBlock(uint8_t blockno, uint8_t *bldata, uint8_t *KEY, bool use_credit_key, bool elite, bool rawkey, bool verbose) { uint8_t MAC[4]={0x00,0x00,0x00,0x00}; uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, verbose)) + if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, verbose)) return 0; UsbCommand resp; @@ -812,6 +823,7 @@ int usage_hf_iclass_writeblock(void) { PrintAndLog(" k : Access Key as 16 hex symbols or 1 hex to select key from memory"); PrintAndLog(" c : If 'c' is specified, the key set is assumed to be the credit key\n"); PrintAndLog(" e : If 'e' is specified, elite computations applied to key"); + PrintAndLog(" r : If 'r' is specified, no computations applied to key"); PrintAndLog("Samples:"); PrintAndLog(" hf iclass writeblk b 0A d AAAAAAAAAAAAAAAA k 001122334455667B"); PrintAndLog(" hf iclass writeblk b 1B d AAAAAAAAAAAAAAAA k 001122334455667B c"); @@ -828,6 +840,7 @@ int CmdHFiClass_WriteBlock(const char *Cmd) { char tempStr[50] = {0}; bool use_credit_key = false; bool elite = false; + bool rawkey= false; bool errors = false; uint8_t cmdp = 0; while(param_getchar(Cmd, cmdp) != 0x00) @@ -883,6 +896,11 @@ int CmdHFiClass_WriteBlock(const char *Cmd) { } cmdp += 2; break; + case 'r': + case 'R': + rawkey = true; + cmdp++; + break; default: PrintAndLog("Unknown parameter '%c'\n", param_getchar(Cmd, cmdp)); errors = true; @@ -892,13 +910,13 @@ int CmdHFiClass_WriteBlock(const char *Cmd) { } if (cmdp < 6) return usage_hf_iclass_writeblock(); - int ans = WriteBlock(blockno, bldata, KEY, use_credit_key, elite, true); + int ans = WriteBlock(blockno, bldata, KEY, use_credit_key, elite, rawkey, true); ul_switch_off_field(); return ans; } int usage_hf_iclass_clone(void) { - PrintAndLog("Usage: hf iclass clone f b l k e c"); + PrintAndLog("Usage: hf iclass clone f b l k c e|r"); PrintAndLog("Options:"); PrintAndLog(" f : specify a filename to clone from"); PrintAndLog(" b : The first block to clone as 2 hex symbols"); @@ -906,6 +924,7 @@ int usage_hf_iclass_clone(void) { PrintAndLog(" k : Access Key as 16 hex symbols or 1 hex to select key from memory"); PrintAndLog(" c : If 'c' is specified, the key set is assumed to be the credit key\n"); PrintAndLog(" e : If 'e' is specified, elite computations applied to key"); + PrintAndLog(" r : If 'r' is specified, no computations applied to key"); PrintAndLog("Samples:"); PrintAndLog(" hf iclass clone f iclass_tagdump-121345.bin b 06 l 1A k 1122334455667788 e"); PrintAndLog(" hf iclass clone f iclass_tagdump-121345.bin b 05 l 19 k 0"); @@ -924,6 +943,7 @@ int CmdHFiClassCloneTag(const char *Cmd) { uint8_t dataLen = 0; bool use_credit_key = false; bool elite = false; + bool rawkey = false; bool errors = false; uint8_t cmdp = 0; while(param_getchar(Cmd, cmdp) != 0x00) @@ -987,6 +1007,11 @@ int CmdHFiClassCloneTag(const char *Cmd) { } cmdp += 2; break; + case 'r': + case 'R': + rawkey = true; + cmdp++; + break; default: PrintAndLog("Unknown parameter '%c'\n", param_getchar(Cmd, cmdp)); errors = true; @@ -1026,7 +1051,7 @@ int CmdHFiClassCloneTag(const char *Cmd) { uint8_t MAC[4]={0x00,0x00,0x00,0x00}; uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, true)) + if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, true)) return 0; UsbCommand w = {CMD_ICLASS_CLONE,{startblock,endblock}}; @@ -1059,11 +1084,11 @@ int CmdHFiClassCloneTag(const char *Cmd) { return 1; } -static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, bool verbose) { +static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, bool rawkey, bool verbose) { uint8_t MAC[4]={0x00,0x00,0x00,0x00}; uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - if (!select_and_auth(KEY, MAC, div_key, (keyType==0x18), elite, verbose)) + if (!select_and_auth(KEY, MAC, div_key, (keyType==0x18), elite, rawkey, verbose)) return 0; UsbCommand resp; @@ -1086,12 +1111,13 @@ static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, } int usage_hf_iclass_readblock(void) { - PrintAndLog("Usage: hf iclass readblk b k c e\n"); + PrintAndLog("Usage: hf iclass readblk b k c e|r\n"); PrintAndLog("Options:"); PrintAndLog(" b : The block number as 2 hex symbols"); PrintAndLog(" k : Access Key as 16 hex symbols or 1 hex to select key from memory"); PrintAndLog(" c : If 'c' is specified, the key set is assumed to be the credit key\n"); PrintAndLog(" e : If 'e' is specified, elite computations applied to key"); + PrintAndLog(" r : If 'r' is specified, no computations applied to key"); PrintAndLog("Samples:"); PrintAndLog(" hf iclass readblk b 06 k 0011223344556677"); PrintAndLog(" hf iclass readblk b 1B k 0011223344556677 c"); @@ -1107,6 +1133,7 @@ int CmdHFiClass_ReadBlock(const char *Cmd) { uint8_t dataLen = 0; char tempStr[50] = {0}; bool elite = false; + bool rawkey = false; bool errors = false; uint8_t cmdp = 0; while(param_getchar(Cmd, cmdp) != 0x00) @@ -1153,6 +1180,11 @@ int CmdHFiClass_ReadBlock(const char *Cmd) { } cmdp += 2; break; + case 'r': + case 'R': + rawkey = true; + cmdp++; + break; default: PrintAndLog("Unknown parameter '%c'\n", param_getchar(Cmd, cmdp)); errors = true; @@ -1163,7 +1195,7 @@ int CmdHFiClass_ReadBlock(const char *Cmd) { if (cmdp < 4) return usage_hf_iclass_readblock(); - return ReadBlock(KEY, blockno, keyType, elite, true); + return ReadBlock(KEY, blockno, keyType, elite, rawkey, true); } int CmdHFiClass_loclass(const char *Cmd) { -- 2.39.5 From 59296346a0453979c7eb8214caf7a3ac98141b5d Mon Sep 17 00:00:00 2001 From: Adam Laurie Date: Sun, 20 Dec 2015 12:37:22 +0000 Subject: [PATCH 04/16] document iclass raw key changes --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34be1b2b..b662caf3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,7 @@ of stream transmissions (marshmellow) - Revised workflow for StandAloneMode14a (Craig Young) - EPA functions (`hf epa`) now support both ISO 14443-A and 14443-B cards (frederikmoellers) - 'hw version' only talks to ARM at startup, after that the info is cached. (pwpiwi) +- Added `r` option to iclass functions - allows key to be provided in raw block 3/4 format ## [2.2.0][2015-07-12] -- 2.39.5 From 7ede3c712254cf389c30c6d564ab7fe9c76962ee Mon Sep 17 00:00:00 2001 From: ikarus Date: Wed, 23 Dec 2015 23:51:49 +0100 Subject: [PATCH 05/16] Remove include statement that causes trouble (fix #151). See: https://github.com/Proxmark/proxmark3/issues/151 --- common/protocols.c | 1 - 1 file changed, 1 deletion(-) diff --git a/common/protocols.c b/common/protocols.c index 0d95cf08..69631f58 100644 --- a/common/protocols.c +++ b/common/protocols.c @@ -1,4 +1,3 @@ -#include #include #include #include -- 2.39.5 From 5490c2d6d2cc8a032acdac5d7aba575765607a5f Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Tue, 5 Jan 2016 21:21:06 -0500 Subject: [PATCH 06/16] add broken_bad and @iceman1001 s q5 trace and ... wipe adjustments --- client/cmdlft55xx.c | 350 +++++++++++++++++++++++++------------------- client/cmdlft55xx.h | 28 ++++ 2 files changed, 230 insertions(+), 148 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 0d277d06..97061c56 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -166,6 +166,19 @@ int usage_t55xx_bruteforce(){ PrintAndLog(""); return 0; } +int usage_t55xx_wipe(){ + PrintAndLog("Usage: lf t55xx wipe [h] [Q5]"); + PrintAndLog("This commands wipes a tag, fills blocks 1-7 with zeros and a default configuration block"); + PrintAndLog("Options:"); + PrintAndLog(" h - this help"); + PrintAndLog(" Q5 - indicates to use the T5555 (Q5) default configuration block"); + PrintAndLog(""); + PrintAndLog("Examples:"); + PrintAndLog(" lf t55xx wipe - wipes a t55x7 tag, config block 0x000880E0"); + PrintAndLog(" lf t55xx wipe Q5 - wipes a t5555 Q5 tag, config block 0x6001F004"); + return 0; +} + static int CmdHelp(const char *Cmd); @@ -417,6 +430,13 @@ bool DecodeT55xxBlock(){ return (bool) ans; } +bool DecodeT5555TraceBlock() { + DemodBufferLen = 0x00; + + // According to datasheet. Always: RF/64, not inverted, Manchester + return (bool) ASKDemod("64 0 1", FALSE, FALSE, 1); +} + int CmdT55xxDetect(const char *Cmd){ bool errors = FALSE; bool useGB = FALSE; @@ -935,58 +955,107 @@ int CmdT55xxReadTrace(const char *Cmd) { if (strlen(Cmd)==0) if ( !AquireData( T55x7_PAGE1, REGULAR_READ_MODE_BLOCK, pwdmode, password ) ) return 0; - - if (!DecodeT55xxBlock()) return 0; - if ( !DemodBufferLen) return 0; + if ( config.Q5 ) { + if (!DecodeT5555TraceBlock()) return 0; + } else { + if (!DecodeT55xxBlock()) return 0; + } + + if ( !DemodBufferLen ) return 0; RepaintGraphWindow(); - uint8_t repeat = 0; - if (config.offset > 5) - repeat = 32; + uint8_t repeat = (config.offset > 5) ? 32 : 0; + uint8_t si = config.offset+repeat; uint32_t bl1 = PackBits(si, 32, DemodBuffer); uint32_t bl2 = PackBits(si+32, 32, DemodBuffer); - - uint32_t acl = PackBits(si, 8, DemodBuffer); si += 8; - uint32_t mfc = PackBits(si, 8, DemodBuffer); si += 8; - uint32_t cid = PackBits(si, 5, DemodBuffer); si += 5; - uint32_t icr = PackBits(si, 3, DemodBuffer); si += 3; - uint32_t year = PackBits(si, 4, DemodBuffer); si += 4; - uint32_t quarter = PackBits(si, 2, DemodBuffer); si += 2; - uint32_t lotid = PackBits(si, 14, DemodBuffer); si += 14; - uint32_t wafer = PackBits(si, 5, DemodBuffer); si += 5; - uint32_t dw = PackBits(si, 15, DemodBuffer); - - time_t t = time(NULL); - struct tm tm = *localtime(&t); - if ( year > tm.tm_year-110) - year += 2000; - else - year += 2010; - if (config.Q5) PrintAndLog("*** Warning *** Info read off a Q5 will not work as expected"); - if ( acl != 0xE0 ) { - PrintAndLog("The modulation is most likely wrong since the ACL is not 0xE0. "); - return 0; + if (config.Q5) { + uint32_t hdr = PackBits(si, 9, DemodBuffer); si += 9; + + if (hdr != 0x1FF) { + PrintAndLog("Invalid Q5 Trace data header (expected 0x1FF, found %X)", hdr); + return 0; + } + + t5555_tracedata_t data = {.bl1 = bl1, .bl2 = bl2, .icr = 0, .lotidc = '?', .lotid = 0, .wafer = 0, .dw =0}; + + data.icr = PackBits(si, 2, DemodBuffer); si += 2; + data.lotidc = 'Z' - PackBits(si, 2, DemodBuffer); si += 3; + + data.lotid = PackBits(si, 4, DemodBuffer); si += 5; + data.lotid <<= 4; + data.lotid |= PackBits(si, 4, DemodBuffer); si += 5; + data.lotid <<= 4; + data.lotid |= PackBits(si, 4, DemodBuffer); si += 5; + data.lotid <<= 4; + data.lotid |= PackBits(si, 4, DemodBuffer); si += 5; + data.lotid <<= 1; + data.lotid |= PackBits(si, 1, DemodBuffer); si += 1; + + data.wafer = PackBits(si, 3, DemodBuffer); si += 4; + data.wafer <<= 2; + data.wafer |= PackBits(si, 2, DemodBuffer); si += 2; + + data.dw = PackBits(si, 2, DemodBuffer); si += 3; + data.dw <<= 4; + data.dw |= PackBits(si, 4, DemodBuffer); si += 5; + data.dw <<= 4; + data.dw |= PackBits(si, 4, DemodBuffer); si += 5; + data.dw <<= 4; + data.dw |= PackBits(si, 4, DemodBuffer); si += 5; + + printT5555Trace(data, repeat); + + } else { + + t55x7_tracedata_t data = {.bl1 = bl1, .bl2 = bl2, .acl = 0, .mfc = 0, .cid = 0, .year = 0, .quarter = 0, .icr = 0, .lotid = 0, .wafer = 0, .dw = 0}; + + data.acl = PackBits(si, 8, DemodBuffer); si += 8; + if ( data.acl != 0xE0 ) { + PrintAndLog("The modulation is most likely wrong since the ACL is not 0xE0. "); + return 0; + } + + data.mfc = PackBits(si, 8, DemodBuffer); si += 8; + data.cid = PackBits(si, 5, DemodBuffer); si += 5; + data.icr = PackBits(si, 3, DemodBuffer); si += 3; + data.year = PackBits(si, 4, DemodBuffer); si += 4; + data.quarter = PackBits(si, 2, DemodBuffer); si += 2; + data.lotid = PackBits(si, 14, DemodBuffer); si += 14; + data.wafer = PackBits(si, 5, DemodBuffer); si += 5; + data.dw = PackBits(si, 15, DemodBuffer); + + time_t t = time(NULL); + struct tm tm = *localtime(&t); + if ( data.year > tm.tm_year-110) + data.year += 2000; + else + data.year += 2010; + + printT55x7Trace(data, repeat); } - PrintAndLog(""); - PrintAndLog("-- T55xx Trace Information ----------------------------------"); + return 0; +} + +void printT55x7Trace( t55x7_tracedata_t data, uint8_t repeat ){ + PrintAndLog("-- T55x7 Trace Information ----------------------------------"); PrintAndLog("-------------------------------------------------------------"); - PrintAndLog(" ACL Allocation class (ISO/IEC 15963-1) : 0x%02X (%d)", acl, acl); - PrintAndLog(" MFC Manufacturer ID (ISO/IEC 7816-6) : 0x%02X (%d) - %s", mfc, mfc, getTagInfo(mfc)); - PrintAndLog(" CID : 0x%02X (%d) - %s", cid, cid, GetModelStrFromCID(cid)); - PrintAndLog(" ICR IC Revision : %d",icr ); + PrintAndLog(" ACL Allocation class (ISO/IEC 15963-1) : 0x%02X (%d)", data.acl, data.acl); + PrintAndLog(" MFC Manufacturer ID (ISO/IEC 7816-6) : 0x%02X (%d) - %s", data.mfc, data.mfc, getTagInfo(data.mfc)); + PrintAndLog(" CID : 0x%02X (%d) - %s", data.cid, data.cid, GetModelStrFromCID(data.cid)); + PrintAndLog(" ICR IC Revision : %d", data.icr ); PrintAndLog(" Manufactured"); - PrintAndLog(" Year/Quarter : %d/%d",year, quarter); - PrintAndLog(" Lot ID : %d", lotid ); - PrintAndLog(" Wafer number : %d", wafer); - PrintAndLog(" Die Number : %d", dw); + PrintAndLog(" Year/Quarter : %d/%d", data.year, data.quarter); + PrintAndLog(" Lot ID : %d", data.lotid ); + PrintAndLog(" Wafer number : %d", data.wafer); + PrintAndLog(" Die Number : %d", data.dw); PrintAndLog("-------------------------------------------------------------"); PrintAndLog(" Raw Data - Page 1"); - PrintAndLog(" Block 1 : 0x%08X %s", bl1, sprint_bin(DemodBuffer+config.offset+repeat,32) ); - PrintAndLog(" Block 2 : 0x%08X %s", bl2, sprint_bin(DemodBuffer+config.offset+repeat+32,32) ); - PrintAndLog("-------------------------------------------------------------"); + PrintAndLog(" Block 1 : 0x%08X %s", data.bl1, sprint_bin(DemodBuffer+config.offset+repeat,32) ); + PrintAndLog(" Block 2 : 0x%08X %s", data.bl2, sprint_bin(DemodBuffer+config.offset+repeat+32,32) ); + PrintAndLog("-------------------------------------------------------------"); /* TRACE - BLOCK O @@ -1004,10 +1073,36 @@ int CmdT55xxReadTrace(const char *Cmd) { 13-17 Wafer number 18-32 DW, die number sequential */ +} + +void printT5555Trace( t5555_tracedata_t data, uint8_t repeat ){ + PrintAndLog("-- T5555 (Q5) Trace Information -----------------------------"); + PrintAndLog("-------------------------------------------------------------"); + PrintAndLog(" ICR IC Revision : %d", data.icr ); + PrintAndLog(" Lot : %c%d", data.lotidc, data.lotid); + PrintAndLog(" Wafer number : %d", data.wafer); + PrintAndLog(" Die Number : %d", data.dw); + PrintAndLog("-------------------------------------------------------------"); + PrintAndLog(" Raw Data - Page 1"); + PrintAndLog(" Block 1 : 0x%08X %s", data.bl1, sprint_bin(DemodBuffer+config.offset+repeat,32) ); + PrintAndLog(" Block 2 : 0x%08X %s", data.bl2, sprint_bin(DemodBuffer+config.offset+repeat+32,32) ); - return 0; + /* + ** Q5 ** + TRACE - BLOCK O and BLOCK1 + Bits Definition HEX + 1-9 Header 0x1FF + 10-11 IC Revision + 12-13 Lot ID char + 15-35 Lot ID (NB parity) + 36-41 Wafer number (NB parity) + 42-58 DW, die number sequential (NB parity) + 60-63 Parity bits + 64 Always zero + */ } +//need to add Q5 info... int CmdT55xxInfo(const char *Cmd){ /* Page 0 Block 0 Configuration data. @@ -1027,6 +1122,7 @@ int CmdT55xxInfo(const char *Cmd){ if (!DecodeT55xxBlock()) return 1; + // too little space to start with if ( DemodBufferLen < 32) return 1; uint8_t si = config.offset; @@ -1046,9 +1142,10 @@ int CmdT55xxInfo(const char *Cmd){ uint32_t fw = PackBits(si, 1, DemodBuffer); si += 1; uint32_t inv = PackBits(si, 1, DemodBuffer); si += 1; uint32_t por = PackBits(si, 1, DemodBuffer); si += 1; + if (config.Q5) PrintAndLog("*** Warning *** Config Info read off a Q5 will not display as expected"); PrintAndLog(""); - PrintAndLog("-- T55xx Configuration & Tag Information --------------------"); + PrintAndLog("-- T55x7 Configuration & Tag Information --------------------"); PrintAndLog("-------------------------------------------------------------"); PrintAndLog(" Safer key : %s", GetSaferStr(safer)); PrintAndLog(" reserved : %d", resv); @@ -1156,45 +1253,19 @@ char * GetModulationStr( uint32_t id){ char *retStr = buf; switch (id){ - case 0: - snprintf(retStr,sizeof(buf),"%d - DIRECT (ASK/NRZ)",id); - break; - case 1: - snprintf(retStr,sizeof(buf),"%d - PSK 1 phase change when input changes",id); - break; - case 2: - snprintf(retStr,sizeof(buf),"%d - PSK 2 phase change on bitclk if input high",id); - break; - case 3: - snprintf(retStr,sizeof(buf),"%d - PSK 3 phase change on rising edge of input",id); - break; - case 4: - snprintf(retStr,sizeof(buf),"%d - FSK 1 RF/8 RF/5",id); - break; - case 5: - snprintf(retStr,sizeof(buf),"%d - FSK 2 RF/8 RF/10",id); - break; - case 6: - snprintf(retStr,sizeof(buf),"%d - FSK 1a RF/5 RF/8",id); - break; - case 7: - snprintf(retStr,sizeof(buf),"%d - FSK 2a RF/10 RF/8",id); - break; - case 8: - snprintf(retStr,sizeof(buf),"%d - Manchester",id); - break; - case 16: - snprintf(retStr,sizeof(buf),"%d - Biphase",id); - break; - case 0x18: - snprintf(retStr,sizeof(buf),"%d - Biphase a - AKA Conditional Dephase Encoding(CDP)",id); - break; - case 17: - snprintf(retStr,sizeof(buf),"%d - Reserved",id); - break; - default: - snprintf(retStr,sizeof(buf),"0x%02X (Unknown)",id); - break; + case 0: snprintf(retStr,sizeof(buf),"%d - DIRECT (ASK/NRZ)",id); break; + case 1: snprintf(retStr,sizeof(buf),"%d - PSK 1 phase change when input changes",id); break; + case 2: snprintf(retStr,sizeof(buf),"%d - PSK 2 phase change on bitclk if input high",id); break; + case 3: snprintf(retStr,sizeof(buf),"%d - PSK 3 phase change on rising edge of input",id); break; + case 4: snprintf(retStr,sizeof(buf),"%d - FSK 1 RF/8 RF/5",id); break; + case 5: snprintf(retStr,sizeof(buf),"%d - FSK 2 RF/8 RF/10",id); break; + case 6: snprintf(retStr,sizeof(buf),"%d - FSK 1a RF/5 RF/8",id); break; + case 7: snprintf(retStr,sizeof(buf),"%d - FSK 2a RF/10 RF/8",id); break; + case 8: snprintf(retStr,sizeof(buf),"%d - Manchester",id); break; + case 16: snprintf(retStr,sizeof(buf),"%d - Biphase",id); break; + case 0x18: snprintf(retStr,sizeof(buf),"%d - Biphase a - AKA Conditional Dephase Encoding(CDP)",id); break; + case 17: snprintf(retStr,sizeof(buf),"%d - Reserved",id); break; + default: snprintf(retStr,sizeof(buf),"0x%02X (Unknown)",id); break; } return buf; } @@ -1214,47 +1285,21 @@ char * GetSelectedModulationStr( uint8_t id){ static char buf[20]; char *retStr = buf; - switch (id){ - case DEMOD_FSK: - snprintf(retStr,sizeof(buf),"FSK"); - break; - case DEMOD_FSK1: - snprintf(retStr,sizeof(buf),"FSK1"); - break; - case DEMOD_FSK1a: - snprintf(retStr,sizeof(buf),"FSK1a"); - break; - case DEMOD_FSK2: - snprintf(retStr,sizeof(buf),"FSK2"); - break; - case DEMOD_FSK2a: - snprintf(retStr,sizeof(buf),"FSK2a"); - break; - case DEMOD_ASK: - snprintf(retStr,sizeof(buf),"ASK"); - break; - case DEMOD_NRZ: - snprintf(retStr,sizeof(buf),"DIRECT/NRZ"); - break; - case DEMOD_PSK1: - snprintf(retStr,sizeof(buf),"PSK1"); - break; - case DEMOD_PSK2: - snprintf(retStr,sizeof(buf),"PSK2"); - break; - case DEMOD_PSK3: - snprintf(retStr,sizeof(buf),"PSK3"); - break; - case DEMOD_BI: - snprintf(retStr,sizeof(buf),"BIPHASE"); - break; - case DEMOD_BIa: - snprintf(retStr,sizeof(buf),"BIPHASEa - (CDP)"); - break; - default: - snprintf(retStr,sizeof(buf),"(Unknown)"); - break; - } + switch (id) { + case DEMOD_FSK: snprintf(retStr,sizeof(buf),"FSK"); break; + case DEMOD_FSK1: snprintf(retStr,sizeof(buf),"FSK1"); break; + case DEMOD_FSK1a: snprintf(retStr,sizeof(buf),"FSK1a"); break; + case DEMOD_FSK2: snprintf(retStr,sizeof(buf),"FSK2"); break; + case DEMOD_FSK2a: snprintf(retStr,sizeof(buf),"FSK2a"); break; + case DEMOD_ASK: snprintf(retStr,sizeof(buf),"ASK"); break; + case DEMOD_NRZ: snprintf(retStr,sizeof(buf),"DIRECT/NRZ"); break; + case DEMOD_PSK1: snprintf(retStr,sizeof(buf),"PSK1"); break; + case DEMOD_PSK2: snprintf(retStr,sizeof(buf),"PSK2"); break; + case DEMOD_PSK3: snprintf(retStr,sizeof(buf),"PSK3"); break; + case DEMOD_BI: snprintf(retStr,sizeof(buf),"BIPHASE"); break; + case DEMOD_BIa: snprintf(retStr,sizeof(buf),"BIPHASEa - (CDP)"); break; + default: snprintf(retStr,sizeof(buf),"(Unknown)"); break; + } return buf; } @@ -1293,13 +1338,22 @@ int CmdT55xxWipe(const char *Cmd) { char writeData[20] = {0}; char *ptrData = writeData; + char cmdp = param_getchar(Cmd, 0); + if ( cmdp == 'h' || cmdp == 'H') return usage_t55xx_wipe(); + + bool Q5 = (cmdp == 'q' || cmdp == 'Q'); + + // Try with the default password to reset block 0 + // With a pwd should work even if pwd bit not set PrintAndLog("\nBeginning Wipe of a T55xx tag (assuming the tag is not password protected)\n"); - //try with the default password to reset block 0 (with a pwd should work even if pwd bit not set) - snprintf(ptrData,sizeof(writeData),"b 0 d 00088040 p 0"); + if ( Q5 ){ + snprintf(ptrData,sizeof(writeData),"b 0 d 6001F004 p 0"); + } else { + snprintf(ptrData,sizeof(writeData),"b 0 d 00088040 p 0"); + } - if (!CmdT55xxWriteBlock(ptrData)) - PrintAndLog("Error writing blk 0"); + if (!CmdT55xxWriteBlock(ptrData)) PrintAndLog("Error writing blk 0"); for (uint8_t blk = 1; blk<8; blk++) { snprintf(ptrData,sizeof(writeData),"b %d d 0", blk); @@ -1343,7 +1397,7 @@ int CmdT55xxBruteForce(const char *Cmd) { return 1; } - while( fgets(buf, sizeof(buf), f) ){ + while( fgets(buf, sizeof(buf), f) ) { if (strlen(buf) < 8 || buf[7] == '\n') continue; while (fgetc(f) != '\n' && !feof(f)) ; //goto next line @@ -1351,7 +1405,7 @@ int CmdT55xxBruteForce(const char *Cmd) { //The line start with # is comment, skip if( buf[0]=='#' ) continue; - if (!isxdigit(buf[0])){ + if (!isxdigit(buf[0])) { PrintAndLog("File content error. '%s' must include 8 HEX symbols", buf); continue; } @@ -1416,39 +1470,39 @@ int CmdT55xxBruteForce(const char *Cmd) { // incremental pwd range search start_password = param_get32ex(Cmd, 0, 0, 16); end_password = param_get32ex(Cmd, 1, 0, 16); - + if ( start_password >= end_password ) return usage_t55xx_bruteforce(); PrintAndLog("Search password range [%08X -> %08X]", start_password, end_password); uint32_t i = start_password; - while ((!found) && (i <= end_password)){ + while ((!found) && (i <= end_password)) { - printf("."); - fflush(stdout); - if (ukbhit()) { - getchar(); - printf("\naborted via keyboard!\n"); - return 0; - } + printf("."); + fflush(stdout); + if (ukbhit()) { + getchar(); + printf("\naborted via keyboard!\n"); + return 0; + } - if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, TRUE, i)) { - PrintAndLog("Aquireing data from device failed. Quitting"); - return 0; - } - found = tryDetectModulation(); - - if (found) break; - i++; + if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, TRUE, i)) { + PrintAndLog("Aquireing data from device failed. Quitting"); + return 0; + } + found = tryDetectModulation(); + + if (found) break; + i++; } PrintAndLog(""); if (found) - PrintAndLog("Found valid password: [%08x]", i); + PrintAndLog("Found valid password: [%08x]", i); else - PrintAndLog("Password NOT found. Last tried: [%08x]", --i); + PrintAndLog("Password NOT found. Last tried: [%08x]", --i); return 0; } @@ -1465,7 +1519,7 @@ static command_t CommandTable[] = { {"dump", CmdT55xxDump, 0, "[password] [o] Dump T55xx card block 0-7. Optional [password], [override]"}, {"special", special, 0, "Show block changes with 64 different offsets"}, {"wakeup", CmdT55xxWakeUp, 0, "Send AOR wakeup command"}, - {"wipe", CmdT55xxWipe, 0, "Wipe a T55xx tag and set defaults (will destroy any data on tag)"}, + {"wipe", CmdT55xxWipe, 0, "[q] Wipe a T55xx tag and set defaults (will destroy any data on tag)"}, {NULL, NULL, 0, NULL} }; diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index 56b1b9b7..8ad98597 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -10,6 +10,30 @@ #ifndef CMDLFT55XX_H__ #define CMDLFT55XX_H__ +typedef struct { + uint32_t bl1; + uint32_t bl2; + uint32_t acl; + uint32_t mfc; + uint32_t cid; + uint32_t year; + uint32_t quarter; + uint32_t icr; + uint32_t lotid; + uint32_t wafer; + uint32_t dw; +} t55x7_tracedata_t; + +typedef struct { + uint32_t bl1; + uint32_t bl2; + uint32_t icr; + char lotidc; + uint32_t lotid; + uint32_t wafer; + uint32_t dw; +} t5555_tracedata_t; + typedef struct { enum { DEMOD_NRZ = 0x00, @@ -61,6 +85,7 @@ char * GetModulationStr( uint32_t id); char * GetModelStrFromCID(uint32_t cid); char * GetSelectedModulationStr( uint8_t id); uint32_t PackBits(uint8_t start, uint8_t len, uint8_t *bitstream); +void printT5xxHeader(uint8_t page); void printT55xxBlock(const char *demodStr); int printConfiguration( t55xx_conf_block_t b); @@ -70,4 +95,7 @@ bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5) int special(const char *Cmd); int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password ); +void printT55x7Trace( t55x7_tracedata_t data, uint8_t repeat ); +void printT5555Trace( t5555_tracedata_t data, uint8_t repeat ); + #endif -- 2.39.5 From 3975d477e10caee062f2b491b33dffcfc208ec29 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Thu, 7 Jan 2016 21:54:32 -0500 Subject: [PATCH 07/16] comment out unused includes and defines prep for permanent removal. --- client/cmdlft55xx.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 97061c56..348cb229 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -10,7 +10,7 @@ #include #include #include -#include +//#include //not used - marshmellow #include "proxmark3.h" #include "ui.h" #include "graph.h" @@ -22,14 +22,14 @@ #include "util.h" #include "data.h" #include "lfdemod.h" -#include "../common/crc.h" -#include "../common/iso14443crc.h" -#include "cmdhf14a.h" +//#include "../common/crc.h" //not used - marshmellow +//#include "../common/iso14443crc.h" //not used - marshmellow +#include "cmdhf14a.h" //for getTagInfo #define T55x7_CONFIGURATION_BLOCK 0x00 #define T55x7_PAGE0 0x00 #define T55x7_PAGE1 0x01 -#define T55x7_PWD 0x00000010 +//#define T55x7_PWD 0x00000010 #define REGULAR_READ_MODE_BLOCK 0xFF // Default configuration -- 2.39.5 From c4c3af7c1604f46e048d127d66cf93c9aced8ebe Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Fri, 8 Jan 2016 18:26:56 -0500 Subject: [PATCH 08/16] some @iceman1001 s coverty scan fixes great work! --- armsrc/BigBuf.c | 2 +- armsrc/des.c | 2 +- client/cmdhfepa.c | 1 + client/cmdhficlass.c | 2 +- client/loclass/cipherutils.c | 2 ++ client/util.c | 10 ++++++++++ client/util.h | 4 ++++ 7 files changed, 20 insertions(+), 3 deletions(-) diff --git a/armsrc/BigBuf.c b/armsrc/BigBuf.c index 8f9ee4be..da3b0ce2 100644 --- a/armsrc/BigBuf.c +++ b/armsrc/BigBuf.c @@ -184,7 +184,7 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_ traceLen += iLen; // parity bytes - if (iLen != 0) { + if (num_paritybytes != 0) { if (parity != NULL) { memcpy(trace + traceLen, parity, num_paritybytes); } else { diff --git a/armsrc/des.c b/armsrc/des.c index a81df9c8..f1aa80da 100644 --- a/armsrc/des.c +++ b/armsrc/des.c @@ -274,7 +274,7 @@ uint32_t des_f(uint32_t r, uint8_t* kr){ uint64_t data; uint8_t *sbp; /* sboxpointer */ permute((uint8_t*)e_permtab, (uint8_t*)&r, (uint8_t*)&data); - for(i=0; i<7; ++i) + for(i=0; i<6; ++i) ((uint8_t*)&data)[i] ^= kr[i]; /* Sbox substitution */ diff --git a/client/cmdhfepa.c b/client/cmdhfepa.c index e9c63f20..f9f69a88 100644 --- a/client/cmdhfepa.c +++ b/client/cmdhfepa.c @@ -58,6 +58,7 @@ int CmdHFEPACollectPACENonces(const char *Cmd) } // print nonce PrintAndLog("Length: %d, Nonce: %s", nonce_length, nonce); + free(nonce); } if (i < n - 1) { sleep(d); diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 99070e18..6c85e1c1 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -406,7 +406,7 @@ int CmdHFiClassDecrypt(const char *Cmd) { fclose(f); saveFile(outfilename,"bin", decrypted, blocknum*8); - + free(decrypted); return 0; } diff --git a/client/loclass/cipherutils.c b/client/loclass/cipherutils.c index 83b3c9fa..9a8256bb 100644 --- a/client/loclass/cipherutils.c +++ b/client/loclass/cipherutils.c @@ -171,6 +171,7 @@ void printarr(char * name, uint8_t* arr, int len) } cx += snprintf(output+cx,outsize-cx,"};"); prnlog(output); + free(output); } void printvar(char * name, uint8_t* arr, int len) @@ -188,6 +189,7 @@ void printvar(char * name, uint8_t* arr, int len) } prnlog(output); + free(output); } void printarr_human_readable(char * title, uint8_t* arr, int len) diff --git a/client/util.c b/client/util.c index 32c06e91..c4f7d200 100644 --- a/client/util.c +++ b/client/util.c @@ -497,3 +497,13 @@ void xor(unsigned char *dst, unsigned char *src, size_t len) { int32_t le24toh (uint8_t data[3]) { return (data[2] << 16) | (data[1] << 8) | data[0]; } + +// RotateLeft - Ultralight, Desfire, works on byte level +// 00-01-02 >> 01-02-00 +void rol(uint8_t *data, const size_t len){ + uint8_t first = data[0]; + for (size_t i = 0; i < len-1; i++) { + data[i] = data[i+1]; + } + data[len-1] = first; +} diff --git a/client/util.h b/client/util.h index 6f9a1177..5674adcf 100644 --- a/client/util.h +++ b/client/util.h @@ -17,6 +17,9 @@ #include #include "data.h" +#ifndef ROTR +# define ROTR(x,n) (((uintmax_t)(x) >> (n)) | ((uintmax_t)(x) << ((sizeof(x) * 8) - (n)))) +#endif #ifndef MIN # define MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif @@ -68,3 +71,4 @@ void wiegand_add_parity(uint8_t *target, uint8_t *source, uint8_t length); void xor(unsigned char *dst, unsigned char *src, size_t len); int32_t le24toh(uint8_t data[3]); +void rol(uint8_t *data, const size_t len); -- 2.39.5 From 9fc602c835d9698151c197ced70198cd687eab65 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Thu, 28 Jan 2016 00:27:53 -0500 Subject: [PATCH 09/16] fix print clock as decimal instead of uint8_t --- client/cmddata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmddata.c b/client/cmddata.c index 05c495d9..6dd96ab0 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -982,7 +982,7 @@ int FSKrawDemod(const char *Cmd, bool verbose) // Now output the bitstream to the scrollback by line of 16 bits if (verbose || g_debugMode) { - PrintAndLog("\nUsing Clock:%d, invert:%d, fchigh:%d, fclow:%d", rfLen, invert, fchigh, fclow); + PrintAndLog("\nUsing Clock:%hu, invert:%hu, fchigh:%hu, fclow:%hu", rfLen, invert, fchigh, fclow); PrintAndLog("%s decoded bitstream:",GetFSKType(fchigh,fclow,invert)); printDemodBuff(); } -- 2.39.5 From 0c1cb4aef074f37ac0368103a7e26421705861aa Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Tue, 9 Feb 2016 13:39:46 -0500 Subject: [PATCH 10/16] fix lf viking clone mask bug should be a 32 bit mask not a 16 bit mask also added client feedback. --- client/cmdlfviking.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdlfviking.c b/client/cmdlfviking.c index e43a9748..8c0656d2 100644 --- a/client/cmdlfviking.c +++ b/client/cmdlfviking.c @@ -74,8 +74,8 @@ int CmdVikingClone(const char *Cmd) { Q5 = true; rawID = getVikingBits(id); - - UsbCommand c = {CMD_VIKING_CLONE_TAG,{rawID >> 32, rawID & 0xFFFF, Q5}}; + PrintAndLog("Cloning - ID: %08X, Raw: %08X%08X",id,(uint32_t)(rawID >> 32),(uint32_t) (rawID & 0xFFFFFFFF)); + UsbCommand c = {CMD_VIKING_CLONE_TAG,{rawID >> 32, rawID & 0xFFFFFFFF, Q5}}; clearCommandBuffer(); SendCommand(&c); //check for ACK -- 2.39.5 From 098015eb75be017a965457290df524b6d0c86e90 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Wed, 10 Feb 2016 10:03:28 -0500 Subject: [PATCH 11/16] fix bug in lf standalone mode clone command mixed up parameters. --- armsrc/appmain.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 97817709..782c57fa 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -662,7 +662,7 @@ void SamyRun() SpinDelay(500); CmdHIDdemodFSK(1, &high[selected], &low[selected], 0); - Dbprintf("Recorded %x %x %x", selected, high[selected], low[selected]); + Dbprintf("Recorded %x %x%08x", selected, high[selected], low[selected]); LEDsoff(); LED(selected + 1, 0); @@ -683,7 +683,7 @@ void SamyRun() LED(LED_ORANGE, 0); // record - Dbprintf("Cloning %x %x %x", selected, high[selected], low[selected]); + Dbprintf("Cloning %x %x%08x", selected, high[selected], low[selected]); // wait for button to be released while(BUTTON_PRESS()) @@ -692,8 +692,8 @@ void SamyRun() /* need this delay to prevent catching some weird data */ SpinDelay(500); - CopyHIDtoT55x7(high[selected], low[selected], 0, 0); - Dbprintf("Cloned %x %x %x", selected, high[selected], low[selected]); + CopyHIDtoT55x7(0, high[selected], low[selected], 0); + Dbprintf("Cloned %x %x%08x", selected, high[selected], low[selected]); LEDsoff(); LED(selected + 1, 0); @@ -726,7 +726,7 @@ void SamyRun() // wait for button to be released while(BUTTON_PRESS()) WDT_HIT(); - Dbprintf("%x %x %x", selected, high[selected], low[selected]); + Dbprintf("%x %x%08x", selected, high[selected], low[selected]); CmdHIDsimTAG(high[selected], low[selected], 0); DbpString("Done playing"); if (BUTTON_HELD(1000) > 0) -- 2.39.5 From 33c795d0bd0ba50616072a806fd5b38e1e2ccaef Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 14 Feb 2016 11:07:16 -0500 Subject: [PATCH 12/16] add check to fread call --- client/cmdhficlass.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 6c85e1c1..59b0ddc3 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -1046,7 +1046,11 @@ int CmdHFiClassCloneTag(const char *Cmd) { // else we have to create a share memory int i; fseek(f,startblock*8,SEEK_SET); - fread(tag_data,sizeof(iclass_block_t),endblock - startblock + 1,f); + if ( fread(tag_data,sizeof(iclass_block_t),endblock - startblock + 1,f) == 0 ) { + PrintAndLog("File reading error."); + fclose(f); + return 2; + } uint8_t MAC[4]={0x00,0x00,0x00,0x00}; uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; -- 2.39.5 From fd9172d5c2bca6370fe98f719e2267ac14159c4f Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 14 Feb 2016 11:26:00 -0500 Subject: [PATCH 13/16] @iceman1001 s coverity fixes resource leak in hf mf sniff possible overflow in hf 14a raw - add check to fix --- client/cmdhf14a.c | 181 ++++++++++++++++++++++++------------------- client/cmdhfmf.c | 191 ++++++++++++++++++++++++---------------------- 2 files changed, 204 insertions(+), 168 deletions(-) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 81716db3..330fbec0 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -352,16 +352,16 @@ int CmdHF14AReader(const char *Cmd) PrintAndLog(" x0 -> <1 kByte"); break; case 0x01: - PrintAndLog(" x1 -> 1 kByte"); + PrintAndLog(" x0 -> 1 kByte"); break; case 0x02: - PrintAndLog(" x2 -> 2 kByte"); + PrintAndLog(" x0 -> 2 kByte"); break; case 0x03: - PrintAndLog(" x3 -> 4 kByte"); + PrintAndLog(" x0 -> 4 kByte"); break; case 0x04: - PrintAndLog(" x4 -> 8 kByte"); + PrintAndLog(" x0 -> 8 kByte"); break; } switch (card.ats[pos + 3] & 0xf0) { @@ -458,86 +458,110 @@ int CmdHF14ACUIDs(const char *Cmd) return 1; } +int usage_hf_14a_sim(void) { + PrintAndLog("\n Emulating ISO/IEC 14443 type A tag with 4 or 7 byte UID\n"); + PrintAndLog("Usage: hf 14a sim t u x"); + PrintAndLog(" Options : "); + PrintAndLog(" h : this help"); + PrintAndLog(" t : 1 = MIFARE Classic"); + PrintAndLog(" 2 = MIFARE Ultralight"); + PrintAndLog(" 3 = MIFARE Desfire"); + PrintAndLog(" 4 = ISO/IEC 14443-4"); + PrintAndLog(" 5 = MIFARE Tnp3xxx"); + PrintAndLog(" 6 = MIFARE Mini"); + PrintAndLog(" 7 = NTAG 215 from emu mem"); + PrintAndLog(" u : 4 or 7 byte UID"); + PrintAndLog(" x : (Optional) performs the 'reader attack', nr/ar attack against a legitimate reader"); + PrintAndLog("\n sample : hf 14a sim t 1 u 1122344"); + PrintAndLog(" : hf 14a sim t 1 u 1122344 x\n"); + return 0; +} // ## simulate iso14443a tag // ## greg - added ability to specify tag UID int CmdHF14ASim(const char *Cmd) { - UsbCommand c = {CMD_SIMULATE_TAG_ISO_14443a,{0,0,0}}; - - // Retrieve the tag type - uint8_t tagtype = param_get8ex(Cmd,0,0,10); - - // When no argument was given, just print help message - if (tagtype == 0) { - PrintAndLog(""); - PrintAndLog(" Emulating ISO/IEC 14443 type A tag with 4 or 7 byte UID"); - PrintAndLog(""); - PrintAndLog(" syntax: hf 14a sim "); - PrintAndLog(" types: 1 = MIFARE Classic"); - PrintAndLog(" 2 = MIFARE Ultralight"); - PrintAndLog(" 3 = MIFARE Desfire"); - PrintAndLog(" 4 = ISO/IEC 14443-4"); - PrintAndLog(" 5 = MIFARE Tnp3xxx"); - PrintAndLog(""); - return 1; - } - - // Store the tag type - c.arg[0] = tagtype; - - // Retrieve the full 4 or 7 byte long uid - uint64_t long_uid = param_get64ex(Cmd,1,0,16); - - // Are we handling the (optional) second part uid? - if (long_uid > 0xffffffff) { - PrintAndLog("Emulating ISO/IEC 14443 type A tag with 7 byte UID (%014"llx")",long_uid); - // Store the second part - c.arg[2] = (long_uid & 0xffffffff); - long_uid >>= 32; - // Store the first part, ignore the first byte, it is replaced by cascade byte (0x88) - c.arg[1] = (long_uid & 0xffffff); - } else { - PrintAndLog("Emulating ISO/IEC 14443 type A tag with 4 byte UID (%08x)",long_uid); - // Only store the first part - c.arg[1] = long_uid & 0xffffffff; + bool errors = FALSE; + uint8_t flags = 0; + uint8_t tagtype = 1; + uint64_t uid = 0; + uint8_t cmdp = 0; + + while(param_getchar(Cmd, cmdp) != 0x00) + { + switch(param_getchar(Cmd, cmdp)) + { + case 'h': + case 'H': + return usage_hf_14a_sim(); + case 't': + case 'T': + // Retrieve the tag type + tagtype = param_get8ex(Cmd, cmdp+1, 0, 10); + if (tagtype == 0) + errors = true; + cmdp += 2; + break; + case 'u': + case 'U': + // Retrieve the full 4 or 7 byte long uid + uid = param_get64ex(Cmd, cmdp+1, 0, 16); + if (uid == 0 ) + errors = TRUE; + + if (uid > 0xffffffff) { + PrintAndLog("Emulating ISO/IEC 14443 type A tag with 7 byte UID (%014"llx")",uid); + flags |= FLAG_7B_UID_IN_DATA; + } else { + PrintAndLog("Emulating ISO/IEC 14443 type A tag with 4 byte UID (%08x)",uid); + flags |= FLAG_4B_UID_IN_DATA; + } + cmdp += 2; + break; + case 'x': + case 'X': + flags |= FLAG_NR_AR_ATTACK; + cmdp++; + break; + default: + PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + if(errors) break; } -/* - // At lease save the mandatory first part of the UID - c.arg[0] = long_uid & 0xffffffff; - if (c.arg[1] == 0) { - PrintAndLog("Emulating ISO/IEC 14443 type A tag with UID %01d %08x %08x",c.arg[0],c.arg[1],c.arg[2]); + //Validations + if (errors) return usage_hf_14a_sim(); + + PrintAndLog("Press pm3-button to abort simulation"); + + UsbCommand c = {CMD_SIMULATE_TAG_ISO_14443a,{ tagtype, flags, 0 }}; + + num_to_bytes(uid, 7, c.d.asBytes); + clearCommandBuffer(); + SendCommand(&c); + + //uint8_t data[40]; + //uint8_t key[6]; + UsbCommand resp; + while(!ukbhit()){ + if ( WaitForResponseTimeout(CMD_ACK,&resp,1500)) { + if ( (resp.arg[0] & 0xffff) == CMD_SIMULATE_MIFARE_CARD ){ + // attempt to get key: + // TODO: + + //memset(data, 0x00, sizeof(data)); + //memset(key, 0x00, sizeof(key)); + //int len = (resp.arg[1] > sizeof(data)) ? sizeof(data) : resp.arg[1]; + //memcpy(data, resp.d.asBytes, len); + //tryMfk32(uid, data, key); + //tryMfk32_moebius(uid, data, key); + //tryMfk64(uid, data, key); + //PrintAndLog("--"); + } + } } - - switch (c.arg[0]) { - case 1: { - PrintAndLog("Emulating ISO/IEC 14443-3 type A tag with 4 byte UID"); - UsbCommand c = {CMD_SIMULATE_TAG_ISO_14443a,param_get32ex(Cmd,0,0,10),param_get32ex(Cmd,1,0,16),param_get32ex(Cmd,2,0,16)}; - } break; - case 2: { - PrintAndLog("Emulating ISO/IEC 14443-4 type A tag with 7 byte UID"); - } break; - default: { - PrintAndLog("Error: unkown tag type (%d)",c.arg[0]); - PrintAndLog("syntax: hf 14a sim ",c.arg[0]); - PrintAndLog(" type1: 4 ",c.arg[0]); - - return 1; - } break; - } -*/ -/* - unsigned int hi = 0, lo = 0; - int n = 0, i = 0; - while (sscanf(&Cmd[i++], "%1x", &n ) == 1) { - hi= (hi << 4) | (lo >> 28); - lo= (lo << 4) | (n & 0xf); - } -*/ -// UsbCommand c = {CMD_SIMULATE_TAG_ISO_14443a,param_get32ex(Cmd,0,0,10),param_get32ex(Cmd,1,0,16),param_get32ex(Cmd,2,0,16)}; -// PrintAndLog("Emulating ISO/IEC 14443 type A tag with UID %01d %08x %08x",c.arg[0],c.arg[1],c.arg[2]); - SendCommand(&c); - return 0; + return 0; } int CmdHF14ASnoop(const char *Cmd) { @@ -705,7 +729,8 @@ int CmdHF14ACmdRaw(const char *cmd) { if(topazmode) c.arg[0] |= ISO14A_TOPAZMODE; - // Max buffer is USB_CMD_DATA_SIZE + // Max buffer is USB_CMD_DATA_SIZE + datalen = (datalen > USB_CMD_DATA_SIZE) ? USB_CMD_DATA_SIZE : datalen; c.arg[1] = (datalen & 0xFFFF) | (numbits << 16); memcpy(c.d.asBytes,data,datalen); diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 48e78b1c..21c0cde2 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -121,10 +121,11 @@ int CmdHF14AMfWrBl(const char *Cmd) PrintAndLog("--block no:%d, key type:%c, key:%s", blockNo, keyType?'B':'A', sprint_hex(key, 6)); PrintAndLog("--data: %s", sprint_hex(bldata, 16)); - UsbCommand c = {CMD_MIFARE_WRITEBL, {blockNo, keyType, 0}}; + UsbCommand c = {CMD_MIFARE_WRITEBL, {blockNo, keyType, 0}}; memcpy(c.d.asBytes, key, 6); memcpy(c.d.asBytes + 10, bldata, 16); - SendCommand(&c); + clearCommandBuffer(); + SendCommand(&c); UsbCommand resp; if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { @@ -142,7 +143,7 @@ int CmdHF14AMfRdBl(const char *Cmd) uint8_t blockNo = 0; uint8_t keyType = 0; uint8_t key[6] = {0, 0, 0, 0, 0, 0}; - + char cmdp = 0x00; @@ -150,8 +151,8 @@ int CmdHF14AMfRdBl(const char *Cmd) PrintAndLog("Usage: hf mf rdbl "); PrintAndLog(" sample: hf mf rdbl 0 A FFFFFFFFFFFF "); return 0; - } - + } + blockNo = param_get8(Cmd, 0); cmdp = param_getchar(Cmd, 1); if (cmdp == 0x00) { @@ -164,10 +165,11 @@ int CmdHF14AMfRdBl(const char *Cmd) return 1; } PrintAndLog("--block no:%d, key type:%c, key:%s ", blockNo, keyType?'B':'A', sprint_hex(key, 6)); - - UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}}; + + UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}}; memcpy(c.d.asBytes, key, 6); - SendCommand(&c); + clearCommandBuffer(); + SendCommand(&c); UsbCommand resp; if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { @@ -217,9 +219,10 @@ int CmdHF14AMfRdSc(const char *Cmd) return 1; } PrintAndLog("--sector no:%d key type:%c key:%s ", sectorNo, keyType?'B':'A', sprint_hex(key, 6)); - + UsbCommand c = {CMD_MIFARE_READSC, {sectorNo, keyType, 0}}; memcpy(c.d.asBytes, key, 6); + clearCommandBuffer(); SendCommand(&c); PrintAndLog(" "); @@ -239,7 +242,7 @@ int CmdHF14AMfRdSc(const char *Cmd) PrintAndLog("Command execute timeout"); } - return 0; + return 0; } uint8_t FirstBlockOfSector(uint8_t sectorNo) @@ -263,7 +266,7 @@ uint8_t NumBlocksPerSector(uint8_t sectorNo) int CmdHF14AMfDump(const char *Cmd) { uint8_t sectorNo, blockNo; - + uint8_t keyA[40][6]; uint8_t keyB[40][6]; uint8_t rights[40][4]; @@ -316,16 +319,17 @@ int CmdHF14AMfDump(const char *Cmd) return 2; } } - + fclose(fin); PrintAndLog("|-----------------------------------------|"); PrintAndLog("|------ Reading sector access bits...-----|"); PrintAndLog("|-----------------------------------------|"); - + for (sectorNo = 0; sectorNo < numSectors; sectorNo++) { UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 0, 0}}; memcpy(c.d.asBytes, keyA[sectorNo], 6); + clearCommandBuffer(); SendCommand(&c); if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { @@ -347,11 +351,11 @@ int CmdHF14AMfDump(const char *Cmd) rights[sectorNo][3] = 0x01; } } - + PrintAndLog("|-----------------------------------------|"); PrintAndLog("|----- Dumping all blocks to file... -----|"); PrintAndLog("|-----------------------------------------|"); - + bool isOK = true; for (sectorNo = 0; isOK && sectorNo < numSectors; sectorNo++) { for (blockNo = 0; isOK && blockNo < NumBlocksPerSector(sectorNo); blockNo++) { @@ -360,6 +364,7 @@ int CmdHF14AMfDump(const char *Cmd) if (blockNo == NumBlocksPerSector(sectorNo) - 1) { // sector trailer. At least the Access Conditions can always be read with key A. UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + blockNo, 0, 0}}; memcpy(c.d.asBytes, keyA[sectorNo], 6); + clearCommandBuffer(); SendCommand(&c); received = WaitForResponseTimeout(CMD_ACK,&resp,1500); } else { // data block. Check if it can be read with key A or key B @@ -367,6 +372,7 @@ int CmdHF14AMfDump(const char *Cmd) if ((rights[sectorNo][data_area] == 0x03) || (rights[sectorNo][data_area] == 0x05)) { // only key B would work UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + blockNo, 1, 0}}; memcpy(c.d.asBytes, keyB[sectorNo], 6); + clearCommandBuffer(); SendCommand(&c); received = WaitForResponseTimeout(CMD_ACK,&resp,1500); } else if (rights[sectorNo][data_area] == 0x07) { // no key would work @@ -375,6 +381,7 @@ int CmdHF14AMfDump(const char *Cmd) } else { // key A would work UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + blockNo, 0, 0}}; memcpy(c.d.asBytes, keyA[sectorNo], 6); + clearCommandBuffer(); SendCommand(&c); received = WaitForResponseTimeout(CMD_ACK,&resp,1500); } @@ -518,6 +525,7 @@ int CmdHF14AMfRestore(const char *Cmd) PrintAndLog("Writing to block %3d: %s", FirstBlockOfSector(sectorNo) + blockNo, sprint_hex(bldata, 16)); memcpy(c.d.asBytes + 10, bldata, 16); + clearCommandBuffer(); SendCommand(&c); UsbCommand resp; @@ -1069,6 +1077,7 @@ int CmdHF14AMf1kSim(const char *Cmd) UsbCommand c = {CMD_SIMULATE_MIFARE_CARD, {flags, exitAfterNReads,0}}; memcpy(c.d.asBytes, uid, sizeof(uid)); + clearCommandBuffer(); SendCommand(&c); if(flags & FLAG_INTERACTIVE) @@ -1077,7 +1086,7 @@ int CmdHF14AMf1kSim(const char *Cmd) PrintAndLog("Press pm3-button to abort simulation"); while(! WaitForResponseTimeout(CMD_ACK,&resp,1500)) { //We're waiting only 1.5 s at a time, otherwise we get the - // annoying message about "Waiting for a response... " + //annoying message about "Waiting for a response... " } } @@ -1144,7 +1153,6 @@ int CmdHF14AMfEClear(const char *Cmd) return 0; } - int CmdHF14AMfESet(const char *Cmd) { uint8_t memBlock[16]; @@ -1172,7 +1180,6 @@ int CmdHF14AMfESet(const char *Cmd) return 0; } - int CmdHF14AMfELoad(const char *Cmd) { FILE * f; @@ -1182,13 +1189,13 @@ int CmdHF14AMfELoad(const char *Cmd) uint8_t buf8[64] = {0x00}; int i, len, blockNum, numBlocks; int nameParamNo = 1; - + uint8_t blockWidth = 32; char ctmp = param_getchar(Cmd, 0); if ( ctmp == 'h' || ctmp == 0x00) { PrintAndLog("It loads emul dump from the file `filename.eml`"); - PrintAndLog("Usage: hf mf eload [card memory] "); - PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K"); + PrintAndLog("Usage: hf mf eload [card memory] [numblocks]"); + PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K, u = UL"); PrintAndLog(""); PrintAndLog(" sample: hf mf eload filename"); PrintAndLog(" hf mf eload 4 filename"); @@ -1201,14 +1208,17 @@ int CmdHF14AMfELoad(const char *Cmd) case '\0': numBlocks = 16*4; break; case '2' : numBlocks = 32*4; break; case '4' : numBlocks = 256; break; + case 'U' : // fall through + case 'u' : numBlocks = 255; blockWidth = 8; break; default: { numBlocks = 16*4; nameParamNo = 0; } } + uint32_t numblk2 = param_get32ex(Cmd,2,0,10); + if (numblk2 > 0) numBlocks = numblk2; len = param_getstr(Cmd,nameParamNo,filename); - if (len > FILE_PATH_SIZE - 4) len = FILE_PATH_SIZE - 4; fnameptr += len; @@ -1235,19 +1245,18 @@ int CmdHF14AMfELoad(const char *Cmd) return 2; } - if (strlen(buf) < 32){ + if (strlen(buf) < blockWidth){ if(strlen(buf) && feof(f)) break; - PrintAndLog("File content error. Block data must include 32 HEX symbols"); + PrintAndLog("File content error. Block data must include %d HEX symbols", blockWidth); fclose(f); return 2; } - for (i = 0; i < 32; i += 2) { + for (i = 0; i < blockWidth; i += 2) { sscanf(&buf[i], "%02x", (unsigned int *)&buf8[i / 2]); - } - - if (mfEmlSetMem(buf8, blockNum, 1)) { + } + if (mfEmlSetMem_xt(buf8, blockNum, 1, blockWidth/2)) { PrintAndLog("Cant set emul block: %3d", blockNum); fclose(f); return 3; @@ -1268,7 +1277,6 @@ int CmdHF14AMfELoad(const char *Cmd) return 0; } - int CmdHF14AMfESave(const char *Cmd) { FILE * f; @@ -1354,7 +1362,6 @@ int CmdHF14AMfESave(const char *Cmd) return 0; } - int CmdHF14AMfECFill(const char *Cmd) { uint8_t keyType = 0; @@ -1394,7 +1401,6 @@ int CmdHF14AMfECFill(const char *Cmd) return 0; } - int CmdHF14AMfEKeyPrn(const char *Cmd) { int i; @@ -1402,7 +1408,9 @@ int CmdHF14AMfEKeyPrn(const char *Cmd) uint8_t data[16]; uint64_t keyA, keyB; - if (param_getchar(Cmd, 0) == 'h') { + char cmdp = param_getchar(Cmd, 0); + + if ( cmdp == 'h' || cmdp == 'H') { PrintAndLog("It prints the keys loaded in the emulator memory"); PrintAndLog("Usage: hf mf ekeyprn [card memory]"); PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K"); @@ -1411,8 +1419,6 @@ int CmdHF14AMfEKeyPrn(const char *Cmd) return 0; } - char cmdp = param_getchar(Cmd, 0); - switch (cmdp) { case '0' : numSectors = 5; break; case '1' : @@ -1439,7 +1445,6 @@ int CmdHF14AMfEKeyPrn(const char *Cmd) return 0; } - int CmdHF14AMfCSetUID(const char *Cmd) { uint8_t wipeCard = 0; @@ -1513,7 +1518,7 @@ int CmdHF14AMfCSetBlk(const char *Cmd) { uint8_t memBlock[16] = {0x00}; uint8_t blockNo = 0; - bool wipeCard = FALSE; + uint8_t params = MAGIC_SINGLE; int res; if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') { @@ -1532,10 +1537,12 @@ int CmdHF14AMfCSetBlk(const char *Cmd) } char ctmp = param_getchar(Cmd, 2); - wipeCard = (ctmp == 'w' || ctmp == 'W'); + if (ctmp == 'w' || ctmp == 'W') + params |= MAGIC_WIPE; + PrintAndLog("--block number:%2d data:%s", blockNo, sprint_hex(memBlock, 16)); - res = mfCSetBlock(blockNo, memBlock, NULL, wipeCard, CSETBLOCK_SINGLE_OPER); + res = mfCSetBlock(blockNo, memBlock, NULL, params); if (res) { PrintAndLog("Can't write block. error=%d", res); return 1; @@ -1543,18 +1550,21 @@ int CmdHF14AMfCSetBlk(const char *Cmd) return 0; } - int CmdHF14AMfCLoad(const char *Cmd) { FILE * f; - char filename[FILE_PATH_SIZE] = {0x00}; + char filename[FILE_PATH_SIZE]; char * fnameptr = filename; char buf[64] = {0x00}; uint8_t buf8[64] = {0x00}; uint8_t fillFromEmulator = 0; int i, len, blockNum, flags=0; - if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) { + memset(filename, 0, sizeof(filename)); + + char ctmp = param_getchar(Cmd, 0); + + if (ctmp == 'h' || ctmp == 'H' || ctmp == 0x00) { PrintAndLog("It loads magic Chinese card from the file `filename.eml`"); PrintAndLog("or from emulator memory (option `e`)"); PrintAndLog("Usage: hf mf cload "); @@ -1563,7 +1573,6 @@ int CmdHF14AMfCLoad(const char *Cmd) return 0; } - char ctmp = param_getchar(Cmd, 0); if (ctmp == 'e' || ctmp == 'E') fillFromEmulator = 1; if (fillFromEmulator) { @@ -1572,11 +1581,11 @@ int CmdHF14AMfCLoad(const char *Cmd) PrintAndLog("Cant get block: %d", blockNum); return 2; } - if (blockNum == 0) flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC; // switch on field and send magic sequence + if (blockNum == 0) flags = MAGIC_INIT + MAGIC_WUPC; // switch on field and send magic sequence if (blockNum == 1) flags = 0; // just write - if (blockNum == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD; // Done. Magic Halt and switch off field. + if (blockNum == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF; // Done. Magic Halt and switch off field. - if (mfCSetBlock(blockNum, buf8, NULL, 0, flags)) { + if (mfCSetBlock(blockNum, buf8, NULL, flags)) { PrintAndLog("Cant set magic card block: %d", blockNum); return 3; } @@ -1619,11 +1628,11 @@ int CmdHF14AMfCLoad(const char *Cmd) for (i = 0; i < 32; i += 2) sscanf(&buf[i], "%02x", (unsigned int *)&buf8[i / 2]); - if (blockNum == 0) flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC; // switch on field and send magic sequence + if (blockNum == 0) flags = MAGIC_INIT + MAGIC_WUPC; // switch on field and send magic sequence if (blockNum == 1) flags = 0; // just write - if (blockNum == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD; // Done. Switch off field. + if (blockNum == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF; // Done. Switch off field. - if (mfCSetBlock(blockNum, buf8, NULL, 0, flags)) { + if (mfCSetBlock(blockNum, buf8, NULL, flags)) { PrintAndLog("Can't set magic card block: %d", blockNum); return 3; } @@ -1644,12 +1653,13 @@ int CmdHF14AMfCLoad(const char *Cmd) } int CmdHF14AMfCGetBlk(const char *Cmd) { - uint8_t memBlock[16]; + uint8_t data[16]; uint8_t blockNo = 0; int res; - memset(memBlock, 0x00, sizeof(memBlock)); + memset(data, 0x00, sizeof(data)); + char ctmp = param_getchar(Cmd, 0); - if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') { + if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') { PrintAndLog("Usage: hf mf cgetblk "); PrintAndLog("sample: hf mf cgetblk 1"); PrintAndLog("Get block data from magic Chinese card (only works with such cards)\n"); @@ -1660,28 +1670,29 @@ int CmdHF14AMfCGetBlk(const char *Cmd) { PrintAndLog("--block number:%2d ", blockNo); - res = mfCGetBlock(blockNo, memBlock, CSETBLOCK_SINGLE_OPER); + res = mfCGetBlock(blockNo, data, MAGIC_SINGLE); if (res) { PrintAndLog("Can't read block. error=%d", res); return 1; } - PrintAndLog("block data:%s", sprint_hex(memBlock, 16)); + PrintAndLog("block data:%s", sprint_hex(data, sizeof(data))); return 0; } - int CmdHF14AMfCGetSc(const char *Cmd) { - uint8_t memBlock[16] = {0x00}; + uint8_t data[16]; uint8_t sectorNo = 0; int i, res, flags; + memset(data, 0x00, sizeof(data)); + char ctmp = param_getchar(Cmd, 0); - if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') { + if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') { PrintAndLog("Usage: hf mf cgetsc "); PrintAndLog("sample: hf mf cgetsc 0"); PrintAndLog("Get sector data from magic Chinese card (only works with such cards)\n"); return 0; - } + } sectorNo = param_get8(Cmd, 0); if (sectorNo > 15) { @@ -1690,37 +1701,37 @@ int CmdHF14AMfCGetSc(const char *Cmd) { } PrintAndLog("--sector number:%d ", sectorNo); + PrintAndLog("block | data"); - flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC; + flags = MAGIC_INIT + MAGIC_WUPC; for (i = 0; i < 4; i++) { if (i == 1) flags = 0; - if (i == 3) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD; + if (i == 3) flags = MAGIC_HALT + MAGIC_OFF; - res = mfCGetBlock(sectorNo * 4 + i, memBlock, flags); + res = mfCGetBlock(sectorNo * 4 + i, data, flags); if (res) { PrintAndLog("Can't read block. %d error=%d", sectorNo * 4 + i, res); return 1; } - - PrintAndLog("block %3d data:%s", sectorNo * 4 + i, sprint_hex(memBlock, 16)); + PrintAndLog(" %3d | %s", sectorNo * 4 + i, sprint_hex(data, sizeof(data))); } return 0; } - int CmdHF14AMfCSave(const char *Cmd) { FILE * f; - char filename[FILE_PATH_SIZE] = {0x00}; + char filename[FILE_PATH_SIZE]; char * fnameptr = filename; uint8_t fillFromEmulator = 0; - uint8_t buf[64] = {0x00}; + uint8_t buf[64]; int i, j, len, flags; - - // memset(filename, 0, sizeof(filename)); - // memset(buf, 0, sizeof(buf)); - if (param_getchar(Cmd, 0) == 'h') { + memset(filename, 0, sizeof(filename)); + memset(buf, 0, sizeof(buf)); + char ctmp = param_getchar(Cmd, 0); + + if ( ctmp == 'h' || ctmp == 'H' ) { PrintAndLog("It saves `magic Chinese` card dump into the file `filename.eml` or `cardID.eml`"); PrintAndLog("or into emulator memory (option `e`)"); PrintAndLog("Usage: hf mf esave [file name w/o `.eml`][e]"); @@ -1728,23 +1739,21 @@ int CmdHF14AMfCSave(const char *Cmd) { PrintAndLog(" hf mf esave filename"); PrintAndLog(" hf mf esave e \n"); return 0; - } - - char ctmp = param_getchar(Cmd, 0); + } if (ctmp == 'e' || ctmp == 'E') fillFromEmulator = 1; if (fillFromEmulator) { // put into emulator - flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC; + flags = MAGIC_INIT + MAGIC_WUPC; for (i = 0; i < 16 * 4; i++) { if (i == 1) flags = 0; - if (i == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD; - + if (i == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF; + if (mfCGetBlock(i, buf, flags)) { PrintAndLog("Cant get block: %d", i); break; } - + if (mfEmlSetMem(buf, i, 1)) { PrintAndLog("Cant set emul block: %d", i); return 3; @@ -1754,15 +1763,15 @@ int CmdHF14AMfCSave(const char *Cmd) { } else { len = strlen(Cmd); if (len > FILE_PATH_SIZE - 4) len = FILE_PATH_SIZE - 4; - + + // get filename based on UID if (len < 1) { - // get filename - if (mfCGetBlock(0, buf, CSETBLOCK_SINGLE_OPER)) { + + if (mfCGetBlock(0, buf, MAGIC_SINGLE)) { PrintAndLog("Cant get block: %d", 0); len = sprintf(fnameptr, "dump"); fnameptr += len; - } - else { + } else { for (j = 0; j < 7; j++, fnameptr += 2) sprintf(fnameptr, "%02x", buf[j]); } @@ -1771,8 +1780,9 @@ int CmdHF14AMfCSave(const char *Cmd) { fnameptr += len; } + // add .eml extension sprintf(fnameptr, ".eml"); - + // open file f = fopen(filename, "w+"); @@ -1782,10 +1792,10 @@ int CmdHF14AMfCSave(const char *Cmd) { } // put hex - flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC; + flags = MAGIC_INIT + MAGIC_WUPC; for (i = 0; i < 16 * 4; i++) { if (i == 1) flags = 0; - if (i == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD; + if (i == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF; if (mfCGetBlock(i, buf, flags)) { PrintAndLog("Cant get block: %d", i); @@ -1795,15 +1805,13 @@ int CmdHF14AMfCSave(const char *Cmd) { fprintf(f, "%02x", buf[j]); fprintf(f,"\n"); } + fflush(f); fclose(f); - PrintAndLog("Saved to file: %s", filename); - return 0; } } - int CmdHF14AMfSniff(const char *Cmd){ bool wantLogToFile = 0; @@ -1873,7 +1881,10 @@ int CmdHF14AMfSniff(const char *Cmd){ uint16_t traceLen = resp.arg[1]; len = resp.arg[2]; - if (res == 0) return 0; // we are done + if (res == 0) { + free(buf); + return 0; // we are done + } if (res == 1) { // there is (more) data to be transferred if (pckNum == 0) { // first packet, (re)allocate necessary buffer @@ -1952,7 +1963,7 @@ int CmdHF14AMfSniff(const char *Cmd){ } //needs nt, ar, at, Data to decrypt -int CmdDecryptTraceCmds(const char *Cmd){ +int CmdHf14MfDecryptBytes(const char *Cmd){ uint8_t data[50]; int len = 0; param_gethex_ex(Cmd,3,data,&len); @@ -1986,7 +1997,7 @@ static command_t CommandTable[] = {"cgetsc", CmdHF14AMfCGetSc, 0, "Read sector - Magic Chinese card"}, {"cload", CmdHF14AMfCLoad, 0, "Load dump into magic Chinese card"}, {"csave", CmdHF14AMfCSave, 0, "Save dump from magic Chinese card into file or emulator"}, - {"decrypt", CmdDecryptTraceCmds,1, "[nt] [ar_enc] [at_enc] [data] - to decrypt snoop or trace"}, + {"decrypt", CmdHf14MfDecryptBytes,1, "[nt] [ar_enc] [at_enc] [data] - to decrypt snoop or trace"}, {NULL, NULL, 0, NULL} }; -- 2.39.5 From 3d4982ddbfebc7eca00daf644ac6dee937488d61 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 14 Feb 2016 11:42:34 -0500 Subject: [PATCH 14/16] =?utf8?q?FIX:=20Coverity,=20unintended=20sign=20ext?= =?utf8?q?ention,=20CID=20#121363,=20(numbits=20<<=2016=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit …) becomes int, then uint64_t. But the signness might set all upper bits to 1 in the process. from @iceman1001 . --- client/cmdhf14a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 330fbec0..b369d187 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -731,7 +731,7 @@ int CmdHF14ACmdRaw(const char *cmd) { // Max buffer is USB_CMD_DATA_SIZE datalen = (datalen > USB_CMD_DATA_SIZE) ? USB_CMD_DATA_SIZE : datalen; - c.arg[1] = (datalen & 0xFFFF) | (numbits << 16); + c.arg[1] = (datalen & 0xFFFF) | ( (uint32_t)(numbits) << 16); memcpy(c.d.asBytes,data,datalen); SendCommand(&c); -- 2.39.5 From 7a616c0d70d3018c6bf81095f7432543a38ad3c9 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 14 Feb 2016 12:06:29 -0500 Subject: [PATCH 15/16] =?utf8?q?FIX,=20Coverity,=20Argument=20can't=20be?= =?utf8?q?=20negative.=20CID#=20212322,=20ftell(f)=20can=20=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit …be negative. Not allowed in malloc... from @iceman1001 --- client/cmdhficlass.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 59b0ddc3..a169e827 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -283,8 +283,12 @@ int CmdHFiClassELoad(const char *Cmd) { long fsize = ftell(f); fseek(f, 0, SEEK_SET); - uint8_t *dump = malloc(fsize); + if (fsize < 0) { + PrintAndLog("Error, when getting filesize"); + return 1; + } + uint8_t *dump = malloc(fsize); size_t bytes_read = fread(dump, 1, fsize, f); fclose(f); -- 2.39.5 From eb5b63b4a6b07fb9d7034c11d99408033613b1d5 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 14 Feb 2016 12:13:22 -0500 Subject: [PATCH 16/16] =?utf8?q?FIX,=20Coverity,=20Argument=20can't=20be?= =?utf8?q?=20negative.=20CID#=20212322,=20ftell(f)=20can=20=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit …be negative. Not allowed in malloc... from iceman1001 --- client/cmdhficlass.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index a169e827..67bcbe76 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -285,6 +285,7 @@ int CmdHFiClassELoad(const char *Cmd) { if (fsize < 0) { PrintAndLog("Error, when getting filesize"); + fclose(f); return 1; } @@ -1506,6 +1507,12 @@ static int loadKeys(char *filename) { long fsize = ftell(f); fseek(f, 0, SEEK_SET); + if ( fsize < 0 ) { + PrintAndLog("Error, when getting filesize"); + fclose(f); + return 1; + } + uint8_t *dump = malloc(fsize); size_t bytes_read = fread(dump, 1, fsize, f); -- 2.39.5