From 85f1785ccb564154a587ccd5dd36a6182473606a Mon Sep 17 00:00:00 2001 From: phaseloop Date: Thu, 15 Dec 2022 20:51:54 +0000 Subject: [PATCH 01/37] initial bruteforce module --- armsrc/em4x50.c | 1 + client/src/cmdlfem4x50.c | 48 +++++++++---- common/bruteforce.c | 149 +++++++++++++++++++++++++++++++++++++++ common/bruteforce.h | 78 ++++++++++++++++++++ include/em4x50.h | 3 + 5 files changed, 267 insertions(+), 12 deletions(-) create mode 100644 common/bruteforce.c create mode 100644 common/bruteforce.h diff --git a/armsrc/em4x50.c b/armsrc/em4x50.c index 86d44cd9a..bc0c255fa 100644 --- a/armsrc/em4x50.c +++ b/armsrc/em4x50.c @@ -27,6 +27,7 @@ #include "BigBuf.h" #include "spiffs.h" #include "appmain.h" // tear +#include "bruteforce.h" // Sam7s has several timers, we will use the source TIMER_CLOCK1 (aka AT91C_TC_CLKS_TIMER_DIV1_CLOCK) // TIMER_CLOCK1 = MCK/2, MCK is running at 48 MHz, Timer is running at 48/2 = 24 MHz diff --git a/client/src/cmdlfem4x50.c b/client/src/cmdlfem4x50.c index 3bed45d1d..a4083d3d0 100644 --- a/client/src/cmdlfem4x50.c +++ b/client/src/cmdlfem4x50.c @@ -349,26 +349,50 @@ int CmdEM4x50Brute(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "lf em 4x50 brute", "Tries to bruteforce the password of a EM4x50 card.\n" - "Function can be stopped by pressing pm3 button.", - "lf em 4x50 brute --first 12330000 --last 12340000 -> tries pwds from 0x12330000 to 0x1234000000\n" + "Function can be stopped by pressing pm3 button.\n", + + "lf em 4x50 brute --mode range --begin 12330000 --end 12340000 -> tries pwds from 0x12330000 to 0x12340000\n" + "lf em 4x50 brute --mode charset --digits --uppercase -> tries all combinations of ASCII codes for digits and uppercase letters\n" ); void *argtable[] = { arg_param_begin, - arg_str1(NULL, "first", "", "first password (start), 4 bytes, lsb"), - arg_str1(NULL, "last", "", "last password (stop), 4 bytes, lsb"), + arg_str1(NULL, "mode", "", "Bruteforce mode (range|charset)"), + arg_str0(NULL, "begin", "", "Range mode - start of the key range"), + arg_str0(NULL, "end", "", "Range mode - end of the key range"), + arg_lit0(NULL, "digits", "Charset mode - include ASCII codes for digits"), + arg_lit0(NULL, "uppercase", "Charset mode - include ASCII codes for uppercase letters"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); - int first_len = 0; - uint8_t first[4] = {0, 0, 0, 0}; - CLIGetHexWithReturn(ctx, 1, first, &first_len); - int last_len = 0; - uint8_t last[4] = {0, 0, 0, 0}; - CLIGetHexWithReturn(ctx, 2, last, &last_len); - CLIParserFree(ctx); + em4x50_data_t etd; + + int mode_len = 64; + char mode[64]; + CLIGetStrWithReturn(ctx, 1, (uint8_t*) mode, &mode_len); + PrintAndLogEx(INFO, "Chosen mode: %s", mode); + + if(strcmp(mode, "range") == 0){ + etd.bruteforce_mode = BRUTEFORCE_MODE_RANGE; + } else if(strcmp(mode, "charset") == 0){ + etd.bruteforce_mode = BRUTEFORCE_MODE_CHARSET; + } else { + PrintAndLogEx(FAILED, "unknown bruteforce mode: %s", mode); + return PM3_EINVARG; + } + + PrintAndLogEx(INFO, "Chosen mode2: %d", etd.bruteforce_mode); + + // int first_len = 0; + // uint8_t first[4] = {0, 0, 0, 0}; + // CLIGetHexWithReturn(ctx, 1, first, &first_len); + // int last_len = 0; + // uint8_t last[4] = {0, 0, 0, 0}; + // CLIGetHexWithReturn(ctx, 2, last, &last_len); + CLIParserFree(ctx); +/* if (first_len != 4) { PrintAndLogEx(FAILED, "password length must be 4 bytes"); return PM3_EINVARG; @@ -410,7 +434,7 @@ int CmdEM4x50Brute(const char *Cmd) { PrintAndLogEx(SUCCESS, "found valid password [ " _GREEN_("%08"PRIX32) " ]", resp.data.asDwords[0]); else PrintAndLogEx(WARNING, "brute pwd failed"); - +*/ return PM3_SUCCESS; } diff --git a/common/bruteforce.c b/common/bruteforce.c new file mode 100644 index 000000000..1d5535277 --- /dev/null +++ b/common/bruteforce.c @@ -0,0 +1,149 @@ +//----------------------------------------------------------------------------- +// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// See LICENSE.txt for the text of the license. +//----------------------------------------------------------------------------- + +#include "bruteforce.h" +#include +#include + +uint8_t charset_digits[] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', +}; + +uint8_t charset_uppercase[] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', + 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'W', + 'X', 'Y', 'Z' +}; + +void generator_init(generator_context_t* ctx, uint8_t mode){ + memset(ctx, 0, sizeof(generator_context_t)); + ctx->mode = mode; +} + +int generator_set_charset(generator_context_t* ctx, uint8_t charsets){ + if (ctx->mode != BRUTEFORCE_MODE_CHARSET){ + return -1; + } + + if(charsets & CHARSET_DIGITS){ + memcpy(ctx->charset, charset_digits, sizeof(charset_digits)); + ctx->charset_length += sizeof(charset_digits); + } + + if(charsets & CHARSET_UPPERCASE){ + memcpy(ctx->charset+ctx->charset_length, charset_uppercase, sizeof(charset_uppercase)); + ctx->charset_length += sizeof(charset_uppercase); + } +} + +int generate32(generator_context_t *ctx){ + + switch(ctx->mode){ + case BRUTEFORCE_MODE_RANGE: + return _generate_mode_range32(ctx); + case BRUTEFORCE_MODE_CHARSET: + return _generate_mode_charset32(ctx); + } +} + +int _generate_mode_range32(generator_context_t *ctx){ + + if(ctx->current_key32 >= ctx->range_high){ + return GENERATOR_END; + } + + // we use flag1 as indicator if value of range_low was already emitted + // so the range generated is + if(ctx->current_key32 <= ctx->range_low && ctx->flag1==false){ + ctx->current_key32 = ctx->range_low; + ctx->pos[0] = true; + return GENERATOR_NEXT; + } + + ctx->current_key32++; + return GENERATOR_NEXT; +} + +int _generate_mode_charset32(generator_context_t *ctx){ + + if(ctx->flag1) + return GENERATOR_END; + + char str[5]; + for (int i = 0; i < 5;i++) + str[i] = ctx->charset[ctx->pos[i]]; + str[4] = 0; + printf("%s\n", str); + + ctx->current_key32 = ctx->charset[ctx->pos[0]] << 24 | ctx->charset[ctx->pos[1]] << 16 | + ctx->charset[ctx->pos[2]] << 8 | ctx->charset[ctx->pos[3]]; + + + if(array_increment(ctx->pos, 4, ctx->charset_length) == -1) + // set flag1 to emit value last time and end generation + ctx->flag1 = true; + + return GENERATOR_NEXT; +} + +// increments values in array with carryover using modulo limit for each byte +// this is used to iterate each byte in key over charset table +// returns -1 if incrementing reaches its end +int array_increment(uint8_t *data, uint8_t data_len, uint8_t modulo){ + + uint8_t prev_value; + + // check if we reached max value already + uint8_t i; + for (i = 0; i < data_len; i++) + if(data[i] < modulo - 1) + break; + + if(i == data_len) + return -1; + + for (uint8_t pos = data_len - 1;; pos--){ + prev_value = ++data[pos]; + data[pos] = data[pos] % modulo; + if (prev_value == data[pos]) + return 0; + else if (pos == 0){ + // we cannot carryover to next byte + // with the max value check in place before, we should not reach this place + return -1; + } + } + + return 0; +} + +/* +int main(){ + generator_context_t ctx; + generator_init(&ctx, BRUTEFORCE_MODE_CHARSET); + generator_set_charset(&ctx, CHARSET_DIGITS | CHARSET_UPPERCASE); + + int ret = 0; + while( (ret=generate32(&ctx)) == GENERATOR_NEXT){ + printf("%X\n", ctx.current_key32); + } + + // printf("Charset len: %d\n", ctx.charset_length); + // printf("Digits len: %d\n", sizeof(charset_digits)); + // printf("Uppercase len: %d\n", sizeof(charset_uppercase)); + return 1; +} +*/ \ No newline at end of file diff --git a/common/bruteforce.h b/common/bruteforce.h new file mode 100644 index 000000000..2b856dfa7 --- /dev/null +++ b/common/bruteforce.h @@ -0,0 +1,78 @@ +//----------------------------------------------------------------------------- +// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// See LICENSE.txt for the text of the license. +//----------------------------------------------------------------------------- +// functions for bruteforcing card keys +//----------------------------------------------------------------------------- + +#ifndef __BRUTEFORCE_H +#define __BRUTEFORCE_H + +#include "common.h" + +typedef uint8_t bruteforce_mode_t; +// bruteforcing all keys sequentially between X and Y +#define BRUTEFORCE_MODE_RANGE 1 + +// try keys based on limited charset/passphrases +// some payment systems use user-provided passphrase as system key +#define BRUTEFORCE_MODE_CHARSET 2 + +// "smart" mode - try some predictable patterns +#define BRUTEFORCE_MODE_SMART 3 + + +typedef uint8_t bruteforce_charset_t; +#define CHARSET_DIGITS 1 +#define CHARSET_UPPERCASE 2 + +#define GENERATOR_END 0 +#define GENERATOR_NEXT 1 +#define GENERATOR_ERROR 2 + +#define CHARSET_DIGITS_SIZE 10 +#define CHARSET_UPPERCASE_SIZE 25 + +extern uint8_t charset_digits[]; +extern uint8_t charset_uppercase[]; + +// structure to hold key generator temporary data +typedef struct { + // position of each of 4 bytes in 32 bit key in charset mode + // add more bytes to support larger keys + // pos[0] is most significant byte - all maths avoid relying on little/big endian memory layout + uint8_t pos[4]; + uint32_t current_key32; + uint8_t mode; + uint8_t charset[ + CHARSET_DIGITS_SIZE + + CHARSET_UPPERCASE_SIZE + ]; + uint8_t charset_length; + + uint32_t range_low; + uint32_t range_high; + // flags to use internally by generators as they wish + bool flag1, flag2, flag3; + +} generator_context_t; + +void generator_init(generator_context_t *ctx, uint8_t mode); +int generator_set_charset(generator_context_t *ctx, uint8_t charsets); +int generate32(generator_context_t *ctx); +int _generate_mode_range32(generator_context_t *ctx); +int _generate_mode_charset32(generator_context_t *ctx); +int _generate_mode_smart32(generator_context_t *ctx); +int array_increment(uint8_t *data, uint8_t data_len, uint8_t modulo); +#endif \ No newline at end of file diff --git a/include/em4x50.h b/include/em4x50.h index bed01901c..9bf1ffc24 100644 --- a/include/em4x50.h +++ b/include/em4x50.h @@ -20,6 +20,7 @@ #define EM4X50_H__ #include "common.h" +#include "bruteforce.h" #define EM4X50_NO_WORDS 34 @@ -62,6 +63,8 @@ typedef struct { uint32_t password2; uint32_t word; uint32_t addresses; + bruteforce_mode_t bruteforce_mode; + bruteforce_charset_t bruteforce_charset; } PACKED em4x50_data_t; typedef struct { From f09a8cfa281e49ab4e2e19c8ecc5d6ba095fb130 Mon Sep 17 00:00:00 2001 From: phaseloop Date: Fri, 5 May 2023 12:57:47 +0000 Subject: [PATCH 02/37] add bruteforce parameters to command line --- armsrc/em4x50.c | 2 +- client/src/cmdlfem4x50.c | 97 +++++++++++++++++++++++++++------------- common/bruteforce.h | 1 + 3 files changed, 69 insertions(+), 31 deletions(-) diff --git a/armsrc/em4x50.c b/armsrc/em4x50.c index bc0c255fa..ed1fdad0e 100644 --- a/armsrc/em4x50.c +++ b/armsrc/em4x50.c @@ -703,7 +703,7 @@ void em4x50_login(uint32_t *password, bool ledcontrol) { reply_ng(CMD_LF_EM4X50_LOGIN, status, NULL, 0); } -// envoke password search +// invoke password search void em4x50_brute(em4x50_data_t *etd, bool ledcontrol) { em4x50_setup_read(); diff --git a/client/src/cmdlfem4x50.c b/client/src/cmdlfem4x50.c index a4083d3d0..a67508848 100644 --- a/client/src/cmdlfem4x50.c +++ b/client/src/cmdlfem4x50.c @@ -19,6 +19,7 @@ #include "cliparser.h" #include "cmdlfem4x50.h" #include +#include #include "cmdparser.h" // command_t #include "util_posix.h" // msclock #include "fileutils.h" @@ -368,6 +369,7 @@ int CmdEM4x50Brute(const char *Cmd) { CLIExecWithReturn(ctx, Cmd, argtable, true); em4x50_data_t etd; + bzero(&etd, sizeof(etd)); int mode_len = 64; char mode[64]; @@ -379,48 +381,83 @@ int CmdEM4x50Brute(const char *Cmd) { } else if(strcmp(mode, "charset") == 0){ etd.bruteforce_mode = BRUTEFORCE_MODE_CHARSET; } else { - PrintAndLogEx(FAILED, "unknown bruteforce mode: %s", mode); + PrintAndLogEx(FAILED, "Unknown bruteforce mode: %s", mode); return PM3_EINVARG; } - PrintAndLogEx(INFO, "Chosen mode2: %d", etd.bruteforce_mode); + if(etd.bruteforce_mode == BRUTEFORCE_MODE_RANGE){ + int begin_len = 0; + uint8_t begin[4] = {0x0}; + CLIGetHexWithReturn(ctx, 2, begin, &begin_len); + + int end_len = 0; + uint8_t end[4] = {0x0}; + CLIGetHexWithReturn(ctx, 3, end, &end_len); + + if(begin_len!=4){ + PrintAndLogEx(FAILED, "'begin' parameter must be 4 bytes"); + return PM3_EINVARG; + } + + if(end_len!=4){ + PrintAndLogEx(FAILED, "'end' parameter must be 4 bytes"); + return PM3_EINVARG; + } + + etd.password1 = BYTES2UINT32_BE(begin); + etd.password2 = BYTES2UINT32_BE(end); + } else if(etd.bruteforce_mode == BRUTEFORCE_MODE_CHARSET){ + bool enable_digits = arg_get_lit(ctx, 4); + bool enable_uppercase = arg_get_lit(ctx, 5); + + if(enable_digits) + etd.bruteforce_charset |= CHARSET_DIGITS; + if(enable_uppercase) + etd.bruteforce_charset |= CHARSET_UPPERCASE; + + if(etd.bruteforce_charset == 0){ + PrintAndLogEx(FAILED, "Please enable at least one charset when using charset bruteforce mode."); + return PM3_EINVARG; + } + + PrintAndLogEx(INFO, "Enabled charsets: %s%s", + enable_digits ? "digits " : "", + enable_uppercase ? "uppercase " : ""); + + } - // int first_len = 0; - // uint8_t first[4] = {0, 0, 0, 0}; - // CLIGetHexWithReturn(ctx, 1, first, &first_len); - // int last_len = 0; - // uint8_t last[4] = {0, 0, 0, 0}; - // CLIGetHexWithReturn(ctx, 2, last, &last_len); CLIParserFree(ctx); -/* - if (first_len != 4) { - PrintAndLogEx(FAILED, "password length must be 4 bytes"); - return PM3_EINVARG; - } - if (last_len != 4) { - PrintAndLogEx(FAILED, "password length must be 4 bytes"); - return PM3_EINVARG; - } - - em4x50_data_t etd; - etd.password1 = BYTES2UINT32_BE(first); - etd.password2 = BYTES2UINT32_BE(last); - + // 27 passwords/second (empirical value) const int speed = 27; + int no_iter = 0; + + if(etd.bruteforce_mode == BRUTEFORCE_MODE_RANGE){ + no_iter = etd.password2 - etd.password1 + 1; + PrintAndLogEx(INFO, "Trying " _YELLOW_("%i") " passwords in range [0x%08x, 0x%08x]" + , no_iter + , etd.password1 + , etd.password2 + ); + } else if(etd.bruteforce_mode == BRUTEFORCE_MODE_CHARSET){ + unsigned int digits = 0; + + if(etd.bruteforce_charset & CHARSET_DIGITS) + digits += CHARSET_DIGITS_SIZE; + + if(etd.bruteforce_charset & CHARSET_UPPERCASE) + digits += CHARSET_UPPERCASE_SIZE; + + no_iter = pow(digits, 4); + } // print some information - int no_iter = etd.password2 - etd.password1 + 1; int dur_s = no_iter / speed; int dur_h = dur_s / 3600; int dur_m = (dur_s - dur_h * 3600) / 60; dur_s -= dur_h * 3600 + dur_m * 60; - PrintAndLogEx(INFO, "Trying " _YELLOW_("%i") " passwords in range [0x%08x, 0x%08x]" - , no_iter - , etd.password1 - , etd.password2 - ); + PrintAndLogEx(INFO, "Estimated duration: %ih %im %is", dur_h, dur_m, dur_s); // start @@ -434,7 +471,7 @@ int CmdEM4x50Brute(const char *Cmd) { PrintAndLogEx(SUCCESS, "found valid password [ " _GREEN_("%08"PRIX32) " ]", resp.data.asDwords[0]); else PrintAndLogEx(WARNING, "brute pwd failed"); -*/ + return PM3_SUCCESS; } @@ -1214,7 +1251,7 @@ int CmdEM4x50Sim(const char *Cmd) { static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"-----------", CmdHelp, AlwaysAvailable, "--------------------- " _CYAN_("operations") " ---------------------"}, - {"brute", CmdEM4x50Brute, IfPm3EM4x50, "Simple bruteforce attack to find password"}, + {"brute", CmdEM4x50Brute, IfPm3EM4x50, "Bruteforce attack to find password"}, {"chk", CmdEM4x50Chk, IfPm3EM4x50, "Check passwords from dictionary"}, {"dump", CmdEM4x50Dump, IfPm3EM4x50, "Dump EM4x50 tag"}, {"info", CmdEM4x50Info, IfPm3EM4x50, "Tag information"}, diff --git a/common/bruteforce.h b/common/bruteforce.h index 2b856dfa7..f01cfd3ca 100644 --- a/common/bruteforce.h +++ b/common/bruteforce.h @@ -34,6 +34,7 @@ typedef uint8_t bruteforce_mode_t; typedef uint8_t bruteforce_charset_t; +// bit flags - can be used together using logical OR #define CHARSET_DIGITS 1 #define CHARSET_UPPERCASE 2 From fa033a98b22f1d94ec208cc7e923356a8d7d0059 Mon Sep 17 00:00:00 2001 From: phaseloop Date: Sat, 6 May 2023 14:45:20 +0000 Subject: [PATCH 03/37] enable em4x50 bruteforce in proxmark firmware --- armsrc/Makefile | 2 ++ armsrc/em4x50.c | 17 +++++++++++++---- common/bruteforce.c | 28 +++++++++++++--------------- common/bruteforce.h | 22 +++++++++++----------- 4 files changed, 39 insertions(+), 30 deletions(-) diff --git a/armsrc/Makefile b/armsrc/Makefile index c0703ccf4..4a088cbf6 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -46,6 +46,7 @@ SRC_CRC = crc.c crc16.c crc32.c SRC_ICLASS = iclass.c optimized_cipherutils.c optimized_ikeys.c optimized_elite.c optimized_cipher.c SRC_LEGIC = legicrf.c legicrfsim.c legic_prng.c SRC_NFCBARCODE = thinfilm.c +SRC_BRUTEFORCE = bruteforce.c # SRC_BEE = bee.c @@ -143,6 +144,7 @@ THUMBSRC = start.c \ $(SRC_FELICA) \ $(SRC_STANDALONE) \ $(SRC_ZX) \ + $(SRC_BRUTEFORCE) \ appmain.c \ printf.c \ dbprint.c \ diff --git a/armsrc/em4x50.c b/armsrc/em4x50.c index ed1fdad0e..5043d753b 100644 --- a/armsrc/em4x50.c +++ b/armsrc/em4x50.c @@ -633,12 +633,21 @@ static int login(uint32_t password) { return PM3_EFAILED; } -// searching for password in given range -static bool brute(uint32_t start, uint32_t stop, uint32_t *pwd) { +// searching for password using chosen bruteforce algorithm +static bool brute(em4x50_data_t *etd, uint32_t *pwd) { + + generator_context_t ctx; bool pwd_found = false; + int generator_ret = 0; int cnt = 0; - for (*pwd = start; *pwd <= stop; (*pwd)++) { + bf_generator_init(&ctx, etd->bruteforce_mode); + + if(etd->bruteforce_mode == BRUTEFORCE_MODE_CHARSET) + bf_generator_set_charset(&ctx, etd->bruteforce_charset); + + while ( (generator_ret=bf_generate32(&ctx)) == GENERATOR_NEXT) { + *pwd = ctx.current_key32; WDT_HIT(); @@ -715,7 +724,7 @@ void em4x50_brute(em4x50_data_t *etd, bool ledcontrol) { LED_C_OFF(); LED_D_ON(); } - bsuccess = brute(etd->password1, etd->password2, &pwd); + bsuccess = brute(etd, &pwd); } if (ledcontrol) LEDsoff(); diff --git a/common/bruteforce.c b/common/bruteforce.c index 1d5535277..62d411240 100644 --- a/common/bruteforce.c +++ b/common/bruteforce.c @@ -28,12 +28,12 @@ uint8_t charset_uppercase[] = { 'X', 'Y', 'Z' }; -void generator_init(generator_context_t* ctx, uint8_t mode){ +void bf_generator_init(generator_context_t* ctx, uint8_t mode){ memset(ctx, 0, sizeof(generator_context_t)); ctx->mode = mode; } -int generator_set_charset(generator_context_t* ctx, uint8_t charsets){ +int bf_generator_set_charset(generator_context_t* ctx, uint8_t charsets){ if (ctx->mode != BRUTEFORCE_MODE_CHARSET){ return -1; } @@ -47,19 +47,23 @@ int generator_set_charset(generator_context_t* ctx, uint8_t charsets){ memcpy(ctx->charset+ctx->charset_length, charset_uppercase, sizeof(charset_uppercase)); ctx->charset_length += sizeof(charset_uppercase); } + + return 0; } -int generate32(generator_context_t *ctx){ +int bf_generate32(generator_context_t *ctx){ switch(ctx->mode){ case BRUTEFORCE_MODE_RANGE: - return _generate_mode_range32(ctx); + return _bf_generate_mode_range32(ctx); case BRUTEFORCE_MODE_CHARSET: - return _generate_mode_charset32(ctx); + return _bf_generate_mode_charset32(ctx); } + + return GENERATOR_ERROR; } -int _generate_mode_range32(generator_context_t *ctx){ +int _bf_generate_mode_range32(generator_context_t *ctx){ if(ctx->current_key32 >= ctx->range_high){ return GENERATOR_END; @@ -77,22 +81,16 @@ int _generate_mode_range32(generator_context_t *ctx){ return GENERATOR_NEXT; } -int _generate_mode_charset32(generator_context_t *ctx){ +int _bf_generate_mode_charset32(generator_context_t *ctx){ if(ctx->flag1) return GENERATOR_END; - char str[5]; - for (int i = 0; i < 5;i++) - str[i] = ctx->charset[ctx->pos[i]]; - str[4] = 0; - printf("%s\n", str); - ctx->current_key32 = ctx->charset[ctx->pos[0]] << 24 | ctx->charset[ctx->pos[1]] << 16 | ctx->charset[ctx->pos[2]] << 8 | ctx->charset[ctx->pos[3]]; - if(array_increment(ctx->pos, 4, ctx->charset_length) == -1) + if(bf_array_increment(ctx->pos, 4, ctx->charset_length) == -1) // set flag1 to emit value last time and end generation ctx->flag1 = true; @@ -102,7 +100,7 @@ int _generate_mode_charset32(generator_context_t *ctx){ // increments values in array with carryover using modulo limit for each byte // this is used to iterate each byte in key over charset table // returns -1 if incrementing reaches its end -int array_increment(uint8_t *data, uint8_t data_len, uint8_t modulo){ +int bf_array_increment(uint8_t *data, uint8_t data_len, uint8_t modulo){ uint8_t prev_value; diff --git a/common/bruteforce.h b/common/bruteforce.h index f01cfd3ca..b8ed3d9ca 100644 --- a/common/bruteforce.h +++ b/common/bruteforce.h @@ -13,11 +13,11 @@ // // See LICENSE.txt for the text of the license. //----------------------------------------------------------------------------- -// functions for bruteforcing card keys +// functions for bruteforcing card keys - key generators //----------------------------------------------------------------------------- -#ifndef __BRUTEFORCE_H -#define __BRUTEFORCE_H +#ifndef BRUTEFORCE_H__ +#define BRUTEFORCE_H__ #include "common.h" @@ -69,11 +69,11 @@ typedef struct { } generator_context_t; -void generator_init(generator_context_t *ctx, uint8_t mode); -int generator_set_charset(generator_context_t *ctx, uint8_t charsets); -int generate32(generator_context_t *ctx); -int _generate_mode_range32(generator_context_t *ctx); -int _generate_mode_charset32(generator_context_t *ctx); -int _generate_mode_smart32(generator_context_t *ctx); -int array_increment(uint8_t *data, uint8_t data_len, uint8_t modulo); -#endif \ No newline at end of file +void bf_generator_init(generator_context_t *ctx, uint8_t mode); +int bf_generator_set_charset(generator_context_t *ctx, uint8_t charsets); +int bf_generate32(generator_context_t *ctx); +int _bf_generate_mode_range32(generator_context_t *ctx); +int _bf_generate_mode_charset32(generator_context_t *ctx); +int _bf_generate_mode_smart32(generator_context_t *ctx); +int bf_array_increment(uint8_t *data, uint8_t data_len, uint8_t modulo); +#endif // BRUTEFORCE_H__ \ No newline at end of file From 19d7851c732781215ec163fca123410442c5ab6f Mon Sep 17 00:00:00 2001 From: PhaseLoop Date: Mon, 8 May 2023 17:08:24 +0000 Subject: [PATCH 04/37] run "make style" --- armsrc/em4x50.c | 4 +- client/src/cmdlfem4x50.c | 48 +++++++-------- client/src/pm3line_vocabulory.h | 1 + common/bruteforce.c | 54 ++++++++--------- common/bruteforce.h | 10 ++-- doc/commands.json | 100 ++++++++++++++++++++------------ doc/commands.md | 5 +- 7 files changed, 124 insertions(+), 98 deletions(-) diff --git a/armsrc/em4x50.c b/armsrc/em4x50.c index 5043d753b..d43a6a15f 100644 --- a/armsrc/em4x50.c +++ b/armsrc/em4x50.c @@ -643,10 +643,10 @@ static bool brute(em4x50_data_t *etd, uint32_t *pwd) { bf_generator_init(&ctx, etd->bruteforce_mode); - if(etd->bruteforce_mode == BRUTEFORCE_MODE_CHARSET) + if (etd->bruteforce_mode == BRUTEFORCE_MODE_CHARSET) bf_generator_set_charset(&ctx, etd->bruteforce_charset); - while ( (generator_ret=bf_generate32(&ctx)) == GENERATOR_NEXT) { + while ((generator_ret = bf_generate32(&ctx)) == GENERATOR_NEXT) { *pwd = ctx.current_key32; WDT_HIT(); diff --git a/client/src/cmdlfem4x50.c b/client/src/cmdlfem4x50.c index a67508848..aeffb9c18 100644 --- a/client/src/cmdlfem4x50.c +++ b/client/src/cmdlfem4x50.c @@ -373,19 +373,19 @@ int CmdEM4x50Brute(const char *Cmd) { int mode_len = 64; char mode[64]; - CLIGetStrWithReturn(ctx, 1, (uint8_t*) mode, &mode_len); + CLIGetStrWithReturn(ctx, 1, (uint8_t *) mode, &mode_len); PrintAndLogEx(INFO, "Chosen mode: %s", mode); - if(strcmp(mode, "range") == 0){ + if (strcmp(mode, "range") == 0) { etd.bruteforce_mode = BRUTEFORCE_MODE_RANGE; - } else if(strcmp(mode, "charset") == 0){ + } else if (strcmp(mode, "charset") == 0) { etd.bruteforce_mode = BRUTEFORCE_MODE_CHARSET; } else { PrintAndLogEx(FAILED, "Unknown bruteforce mode: %s", mode); return PM3_EINVARG; } - if(etd.bruteforce_mode == BRUTEFORCE_MODE_RANGE){ + if (etd.bruteforce_mode == BRUTEFORCE_MODE_RANGE) { int begin_len = 0; uint8_t begin[4] = {0x0}; CLIGetHexWithReturn(ctx, 2, begin, &begin_len); @@ -394,58 +394,58 @@ int CmdEM4x50Brute(const char *Cmd) { uint8_t end[4] = {0x0}; CLIGetHexWithReturn(ctx, 3, end, &end_len); - if(begin_len!=4){ + if (begin_len != 4) { PrintAndLogEx(FAILED, "'begin' parameter must be 4 bytes"); return PM3_EINVARG; } - if(end_len!=4){ + if (end_len != 4) { PrintAndLogEx(FAILED, "'end' parameter must be 4 bytes"); return PM3_EINVARG; } etd.password1 = BYTES2UINT32_BE(begin); etd.password2 = BYTES2UINT32_BE(end); - } else if(etd.bruteforce_mode == BRUTEFORCE_MODE_CHARSET){ + } else if (etd.bruteforce_mode == BRUTEFORCE_MODE_CHARSET) { bool enable_digits = arg_get_lit(ctx, 4); bool enable_uppercase = arg_get_lit(ctx, 5); - if(enable_digits) + if (enable_digits) etd.bruteforce_charset |= CHARSET_DIGITS; - if(enable_uppercase) + if (enable_uppercase) etd.bruteforce_charset |= CHARSET_UPPERCASE; - - if(etd.bruteforce_charset == 0){ + + if (etd.bruteforce_charset == 0) { PrintAndLogEx(FAILED, "Please enable at least one charset when using charset bruteforce mode."); return PM3_EINVARG; } - PrintAndLogEx(INFO, "Enabled charsets: %s%s", - enable_digits ? "digits " : "", - enable_uppercase ? "uppercase " : ""); + PrintAndLogEx(INFO, "Enabled charsets: %s%s", + enable_digits ? "digits " : "", + enable_uppercase ? "uppercase " : ""); } CLIParserFree(ctx); - + // 27 passwords/second (empirical value) const int speed = 27; int no_iter = 0; - if(etd.bruteforce_mode == BRUTEFORCE_MODE_RANGE){ + if (etd.bruteforce_mode == BRUTEFORCE_MODE_RANGE) { no_iter = etd.password2 - etd.password1 + 1; PrintAndLogEx(INFO, "Trying " _YELLOW_("%i") " passwords in range [0x%08x, 0x%08x]" - , no_iter - , etd.password1 - , etd.password2 - ); - } else if(etd.bruteforce_mode == BRUTEFORCE_MODE_CHARSET){ + , no_iter + , etd.password1 + , etd.password2 + ); + } else if (etd.bruteforce_mode == BRUTEFORCE_MODE_CHARSET) { unsigned int digits = 0; - if(etd.bruteforce_charset & CHARSET_DIGITS) + if (etd.bruteforce_charset & CHARSET_DIGITS) digits += CHARSET_DIGITS_SIZE; - if(etd.bruteforce_charset & CHARSET_UPPERCASE) + if (etd.bruteforce_charset & CHARSET_UPPERCASE) digits += CHARSET_UPPERCASE_SIZE; no_iter = pow(digits, 4); @@ -457,7 +457,7 @@ int CmdEM4x50Brute(const char *Cmd) { int dur_m = (dur_s - dur_h * 3600) / 60; dur_s -= dur_h * 3600 + dur_m * 60; - + PrintAndLogEx(INFO, "Estimated duration: %ih %im %is", dur_h, dur_m, dur_s); // start diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index 6b15007c3..f70717c8f 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -349,6 +349,7 @@ const static vocabulory_t vocabulory[] = { { 0, "hf mf gen3freeze" }, { 0, "hf mf ggetblk" }, { 0, "hf mf gload" }, + { 0, "hf mf gsave" }, { 0, "hf mf gsetblk" }, { 0, "hf mf gview" }, { 0, "hf mf ndefformat" }, diff --git a/common/bruteforce.c b/common/bruteforce.c index 62d411240..d4855aefa 100644 --- a/common/bruteforce.c +++ b/common/bruteforce.c @@ -28,50 +28,50 @@ uint8_t charset_uppercase[] = { 'X', 'Y', 'Z' }; -void bf_generator_init(generator_context_t* ctx, uint8_t mode){ +void bf_generator_init(generator_context_t *ctx, uint8_t mode) { memset(ctx, 0, sizeof(generator_context_t)); ctx->mode = mode; } -int bf_generator_set_charset(generator_context_t* ctx, uint8_t charsets){ - if (ctx->mode != BRUTEFORCE_MODE_CHARSET){ +int bf_generator_set_charset(generator_context_t *ctx, uint8_t charsets) { + if (ctx->mode != BRUTEFORCE_MODE_CHARSET) { return -1; } - if(charsets & CHARSET_DIGITS){ + if (charsets & CHARSET_DIGITS) { memcpy(ctx->charset, charset_digits, sizeof(charset_digits)); ctx->charset_length += sizeof(charset_digits); } - if(charsets & CHARSET_UPPERCASE){ - memcpy(ctx->charset+ctx->charset_length, charset_uppercase, sizeof(charset_uppercase)); + if (charsets & CHARSET_UPPERCASE) { + memcpy(ctx->charset + ctx->charset_length, charset_uppercase, sizeof(charset_uppercase)); ctx->charset_length += sizeof(charset_uppercase); } return 0; } -int bf_generate32(generator_context_t *ctx){ +int bf_generate32(generator_context_t *ctx) { - switch(ctx->mode){ + switch (ctx->mode) { case BRUTEFORCE_MODE_RANGE: return _bf_generate_mode_range32(ctx); case BRUTEFORCE_MODE_CHARSET: return _bf_generate_mode_charset32(ctx); - } + } - return GENERATOR_ERROR; + return GENERATOR_ERROR; } -int _bf_generate_mode_range32(generator_context_t *ctx){ - - if(ctx->current_key32 >= ctx->range_high){ +int _bf_generate_mode_range32(generator_context_t *ctx) { + + if (ctx->current_key32 >= ctx->range_high) { return GENERATOR_END; } // we use flag1 as indicator if value of range_low was already emitted // so the range generated is - if(ctx->current_key32 <= ctx->range_low && ctx->flag1==false){ + if (ctx->current_key32 <= ctx->range_low && ctx->flag1 == false) { ctx->current_key32 = ctx->range_low; ctx->pos[0] = true; return GENERATOR_NEXT; @@ -81,44 +81,44 @@ int _bf_generate_mode_range32(generator_context_t *ctx){ return GENERATOR_NEXT; } -int _bf_generate_mode_charset32(generator_context_t *ctx){ +int _bf_generate_mode_charset32(generator_context_t *ctx) { - if(ctx->flag1) + if (ctx->flag1) return GENERATOR_END; ctx->current_key32 = ctx->charset[ctx->pos[0]] << 24 | ctx->charset[ctx->pos[1]] << 16 | ctx->charset[ctx->pos[2]] << 8 | ctx->charset[ctx->pos[3]]; - - if(bf_array_increment(ctx->pos, 4, ctx->charset_length) == -1) + + if (bf_array_increment(ctx->pos, 4, ctx->charset_length) == -1) // set flag1 to emit value last time and end generation ctx->flag1 = true; - + return GENERATOR_NEXT; } // increments values in array with carryover using modulo limit for each byte // this is used to iterate each byte in key over charset table // returns -1 if incrementing reaches its end -int bf_array_increment(uint8_t *data, uint8_t data_len, uint8_t modulo){ - +int bf_array_increment(uint8_t *data, uint8_t data_len, uint8_t modulo) { + uint8_t prev_value; // check if we reached max value already uint8_t i; for (i = 0; i < data_len; i++) - if(data[i] < modulo - 1) + if (data[i] < modulo - 1) break; - if(i == data_len) - return -1; + if (i == data_len) + return -1; - for (uint8_t pos = data_len - 1;; pos--){ + for (uint8_t pos = data_len - 1;; pos--) { prev_value = ++data[pos]; data[pos] = data[pos] % modulo; if (prev_value == data[pos]) return 0; - else if (pos == 0){ + else if (pos == 0) { // we cannot carryover to next byte // with the max value check in place before, we should not reach this place return -1; @@ -144,4 +144,4 @@ int main(){ // printf("Uppercase len: %d\n", sizeof(charset_uppercase)); return 1; } -*/ \ No newline at end of file +*/ diff --git a/common/bruteforce.h b/common/bruteforce.h index b8ed3d9ca..91e01172d 100644 --- a/common/bruteforce.h +++ b/common/bruteforce.h @@ -25,11 +25,11 @@ typedef uint8_t bruteforce_mode_t; // bruteforcing all keys sequentially between X and Y #define BRUTEFORCE_MODE_RANGE 1 -// try keys based on limited charset/passphrases +// try keys based on limited charset/passphrases // some payment systems use user-provided passphrase as system key #define BRUTEFORCE_MODE_CHARSET 2 -// "smart" mode - try some predictable patterns +// "smart" mode - try some predictable patterns #define BRUTEFORCE_MODE_SMART 3 @@ -57,8 +57,8 @@ typedef struct { uint32_t current_key32; uint8_t mode; uint8_t charset[ - CHARSET_DIGITS_SIZE - + CHARSET_UPPERCASE_SIZE + CHARSET_DIGITS_SIZE + + CHARSET_UPPERCASE_SIZE ]; uint8_t charset_length; @@ -76,4 +76,4 @@ int _bf_generate_mode_range32(generator_context_t *ctx); int _bf_generate_mode_charset32(generator_context_t *ctx); int _bf_generate_mode_smart32(generator_context_t *ctx); int bf_array_increment(uint8_t *data, uint8_t data_len, uint8_t modulo); -#endif // BRUTEFORCE_H__ \ No newline at end of file +#endif // BRUTEFORCE_H__ diff --git a/doc/commands.json b/doc/commands.json index a94e5bc6a..633dd198e 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -3391,6 +3391,20 @@ ], "usage": "hf jooki sim [-h] [-b ]" }, + "hf ksx6924 balance": { + "command": "hf ksx6924 balance", + "description": "Gets the current purse balance", + "notes": [ + "hf ksx6924 balance" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-k, --keep keep field ON for next command", + "-a, --apdu Show APDU requests and responses" + ], + "usage": "hf ksx6924 balance [-hka]" + }, "hf ksx6924 help": { "command": "hf ksx6924 help", "description": "help This help", @@ -3399,19 +3413,6 @@ "options": [], "usage": "" }, - "hf ksx6924 select": { - "command": "hf ksx6924 select", - "description": "Selects KS X 6924 application, and leaves field up", - "notes": [ - "hf ksx6924 select" - ], - "offline": false, - "options": [ - "-h, --help This help", - "-a, --apdu Show APDU requests and responses" - ], - "usage": "hf ksx6924 select [-ha]" - }, "hf ksx6924 info": { "command": "hf ksx6924 info", "description": "Get info about a KS X 6924 transit card. This application is used by T-Money (South Korea) and Snapper+ (Wellington, New Zealand).", @@ -3426,23 +3427,9 @@ ], "usage": "hf ksx6924 info [-hka]" }, - "hf ksx6924 balance": { - "command": "hf ksx6924 balance", - "description": "Gets the current purse balance", - "notes": [ - "hf ksx6924 balance" - ], - "offline": false, - "options": [ - "-h, --help This help", - "-k, --keep keep field ON for next command", - "-a, --apdu Show APDU requests and responses" - ], - "usage": "hf ksx6924 balance [-hka]" - }, "hf ksx6924 init": { "command": "hf ksx6924 init", - "description": "Perform transaction initialization (mpda)", + "description": "Perform transaction initialization with Mpda (Money of Purchase Transaction)", "notes": [ "hf ksx6924 init 000003e8 -> Mpda" ], @@ -3468,7 +3455,19 @@ ], "usage": "hf ksx6924 prec [-hka] " }, - + "hf ksx6924 select": { + "command": "hf ksx6924 select", + "description": "Selects KS X 6924 application, and leaves field up", + "notes": [ + "hf ksx6924 select" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-a, --apdu Show APDU requests and responses" + ], + "usage": "hf ksx6924 select [-ha]" + }, "hf legic crc": { "command": "hf legic crc", "description": "Calculates the legic crc8/crc16 on the given data", @@ -3971,7 +3970,7 @@ "--1k MIFARE Classic 1k / S50 (def)", "--2k MIFARE Classic/Plus 2k", "--4k MIFARE Classic 4k / S70", - "--emu from emulator memory" + "--emu to emulator memory" ], "usage": "hf mf csave [-h] [-f ] [--mini] [--1k] [--2k] [--4k] [--emu]" }, @@ -4348,6 +4347,27 @@ ], "usage": "hf mf gload [-hv] [--mini] [--1k] [--2k] [--4k] [-p ] [-f ] [--emu] [--start ] [--end ]" }, + "hf mf gsave": { + "command": "hf mf gsave", + "description": "Save `magic gen4 gtu` card memory into three files (BIN/EML/JSON)or into emulator memory", + "notes": [ + "hf mf gsave", + "hf mf gsave --4k", + "hf mf gsave -p DEADBEEF -f hf-mf-01020304.json" + ], + "offline": false, + "options": [ + "-h, --help This help", + "--mini MIFARE Classic Mini / S20", + "--1k MIFARE Classic 1k / S50 (def)", + "--2k MIFARE Classic/Plus 2k", + "--4k MIFARE Classic 4k / S70", + "-p, --pwd password 4bytes", + "-f, --file filename of dump", + "--emu to emulator memory" + ], + "usage": "hf mf gsave [-h] [--mini] [--1k] [--2k] [--4k] [-p ] [-f ] [--emu]" + }, "hf mf gsetblk": { "command": "hf mf gsetblk", "description": "Set block data on a magic gen4 GTU card", @@ -6176,7 +6196,7 @@ }, "hf mfu esave": { "command": "hf mfu esave", - "description": "Saves emulator memory to a MIFARE Ultralight/NTAG dump file (bin/eml/json) By default number of pages saved depends on defined tag type. You can overrife this with option --end.", + "description": "Saves emulator memory to a MIFARE Ultralight/NTAG dump file (bin/eml/json) By default number of pages saved depends on defined tag type. You can override this with option --end.", "notes": [ "hf mfu esave", "hf mfu esave --end 255 -> saves whole memory", @@ -6192,7 +6212,7 @@ }, "hf mfu eview": { "command": "hf mfu eview", - "description": "Displays emulator memory By default number of pages shown depends on defined tag type. You can overrife this with option --end.", + "description": "Displays emulator memory By default number of pages shown depends on defined tag type. You can override this with option --end.", "notes": [ "hf mfu eview", "hf mfu eview --end 255 -> dumps whole memory" @@ -7799,15 +7819,19 @@ "command": "lf em 4x50 brute", "description": "Tries to bruteforce the password of a EM4x50 card. Function can be stopped by pressing pm3 button.", "notes": [ - "lf em 4x50 brute --first 12330000 --last 12340000 -> tries pwds from 0x12330000 to 0x1234000000" + "lf em 4x50 brute --mode range --begin 12330000 --end 12340000 -> tries pwds from 0x12330000 to 0x12340000", + "lf em 4x50 brute --mode charset --digits --uppercase -> tries all combinations of ASCII codes for digits and uppercase letters" ], "offline": false, "options": [ "-h, --help This help", - "--first first password (start), 4 bytes, lsb", - "--last last password (stop), 4 bytes, lsb" + "--mode Bruteforce mode (range|charset)", + "--begin Range mode - start of the key range", + "--end Range mode - end of the key range", + "--digits Charset mode - include ASCII codes for digits", + "--uppercase Charset mode - include ASCII codes for uppercase letters" ], - "usage": "lf em 4x50 brute [-h] --first --last " + "usage": "lf em 4x50 brute [-h] --mode [--begin ] [--end ] [--digits] [--uppercase]" }, "lf em 4x50 chk": { "command": "lf em 4x50 chk", @@ -11616,8 +11640,8 @@ } }, "metadata": { - "commands_extracted": 732, + "commands_extracted": 733, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2022-11-20T20:19:15" + "extracted_on": "2023-05-08T17:05:11" } } \ No newline at end of file diff --git a/doc/commands.md b/doc/commands.md index 4b91901f4..2cd9fe2b3 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -370,7 +370,7 @@ Check column "offline" for their availability. |`hf ksx6924 select `|N |`Select application, and leave field up` |`hf ksx6924 info `|N |`Get info about a KS X 6924 (T-Money, Snapper+) transit card` |`hf ksx6924 balance `|N |`Get current purse balance` -|`hf ksx6924 init `|N |`Perform transaction initialization with Mpda (Money of Purchase Transaction)` +|`hf ksx6924 init `|N |`Perform transaction initialization with Mpda` |`hf ksx6924 prec `|N |`Send proprietary get record command (CLA=90, INS=4C)` @@ -512,6 +512,7 @@ Check column "offline" for their availability. |`hf mf gen3freeze `|N |`Perma lock UID changes. irreversible` |`hf mf ggetblk `|N |`Read block from card` |`hf mf gload `|N |`Load dump to card` +|`hf mf gsave `|N |`Save dump from card into file or emulator` |`hf mf gsetblk `|N |`Write block to card` |`hf mf gview `|N |`View card` |`hf mf ndefformat `|N |`Format MIFARE Classic Tag as NFC Tag` @@ -851,7 +852,7 @@ Check column "offline" for their availability. |command |offline |description |------- |------- |----------- |`lf em 4x50 help `|Y |`This help` -|`lf em 4x50 brute `|N |`Simple bruteforce attack to find password` +|`lf em 4x50 brute `|N |`Bruteforce attack to find password` |`lf em 4x50 chk `|N |`Check passwords from dictionary` |`lf em 4x50 dump `|N |`Dump EM4x50 tag` |`lf em 4x50 info `|N |`Tag information` From d74b625b8b8d92b4db9913ee12f0e01098e126ea Mon Sep 17 00:00:00 2001 From: PhaseLoop Date: Mon, 8 May 2023 17:20:35 +0000 Subject: [PATCH 05/37] place bruteforce lib with em4x50 in Makefile --- armsrc/Makefile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/armsrc/Makefile b/armsrc/Makefile index 4a088cbf6..32bfef50c 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -46,7 +46,6 @@ SRC_CRC = crc.c crc16.c crc32.c SRC_ICLASS = iclass.c optimized_cipherutils.c optimized_ikeys.c optimized_elite.c optimized_cipher.c SRC_LEGIC = legicrf.c legicrfsim.c legic_prng.c SRC_NFCBARCODE = thinfilm.c -SRC_BRUTEFORCE = bruteforce.c # SRC_BEE = bee.c @@ -78,7 +77,7 @@ else endif ifneq (,$(findstring WITH_EM4x50,$(APP_CFLAGS))) - SRC_EM4x50 = em4x50.c + SRC_EM4x50 = em4x50.c bruteforce.c else SRC_EM4x50 = endif @@ -144,7 +143,6 @@ THUMBSRC = start.c \ $(SRC_FELICA) \ $(SRC_STANDALONE) \ $(SRC_ZX) \ - $(SRC_BRUTEFORCE) \ appmain.c \ printf.c \ dbprint.c \ From 1fd331ea7ff09a07237ab79caade894cbe111417 Mon Sep 17 00:00:00 2001 From: PhaseLoop Date: Mon, 8 May 2023 17:57:14 +0000 Subject: [PATCH 06/37] remove dead code --- common/bruteforce.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/common/bruteforce.c b/common/bruteforce.c index d4855aefa..891796690 100644 --- a/common/bruteforce.c +++ b/common/bruteforce.c @@ -127,21 +127,3 @@ int bf_array_increment(uint8_t *data, uint8_t data_len, uint8_t modulo) { return 0; } - -/* -int main(){ - generator_context_t ctx; - generator_init(&ctx, BRUTEFORCE_MODE_CHARSET); - generator_set_charset(&ctx, CHARSET_DIGITS | CHARSET_UPPERCASE); - - int ret = 0; - while( (ret=generate32(&ctx)) == GENERATOR_NEXT){ - printf("%X\n", ctx.current_key32); - } - - // printf("Charset len: %d\n", ctx.charset_length); - // printf("Digits len: %d\n", sizeof(charset_digits)); - // printf("Uppercase len: %d\n", sizeof(charset_uppercase)); - return 1; -} -*/ From 9ee7bd29365888e05d3d184dd6071a9969f31c10 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 25 May 2023 07:15:43 +0200 Subject: [PATCH 07/37] adjust potential type conversion --- client/src/cmdhfmf.c | 1 - client/src/mifare/mifare4.c | 10 +++++----- client/src/mifare/mifare4.h | 6 +++--- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 12799b25f..335898ef1 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -308,7 +308,6 @@ static int mf_print_keys(uint16_t n, uint8_t *d) { } for (uint16_t i = 0; i < n; i++) { - if (mfIsSectorTrailer(i)) { e_sector[mfSectorNum(i)].foundKey[0] = 1; e_sector[mfSectorNum(i)].Key[0] = bytes_to_num(d + (i * MFBLOCK_SIZE), MIFARE_KEY_SIZE); diff --git a/client/src/mifare/mifare4.c b/client/src/mifare/mifare4.c index f42111ba8..ec8d1a6bf 100644 --- a/client/src/mifare/mifare4.c +++ b/client/src/mifare/mifare4.c @@ -530,7 +530,7 @@ uint8_t mfSectorTrailerOfSector(uint8_t sectorNo) { } // assumes blockno is 0-255.. -uint8_t mfSectorTrailer(uint8_t blockNo) { +uint8_t mfSectorTrailer(uint16_t blockNo) { if (blockNo < 32 * 4) { return (blockNo | 0x03); } else { @@ -539,15 +539,15 @@ uint8_t mfSectorTrailer(uint8_t blockNo) { } // assumes blockno is 0-255.. -bool mfIsSectorTrailer(uint8_t blockNo) { +bool mfIsSectorTrailer(uint16_t blockNo) { return (blockNo == mfSectorTrailer(blockNo)); } // assumes blockno is 0-255.. -uint8_t mfSectorNum(uint8_t blockNo) { +uint8_t mfSectorNum(uint16_t blockNo) { if (blockNo < 32 * 4) - return blockNo / 4; + return (blockNo / 4); else - return 32 + (blockNo - 32 * 4) / 16; + return (32 + (blockNo - 32 * 4) / 16); } diff --git a/client/src/mifare/mifare4.h b/client/src/mifare/mifare4.h index 489add9f3..80d55db7b 100644 --- a/client/src/mifare/mifare4.h +++ b/client/src/mifare/mifare4.h @@ -77,9 +77,9 @@ const char *mfGetAccessConditionsDesc(uint8_t blockn, const uint8_t *data); uint8_t mfNumBlocksPerSector(uint8_t sectorNo); uint8_t mfFirstBlockOfSector(uint8_t sectorNo); uint8_t mfSectorTrailerOfSector(uint8_t sectorNo); -uint8_t mfSectorTrailer(uint8_t blockNo); -bool mfIsSectorTrailer(uint8_t blockNo); -uint8_t mfSectorNum(uint8_t blockNo); +uint8_t mfSectorTrailer(uint16_t blockNo); +bool mfIsSectorTrailer(uint16_t blockNo); +uint8_t mfSectorNum(uint16_t blockNo); #endif // mifare4.h From 7b92c008271f9eca876db16ef18ae6d1eb031aac Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 25 May 2023 07:58:43 +0200 Subject: [PATCH 08/37] hide false positive in CMAKE on MINGW --- client/CMakeLists.txt | 11 +++++++++++ client/experimental_lib/CMakeLists.txt | 12 ++++++++++++ 2 files changed, 23 insertions(+) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index ee1ddcc25..3fd255997 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -586,6 +586,17 @@ if (MINGW) set(CMAKE_C_FLAGS "-mno-ms-bitfields -fexec-charset=cp850 ${CMAKE_C_FLAGS}") set(CMAKE_CXX_FLAGS "-mno-ms-bitfields -fexec-charset=cp850 ${CMAKE_CXX_FLAGS}") + # GCC 10 has issues with false positives on stringop-overflow, + # let's disable them for now (cf https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92955, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94335) + # beware these flags didn't exist for GCC < 7 + if(CMAKE_COMPILER_IS_GNUCXX) + execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) + if (GCC_VERSION VERSION_GREATER 10.0 OR GCC_VERSION VERSION_EQUAL 10.0) + set(CMAKE_C_FLAGS "-Wno-stringop-overflow -Wno-error=stringop-overflow ${CMAKE_C_FLAGS}") + set(CMAKE_CXX_FLAGS "-Wno-stringop-overflow -Wno-error=stringop-overflow ${CMAKE_CXX_FLAGS}") + endif() + endif(CMAKE_COMPILER_IS_GNUCXX) + # link Winsock2 set(ADDITIONAL_LNK ws2_32 ${ADDITIONAL_LNK}) endif (MINGW) diff --git a/client/experimental_lib/CMakeLists.txt b/client/experimental_lib/CMakeLists.txt index bdc122e58..2ac10f871 100644 --- a/client/experimental_lib/CMakeLists.txt +++ b/client/experimental_lib/CMakeLists.txt @@ -585,6 +585,18 @@ if (MINGW) set(CMAKE_C_FLAGS "-mno-ms-bitfields -fexec-charset=cp850 ${CMAKE_C_FLAGS}") set(CMAKE_CXX_FLAGS "-mno-ms-bitfields -fexec-charset=cp850 ${CMAKE_CXX_FLAGS}") + + # GCC 10 has issues with false positives on stringop-overflow, + # let's disable them for now (cf https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92955, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94335) + # beware these flags didn't exist for GCC < 7 + if(CMAKE_COMPILER_IS_GNUCXX) + execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) + if (GCC_VERSION VERSION_GREATER 10.0 OR GCC_VERSION VERSION_EQUAL 10.0) + set(CMAKE_C_FLAGS "-Wno-stringop-overflow -Wno-error=stringop-overflow ${CMAKE_C_FLAGS}") + set(CMAKE_CXX_FLAGS "-Wno-stringop-overflow -Wno-error=stringop-overflow ${CMAKE_CXX_FLAGS}") + endif() + endif(CMAKE_COMPILER_IS_GNUCXX) + endif (MINGW) target_include_directories(pm3rrg_rdv4 PRIVATE From c13632a9807a6421296f5e8da3a55f6c6b040c39 Mon Sep 17 00:00:00 2001 From: berlin4apk <83521068+berlin4apk@users.noreply.github.com> Date: Thu, 25 May 2023 20:19:59 +0200 Subject: [PATCH 09/37] New keys --- client/dictionaries/mfc_default_keys.dic | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 7ae6ead7f..1de1ba96a 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -267,12 +267,19 @@ E3429281EFC1 AAFB06045877 # # gym +# # Fysiken A 3E65E4FB65B3 # # Fysiken B 25094DF6F148 # +# gym wistband A form https://mattionline.de/fitnessstudio-armband-reverse-engineering/ / https://mattionline.de/milazycracker/ +# 3E65E4FB65B3 # the same as Fysiken A +# gym wistband B +81CC25EBBB6A +195DC63DB3A3 +# # CleverFit A05DBD98E0FC # From a62811ae696f9e5de160bdf77ba9cd750ff64e59 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 26 May 2023 05:10:37 +0200 Subject: [PATCH 10/37] hf mf hardnested, now indicates if it failed when recovering key --- client/src/cmdhfmfhard.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/src/cmdhfmfhard.c b/client/src/cmdhfmfhard.c index 4cb7873af..7f7718adc 100644 --- a/client/src/cmdhfmfhard.c +++ b/client/src/cmdhfmfhard.c @@ -2460,6 +2460,9 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc free_bitarray(all_bitflips_bitarray[EVEN_STATE]); free_sum_bitarrays(); free_part_sum_bitarrays(); + + return (key_found) ? PM3_SUCCESS : PM3_EFAILED; } + return PM3_SUCCESS; } From 15c751231f8d13f17fcc2f59a04f013e86dd7c02 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 26 May 2023 05:11:17 +0200 Subject: [PATCH 11/37] adapting default keys array --- client/src/mifare/mifaredefault.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/client/src/mifare/mifaredefault.h b/client/src/mifare/mifaredefault.h index 941abf41c..e3590329d 100644 --- a/client/src/mifare/mifaredefault.h +++ b/client/src/mifare/mifaredefault.h @@ -45,7 +45,10 @@ static const uint64_t g_mifare_default_keys[] = { 0xffffffffffff, // Default key (first key used by program if no user defined key) 0xa0a1a2a3a4a5, // NFCForum MAD key 0xd3f7d3f7d3f7, // NDEF public key - 0x4b791bea7bcc, // MFC EV1 Signature B + 0x4b791bea7bcc, // MFC EV1 Signature 17 B + 0x5C8FF9990DA2, // MFC EV1 Signature 16 A + 0xD01AFEEB890A, // MFC EV1 Signature 16 B + 0x75CCB59C9BED, // MFC EV1 Signature 17 A 0xfc00018778f7, // Public Transport 0x6471a5ef2d1a, // SimonsVoss 0x4E3552426B32, // ID06 @@ -72,6 +75,11 @@ static const uint64_t g_mifare_default_keys[] = { 0x199404281998, // NSP B 0x6A1987C40A21, // SALTO 0x7F33625BC129, // SALTO + 0x484944204953, // HID + 0x204752454154, // HID + 0x3B7E4FD575AD, // HID + 0x11496F97752A, // HID + 0x3E65E4FB65B3, // Gym 0x000000000000, // Blank key 0xb0b1b2b3b4b5, 0xaabbccddeeff, From 71ae06cf8bb263f525d5fb17cca29a3d9eeaade3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 26 May 2023 05:12:01 +0200 Subject: [PATCH 12/37] style --- client/dictionaries/mfc_default_keys.dic | 40 ++++++++++++++---------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 1de1ba96a..63598f78b 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -18,6 +18,19 @@ A5A4A3A2A1A0 # MAD access key B 89ECA97F8C2A # +# Mifare 1k EV1 (S50) hidden blocks, Signature data +# 16 A +5C8FF9990DA2 +# +# 17 A +75CCB59C9BED +# +# 16 B +D01AFEEB890A +# +# 17 B +4B791BEA7BCC +# # B0B1B2B3B4B5 C0C1C2C3C4C5 @@ -111,7 +124,7 @@ F1D83F964314 # Access control system 605F5E5D5C5B # -#NSP Global keys A and B (uk housing access control) +# NSP Global keys A and B (uk housing access control) 199404281970 199404281998 # @@ -263,7 +276,7 @@ E3429281EFC1 460722122510 # # 3dprinter -# EPI Envisionte# 3dprinter +# EPI Envisionte AAFB06045877 # # gym @@ -274,8 +287,10 @@ AAFB06045877 # Fysiken B 25094DF6F148 # -# gym wistband A form https://mattionline.de/fitnessstudio-armband-reverse-engineering/ / https://mattionline.de/milazycracker/ -# 3E65E4FB65B3 # the same as Fysiken A +# +# https://mattionline.de/fitnessstudio-armband-reverse-engineering/ +# https://mattionline.de/milazycracker/ +# gym wistband A, same as Fysiken A # gym wistband B 81CC25EBBB6A 195DC63DB3A3 @@ -287,6 +302,10 @@ A05DBD98E0FC AA4DDA458EBB EAB8066C7479 # +# Nordic Wellness A, same as Fysiken A +# Nordic Wellness B +E5519E1CC92B +# # Hotel KeyCard D3B595E9DD63 AFBECD121004 @@ -633,19 +652,6 @@ A8844B0BCA06 564C505F4D41 BA5B895DA162 # -# Vigik mystery Keys Mifare 1k EV1 (S50) -# 16 A -5C8FF9990DA2 -# -# 17 A -75CCB59C9BED -# -# 16 B -D01AFEEB890A -# -# 17 B -4B791BEA7BCC -# # BTCINO UNDETERMINED SPREAKD 0x01->0x13 key 021209197591 # From c35749dd13d9ca0150321c2f05169b492df80f85 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 26 May 2023 05:20:29 +0200 Subject: [PATCH 13/37] adapting to the new return value from hardnested --- client/src/cmdhfmf.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 335898ef1..553317bcd 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -2170,6 +2170,10 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { case PM3_ESTATIC_NONCE: PrintAndLogEx(ERR, "Error: Static encrypted nonce detected. Aborted\n"); break; + case PM3_EFAILED: { + PrintAndLogEx(FAILED, "\nFailed to recover a key..."); + break; + } default : break; } @@ -2862,7 +2866,7 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack foundkey = 0; isOK = mfnestedhard(mfFirstBlockOfSector(sectorno), keytype, key, mfFirstBlockOfSector(current_sector_i), current_key_type_i, NULL, false, false, slow, 0, &foundkey, NULL); DropField(); - if (isOK) { + if (isOK != PM3_SUCCESS) { switch (isOK) { case PM3_ETIMEOUT: { PrintAndLogEx(ERR, "\nError: No response from Proxmark3"); @@ -2885,6 +2889,10 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack PrintAndLogEx(NORMAL, ""); break; } + case PM3_EFAILED: { + PrintAndLogEx(FAILED, "\nFailed to recover a key..."); + continue; + } default: { break; } From 01333c7a272bfa321d3ee49681ce16fbdeefe9bc Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 26 May 2023 05:22:04 +0200 Subject: [PATCH 14/37] simplify logic --- client/src/cmdhfmf.c | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 553317bcd..7e8aee55c 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -2154,30 +2154,27 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { uint64_t foundkey = 0; int16_t isOK = mfnestedhard(blockno, keytype, key, trg_blockno, trg_keytype, known_target_key ? trg_key : NULL, nonce_file_read, nonce_file_write, slow, tests, &foundkey, filename); - + switch (isOK) { + case PM3_ETIMEOUT : + PrintAndLogEx(ERR, "Error: No response from Proxmark3\n"); + break; + case PM3_EOPABORTED: + PrintAndLogEx(WARNING, "Button pressed. Aborted\n"); + break; + case PM3_ESTATIC_NONCE: + PrintAndLogEx(ERR, "Error: Static encrypted nonce detected. Aborted\n"); + break; + case PM3_EFAILED: { + PrintAndLogEx(FAILED, "\nFailed to recover a key..."); + break; + } + default : + break; + } + if ((tests == 0) && IfPm3Iso14443a()) { DropField(); } - - if (isOK) { - switch (isOK) { - case PM3_ETIMEOUT : - PrintAndLogEx(ERR, "Error: No response from Proxmark3\n"); - break; - case PM3_EOPABORTED: - PrintAndLogEx(WARNING, "Button pressed. Aborted\n"); - break; - case PM3_ESTATIC_NONCE: - PrintAndLogEx(ERR, "Error: Static encrypted nonce detected. Aborted\n"); - break; - case PM3_EFAILED: { - PrintAndLogEx(FAILED, "\nFailed to recover a key..."); - break; - } - default : - break; - } - } return isOK; } From 94e4afaa03b463c63101ff97d211110b7d037bcc Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 26 May 2023 05:36:07 +0200 Subject: [PATCH 15/37] fix signature key bug and simplify logic --- client/src/cmdhfmf.c | 116 +++++++++++++++++++++---------------------- 1 file changed, 57 insertions(+), 59 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 7e8aee55c..aebce5737 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -2171,7 +2171,7 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { default : break; } - + if ((tests == 0) && IfPm3Iso14443a()) { DropField(); } @@ -2389,14 +2389,6 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { if (is_ev1) { PrintAndLogEx(INFO, "MIFARE Classic EV1 card detected"); - // Store the keys - e_sector[16].Key[MF_KEY_A] = bytes_to_num((uint8_t *)g_mifare_signature_key_a, sizeof(g_mifare_signature_key_a)); - e_sector[16].foundKey[MF_KEY_A] = 'D'; - - e_sector[17].Key[MF_KEY_A] = bytes_to_num((uint8_t *)g_mifare_signature_key_a, sizeof(g_mifare_signature_key_a)); - e_sector[17].foundKey[MF_KEY_A] = 'D'; - e_sector[17].Key[MF_KEY_B] = bytes_to_num((uint8_t *)g_mifare_signature_key_b, sizeof(g_mifare_signature_key_b)); - e_sector[17].foundKey[MF_KEY_B] = 'D'; // use found key if not supplied if (known_key == false) { @@ -2431,7 +2423,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { PrintAndLogEx(INFO, " key supplied .. " _YELLOW_("%s"), known_key ? "True" : "False"); PrintAndLogEx(INFO, " known sector .. " _YELLOW_("%d"), sectorno); PrintAndLogEx(INFO, " keytype ....... " _YELLOW_("%c"), (keytype == MF_KEY_B) ? 'B' : 'A'); - PrintAndLogEx(INFO, " known key ..... " _YELLOW_("%s"), sprint_hex(key, sizeof(key))); + PrintAndLogEx(INFO, " known key ..... " _YELLOW_("%s"), sprint_hex_inrow(key, sizeof(key))); if (has_staticnonce == NONCE_STATIC) PrintAndLogEx(INFO, " card PRNG ..... " _YELLOW_("STATIC")); @@ -2458,10 +2450,10 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { } if (mfCheckKeys(mfFirstBlockOfSector(sectorno), keytype, true, 1, key, &key64) == PM3_SUCCESS) { - PrintAndLogEx(INFO, "target sector %3u key type %c -- using valid key [ " _GREEN_("%s") "] (used for nested / hardnested attack)", + PrintAndLogEx(INFO, "target sector %3u key type %c -- using valid key [ " _GREEN_("%s") " ] (used for nested / hardnested attack)", sectorno, (keytype == MF_KEY_B) ? 'B' : 'A', - sprint_hex(key, sizeof(key)) + sprint_hex_inrow(key, sizeof(key)) ); // Store the key for the nested / hardnested attack (if supplied by the user) @@ -2474,7 +2466,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { PrintAndLogEx(FAILED, "Key is wrong. Can't authenticate to sector"_RED_("%3d") " key type "_RED_("%c") " key " _RED_("%s"), sectorno, (keytype == MF_KEY_B) ? 'B' : 'A', - sprint_hex(key, sizeof(key)) + sprint_hex_inrow(key, sizeof(key)) ); PrintAndLogEx(WARNING, "falling back to dictionary"); } @@ -2482,31 +2474,34 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // Check if the user supplied key is used by other sectors for (int i = 0; i < sector_cnt; i++) { for (int j = MF_KEY_A; j <= MF_KEY_B; j++) { - if (e_sector[i].foundKey[j] == 0) { - if (mfCheckKeys(mfFirstBlockOfSector(i), j, true, 1, key, &key64) == PM3_SUCCESS) { - e_sector[i].Key[j] = bytes_to_num(key, 6); - e_sector[i].foundKey[j] = 'U'; - // If the user supplied secctor / keytype was wrong --> just be nice and correct it ;) - if (known_key == false) { - num_to_bytes(e_sector[i].Key[j], 6, key); - known_key = true; - sectorno = i; - keytype = j; - PrintAndLogEx(SUCCESS, "target sector %3u key type %c -- found valid key [ " _GREEN_("%s") " ] (used for nested / hardnested attack)", - i, - (j == MF_KEY_B) ? 'B' : 'A', - sprint_hex_inrow(key, sizeof(key)) - ); - } else { - PrintAndLogEx(SUCCESS, "target sector %3u key type %c -- found valid key [ " _GREEN_("%s") " ]", - i, - (j == MF_KEY_B) ? 'B' : 'A', - sprint_hex_inrow(key, sizeof(key)) - ); - } - ++num_found_keys; + if (e_sector[i].foundKey[j]) { + continue; + } + + if (mfCheckKeys(mfFirstBlockOfSector(i), j, true, 1, key, &key64) == PM3_SUCCESS) { + e_sector[i].Key[j] = bytes_to_num(key, 6); + e_sector[i].foundKey[j] = 'U'; + + // If the user supplied secctor / keytype was wrong --> just be nice and correct it ;) + if (known_key == false) { + num_to_bytes(e_sector[i].Key[j], 6, key); + known_key = true; + sectorno = i; + keytype = j; + PrintAndLogEx(SUCCESS, "target sector %3u key type %c -- found valid key [ " _GREEN_("%s") " ] (used for nested / hardnested attack)", + i, + (j == MF_KEY_B) ? 'B' : 'A', + sprint_hex_inrow(key, sizeof(key)) + ); + } else { + PrintAndLogEx(SUCCESS, "target sector %3u key type %c -- found valid key [ " _GREEN_("%s") " ]", + i, + (j == MF_KEY_B) ? 'B' : 'A', + sprint_hex_inrow(key, sizeof(key)) + ); } + ++num_found_keys; } } } @@ -2551,7 +2546,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { PrintAndLogEx(INFO, "." NOLF); // Check all the sectors for (int i = 0; i < sector_cnt; i++) { - for (int j = 0; j < 2; j++) { + for (int j = MF_KEY_A; j <= MF_KEY_B; j++) { // Check if the key is known if (e_sector[i].foundKey[j] == 0) { for (uint32_t k = 0; k < key_cnt; k++) { @@ -2608,28 +2603,30 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { // Analyse the dictionary attack for (int i = 0; i < sector_cnt; i++) { for (int j = MF_KEY_A; j <= MF_KEY_B; j++) { - if (e_sector[i].foundKey[j] == 1) { - e_sector[i].foundKey[j] = 'D'; - num_to_bytes(e_sector[i].Key[j], 6, tmp_key); + if (e_sector[i].foundKey[j] != 1) { + continue; + } - // Store valid credentials for the nested / hardnested attack if none exist - if (known_key == false) { - num_to_bytes(e_sector[i].Key[j], 6, key); - known_key = true; - sectorno = i; - keytype = j; - PrintAndLogEx(SUCCESS, "target sector %3u key type %c -- found valid key [ " _GREEN_("%s") " ] (used for nested / hardnested attack)", - i, - (j == MF_KEY_B) ? 'B' : 'A', - sprint_hex_inrow(tmp_key, sizeof(tmp_key)) - ); - } else { - PrintAndLogEx(SUCCESS, "target sector %3u key type %c -- found valid key [ " _GREEN_("%s") " ]", - i, - (j == MF_KEY_B) ? 'B' : 'A', - sprint_hex_inrow(tmp_key, sizeof(tmp_key)) - ); - } + e_sector[i].foundKey[j] = 'D'; + num_to_bytes(e_sector[i].Key[j], 6, tmp_key); + + // Store valid credentials for the nested / hardnested attack if none exist + if (known_key == false) { + num_to_bytes(e_sector[i].Key[j], 6, key); + known_key = true; + sectorno = i; + keytype = j; + PrintAndLogEx(SUCCESS, "target sector %3u key type %c -- found valid key [ " _GREEN_("%s") " ] (used for nested / hardnested attack)", + i, + (j == MF_KEY_B) ? 'B' : 'A', + sprint_hex_inrow(tmp_key, sizeof(tmp_key)) + ); + } else { + PrintAndLogEx(SUCCESS, "target sector %3u key type %c -- found valid key [ " _GREEN_("%s") " ]", + i, + (j == MF_KEY_B) ? 'B' : 'A', + sprint_hex_inrow(tmp_key, sizeof(tmp_key)) + ); } } } @@ -2690,7 +2687,8 @@ noValidKeyFound: // Iterate over each sector and key(A/B) for (current_sector_i = 0; current_sector_i < sector_cnt; current_sector_i++) { - for (current_key_type_i = 0; current_key_type_i < 2; current_key_type_i++) { + + for (current_key_type_i = MF_KEY_A; current_key_type_i <= MF_KEY_B; current_key_type_i++) { // If the key is already known, just skip it if (e_sector[current_sector_i].foundKey[current_key_type_i] == 0) { From 22ae67d2cfc588b4095d329d21f7bb4f10fb7d85 Mon Sep 17 00:00:00 2001 From: PhaseLoop Date: Fri, 26 May 2023 07:20:27 +0000 Subject: [PATCH 16/37] Revert doc autostyle --- doc/commands.json | 100 ++++++++++++++++++---------------------------- doc/commands.md | 5 +-- 2 files changed, 40 insertions(+), 65 deletions(-) diff --git a/doc/commands.json b/doc/commands.json index 633dd198e..a94e5bc6a 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -3391,20 +3391,6 @@ ], "usage": "hf jooki sim [-h] [-b ]" }, - "hf ksx6924 balance": { - "command": "hf ksx6924 balance", - "description": "Gets the current purse balance", - "notes": [ - "hf ksx6924 balance" - ], - "offline": false, - "options": [ - "-h, --help This help", - "-k, --keep keep field ON for next command", - "-a, --apdu Show APDU requests and responses" - ], - "usage": "hf ksx6924 balance [-hka]" - }, "hf ksx6924 help": { "command": "hf ksx6924 help", "description": "help This help", @@ -3413,6 +3399,19 @@ "options": [], "usage": "" }, + "hf ksx6924 select": { + "command": "hf ksx6924 select", + "description": "Selects KS X 6924 application, and leaves field up", + "notes": [ + "hf ksx6924 select" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-a, --apdu Show APDU requests and responses" + ], + "usage": "hf ksx6924 select [-ha]" + }, "hf ksx6924 info": { "command": "hf ksx6924 info", "description": "Get info about a KS X 6924 transit card. This application is used by T-Money (South Korea) and Snapper+ (Wellington, New Zealand).", @@ -3427,9 +3426,23 @@ ], "usage": "hf ksx6924 info [-hka]" }, + "hf ksx6924 balance": { + "command": "hf ksx6924 balance", + "description": "Gets the current purse balance", + "notes": [ + "hf ksx6924 balance" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-k, --keep keep field ON for next command", + "-a, --apdu Show APDU requests and responses" + ], + "usage": "hf ksx6924 balance [-hka]" + }, "hf ksx6924 init": { "command": "hf ksx6924 init", - "description": "Perform transaction initialization with Mpda (Money of Purchase Transaction)", + "description": "Perform transaction initialization (mpda)", "notes": [ "hf ksx6924 init 000003e8 -> Mpda" ], @@ -3455,19 +3468,7 @@ ], "usage": "hf ksx6924 prec [-hka] " }, - "hf ksx6924 select": { - "command": "hf ksx6924 select", - "description": "Selects KS X 6924 application, and leaves field up", - "notes": [ - "hf ksx6924 select" - ], - "offline": false, - "options": [ - "-h, --help This help", - "-a, --apdu Show APDU requests and responses" - ], - "usage": "hf ksx6924 select [-ha]" - }, + "hf legic crc": { "command": "hf legic crc", "description": "Calculates the legic crc8/crc16 on the given data", @@ -3970,7 +3971,7 @@ "--1k MIFARE Classic 1k / S50 (def)", "--2k MIFARE Classic/Plus 2k", "--4k MIFARE Classic 4k / S70", - "--emu to emulator memory" + "--emu from emulator memory" ], "usage": "hf mf csave [-h] [-f ] [--mini] [--1k] [--2k] [--4k] [--emu]" }, @@ -4347,27 +4348,6 @@ ], "usage": "hf mf gload [-hv] [--mini] [--1k] [--2k] [--4k] [-p ] [-f ] [--emu] [--start ] [--end ]" }, - "hf mf gsave": { - "command": "hf mf gsave", - "description": "Save `magic gen4 gtu` card memory into three files (BIN/EML/JSON)or into emulator memory", - "notes": [ - "hf mf gsave", - "hf mf gsave --4k", - "hf mf gsave -p DEADBEEF -f hf-mf-01020304.json" - ], - "offline": false, - "options": [ - "-h, --help This help", - "--mini MIFARE Classic Mini / S20", - "--1k MIFARE Classic 1k / S50 (def)", - "--2k MIFARE Classic/Plus 2k", - "--4k MIFARE Classic 4k / S70", - "-p, --pwd password 4bytes", - "-f, --file filename of dump", - "--emu to emulator memory" - ], - "usage": "hf mf gsave [-h] [--mini] [--1k] [--2k] [--4k] [-p ] [-f ] [--emu]" - }, "hf mf gsetblk": { "command": "hf mf gsetblk", "description": "Set block data on a magic gen4 GTU card", @@ -6196,7 +6176,7 @@ }, "hf mfu esave": { "command": "hf mfu esave", - "description": "Saves emulator memory to a MIFARE Ultralight/NTAG dump file (bin/eml/json) By default number of pages saved depends on defined tag type. You can override this with option --end.", + "description": "Saves emulator memory to a MIFARE Ultralight/NTAG dump file (bin/eml/json) By default number of pages saved depends on defined tag type. You can overrife this with option --end.", "notes": [ "hf mfu esave", "hf mfu esave --end 255 -> saves whole memory", @@ -6212,7 +6192,7 @@ }, "hf mfu eview": { "command": "hf mfu eview", - "description": "Displays emulator memory By default number of pages shown depends on defined tag type. You can override this with option --end.", + "description": "Displays emulator memory By default number of pages shown depends on defined tag type. You can overrife this with option --end.", "notes": [ "hf mfu eview", "hf mfu eview --end 255 -> dumps whole memory" @@ -7819,19 +7799,15 @@ "command": "lf em 4x50 brute", "description": "Tries to bruteforce the password of a EM4x50 card. Function can be stopped by pressing pm3 button.", "notes": [ - "lf em 4x50 brute --mode range --begin 12330000 --end 12340000 -> tries pwds from 0x12330000 to 0x12340000", - "lf em 4x50 brute --mode charset --digits --uppercase -> tries all combinations of ASCII codes for digits and uppercase letters" + "lf em 4x50 brute --first 12330000 --last 12340000 -> tries pwds from 0x12330000 to 0x1234000000" ], "offline": false, "options": [ "-h, --help This help", - "--mode Bruteforce mode (range|charset)", - "--begin Range mode - start of the key range", - "--end Range mode - end of the key range", - "--digits Charset mode - include ASCII codes for digits", - "--uppercase Charset mode - include ASCII codes for uppercase letters" + "--first first password (start), 4 bytes, lsb", + "--last last password (stop), 4 bytes, lsb" ], - "usage": "lf em 4x50 brute [-h] --mode [--begin ] [--end ] [--digits] [--uppercase]" + "usage": "lf em 4x50 brute [-h] --first --last " }, "lf em 4x50 chk": { "command": "lf em 4x50 chk", @@ -11640,8 +11616,8 @@ } }, "metadata": { - "commands_extracted": 733, + "commands_extracted": 732, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2023-05-08T17:05:11" + "extracted_on": "2022-11-20T20:19:15" } } \ No newline at end of file diff --git a/doc/commands.md b/doc/commands.md index 2cd9fe2b3..4b91901f4 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -370,7 +370,7 @@ Check column "offline" for their availability. |`hf ksx6924 select `|N |`Select application, and leave field up` |`hf ksx6924 info `|N |`Get info about a KS X 6924 (T-Money, Snapper+) transit card` |`hf ksx6924 balance `|N |`Get current purse balance` -|`hf ksx6924 init `|N |`Perform transaction initialization with Mpda` +|`hf ksx6924 init `|N |`Perform transaction initialization with Mpda (Money of Purchase Transaction)` |`hf ksx6924 prec `|N |`Send proprietary get record command (CLA=90, INS=4C)` @@ -512,7 +512,6 @@ Check column "offline" for their availability. |`hf mf gen3freeze `|N |`Perma lock UID changes. irreversible` |`hf mf ggetblk `|N |`Read block from card` |`hf mf gload `|N |`Load dump to card` -|`hf mf gsave `|N |`Save dump from card into file or emulator` |`hf mf gsetblk `|N |`Write block to card` |`hf mf gview `|N |`View card` |`hf mf ndefformat `|N |`Format MIFARE Classic Tag as NFC Tag` @@ -852,7 +851,7 @@ Check column "offline" for their availability. |command |offline |description |------- |------- |----------- |`lf em 4x50 help `|Y |`This help` -|`lf em 4x50 brute `|N |`Bruteforce attack to find password` +|`lf em 4x50 brute `|N |`Simple bruteforce attack to find password` |`lf em 4x50 chk `|N |`Check passwords from dictionary` |`lf em 4x50 dump `|N |`Dump EM4x50 tag` |`lf em 4x50 info `|N |`Tag information` From d1783ce2a45a2ac1352904701fa313152ab77154 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 27 May 2023 08:49:18 +0200 Subject: [PATCH 17/37] text --- client/deps/hardnested/hardnested_bruteforce.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/deps/hardnested/hardnested_bruteforce.c b/client/deps/hardnested/hardnested_bruteforce.c index b5b36595c..7766b28d3 100644 --- a/client/deps/hardnested/hardnested_bruteforce.c +++ b/client/deps/hardnested/hardnested_bruteforce.c @@ -182,7 +182,7 @@ crack_states_thread(void *x) { } else { if (!thread_arg->silent) { char progress_text[80]; - snprintf(progress_text, sizeof(progress_text), "Brute force phase: %6.02f%%\t", 100.0 * (float)num_keys_tested / (float)(thread_arg->maximum_states)); + snprintf(progress_text, sizeof(progress_text), "Brute force phase: %6.02f%% ", 100.0 * (float)num_keys_tested / (float)(thread_arg->maximum_states)); float remaining_bruteforce = thread_arg->nonces[thread_arg->best_first_bytes[0]].expected_num_brute_force - (float)num_keys_tested / 2; hardnested_print_progress(thread_arg->num_acquired_nonces, progress_text, remaining_bruteforce, 5000); } From 0f4b787df1fd63321c174ece3b4f96cb3d38e79f Mon Sep 17 00:00:00 2001 From: PhaseLoop Date: Sat, 27 May 2023 07:18:59 +0000 Subject: [PATCH 18/37] replace bzero with memset --- client/src/cmdlfem4x50.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdlfem4x50.c b/client/src/cmdlfem4x50.c index aeffb9c18..56bf9f6d7 100644 --- a/client/src/cmdlfem4x50.c +++ b/client/src/cmdlfem4x50.c @@ -369,7 +369,7 @@ int CmdEM4x50Brute(const char *Cmd) { CLIExecWithReturn(ctx, Cmd, argtable, true); em4x50_data_t etd; - bzero(&etd, sizeof(etd)); + memset(&etd, 0, sizeof(etd)); int mode_len = 64; char mode[64]; From 5c604de4c18d3c63c141f40a37d8f2b5d33f346c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 27 May 2023 10:26:30 +0200 Subject: [PATCH 19/37] adapt hardnested bitflip arrays to load --- client/src/cmdhfmfhard.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/client/src/cmdhfmfhard.c b/client/src/cmdhfmfhard.c index 7f7718adc..acbf32ea5 100644 --- a/client/src/cmdhfmfhard.c +++ b/client/src/cmdhfmfhard.c @@ -34,7 +34,6 @@ #include "commonutil.h" // ARRAYLEN #include "comms.h" - #include "proxmark3.h" #include "ui.h" #include "util_posix.h" @@ -48,7 +47,8 @@ #define NUM_CHECK_BITFLIPS_THREADS (num_CPUs()) #define NUM_REDUCTION_WORKING_THREADS (num_CPUs()) -#define IGNORE_BITFLIP_THRESHOLD 0.99 // ignore bitflip arrays which have nearly only valid states +// ignore bitflip arrays which have nearly only valid states +#define IGNORE_BITFLIP_THRESHOLD 0.9901 #define STATE_FILES_DIRECTORY "hardnested_tables/" #define STATE_FILE_TEMPLATE "bitflip_%d_%03" PRIx16 "_states.bin.bz2" @@ -57,7 +57,11 @@ // #define DEBUG_REDUCTION // possible sum property values -static uint16_t sums[NUM_SUMS] = {0, 32, 56, 64, 80, 96, 104, 112, 120, 128, 136, 144, 152, 160, 176, 192, 200, 224, 256}; +static uint16_t sums[NUM_SUMS] = { + 0, 32, 56, 64, 80, 96, 104, 112, + 120, 128, 136, 144, 152, 160, 176, 192, + 200, 224, 256 +}; // number of possible partial sum property values #define NUM_PART_SUMS 9 @@ -505,8 +509,11 @@ static void free_sum_bitarrays(void) { static char failstr[250] = ""; #endif -static const float p_K0[NUM_SUMS] = { // the probability that a random nonce has a Sum Property K - 0.0290, 0.0083, 0.0006, 0.0339, 0.0048, 0.0934, 0.0119, 0.0489, 0.0602, 0.4180, 0.0602, 0.0489, 0.0119, 0.0934, 0.0048, 0.0339, 0.0006, 0.0083, 0.0290 +// the probability that a random nonce has a Sum Property K +static const float p_K0[NUM_SUMS] = { + 0.0290, 0.0083, 0.0006, 0.0339, 0.0048, 0.0934, 0.0119, 0.0489, + 0.0602, 0.4180, 0.0602, 0.0489, 0.0119, 0.0934, 0.0048, 0.0339, + 0.0006, 0.0083, 0.0290 }; static float my_p_K[NUM_SUMS]; static const float *p_K; @@ -1275,6 +1282,7 @@ static void apply_sum_a0(void) { } static void simulate_MFplus_RNG(uint32_t test_cuid, uint64_t test_key, uint32_t *nt_enc, uint8_t *par_enc) { + struct Crypto1State sim_cs = {0, 0}; // init cryptostate with key: @@ -1285,12 +1293,20 @@ static void simulate_MFplus_RNG(uint32_t test_cuid, uint64_t test_key, uint32_t *par_enc = 0; uint32_t nt = (rand() & 0xff) << 24 | (rand() & 0xff) << 16 | (rand() & 0xff) << 8 | (rand() & 0xff); + for (int8_t byte_pos = 3; byte_pos >= 0; byte_pos--) { + uint8_t nt_byte_dec = (nt >> (8 * byte_pos)) & 0xff; - uint8_t nt_byte_enc = crypto1_byte(&sim_cs, nt_byte_dec ^ (test_cuid >> (8 * byte_pos)), false) ^ nt_byte_dec; // encode the nonce byte + + // encode the nonce byte + uint8_t nt_byte_enc = crypto1_byte(&sim_cs, nt_byte_dec ^ (test_cuid >> (8 * byte_pos)), false) ^ nt_byte_dec; *nt_enc = (*nt_enc << 8) | nt_byte_enc; - uint8_t ks_par = filter(sim_cs.odd); // the keystream bit to encode/decode the parity bit - uint8_t nt_byte_par_enc = ks_par ^ oddparity8(nt_byte_dec); // determine the nt byte's parity and encode it + + // the keystream bit to encode/decode the parity bit + uint8_t ks_par = filter(sim_cs.odd); + + // determine the nt byte's parity and encode it + uint8_t nt_byte_par_enc = ks_par ^ oddparity8(nt_byte_dec); *par_enc = (*par_enc << 1) | nt_byte_par_enc; } } From 71f934dbd766c0f3a18fb2c4d4c8943fd05dc5ef Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 27 May 2023 10:28:54 +0200 Subject: [PATCH 20/37] text --- client/src/fileutils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/fileutils.c b/client/src/fileutils.c index bb9c7635e..d26470ed5 100644 --- a/client/src/fileutils.c +++ b/client/src/fileutils.c @@ -805,7 +805,7 @@ int createMfcKeyDump(const char *preferredName, uint8_t sectorsCnt, sector_t *e_ fflush(f); fclose(f); PrintAndLogEx(SUCCESS, "Found keys have been dumped to " _YELLOW_("%s"), fileName); - PrintAndLogEx(INFO, "FYI! --> " _YELLOW_("0xFFFFFFFFFFFF") " <-- has been inserted for unknown keys where " _YELLOW_("res") " is " _YELLOW_("0")); + PrintAndLogEx(INFO, "FYI! --> " _YELLOW_("0xFFFFFFFFFFFF") " <-- has been inserted for unknown keys where " _YELLOW_("res") " is " _RED_("0")); free(fileName); return PM3_SUCCESS; } From 82886e20362732ccda212084d7e9b1c1bc287bb8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 27 May 2023 10:30:52 +0200 Subject: [PATCH 21/37] reverting back to threshold 5, HF reading becomes better. Keeping the Simulation threshold --- fpga-xc2s30/fpga_felica.bit | Bin 42172 -> 42179 bytes fpga-xc2s30/fpga_hf.bit | Bin 42168 -> 42175 bytes fpga-xc2s30/fpga_hf_15.bit | Bin 42171 -> 42178 bytes fpga-xc2s30/fpga_lf.bit | Bin 42168 -> 42175 bytes fpga-xc2s30/hi_iso14443a.v | 2 +- 5 files changed, 1 insertion(+), 1 deletion(-) diff --git a/fpga-xc2s30/fpga_felica.bit b/fpga-xc2s30/fpga_felica.bit index 83009b499879dedcd6b741fb39cd016f915c9107..30ea16e332b8d28b03a80605bc0531fd5864d0c5 100644 GIT binary patch literal 42179 zcmZSJ51`asX3X+iMjXMoCc8Zamz^BD~o92f!^RFWBl1Q>7wmIkmK5o#2ez$$SO5Oau8 zBZSKckT}deAT}-xRU?c`9wg2JA{g!qFg7q0Fvu{lGcX9NH(w;*dI9n zQgndzPs9HPdj%d3W+R3pEgKbhPB4FB_@7|@g!cn;0Yd>uO@qLDhusZ&3LG<-7BO@; zC?#;rV0y-||AN&C4!b4=76Xu)4%Raan;CQ*xD=Rr7#1)nFi3DPonqLmpmKoIgei#; zY|a7EHH^C%^b)wXFzG0)782qrk_&+~DxS z!N`cGgZY8OZw9jiyc?JUSit5yVBDkdpTWL?_loxiruz)`AM_6}e_{B|V1IzGfO!W4 z*c=CeHH^O*>;!n0FzYh>axh}xX<*i1_{?B;KxYH90E+_1t`n>_9J?9x8aOsE=P(#E zC>-Ejz@*i%pTX<^#}6(e1_zLu2dw^%n^|-kG#D5f7&b5{G;k_#F*j^x(mKFlp=7}j z08*pCD95?IQP+Uu43jX!wgbu=IPWltF>Ifx`hcU7i34Je2L}(sW(J!BIzn6x4Idab zH1H}gvoL&SusXnFa99YEa2#a!FxWHLI`Cg${=o1@z`lXMfcXoZ?dB*UpZr4tQHI^{{MaP&mP1z;uS8nL*=#hXIoiB;H?$b};N}ux;Rf#C=QQAA{u#o(Igg z6i%_&HLxyVu7cR*!SImbhk%^|e*;4j!w&^J2L1--2Miw=m_Uq64B+&`A@GFZB!iIy z&jfB2mXi#24m=Z@!6J@46POP{>}p_1Wol$la^MhPQeo(1&~xCJ!1RQnlVJgf@qhuG z(Ir?_7IZQwJ>Zz3q{h(Mpa)5-os3Ej8Z(%VLE?ggg@vILWX=R86{bdzIRZ>i_!>2o z95jTQ4uOjih8?^~3r;X>0wo&-h7$~SAjSiR69q<$JnhWyn8EQrL-q;7Uk3XF+8>y| zFnndObp07b3yW#28#v5E+)MOjs;8{3|$OL4g3m1 z8Z5gQj2bu^n7ANup~30`DmNH37@QgyCNL~uU|?WkVO-6iaDdyAi3^s$Bp9|c=sR%S za5G_;%b=Vfd4WlUVY`Cr3(hJw4X8OBatzxWY!~okFwJ7P)?m7TCxcl|;Q12cpZx#0 zwIKP6Lv{_rZw8wK{07W#7#=g&9gyF^{D$SX!>)sT+nNtS@|OeaHwRF8$bZ8563dY$ zLr}pe=5YRo@q?Tn%nXqDS|K=xVLP*~3wI#X6^2#;MGuZZCJ~2z1LY$e1x#9yaAt6r z!?B$~w~0G}>4!s~gK~rA6Q=rrc7{Yy9%O*zuLKcrnfZX*1eC2B6Ap12u=y}FGbA10 z*ucaAiT4$vOBi-D*f8+7GCg28p|FXGw}&~A;XK3U13Vj;p>{PeJYo3FUo=;Xi}X0iFV821x!|APX-24)A|q{=@R0!5+l;!SJ8K8pL=3$zKOpKQa7gF;?I` z!EMBFhQXMD=K!+-!@mjU4?qk?aGBX4@IYXHfD!|TfRGAHM}v~0#|$PlhD{2}2e>+z z;Puym1sin~95fr4KqdVG1`YjC3t zj_(co5AYvg{=o3V#qJ3I1Lg{bf1pzR0rw9`{&Eml!0?k{6OYaUW(9@=TozY&1eu>W z{9-aXpu@;~0g}H?uqrU@+@f@WLzPL>;dF!21CAX`?-+J5C?DWh!1M_c7Y|rH7&baA zSiqqm#33-5L4(7CNywqWis8`#4hE(lu>2+Eu(2^wL8D@lnL=BO;sTBcr)vz`8WbOJ zcqpBKnB&30!SI>U=!6afGe^Tk4GRYiCT0(YPYebJcnp{?LGqV_>`sCI6YU-JFACpb zgH~IA9R4xbALIXssJ{*|om4Pr(AglY!*H6(NTFv1vjWE{2D=kF6PUFGz-6X~-~>>% zI>1rDCBo3gqR^nF;Kjkz#-MWsx&GS3(B7cDpyNlAonT|5VxmL@lNdu=gYE+k2_^$b z{_+qx#L~^O;39`f6R$!uqrw9&n_ z2|P2HnIL(&fhC1yr-Oon$4o92rcMT>0`3`1&zd?J^a?yCGAY38FNU34@)PD z5~%2Y($LAEn~PN{iT?}b!n0ain?b?B;}VmIKrf@R z1IGm+8^%rsHBcbH>MzkJ;AT(X1ZEYNn}>t~bmnraI-g`Ta^RoC46DBwmoWU)*ypG} zf%%!hPk}uS{1VN_7=AKXIq*(G)L#o2PB3g{;s+HMR}_pHbPh0oU^>BI#Guo{d`or1)L2CE-ax5JVz+6GKK49y2L4scj7 zone^Fu;2%W2Gc1>{#w8&$I#B9%D~~kB*4(%kio#=&~$-ex`M(Zjs&F_5OY>=*fAVx zFn_>*gV~Phc*9NwjtJ&M3fET{f-16Cko*OzzkV@TG4L>u#IU_JoJUn>NsFl-fCcm(90hU)@~ z4IG6`0uJpAx)-<;m|j8BJOjfNhHVUrOd0`9G8`=ostw!;Oact;47v>52}}nd`Ab3M z2*UUIARAEntS%U*8x$9N2t-|3LSqmJ>}z z4m=IaI-nZu2>%nL`io;ngEE80mnNHrZU&_Z99x(a8M+ztK5#3*>n~Ovhn=97)dHmj z0^L$cOdJ!M6dbx4^cc7o!0Rs-9#F}DfJ4BEhoOO0;Q)sMC~_H87`PQ+`HO)!hv5f9 z0RumSa|6R^P_?xI>>fJ?{soBo>kp{)en9^N_aBBo4E7BCpaTCtgaNO={xLjhFnz#V z!EDE{y1gZWKebDfm!G?iHgPDQhV1to@js!Cwhc`pr0e&N9ElB&&LvV`2b_PWT4p5e9 z1u-0$WI%c60Cy>(|22(a{{ejijuT8q3_T6X3LH0>%sAT{bRTqA!0RuTBMh4kC}?P~ za4|A9Ff3s3VBlh50>>$${$gDz@U6jS0?z_wt%g$_Mh!d*m^B!>zzr&HME%tO?shdX zKWO;DU?;%e;QRr-{$hB;@N>eh3{by-!IQx*1Jw8jxB2}iaKq{^k(7X)3`zwYbC`}Y zbRN+2;GV*IzmeI~}x~I4(7PQRwZ^ci_I!^v_^tgPsHT45a#tVJE|4 z2aW)yFHB1rbU}TYD-0VObR4*)VEJnYZvw*y1}g>~P@N0vfAKdk!rct3zj&W8{D-xB zZ!*|G8^DZq4*nP6^_M89k7f$0wp760;hDe;X(aPsK;P9=ObXzR7)JvW$Syrl zM-0~gVm-sKmqFEm1Jw1{%AoI{8NhUfVI!n*3+sQeE@9ZIpmc!a5|atTUWR-J&I@dR z99DwD2hsmxeX8)&#ms?6f?0*(XM&vrFUUPRnd}_6Cm`ytHDIUe&wzHj_&{pF<>3T) z{l&15;g5qgxY}a)<6+Oif1vq;!VeBR2L2{)SpQ2@gJF|{!U~R6OfMOB9njgpy@u(9 z!ma~)4csq~`(N7%>;ttb3z+UGZ0FED z$X(EMhhaO1?g8$MNzne+3Jx)cZw;0UdOVmfF??yTRp19PzE7}yz%K#sfAOwm_y~%x z4a}hag&n9!fivLs*FA=F4dw~_KbS8uoN2Iqz;i?Ro5$Y<;|KgG{jX~b3tPAyneKwJ z6$4L-(hY{K45kOT3%HaTuK{q-Hx5i4MZ*I%C)jx-o6@Pft<&or2V7$yw=8-yG9e=r$9 z%EJbMM+{vJN(((Yn3Nbg8nhHRI+)ZLb~k7xaBpB*0BI+5upVG&V$f=kW&roUR2VoL znEDuYw}2}$B}hB-faoHIE)J~*t{osRGl0h-*D>sXn6m-WZgCJj)^Ol}l?49`ZeE7w zMzcg-3GQVKJD7|Y@q@E8r?P(@Y(s-QvrN<{tT@S4de zK)#t-m*KX8(HU^N_Z6g~hxfm91G*U$95^hP^cq$(C_LcU!LWkiB8M5MBL?q(`7t#d zR8eA3VRCM0IH0g0LW6;Yp`k&+fnz74|0Ua>%))e#!N5TWssA;H;je(@fxeH-a~Pfr*dO5j z$b5z6TY#+t^7!Eqh7%q(96Sc#`pXP79>v3O*um%k`v&G$kofWtoCC^Mhd2s^1Q=Qv z6hTcs8HVeiyi>q*2@=i+80IOpH{?F>@L;lISPrUcZ#3C4^fV|w;;vx&0BIkB#t)kv zbwHzqJWPwHC>-IoP~u~lyinl*w*k{7NW8xgoxyO(!)}?*Q*LXAcLC;8_;a}>7!EDi zynufJ(=Ui!9t;l@ekjNZ_%|>=aFB2S)nCew96+N_{0+?T@xx~grxmOY=uBZ&Yj`=q zE`?_TvkJp)1|tXl8Hn-2bcRj`1rH7pCKiUyBRT~fQ| zOY}*=&jVH|ypxzym`*wxIp|DbR#!O5uql9Nf-=1SwT$H_i&?_?S+k=e85-1EXQ=E!SDfpgfgQ4#qpED z>Hui?n&St99s~ad<}(ZrA>};0{`v=Ly@SlT-(U-xPx;62tikvJ%ME7GBn$%s!wSI} zOf3q!EZh!^0Sqk)x(9g^neH%Lk&4u_^Y41ElW z2RH%{{jW0&O$TxqxDA|q7$!652yp5ton@H7knuxm1ET-6j^U()-3NXSW(9@|pmKf- z^BIOi7mOb8On}+d!0>|Mmy?|V|3>CF46nWInE0nSztQ;3V0VNcss8%F@UO|9f&UP* z0mFR(V+H;P%x@UZF&I7Izrh3_KglLHweFB0(HdrConfa#y1woUSaspXb&pY|1jJK zRa*y`|A0p9K^YBRfBgXu8}c7eHsCzNVC}$vfH{ES&H-Zu{vXWH`s;we6PAvKMGD-Y z`s+r6QX+^U(50l5z`X<3|2n~XgrR{!fq|QWiG>5q5MW|qX;OILz-_>`2v&coFm!Mz zF?TmGsX)g0H!!KNa5N|_;NHLlufM)A90@QM;lIc&;Lt0u+l9Y_JB#7g0;42;1MUfs z@xu>{{R}@E>=gNDI6q?g*QGhE02KuSoeWBX92=N;K>g(h+&h}!^_LGrbHjoIS{hs& zO-&684rnMaH8HGW)X8ABXn>9%ZeWyiXrH9`f-7T_luO$j(6Awskiyalx(eLL^%v7& z0fPg43d}qVhXf27cnp|(7#=X#H1H$UUwfGTi`bvweE{lz3D_^-|H!<@;XbH5L>fPQ z0~$62jXH7&TxKvj&{C4JIju{szSd+=%{{$U7&nIR;!j0+U%38aND?coiC57A)XK z^uI(`Fq~r8)Uaj=vj)R0hfNKg|HbeFG=|^Me1PErhb;p?6Y~Mk zL>L=#{q=3m~cXX$%Ua)K*51S zKnPxcB`-M9proMF!L7t}qQO`}r>k3O!3ifLP>&2g|Mjiur^CJg{wd5)Iet3W1o&SN z{=)Egfjy`r2A}`>rf_nBafbgbBUo9q+#FEE>c>MsYL3(Rbg_J)PPqlS(kGY0Nf zqn8XF4r&724O|LL9Sn;aG#a@0AngPX)*}jy3@QQL0!&94COYT@a0`GcaRwy^E&-+{ zNdA%#UB=MKu*|_5GA#)1a;h>^%6VG^;jr zG8!cCO<-OD$zK_aOE`YB*g0}faDF22lL6dD0*yM_dGJnP_JZUu(EQg40Z_4{tO%O_ z65?s#W@Na*VaKqh5mA3xf!e*G+RB2VuR(bN#{wpcgf<5K295+o{guPe+@$cJ+k%OQ zqlrP~LWcnpA48La&J6~G2Ke})EDJk>;$iL@AsKMy3>4EsRct_KXi81{kcuLlgTKpp1|%!vAn z>3oyn1Dzkr{}|3S886_eU^Zho*I@jB=LMqvn!?b|qIiI#!08S{8<@c*!_>y2*uWbA zt5X;lKy66HBOHZHcO2Rn6q`6om_$J%iVYkEi2CaZOCys4Xfz(w_+P-lVIjoAw8=ps zf|J1sK7P1{;WUE~sC)8&=@f%OfzF0*9j4s}3?A@oV1EUP(*}lj48Iw{{(8#ri^0yB z-@y3|Lw|%_0)K-$eEjea!+8e72RT2KUore@v3kMxftdr64qpgE>#qiuI)>(kMGrZ4 zFg;+{1zPa1K}b=dagkOLmjt5zQe)^=P&&b}k?BFgE&)9Tt_@5Ij9m&!3pkn(8(;`t~p3KfsLC{{r=(`L=<^3LLB&_%|>=VK~8H6u>iuc>-j7{sgN&%VtKs100hW z-Y{+sFlpf4#Praqi9tw!X98mU&_iLv0-YCJDxl&12?`9{TbMv|B}+DG8X)z*7`8U( zK8WyOy2P-rK{Y`-g6*0^e}nQOjtC|XNSnmNgNNY*m(5{51*Q`W8yyTllgLM$4l$H) z_-;bXf9+xT>uBG=e?j@9!xsU02KEn(e;ob^*fQ{6V4eV(UtYobg2i%?(Ix&Z><=40 zGZ+bg`~_;aH1JG-)n6WhGaA4n6^=|77`8EJGI19$eF0Tu4IBZ8@xyrsrZ+4E)mE1n z_BJSjs@iKzZ4Jr_5;x%EhazVLH!CP)a*MD%a@f$IWx;L1bdsaVA%Q_dgbluaV}-*l z1)~-G3z=Uq{9CeV2LFoYA57;wHc#M5K-6CkLDQ51{0+oep{qp!CDg>7eAmF@@;~Q=@}O zfW`!r`7e-~2~AIgK#MdarZF7>DGorH|6WGcKH)c@MSpvA!5pv1tigJB_qMh6qL z{^9`5e}P6gLDkky@U)kc2*XwuMF*})O-|7ID|9L2P7%Eb?g>mw6m~LbIWU9zXj>T) z9k?d2u|di@(E5#^jdqUw)0kC36JbI8Gq_b*emZPQ<(tHu0m&Dj^&7t%><;u#5KdvJ zoM4y2KZW_3!_Nhv!A9;=kiNNwz(R%}9CjT14b7m*O;AO~tiW)B(H>O4dqK@%(Pr4i zpf`~_jp+r$wgX8G+z*;GIJz427O*BTb3uwR4OagHn;UeFa2qI{Vc49s-~e||8xKQs zgU$j51=#qZ0;3GWb_d-9+yP8?8n!qnp5Q*fCdJUsq1(jy05(3a!6C-*eX?y*zX$WZ z30oQzKk#R8%P|~lw0+={!_5Vo|5~E(L%}YBeFF0vQ1>6y5qrV(3)KHofYo0PqW>87 zPOyE#lgTXSa11n|_JjEz!`UWt1)dCM0Z4qUketJ^)j`*Zql7uep-sW?2zLt84N#|; zfh&<|6(pQN^Iuz;^%+(?Xsco2V^BT7oxt>mVG4t4632rk==fm*%TdJ*3_1oJ226eo zO%5stxH*_!F->4p%kWZQngMCItPoub8fQDe)4^P$e2~HX0{G z8yH@){BE%8;Ge?$hT*4&)eHU><_8R~g{&I<5%XUG9~}O3*n{T3Y#9DB7$4|=!2Ct! z9K+@VJP){`^;aWH0^<%xy-C~xOggMP4=5er?_qkx)Wo24fcJrO0<8a~$*@a6?+EuI zCLNaD5?TkiS1>(k>||16;8?(<0GY4kVBlcb#G=E%4Vu&3&7g3Ai-G9?QzwH0gXRJz zCss(r^CU3rVgb)Q>M-nPSapDVf%6lF6O2X9*-ARxqhfXPMg3-?~c`i-211r9j} zJPa0{o7BvxAix1yi8>K9$BMLmLyn=XG4}z72bYl3ga*Y25;vIa7^XGoCU8d}jUOsJ zV6ZvB!@zt*;W5L813CiAJPemrK>aUg`1*}KEPokfkLZ77z9IC7(Vn6I0rLlkH;^7Q z()zF|r8ei_e$X88QqA*UY>b`1JQ zm^TRgVYX)QJHS-H@JG>(0lEM6jN#+~BL^P=?qdoUIjlevMo(CNvZy%l2q5aObcW6Z zr3j5FOlqKs)Bx5AOwS#Ds^~drOyWY!e}Pxrt(d^{rC~0EHfX}=3&UO}HBkQxv3|n| zwDN%?kV#aamEmCuX8_Y3hOMB6q5xw4D|tZ&gAoIV-r`3aZmh5n;9+2X!0?B`OpB+h z8D4*VYxv5r*TH`l^E1$d5oFHpB`AL(t>5^z;4Oo(1J4}hZ45UXj2&1&25?2yI}7ciVqG~&={VP*j3 zF9ALlW&==Z!@++5-v45>U}#HFUc|eEyNaQUNqGUs5~dXlRvmT?-bmwzzDmsv3KKYt z7QZD=g;YC}f)B zu~k5kg}V^B|J7rp+R&xICF3yNQ1L+L2BsL1{eqeoxI+;Auj394Oezz&)R@?gOx~a* z&|$&Utgzw03Px@P#Q5QQrvnE}Ch+Z$Qf0X9u;_vAlIBEEEzH2bz!~2EI?D3H#j25Y zgY#2{*9>-t_?1A7b_TTr{1XuKUvHSsa1=N3Bq)n89cD1zp!0y)hT$)VJtO}Q<^!1||gt zE0CH+Ob;M!bdNU2ONKz_64kOP-5Uf>VF+r z(5%JK$ZWvGz_6J~?*NA(Q%_5?KmrqZ{UM~T6kWv7%%Jp9dV`o6!zu^83mhAS)`0qP z3>*`TyA>76U7W)f4GF<|AGAn`af_#VR#1` zHr&9RBk-Tm{)qoX#QMV}2W~giP2kzY{D9%KgB_@!!XxmQ!4A|^gL4f-KZ8{R$5dt`NL)N%O<|a*r1OBwgy{f7GlL65_XY+Ymc^hIqykJ8 z4B&Qx0;3p1YlChQcLmcWg|-Q~3fz@UaSZK^8VVd0u=b$`2Lr=J0i6SU224j84l}5* z@EZv8Fg;cPt*GY?VgkphgX{(t(0XkC56oXU{xR6I@_%9e~<2v4y+HNk(D0!b%730_6H@d!znC zg(}ec`G$uE+!joJ4WJQ4ZXHDb>m0-G7Et$}=?ueW2L*+011=wi#S9wXxR-Fj`(Ha5 zel4)?;90=@)8UtZ(SrU3%oz-)7&cGff58l|zaD~mTMYayjG(r<9g}|pa|3k!22%fv z;pYS+2i`f%te|=71N{@2Aq(k!W@^LMZ?L2~>~v6a@RkABUuvL%G8KkS0X+xaDTw+@ zg<&Uyk_Yz`@EUtH2W|mA&|-TX2aX9%i2BQ6;{?#MLoODEMivzZZlNZY1&s_kE}Vj} z`Q;tF*$aL+Y+~T=nyj>_gTah}zg<}I(1{gxRy=*k_1E78wvPN0oWC&qWHfVNo*?{$ zheAzr`{!5Rcn}JC|;09<- zS08f!s~OzwVq#%zWXN&g290?(g4S<<+zifN5~52K8X1(5xF%g6`=!(L22HgYP zMNBdc&5bHAxJsDd>o@Ee&NUS#@MkdJWBA@+`+&bn*}my$gXssJ8}RiTvP(FAFxY{X z9YU9FY?Xey;3w0rOZ-z1_18CsKMUP(E?|PXr+{fr!*vDSliYz#&^{5U|FuPt7qoukj>C2a%> TrnK247mrmE101D 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%0A(wY9V~hc935OrEgcL>47@1) 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 QRvj=hFdRfoOF<0*0AvjO_5c6? literal 42168 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 & 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�L|LlCh&VOUt`$XV7Z8|g835T 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 diff --git a/fpga-xc2s30/fpga_lf.bit b/fpga-xc2s30/fpga_lf.bit index 93a26841a35f0e01f50465fe6acfd602abd8e758..f5e5ce630e41b642c066a90aff5e6cfcc201d220 100644 GIT binary patch literal 42175 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 literal 42168 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 Date: Sat, 27 May 2023 10:46:42 +0200 Subject: [PATCH 22/37] added "--sk" param to hf mf eview and view commands. This param extracts and saves keys to binary key file --- CHANGELOG.md | 10 +++++--- client/src/cmdhfmf.c | 59 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85593f3b2..0906e8800 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Changed `hf mf eview --sk` - now can extract keys and save to file (@iceman1001) + - Changed `hf mf view --sk` - now can extract keys and save to file (@iceman1001) - Changed `hf mf sim` - reduce 6ms threshold to 4ms for reset to idle #1974 (@net147) - Rebuilt the Spartan-2 `fpga_*.bit` files to include the `hi_iso14443a.v` update (@d18c7db) - Added minor orphaned change from `hi_iso14443a.v` in `fpga-xc3s100e` to `hi_iso14443a.v` in `fpga-xc2s30` (@d18c7db) @@ -22,7 +24,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Changed `hf mf supercard` - Support editing UID and recovery of keys from second generation card (@AloneLiberty) - Added iClass credit key to default iClass key table and reorganized key order (@GuruSteve) - Changed `hf mf value` - ability to use transfer on different block (@AloneLiberty) - - Change `hf mf dump --ns` - dump command now supports `no save` of MFC card memory (@iceman1001) + - Changed `hf mf dump --ns` - dump command now supports `no save` of MFC card memory (@iceman1001) - Added `hf mf gdmsetcfg` - Supprt Gen4 GDM write configuration block (@iceman1001) - Added `hf mf gdmcfg` - Support Gen4 GDM read configuration block (@iceman1001) - Changed magic note to include a section about GDM tags (@iceman1001) @@ -62,11 +64,11 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added `hf legic info` command for other sources (@0xdeb) - Added `hf legic einfo` - views emulator menory (@0xdeb) - Changed `hf legic view` - now also print the decoded info of the dump file (@0xdeb) - - Now `script run hf_mf_ultimatecard.lua -u` supports 10bytes UID (@alejandro12120) - - Update documentation for installation on macOS with MacPorts (@linuxgemini) + - Changed `script run hf_mf_ultimatecard.lua -u` to support 10bytes UID (@alejandro12120) + - Updated documentation for installation on macOS with MacPorts (@linuxgemini) - Added possible Paxton id to hitag2 tag info output - Changed `hf mf sim` - reduce 50ms threshold to 6ms for reset to idle #1974 (@net147) - - Update `amiibo_tools.lua` with new identifiers and create a python script `update_amiibo_tools_lua.py` to automate the process in the future. (@CorySolovewicz) + - Updated `amiibo_tools.lua` with new identifiers and create a python script `update_amiibo_tools_lua.py` to automate the process in the future. (@CorySolovewicz) ## [Nitride.4.16191][2023-01-29] - Changed `build_all_firmwares.sh` to fit GENERIC 256kb firmware images (@doegox) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index aebce5737..7487088dd 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -320,6 +320,52 @@ static int mf_print_keys(uint16_t n, uint8_t *d) { return PM3_SUCCESS; } +// MFC dump , extract and save the keys to key file +static int mf_save_keys_from_arr(uint16_t n, uint8_t *d) { + uint8_t sectors = 0; + switch (n) { + case MIFARE_MINI_MAXBLOCK: + sectors = MIFARE_MINI_MAXSECTOR; + break; + case MIFARE_2K_MAXBLOCK: + sectors = MIFARE_2K_MAXSECTOR; + break; + case MIFARE_4K_MAXBLOCK: + sectors = MIFARE_4K_MAXSECTOR; + break; + case MIFARE_1K_MAXBLOCK: + default: + sectors = MIFARE_1K_MAXSECTOR; + break; + } + + uint16_t keysize = 2 * MIFARE_KEY_SIZE * sectors; + + uint8_t *keys = calloc(keysize, sizeof(uint8_t)); + if (keys == NULL) { + return PM3_EMALLOC; + } + + uint8_t sector = 0; + for (uint16_t i = 0; i < n; i++) { + if (mfIsSectorTrailer(i)) { + // key A offset in ST block + memcpy(keys + (MIFARE_KEY_SIZE * sector), d + (i * MFBLOCK_SIZE), MIFARE_KEY_SIZE); + + // key B offset in ST block + memcpy(keys + (MIFARE_KEY_SIZE * sectors) + (MIFARE_KEY_SIZE * sector), d + (i * MFBLOCK_SIZE) + 10, MIFARE_KEY_SIZE); + + sector++; + } + } + + char fn[FILE_PATH_SIZE] = {0}; + snprintf(fn, sizeof(fn), "hf-mf-%s-keys", sprint_hex_inrow(d, 4)); + saveFile(fn, ".bin", keys, keysize); + free(keys); + return PM3_SUCCESS; +} + /* static void mf_print_values(uint16_t n, uint8_t *d) { @@ -4396,6 +4442,7 @@ static int CmdHF14AMfEView(const char *Cmd) { arg_lit0(NULL, "2k", "MIFARE Classic/Plus 2k"), arg_lit0(NULL, "4k", "MIFARE Classic 4k / S70"), arg_lit0("v", "verbose", "verbose output"), + arg_lit0(NULL, "sk", "Save extracted keys to file"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -4404,6 +4451,7 @@ static int CmdHF14AMfEView(const char *Cmd) { bool m2 = arg_get_lit(ctx, 3); bool m4 = arg_get_lit(ctx, 4); bool verbose = arg_get_lit(ctx, 5); + bool save_keys = arg_get_lit(ctx, 6); CLIParserFree(ctx); // validations @@ -4449,6 +4497,11 @@ static int CmdHF14AMfEView(const char *Cmd) { if (verbose) { mf_print_keys(block_cnt, dump); } + + if (save_keys) { + mf_save_keys_from_arr(block_cnt, dump); + } + free(dump); return PM3_SUCCESS; } @@ -7028,6 +7081,7 @@ static int CmdHF14AMfView(const char *Cmd) { arg_param_begin, arg_str1("f", "file", "", "filename of dump"), arg_lit0("v", "verbose", "verbose output"), + arg_lit0(NULL, "sk", "Save extracted keys to file"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); @@ -7035,6 +7089,7 @@ static int CmdHF14AMfView(const char *Cmd) { char filename[FILE_PATH_SIZE]; CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); bool verbose = arg_get_lit(ctx, 2); + bool save_keys = arg_get_lit(ctx, 3); CLIParserFree(ctx); // read dump file @@ -7065,6 +7120,10 @@ static int CmdHF14AMfView(const char *Cmd) { mf_analyse_acl(block_cnt, dump); } + if (save_keys) { + mf_save_keys_from_arr(block_cnt, dump); + } + int sector = DetectHID(dump, 0x4910); if (sector > -1) { // decode it From 0cc7373655f949f5eadfa3d5a562e7cfebd5c120 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 27 May 2023 12:10:32 +0200 Subject: [PATCH 23/37] fix resource leaks --- client/src/cmdlfem4x50.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/src/cmdlfem4x50.c b/client/src/cmdlfem4x50.c index 017f1c121..07b1f91b0 100644 --- a/client/src/cmdlfem4x50.c +++ b/client/src/cmdlfem4x50.c @@ -382,6 +382,7 @@ int CmdEM4x50Brute(const char *Cmd) { etd.bruteforce_mode = BRUTEFORCE_MODE_CHARSET; } else { PrintAndLogEx(FAILED, "Unknown bruteforce mode: %s", mode); + CLIParserFree(ctx); return PM3_EINVARG; } @@ -396,11 +397,13 @@ int CmdEM4x50Brute(const char *Cmd) { if (begin_len != 4) { PrintAndLogEx(FAILED, "'begin' parameter must be 4 bytes"); + CLIParserFree(ctx); return PM3_EINVARG; } if (end_len != 4) { PrintAndLogEx(FAILED, "'end' parameter must be 4 bytes"); + CLIParserFree(ctx); return PM3_EINVARG; } @@ -417,6 +420,7 @@ int CmdEM4x50Brute(const char *Cmd) { if (etd.bruteforce_charset == 0) { PrintAndLogEx(FAILED, "Please enable at least one charset when using charset bruteforce mode."); + CLIParserFree(ctx); return PM3_EINVARG; } From 32fcf5e870f1e596092bbfc0c7963a236e7a8379 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 27 May 2023 17:00:28 +0200 Subject: [PATCH 24/37] make 16 bytes default cols --- CHANGELOG.md | 1 + client/src/cmdflashmemspiffs.c | 4 ++-- client/src/cmdusart.c | 2 +- doc/uart_notes.md | 2 +- tools/btaddon/requirements.txt | 1 + 5 files changed, 6 insertions(+), 4 deletions(-) create mode 100644 tools/btaddon/requirements.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index 0906e8800..118c4b793 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Changed `usart btfactory` - handles the new BT board with version "BT SPP V3.0" (@iceman1001) - Changed `hf mf eview --sk` - now can extract keys and save to file (@iceman1001) - Changed `hf mf view --sk` - now can extract keys and save to file (@iceman1001) - Changed `hf mf sim` - reduce 6ms threshold to 4ms for reset to idle #1974 (@net147) diff --git a/client/src/cmdflashmemspiffs.c b/client/src/cmdflashmemspiffs.c index a1923d588..e84b3e597 100644 --- a/client/src/cmdflashmemspiffs.c +++ b/client/src/cmdflashmemspiffs.c @@ -531,7 +531,7 @@ static int CmdFlashMemSpiFFSView(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_str1("f", "file", "", "SPIFFS file to view"), - arg_int0("c", "cols", "", "column breaks (def 32)"), + arg_int0("c", "cols", "", "column breaks (def 16)"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); @@ -540,7 +540,7 @@ static int CmdFlashMemSpiFFSView(const char *Cmd) { char fn[32] = {0}; CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)fn, 32, &fnlen); - int breaks = arg_get_int_def(ctx, 2, 32); + int breaks = arg_get_int_def(ctx, 2, 16); CLIParserFree(ctx); uint8_t *dump = NULL; diff --git a/client/src/cmdusart.c b/client/src/cmdusart.c index d67ae9bf1..2b98181d0 100644 --- a/client/src/cmdusart.c +++ b/client/src/cmdusart.c @@ -157,7 +157,7 @@ static int usart_bt_testcomm(uint32_t baudrate, uint8_t parity) { ret = usart_txrx((uint8_t *)string, strlen(string), data, &len, 1000); // such large timeout needed if (ret == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "RX (%3zu):%.*s", len, (int)len, data); - if (strcmp((char *)data, "hc01.comV2.0") == 0) { + if (strcmp((char *)data, "hc01.comV2.0") == 0 || strcmp((char *)data, "BT SPP V3.0") == 0) { PrintAndLogEx(SUCCESS, "Add-on " _GREEN_("found!")); return PM3_SUCCESS; } diff --git a/doc/uart_notes.md b/doc/uart_notes.md index 5c8cb65b6..eeee8a1d0 100644 --- a/doc/uart_notes.md +++ b/doc/uart_notes.md @@ -199,7 +199,7 @@ The ROLE command takes its parameter after an equal sign: |Command |Description |Reply | |-------------------|------------------------------------------------------|--------------| -|`AT+VERSION` |print firmware version |`hc01.comV2.0`| +|`AT+VERSION` |print firmware version |`hc01.comV2.0` or `BT SPP V3.0`| |`AT+BAUD8` |set baudrate to 115200 |`OK115200` | |`AT+PIN1234` |set PINCODE to 1234. (must be numbers) |`OKsetPIN` | |`AT+NAMEPM3_RDV4.0`|set device name (as shown to BT hosts) to `PM3_RDV4.0`|`OKsetname` | diff --git a/tools/btaddon/requirements.txt b/tools/btaddon/requirements.txt new file mode 100644 index 000000000..3452b96e3 --- /dev/null +++ b/tools/btaddon/requirements.txt @@ -0,0 +1 @@ +pyserial==3.5.0 From 1d0da726ecbc73e11d60df028df1984be4c786b4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 27 May 2023 21:10:11 +0200 Subject: [PATCH 25/37] the clocks for usart rxtx wasnt enabled. --- armsrc/appmain.c | 15 ++++++++++--- armsrc/usart.c | 52 ++++++++++++++++++++++++++++------------------ client/src/comms.c | 9 +++++--- 3 files changed, 50 insertions(+), 26 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index f68739da2..310aa6a0d 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -2051,11 +2051,16 @@ static void PacketReceived(PacketCommandNG *packet) { } PACKED; struct p *payload = (struct p *) &packet->data.asBytes; usart_writebuffer_sync(payload->data, packet->length - sizeof(payload)); + uint16_t available; uint16_t pre_available = 0; uint8_t *dest = BigBuf_malloc(USART_FIFOLEN); uint32_t wait = payload->waittime; + + StartTicks(); + uint32_t ti = GetTickCount(); + while (true) { WaitMS(50); available = usart_rxdata_available(); @@ -2070,12 +2075,15 @@ static void PacketReceived(PacketCommandNG *packet) { if (GetTickCountDelta(ti) > wait) break; } + if (available > 0) { uint16_t len = usart_read_ng(dest, available); reply_ng(CMD_USART_TXRX, PM3_SUCCESS, dest, len); } else { reply_ng(CMD_USART_TXRX, PM3_ENODATA, NULL, 0); } + + StopTicks(); BigBuf_free(); LED_B_OFF(); break; @@ -2718,9 +2726,6 @@ void __attribute__((noreturn)) AppMain(void) { } #endif -#ifdef WITH_FPC_USART - usart_init(USART_BAUD_RATE, USART_PARITY); -#endif #ifdef WITH_FLASH // If flash is not present, BUSY_TIMEOUT kicks in, let's do it after USB @@ -2733,6 +2738,10 @@ void __attribute__((noreturn)) AppMain(void) { rdv40_spiffs_check(); #endif +#ifdef WITH_FPC_USART + usart_init(USART_BAUD_RATE, USART_PARITY); +#endif + // This is made as late as possible to ensure enumeration without timeout // against device such as http://www.hobbytronics.co.uk/usb-host-board-v2 // In other words, keep the interval between usb_enable() and the main loop as short as possible. diff --git a/armsrc/usart.c b/armsrc/usart.c index f92e9c701..915d4a445 100644 --- a/armsrc/usart.c +++ b/armsrc/usart.c @@ -46,8 +46,8 @@ void usart_close(void) { } */ -static uint8_t us_inbuf1[USART_BUFFLEN]; -static uint8_t us_inbuf2[USART_BUFFLEN]; +static uint8_t us_in_a[USART_BUFFLEN]; +static uint8_t us_in_b[USART_BUFFLEN]; static uint8_t *usart_cur_inbuf = NULL; static uint16_t usart_cur_inbuf_off = 0; static uint8_t us_rxfifo[USART_FIFOLEN]; @@ -56,7 +56,9 @@ static size_t us_rxfifo_high = 0; static void usart_fill_rxfifo(void) { - uint16_t rxfifo_free ; + + uint16_t rxfifo_free = 0; + if (pUS1->US_RNCR == 0) { // One buffer got filled, backup buffer being used if (us_rxfifo_low > us_rxfifo_high) @@ -79,19 +81,22 @@ static void usart_fill_rxfifo(void) { pUS1->US_RNCR = USART_BUFFLEN; // Swap current buff - if (usart_cur_inbuf == us_inbuf1) - usart_cur_inbuf = us_inbuf2; + if (usart_cur_inbuf == us_in_a) + usart_cur_inbuf = us_in_b; else - usart_cur_inbuf = us_inbuf1; + usart_cur_inbuf = us_in_a; usart_cur_inbuf_off = 0; } else { // Take only what we have room for available = rxfifo_free; for (uint16_t i = 0; i < available; i++) { + us_rxfifo[us_rxfifo_high++] = usart_cur_inbuf[usart_cur_inbuf_off + i]; - if (us_rxfifo_high == sizeof(us_rxfifo)) + + if (us_rxfifo_high == sizeof(us_rxfifo)) { us_rxfifo_high = 0; + } } usart_cur_inbuf_off += available; return; @@ -101,18 +106,20 @@ static void usart_fill_rxfifo(void) { if (pUS1->US_RCR < USART_BUFFLEN - usart_cur_inbuf_off) { // Current buffer partially filled if (us_rxfifo_low > us_rxfifo_high) - rxfifo_free = us_rxfifo_low - us_rxfifo_high; + rxfifo_free = (us_rxfifo_low - us_rxfifo_high); else - rxfifo_free = sizeof(us_rxfifo) - us_rxfifo_high + us_rxfifo_low; + rxfifo_free = (sizeof(us_rxfifo) - us_rxfifo_high + us_rxfifo_low); - uint16_t available = USART_BUFFLEN - pUS1->US_RCR - usart_cur_inbuf_off; + uint16_t available = (USART_BUFFLEN - pUS1->US_RCR - usart_cur_inbuf_off); if (available > rxfifo_free) available = rxfifo_free; + for (uint16_t i = 0; i < available; i++) { us_rxfifo[us_rxfifo_high++] = usart_cur_inbuf[usart_cur_inbuf_off + i]; - if (us_rxfifo_high == sizeof(us_rxfifo)) + if (us_rxfifo_high == sizeof(us_rxfifo)) { us_rxfifo_high = 0; + } } usart_cur_inbuf_off += available; } @@ -121,9 +128,9 @@ static void usart_fill_rxfifo(void) { uint16_t usart_rxdata_available(void) { usart_fill_rxfifo(); if (us_rxfifo_low <= us_rxfifo_high) - return us_rxfifo_high - us_rxfifo_low; + return (us_rxfifo_high - us_rxfifo_low); else - return sizeof(us_rxfifo) - us_rxfifo_low + us_rxfifo_high; + return (sizeof(us_rxfifo) - us_rxfifo_low + us_rxfifo_high); } uint32_t usart_read_ng(uint8_t *data, size_t len) { @@ -143,9 +150,10 @@ uint32_t usart_read_ng(uint8_t *data, size_t len) { uint32_t maxtry = 10 * (3000000 / USART_BAUD_RATE) + tryconstant; while (len) { - uint32_t available = usart_rxdata_available(); + uint32_t available = usart_rxdata_available(); uint32_t packetSize = MIN(available, len); + if (available > 0) { // Dbprintf_usb("Dbg USART ask %d bytes, available %d bytes, packetsize %d bytes", len, available, packetSize); // highest_observed_try = MAX(highest_observed_try, try); @@ -153,8 +161,9 @@ uint32_t usart_read_ng(uint8_t *data, size_t len) { } len -= packetSize; while (packetSize--) { - if (us_rxfifo_low == sizeof(us_rxfifo)) + if (us_rxfifo_low == sizeof(us_rxfifo)) { us_rxfifo_low = 0; + } data[bytes_rcv++] = us_rxfifo[us_rxfifo_low++]; } if (try++ == maxtry) { @@ -183,10 +192,13 @@ int usart_writebuffer_sync(uint8_t *data, size_t len) { void usart_init(uint32_t baudrate, uint8_t parity) { - if (baudrate != 0) + if (baudrate != 0) { g_usart_baudrate = baudrate; - if ((parity == 'N') || (parity == 'O') || (parity == 'E')) + } + + if ((parity == 'N') || (parity == 'O') || (parity == 'E')) { g_usart_parity = parity; + } // For a nice detailed sample, interrupt driven but still relevant. // See https://www.sparkfun.com/datasheets/DevTools/SAM7/at91sam7%20serial%20communications.pdf @@ -262,11 +274,11 @@ void usart_init(uint32_t baudrate, uint8_t parity) { pUS1->US_TCR = 0; pUS1->US_TNPR = (uint32_t)0; pUS1->US_TNCR = 0; - pUS1->US_RPR = (uint32_t)us_inbuf1; + pUS1->US_RPR = (uint32_t)us_in_a; pUS1->US_RCR = USART_BUFFLEN; - usart_cur_inbuf = us_inbuf1; + usart_cur_inbuf = us_in_a; usart_cur_inbuf_off = 0; - pUS1->US_RNPR = (uint32_t)us_inbuf2; + pUS1->US_RNPR = (uint32_t)us_in_b; pUS1->US_RNCR = USART_BUFFLEN; // Initialize our fifo diff --git a/client/src/comms.c b/client/src/comms.c index a8ed8be4c..64bea9f65 100644 --- a/client/src/comms.c +++ b/client/src/comms.c @@ -30,8 +30,8 @@ #include "util_posix.h" // msclock #include "util_darwin.h" // en/dis-ableNapp(); -//#define COMMS_DEBUG -//#define COMMS_DEBUG_RAW +// #define COMMS_DEBUG +// #define COMMS_DEBUG_RAW // Serial port that we are communicating with the PM3 on. static serial_port sp = NULL; @@ -369,6 +369,7 @@ __attribute__((force_align_arg_pointer)) } res = uart_receive(sp, (uint8_t *)&rx_raw.pre, sizeof(PacketResponseNGPreamble), &rxlen); + if ((res == PM3_SUCCESS) && (rxlen == sizeof(PacketResponseNGPreamble))) { rx.magic = rx_raw.pre.magic; uint16_t length = rx_raw.pre.length; @@ -380,6 +381,7 @@ __attribute__((force_align_arg_pointer)) PrintAndLogEx(WARNING, "Received packet frame with incompatible length: 0x%04x", length); error = true; } + if ((!error) && (length > 0)) { // Get the variable length payload res = uart_receive(sp, (uint8_t *)&rx_raw.data, length, &rxlen); @@ -418,10 +420,10 @@ __attribute__((force_align_arg_pointer)) rx.length = 0; // set received length to 0 else { // old frames can't be empty PrintAndLogEx(WARNING, "Received empty MIX packet frame (length: 0x00)"); - error = true; } } + if (!error) { // Get the postamble res = uart_receive(sp, (uint8_t *)&rx_raw.foopost, sizeof(PacketResponseNGPostamble), &rxlen); if ((res != PM3_SUCCESS) || (rxlen != sizeof(PacketResponseNGPostamble))) { @@ -429,6 +431,7 @@ __attribute__((force_align_arg_pointer)) error = true; } } + if (!error) { // Check CRC, accept MAGIC as placeholder rx.crc = rx_raw.foopost.crc; if (rx.crc != RESPONSENG_POSTAMBLE_MAGIC) { From 62b184ce490dbd37d8f0d2edfe53291afd6d947f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 27 May 2023 21:12:58 +0200 Subject: [PATCH 26/37] adapt usart rx to enable clocks --- armsrc/appmain.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 310aa6a0d..38c680050 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -2014,11 +2014,16 @@ static void PacketReceived(PacketCommandNG *packet) { uint32_t waittime; } PACKED; struct p *payload = (struct p *) &packet->data.asBytes; + uint16_t available; uint16_t pre_available = 0; uint8_t *dest = BigBuf_malloc(USART_FIFOLEN); uint32_t wait = payload->waittime; + + StartTicks(); + uint32_t ti = GetTickCount(); + while (true) { WaitMS(50); available = usart_rxdata_available(); @@ -2039,6 +2044,8 @@ static void PacketReceived(PacketCommandNG *packet) { } else { reply_ng(CMD_USART_RX, PM3_ENODATA, NULL, 0); } + + StopTicks(); BigBuf_free(); LED_B_OFF(); break; From c5c0ef36a730f5af0417d3daf13485b08f413f74 Mon Sep 17 00:00:00 2001 From: d18c7db Date: Sat, 27 May 2023 21:47:51 +0200 Subject: [PATCH 27/37] Fix truncated FPGA upload due to incorrect integer size variable --- CHANGELOG.md | 1 + armsrc/fpgaloader.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 118c4b793..8d8885d30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Fixed truncated FPGA upload due to incorrect integer size variable (@d18c7db) - Changed `usart btfactory` - handles the new BT board with version "BT SPP V3.0" (@iceman1001) - Changed `hf mf eview --sk` - now can extract keys and save to file (@iceman1001) - Changed `hf mf view --sk` - now can extract keys and save to file (@iceman1001) diff --git a/armsrc/fpgaloader.c b/armsrc/fpgaloader.c index 802c77558..61c2df9d1 100644 --- a/armsrc/fpgaloader.c +++ b/armsrc/fpgaloader.c @@ -393,7 +393,7 @@ static int bitparse_find_section(int bitstream_version, char section_name, uint3 while (numbytes < MAX_FPGA_BIT_STREAM_HEADER_SEARCH) { char current_name = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer); numbytes++; - uint16_t current_length = 0; + uint32_t current_length = 0; if (current_name < 'a' || current_name > 'e') { /* Strange section name, abort */ break; From 336bd06d8844d09ed3dc2c21a11278f6bfe6e22d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 28 May 2023 07:34:27 +0200 Subject: [PATCH 28/37] type fix --- armsrc/fpgaloader.c | 2 +- client/src/cmdusart.c | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/armsrc/fpgaloader.c b/armsrc/fpgaloader.c index 61c2df9d1..6f8dd7a0b 100644 --- a/armsrc/fpgaloader.c +++ b/armsrc/fpgaloader.c @@ -423,7 +423,7 @@ static int bitparse_find_section(int bitstream_version, char section_name, uint3 break; } - for (uint16_t i = 0; i < current_length && numbytes < MAX_FPGA_BIT_STREAM_HEADER_SEARCH; i++) { + for (uint32_t i = 0; i < current_length && numbytes < MAX_FPGA_BIT_STREAM_HEADER_SEARCH; i++) { get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer); numbytes++; } diff --git a/client/src/cmdusart.c b/client/src/cmdusart.c index 2b98181d0..f8538caf3 100644 --- a/client/src/cmdusart.c +++ b/client/src/cmdusart.c @@ -68,15 +68,20 @@ static int usart_txrx(uint8_t *srcdata, size_t srclen, uint8_t *dstdata, size_t struct payload_header header; uint8_t data[PM3_CMD_DATA_SIZE - sizeof(uint32_t)]; } PACKED payload; + payload.header.waittime = waittime; - if (srclen >= sizeof(payload.data)) + + if (srclen >= sizeof(payload.data)) { return PM3_EOVFLOW; + } + memcpy(payload.data, srcdata, srclen); SendCommandNG(CMD_USART_TXRX, (uint8_t *)&payload, srclen + sizeof(payload.header)); PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_USART_TXRX, &resp, waittime + 500)) { + if (WaitForResponseTimeout(CMD_USART_TXRX, &resp, waittime + 500) == false) { return PM3_ETIMEOUT; } + if (resp.status == PM3_SUCCESS) { *dstlen = resp.length; memcpy(dstdata, resp.data.asBytes, resp.length); @@ -154,7 +159,8 @@ static int usart_bt_testcomm(uint32_t baudrate, uint8_t parity) { PrintAndLogEx(SUCCESS, "TX (%3zu):%.*s at %u 8%c1", strlen(string), (int)strlen(string), string, baudrate, parity); - ret = usart_txrx((uint8_t *)string, strlen(string), data, &len, 1000); // such large timeout needed + // 1000, such large timeout needed + ret = usart_txrx((uint8_t *)string, strlen(string), data, &len, 1000); if (ret == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "RX (%3zu):%.*s", len, (int)len, data); if (strcmp((char *)data, "hc01.comV2.0") == 0 || strcmp((char *)data, "BT SPP V3.0") == 0) { From da250f9eed3b2f1a0ed61077823e3f179a3fbd24 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 28 May 2023 08:24:06 +0200 Subject: [PATCH 29/37] adapted to handle the bluetooth identifier on a Proxmark SE device. Full name is identifier is: Proxmark SE(TEST) --- pm3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pm3 b/pm3 index 7c1d0e289..d59d10ea6 100755 --- a/pm3 +++ b/pm3 @@ -115,7 +115,7 @@ function get_pm3_list_Linux { if $FINDBTDIRECT; then # check if the MAC of a Proxmark3 was registered in the known devices for MAC in $(dbus-send --system --print-reply --type=method_call --dest='org.bluez' '/' org.freedesktop.DBus.ObjectManager.GetManagedObjects 2>/dev/null|\ - awk '/"Address"/{getline;gsub(/"/,"",$3);a=$3}/Name/{getline;if (/PM3_RDV4/) print a}'); do + awk '/"Address"/{getline;gsub(/"/,"",$3);a=$3}/Name/{getline;if (/PM3_RDV4/ || /Proxmark3 SE/) print a}'); do PM3LIST+=("bt:$MAC") done # we don't probe the device so there is no guarantee the device is actually present From 6d22b606c2c71c555a1bd3f7f50e4233e813ad93 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 28 May 2023 10:26:07 +0200 Subject: [PATCH 30/37] adapt comparison --- client/src/cmdusart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdusart.c b/client/src/cmdusart.c index f8538caf3..0d33ef374 100644 --- a/client/src/cmdusart.c +++ b/client/src/cmdusart.c @@ -163,7 +163,7 @@ static int usart_bt_testcomm(uint32_t baudrate, uint8_t parity) { ret = usart_txrx((uint8_t *)string, strlen(string), data, &len, 1000); if (ret == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "RX (%3zu):%.*s", len, (int)len, data); - if (strcmp((char *)data, "hc01.comV2.0") == 0 || strcmp((char *)data, "BT SPP V3.0") == 0) { + if (str_startswith((char *)data, "hc01.comV2.0") || str_startswith((char *)data, "BT SPP V3.0")) { PrintAndLogEx(SUCCESS, "Add-on " _GREEN_("found!")); return PM3_SUCCESS; } From 2b90683aff8472801c2a5fd33cc18e0355b510cc Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 28 May 2023 12:34:29 +0200 Subject: [PATCH 31/37] added debug output for usart comms --- client/src/uart/uart_posix.c | 4 ++++ client/src/uart/uart_win32.c | 2 ++ 2 files changed, 6 insertions(+) diff --git a/client/src/uart/uart_posix.c b/client/src/uart/uart_posix.c index b2a858e09..58e497d55 100644 --- a/client/src/uart/uart_posix.c +++ b/client/src/uart/uart_posix.c @@ -263,6 +263,7 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) { sp->fd = open(pcPortName, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK); if (sp->fd == -1) { + PrintAndLogEx(ERR, "error: UART file descriptor"); uart_close(sp); return INVALID_SERIAL_PORT; } @@ -285,6 +286,7 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) { // Try to retrieve the old (current) terminal info struct if (tcgetattr(sp->fd, &sp->tiOld) == -1) { + PrintAndLogEx(ERR, "error: UART get terminal info attribute"); uart_close(sp); return INVALID_SERIAL_PORT; } @@ -305,6 +307,8 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) { // Try to set the new terminal info struct if (tcsetattr(sp->fd, TCSANOW, &sp->tiNew) == -1) { + PrintAndLogEx(ERR, "error: UART set terminal info attribute"); + perror("tcsetattr() error"); uart_close(sp); return INVALID_SERIAL_PORT; } diff --git a/client/src/uart/uart_win32.c b/client/src/uart/uart_win32.c index 9cdcc41d1..699ac4525 100644 --- a/client/src/uart/uart_win32.c +++ b/client/src/uart/uart_win32.c @@ -98,6 +98,7 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) { free(prefix); if (strlen(pcPortName) <= 4) { + PrintAndLogEx(ERR, "error: tcp port name length too short"); free(sp); return INVALID_SERIAL_PORT; } @@ -193,6 +194,7 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) { sp->hPort = CreateFileA(acPortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (sp->hPort == INVALID_HANDLE_VALUE) { uart_close(sp); + PrintAndLogEx(ERR, "error: invalid handle"); return INVALID_SERIAL_PORT; } From f17ce1fd682c00bdecd40058ece14762c935decd Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 28 May 2023 12:40:57 +0200 Subject: [PATCH 32/37] revert one debug message --- client/src/uart/uart_posix.c | 1 - client/src/uart/uart_win32.c | 1 - 2 files changed, 2 deletions(-) diff --git a/client/src/uart/uart_posix.c b/client/src/uart/uart_posix.c index 58e497d55..86d76317b 100644 --- a/client/src/uart/uart_posix.c +++ b/client/src/uart/uart_posix.c @@ -263,7 +263,6 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) { sp->fd = open(pcPortName, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK); if (sp->fd == -1) { - PrintAndLogEx(ERR, "error: UART file descriptor"); uart_close(sp); return INVALID_SERIAL_PORT; } diff --git a/client/src/uart/uart_win32.c b/client/src/uart/uart_win32.c index 699ac4525..cb8b92a73 100644 --- a/client/src/uart/uart_win32.c +++ b/client/src/uart/uart_win32.c @@ -194,7 +194,6 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) { sp->hPort = CreateFileA(acPortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (sp->hPort == INVALID_HANDLE_VALUE) { uart_close(sp); - PrintAndLogEx(ERR, "error: invalid handle"); return INVALID_SERIAL_PORT; } From 7368cccdf90b4c68ae598ff27ee2e9db5b71e1a4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 29 May 2023 06:57:39 +0200 Subject: [PATCH 33/37] Disney MagicBand --- client/resources/aid_desfire.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/client/resources/aid_desfire.json b/client/resources/aid_desfire.json index 45df737e5..f5387ff45 100644 --- a/client/resources/aid_desfire.json +++ b/client/resources/aid_desfire.json @@ -367,5 +367,21 @@ "Name": "University of Ljubljana Student ID", "Description": "", "Type": "student" + }, + { + "AID": "27E178", + "Vendor": "Disney", + "Country": "US", + "Name": "Disney MagicBand", + "Description": "", + "Type": "payment system" + }, + { + "AID": "44434C", + "Vendor": "Disney", + "Country": "US", + "Name": "Disney MagicBand", + "Description": "AID found on MagicBand desfire cards", + "Type": "payment system" } ] From 7c8e9db822280e5b1731ec0af6396361c1dc673b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 30 May 2023 13:46:52 +0200 Subject: [PATCH 34/37] allow user abort when wiping --- client/src/cmdhfmf.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 7487088dd..6d017a849 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -5919,8 +5919,9 @@ int CmdHFMFNDEFRead(const char *Cmd) { CLIParserFree(ctx); uint16_t ndef_aid = NDEF_MFC_AID; - if (aidlen == 2) + if (aidlen == 2){ ndef_aid = (aid[0] << 8) + aid[1]; + } uint8_t ndefkey[6] = {0}; memcpy(ndefkey, g_mifare_ndef_key, 6); @@ -7007,6 +7008,7 @@ static int CmdHF14AMfWipe(const char *Cmd) { PrintAndLogEx(INFO, "Forcing overwrite of sector 0 / block 0 "); else PrintAndLogEx(INFO, "Skipping sector 0 / block 0"); + PrintAndLogEx(NORMAL, ""); uint8_t zeros[MFBLOCK_SIZE] = {0}; @@ -7018,7 +7020,12 @@ static int CmdHF14AMfWipe(const char *Cmd) { for (uint8_t b = 0; b < mfNumBlocksPerSector(s); b++) { - // Skipp write to manufacture block if not enforced + if (kbd_enter_pressed()) { + PrintAndLogEx(WARNING, "\naborted via keyboard!\n"); + goto out; + } + + // Skip write to manufacture block if not enforced if (s == 0 && b == 0 && gen2 == false) { continue; } From 2356dfea73ad3bfca1581ad7f5f32169de8a0297 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 30 May 2023 14:14:21 +0200 Subject: [PATCH 35/37] hf mf restore - now uses the binary key loading fct() --- client/src/cmdhfmf.c | 71 ++++++++++++++++---------------------------- 1 file changed, 26 insertions(+), 45 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 6d017a849..386482483 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -1256,52 +1256,40 @@ static int CmdHF14AMfRestore(const char *Cmd) { free(fptr); } - FILE *f; - if ((f = fopen(keyfilename, "rb")) == NULL) { - PrintAndLogEx(WARNING, "Could not find file " _YELLOW_("%s"), keyfilename); - return PM3_EFILE; - } - - // key arrays - uint8_t keyA[40][6]; - uint8_t keyB[40][6]; - - // read key file - size_t bytes_read; - for (uint8_t s = 0; s < sectors; s++) { - bytes_read = fread(keyA[s], 1, 6, f); - if (bytes_read != 6) { - PrintAndLogEx(ERR, "File reading error " _YELLOW_("%s"), keyfilename); - fclose(f); - return PM3_EFILE; + // + size_t alen = 0, blen = 0; + uint8_t *keyA, *keyB; + if (loadFileBinaryKey(keyfilename, "", (void**)&keyA, (void**)&keyB, &alen, &blen) != PM3_SUCCESS) { + if (keyA) { + free(keyA); } + return PM3_ESOFT; } - for (uint8_t s = 0; s < sectors; s++) { - bytes_read = fread(keyB[s], 1, 6, f); - if (bytes_read != 6) { - PrintAndLogEx(ERR, "File reading error " _YELLOW_("%s"), keyfilename); - fclose(f); - return PM3_EFILE; - } - } - fclose(f); // try reading card uid and create filename if (datafnlen == 0) { char *fptr = GenerateFilename("hf-mf-", "-dump.bin"); - if (fptr == NULL) + if (fptr == NULL) { + if (keyA) { + free(keyA); + } + if (keyB) { + free(keyB); + } return PM3_ESOFT; - + } strcpy(datafilename, fptr); free(fptr); } // read dump file uint8_t *dump = NULL; - bytes_read = 0; + size_t bytes_read = 0; int res = pm3_load_dump(datafilename, (void **)&dump, &bytes_read, (MFBLOCK_SIZE * MIFARE_4K_MAXBLOCK)); if (res != PM3_SUCCESS) { + free(keyA); + free(keyB); return res; } @@ -1326,19 +1314,10 @@ static int CmdHF14AMfRestore(const char *Cmd) { if (mfNumBlocksPerSector(s) - 1 == b) { if (use_keyfile_for_auth == false) { // replace KEY A - bldata[0] = (keyA[s][0]); - bldata[1] = (keyA[s][1]); - bldata[2] = (keyA[s][2]); - bldata[3] = (keyA[s][3]); - bldata[4] = (keyA[s][4]); - bldata[5] = (keyA[s][5]); + memcpy(bldata, keyA + (s * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE); + // replace KEY B - bldata[10] = (keyB[s][0]); - bldata[11] = (keyB[s][1]); - bldata[12] = (keyB[s][2]); - bldata[13] = (keyB[s][3]); - bldata[14] = (keyB[s][4]); - bldata[15] = (keyB[s][5]); + memcpy(bldata + 10, keyB + (s * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE); } // ensure access right isn't messed up. @@ -1372,12 +1351,12 @@ static int CmdHF14AMfRestore(const char *Cmd) { for (int8_t kt = MF_KEY_B; kt > -1; kt--) { if (use_keyfile_for_auth) { if (kt == MF_KEY_A) - memcpy(wdata, keyA[s], 6); + memcpy(wdata, keyA + (s * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE); else - memcpy(wdata, keyB[s], 6); + memcpy(wdata, keyB+ (s * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE); } else { // use default key to authenticate for the write command - memcpy(wdata, default_key, 6); + memcpy(wdata, default_key, MIFARE_KEY_SIZE); } PrintAndLogEx(INFO, "block %3d: %s", mfFirstBlockOfSector(s) + b, sprint_hex(bldata, sizeof(bldata))); @@ -1404,6 +1383,8 @@ static int CmdHF14AMfRestore(const char *Cmd) { } // end loop S free(ref_dump); + free(keyA); + free(keyB); PrintAndLogEx(INFO, "Done!"); return PM3_SUCCESS; } From 1107c214c520e95ffd9a48401773f87f569f78d5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 30 May 2023 16:19:33 +0200 Subject: [PATCH 36/37] hf mf ndefformat now uses the binary key loading --- client/src/cmdhfmf.c | 43 +++++++++++++++---------------------------- 1 file changed, 15 insertions(+), 28 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 386482483..afadc9e78 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -1266,6 +1266,7 @@ static int CmdHF14AMfRestore(const char *Cmd) { return PM3_ESOFT; } + PrintAndLogEx(INFO, "Using `" _YELLOW_("%s") "`", keyfilename); // try reading card uid and create filename if (datafnlen == 0) { @@ -6116,39 +6117,27 @@ int CmdHFMFNDEFFormat(const char *Cmd) { DropField(); } + // load key file if exist if (strlen(keyFilename)) { - - FILE *f; - if ((f = fopen(keyFilename, "rb")) == NULL) { - // PrintAndLogEx(WARNING, "Could not find file " _YELLOW_("%s"), keyFilename); + // + size_t alen = 0, blen = 0; + uint8_t *tmpA, *tmpB; + if (loadFileBinaryKey(keyFilename, "", (void**)&tmpA, (void**)&tmpB, &alen, &blen) != PM3_SUCCESS) { + if (tmpA) { + free(tmpA); + } goto skipfile; } PrintAndLogEx(INFO, "Using `" _YELLOW_("%s") "`", keyFilename); - - // Read keys A from file - size_t bytes_read; - for (uint8_t i = 0; i < numSectors; i++) { - bytes_read = fread(keyA[i], 1, MFKEY_SIZE, f); - if (bytes_read != MFKEY_SIZE) { - PrintAndLogEx(ERR, "File reading error."); - fclose(f); - return PM3_EFILE; - } + + for (int i=0; i < numSectors; i++) { + memcpy(keyA[i], tmpA + (i *MIFARE_KEY_SIZE), MIFARE_KEY_SIZE); + memcpy(keyB[i], tmpB + (i *MIFARE_KEY_SIZE), MIFARE_KEY_SIZE); } - - // Read keys B from file - for (uint8_t i = 0; i < numSectors; i++) { - bytes_read = fread(keyB[i], 1, MFKEY_SIZE, f); - if (bytes_read != MFKEY_SIZE) { - PrintAndLogEx(ERR, "File reading error."); - fclose(f); - return PM3_EFILE; - } - } - - fclose(f); + free(tmpA); + free(tmpB); } skipfile: @@ -6191,7 +6180,6 @@ skipfile: } break; } - } // write to card, try B key first @@ -6206,7 +6194,6 @@ skipfile: } PrintAndLogEx(NORMAL, ""); - return PM3_SUCCESS; } From 97eb0238b101bc9fd79802b39b62e28c6e8e4d89 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 2 Jun 2023 10:45:04 +0200 Subject: [PATCH 37/37] style --- armsrc/Standalone/hf_msdsal.c | 8 +- armsrc/appmain.c | 2 +- armsrc/iso14443a.c | 10 +- armsrc/mifarecmd.c | 4 +- client/luascripts/hf_mf_ultimatecard.lua | 10 +- client/src/cmdhfmf.c | 148 +++++++++++------------ client/src/cmdhfmfhard.c | 2 +- client/src/cmdhfmfp.c | 6 +- client/src/cmdlfhitag.c | 2 +- client/src/cmdlft55xx.c | 2 +- client/src/fileutils.c | 12 +- client/src/mifare/mad.c | 8 +- client/src/nfc/ndef.c | 22 ++-- client/src/pm3line_vocabulory.h | 3 +- client/update_amiibo_tools_lua.py | 14 +-- doc/commands.json | 91 +++++++++----- doc/commands.md | 7 +- 17 files changed, 191 insertions(+), 160 deletions(-) diff --git a/armsrc/Standalone/hf_msdsal.c b/armsrc/Standalone/hf_msdsal.c index b0d81ff79..f97a2e57f 100644 --- a/armsrc/Standalone/hf_msdsal.c +++ b/armsrc/Standalone/hf_msdsal.c @@ -376,7 +376,7 @@ void RunMod(void) { // dynamic_response_info will be in charge of responses dynamic_response_info.response_n = 0; - + //Dbprintf("receivedCmd: %02x\n", receivedCmd); // received a REQUEST if (receivedCmd[0] == ISO14443A_CMD_REQA && len == 1) { @@ -399,12 +399,12 @@ void RunMod(void) { // received request for UID (cascade 1) } else if (receivedCmd[1] == 0x20 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT && len == 2) { //DbpString(_YELLOW_("+") "Request for UID C1"); - p_response = &responses[RESP_INDEX_UIDC1]; + p_response = &responses[RESP_INDEX_UIDC1]; // received a SELECT (cascade 1) } else if (receivedCmd[1] == 0x70 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT && len == 9) { //DbpString(_YELLOW_("+") "Request for SELECT S1"); - p_response = &responses[RESP_INDEX_SAKC1]; + p_response = &responses[RESP_INDEX_SAKC1]; // received a RATS request } else if (receivedCmd[0] == ISO14443A_CMD_RATS && len == 4) { @@ -412,7 +412,7 @@ void RunMod(void) { prevCmd = 0; //p_response = &responses[RESP_INDEX_RATS]; - static uint8_t rRATS[] = { 0x13, 0x78, 0x80, 0x72, 0x02, 0x80, 0x31, 0x80, 0x66, 0xb1, 0x84, 0x0c, 0x01, 0x6e, 0x01, 0x83, 0x00, 0x90, 0x00 }; + static uint8_t rRATS[] = { 0x13, 0x78, 0x80, 0x72, 0x02, 0x80, 0x31, 0x80, 0x66, 0xb1, 0x84, 0x0c, 0x01, 0x6e, 0x01, 0x83, 0x00, 0x90, 0x00 }; memcpy(&dynamic_response_info.response[0], rRATS, sizeof(rRATS)); dynamic_response_info.response_n = sizeof(rRATS); diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 38c680050..184307042 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -2045,7 +2045,7 @@ static void PacketReceived(PacketCommandNG *packet) { reply_ng(CMD_USART_RX, PM3_ENODATA, NULL, 0); } - StopTicks(); + StopTicks(); BigBuf_free(); LED_B_OFF(); break; diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index b4730b62d..01eed12c1 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1189,12 +1189,12 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, tag_r // Configure the ATQA and SAK accordingly rATQA[0] &= 0xBF; - if(tagType == 11){ - rSAKc1[0] = sak & 0xFC & 0X70; - }else{ - rSAKc1[0] = sak & 0xFB; + if (tagType == 11) { + rSAKc1[0] = sak & 0xFC & 0X70; + } else { + rSAKc1[0] = sak & 0xFB; } - + AddCrc14A(rSAKc1, sizeof(rSAKc1) - 2); *cuid = bytes_to_num(data, 4); diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 30558541d..5dd5dfcf6 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1300,7 +1300,7 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 break; } */ - + uint32_t nttmp = prng_successor(nt1, 100); //NXP Mifare is typical around 840,but for some unlicensed/compatible mifare card this can be 160 for (i = 101; i < 1200; i++) { nttmp = prng_successor(nttmp, 1); @@ -1354,7 +1354,7 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 LED_C_ON(); // get crypted nonces for target sector - for (i = 0; ((i < 2) && (isOK == PM3_SUCCESS)); i++) { + for (i = 0; ((i < 2) && (isOK == PM3_SUCCESS)); i++) { // look for exactly two different nonces diff --git a/client/luascripts/hf_mf_ultimatecard.lua b/client/luascripts/hf_mf_ultimatecard.lua index 09b53937f..4bb6034ee 100644 --- a/client/luascripts/hf_mf_ultimatecard.lua +++ b/client/luascripts/hf_mf_ultimatecard.lua @@ -50,20 +50,20 @@ arguments = [[ -c read magic configuration -u UID (8-20 hexsymbols), set UID on tag -t tag type to impersonate - 1 = Mifare Mini S20 4-byte + 1 = Mifare Mini S20 4-byte 2 = Mifare Mini S20 7-byte 15 = NTAG 210 3 = Mifare Mini S20 10-byte 16 = NTAG 212 4 = Mifare 1k S50 4-byte 17 = NTAG 213 5 = Mifare 1k S50 7-byte 18 = NTAG 215 - 6 = Mifare 1k S50 10-byte 19 = NTAG 216 + 6 = Mifare 1k S50 10-byte 19 = NTAG 216 7 = Mifare 4k S70 4-byte 20 = NTAG I2C 1K 8 = Mifare 4k S70 7-byte 21 = NTAG I2C 2K 9 = Mifare 4k S70 10-byte 22 = NTAG I2C 1K PLUS *** 10 = UL - NOT WORKING FULLY 23 = NTAG I2C 2K PLUS *** 11 = UL-C - NOT WORKING FULLY 24 = NTAG 213F 12 = UL EV1 48b 25 = NTAG 216F - 13 = UL EV1 128b - *** 14 = UL Plus - NOT WORKING YET + 13 = UL EV1 128b + *** 14 = UL Plus - NOT WORKING YET -p NTAG password (8 hexsymbols), set NTAG password on tag. -a NTAG pack ( 4 hexsymbols), set NTAG pack on tag. @@ -297,7 +297,7 @@ return true, 'Ok' end --- -- calculate block0 -local function calculate_block0(useruid) +local function calculate_block0(useruid) local uidbytes = utils.ConvertHexToBytes(useruid) local i = 1 local bcc = bxor(uidbytes[i], uidbytes[i+1]); diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index afadc9e78..3dee09d3b 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -349,13 +349,13 @@ static int mf_save_keys_from_arr(uint16_t n, uint8_t *d) { uint8_t sector = 0; for (uint16_t i = 0; i < n; i++) { if (mfIsSectorTrailer(i)) { - // key A offset in ST block - memcpy(keys + (MIFARE_KEY_SIZE * sector), d + (i * MFBLOCK_SIZE), MIFARE_KEY_SIZE); + // key A offset in ST block + memcpy(keys + (MIFARE_KEY_SIZE * sector), d + (i * MFBLOCK_SIZE), MIFARE_KEY_SIZE); - // key B offset in ST block - memcpy(keys + (MIFARE_KEY_SIZE * sectors) + (MIFARE_KEY_SIZE * sector), d + (i * MFBLOCK_SIZE) + 10, MIFARE_KEY_SIZE); + // key B offset in ST block + memcpy(keys + (MIFARE_KEY_SIZE * sectors) + (MIFARE_KEY_SIZE * sector), d + (i * MFBLOCK_SIZE) + 10, MIFARE_KEY_SIZE); - sector++; + sector++; } } @@ -484,7 +484,7 @@ static int mf_analyse_st_block(uint8_t blockno, uint8_t *block, bool force) { * @param numSectors: size of the card * @param keyFileName: filename containing keys or NULL. */ -static int mfc_read_tag(iso14a_card_select_t *card, uint8_t *carddata, uint8_t numSectors, char *keyfn){ +static int mfc_read_tag(iso14a_card_select_t *card, uint8_t *carddata, uint8_t numSectors, char *keyfn) { // Select card to get UID/UIDLEN/ATQA/SAK information clearCommandBuffer(); @@ -517,7 +517,7 @@ static int mfc_read_tag(iso14a_card_select_t *card, uint8_t *carddata, uint8_t n size_t alen = 0, blen = 0; uint8_t *keyA, *keyB; - if (loadFileBinaryKey(keyfn, "", (void**)&keyA, (void**)&keyB, &alen, &blen) != PM3_SUCCESS) { + if (loadFileBinaryKey(keyfn, "", (void **)&keyA, (void **)&keyB, &alen, &blen) != PM3_SUCCESS) { if (keyA) { free(keyA); } @@ -607,7 +607,7 @@ static int mfc_read_tag(iso14a_card_select_t *card, uint8_t *carddata, uint8_t n received = WaitForResponseTimeout(CMD_HF_MIFARE_READBL, &resp, 1500); } else { // data block. Check if it can be read with key A or key B - if ((rights[sectorNo][data_area] == 0x03) || (rights[sectorNo][data_area] == 0x05)) { + if ((rights[sectorNo][data_area] == 0x03) || (rights[sectorNo][data_area] == 0x05)) { // only key B would work payload.blockno = mfFirstBlockOfSector(sectorNo) + blockNo; payload.keytype = MF_KEY_B; @@ -617,7 +617,7 @@ static int mfc_read_tag(iso14a_card_select_t *card, uint8_t *carddata, uint8_t n SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); received = WaitForResponseTimeout(CMD_HF_MIFARE_READBL, &resp, 1500); } else { - // key A would work + // key A would work payload.blockno = mfFirstBlockOfSector(sectorNo) + blockNo; payload.keytype = current_key; memcpy(payload.key, (current_key == MF_KEY_A) ? keyA + (sectorNo * MIFARE_KEY_SIZE) : keyB + (sectorNo * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE); @@ -649,9 +649,9 @@ static int mfc_read_tag(iso14a_card_select_t *card, uint8_t *carddata, uint8_t n uint8_t *data = resp.data.asBytes; - if (mfIsSectorTrailer(blockNo)) { + if (mfIsSectorTrailer(blockNo)) { // sector trailer. Fill in the keys. - memcpy(data , keyA + (sectorNo * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE); + memcpy(data, keyA + (sectorNo * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE); memcpy(data + 10, keyB + (sectorNo * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE); } @@ -1096,7 +1096,7 @@ static int CmdHF14AMfDump(const char *Cmd) { } else if (m2) { numSectors = MIFARE_2K_MAXSECTOR; bytes = MIFARE_2K_MAX_BYTES; - } else if (m4) { + } else if (m4) { numSectors = MIFARE_4K_MAXSECTOR; bytes = MIFARE_4K_MAX_BYTES; } else { @@ -1259,7 +1259,7 @@ static int CmdHF14AMfRestore(const char *Cmd) { // size_t alen = 0, blen = 0; uint8_t *keyA, *keyB; - if (loadFileBinaryKey(keyfilename, "", (void**)&keyA, (void**)&keyB, &alen, &blen) != PM3_SUCCESS) { + if (loadFileBinaryKey(keyfilename, "", (void **)&keyA, (void **)&keyB, &alen, &blen) != PM3_SUCCESS) { if (keyA) { free(keyA); } @@ -1354,7 +1354,7 @@ static int CmdHF14AMfRestore(const char *Cmd) { if (kt == MF_KEY_A) memcpy(wdata, keyA + (s * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE); else - memcpy(wdata, keyB+ (s * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE); + memcpy(wdata, keyB + (s * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE); } else { // use default key to authenticate for the write command memcpy(wdata, default_key, MIFARE_KEY_SIZE); @@ -2518,16 +2518,16 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { sectorno = i; keytype = j; PrintAndLogEx(SUCCESS, "target sector %3u key type %c -- found valid key [ " _GREEN_("%s") " ] (used for nested / hardnested attack)", - i, - (j == MF_KEY_B) ? 'B' : 'A', - sprint_hex_inrow(key, sizeof(key)) - ); + i, + (j == MF_KEY_B) ? 'B' : 'A', + sprint_hex_inrow(key, sizeof(key)) + ); } else { PrintAndLogEx(SUCCESS, "target sector %3u key type %c -- found valid key [ " _GREEN_("%s") " ]", - i, - (j == MF_KEY_B) ? 'B' : 'A', - sprint_hex_inrow(key, sizeof(key)) - ); + i, + (j == MF_KEY_B) ? 'B' : 'A', + sprint_hex_inrow(key, sizeof(key)) + ); } ++num_found_keys; } @@ -2645,16 +2645,16 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { sectorno = i; keytype = j; PrintAndLogEx(SUCCESS, "target sector %3u key type %c -- found valid key [ " _GREEN_("%s") " ] (used for nested / hardnested attack)", - i, - (j == MF_KEY_B) ? 'B' : 'A', - sprint_hex_inrow(tmp_key, sizeof(tmp_key)) - ); + i, + (j == MF_KEY_B) ? 'B' : 'A', + sprint_hex_inrow(tmp_key, sizeof(tmp_key)) + ); } else { PrintAndLogEx(SUCCESS, "target sector %3u key type %c -- found valid key [ " _GREEN_("%s") " ]", - i, - (j == MF_KEY_B) ? 'B' : 'A', - sprint_hex_inrow(tmp_key, sizeof(tmp_key)) - ); + i, + (j == MF_KEY_B) ? 'B' : 'A', + sprint_hex_inrow(tmp_key, sizeof(tmp_key)) + ); } } } @@ -3839,7 +3839,7 @@ static int CmdHF14AMfSim(const char *Cmd) { if ((flags & FLAG_NR_AR_ATTACK) != FLAG_NR_AR_ATTACK) break; - + if ((resp.oldarg[0] & 0xffff) != CMD_HF_MIFARE_SIMULATE) break; @@ -3949,11 +3949,11 @@ void printKeyTableEx(size_t sectorscnt, sector_t *e_sector, uint8_t start_sector } PrintAndLogEx(SUCCESS, " " _YELLOW_("%03d") " | %03d | %s | %s | %s | %s" - , s - , mfSectorTrailerOfSector(s) - , strA, resA - , strB, resB - ); + , s + , mfSectorTrailerOfSector(s) + , strA, resA + , strB, resB + ); } PrintAndLogEx(SUCCESS, "-----+-----+--------------+---+--------------+----"); @@ -4424,7 +4424,7 @@ static int CmdHF14AMfEView(const char *Cmd) { arg_lit0(NULL, "2k", "MIFARE Classic/Plus 2k"), arg_lit0(NULL, "4k", "MIFARE Classic 4k / S70"), arg_lit0("v", "verbose", "verbose output"), - arg_lit0(NULL, "sk", "Save extracted keys to file"), + arg_lit0(NULL, "sk", "Save extracted keys to file"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -5901,7 +5901,7 @@ int CmdHFMFNDEFRead(const char *Cmd) { CLIParserFree(ctx); uint16_t ndef_aid = NDEF_MFC_AID; - if (aidlen == 2){ + if (aidlen == 2) { ndef_aid = (aid[0] << 8) + aid[1]; } @@ -6123,7 +6123,7 @@ int CmdHFMFNDEFFormat(const char *Cmd) { // size_t alen = 0, blen = 0; uint8_t *tmpA, *tmpB; - if (loadFileBinaryKey(keyFilename, "", (void**)&tmpA, (void**)&tmpB, &alen, &blen) != PM3_SUCCESS) { + if (loadFileBinaryKey(keyFilename, "", (void **)&tmpA, (void **)&tmpB, &alen, &blen) != PM3_SUCCESS) { if (tmpA) { free(tmpA); } @@ -6131,13 +6131,13 @@ int CmdHFMFNDEFFormat(const char *Cmd) { } PrintAndLogEx(INFO, "Using `" _YELLOW_("%s") "`", keyFilename); - - for (int i=0; i < numSectors; i++) { - memcpy(keyA[i], tmpA + (i *MIFARE_KEY_SIZE), MIFARE_KEY_SIZE); - memcpy(keyB[i], tmpB + (i *MIFARE_KEY_SIZE), MIFARE_KEY_SIZE); + + for (int i = 0; i < numSectors; i++) { + memcpy(keyA[i], tmpA + (i * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE); + memcpy(keyB[i], tmpB + (i * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE); } free(tmpA); - free(tmpB); + free(tmpB); } skipfile: @@ -6680,7 +6680,7 @@ static int CmdHf14AMfSuperCard(const char *Cmd) { return PM3_EINVARG; } - #define SUPER_MAX_TRACES 7 +#define SUPER_MAX_TRACES 7 uint8_t trace = 0; uint8_t traces[SUPER_MAX_TRACES][16]; @@ -7056,7 +7056,7 @@ static int CmdHF14AMfView(const char *Cmd) { arg_param_begin, arg_str1("f", "file", "", "filename of dump"), arg_lit0("v", "verbose", "verbose output"), - arg_lit0(NULL, "sk", "Save extracted keys to file"), + arg_lit0(NULL, "sk", "Save extracted keys to file"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); @@ -7964,24 +7964,24 @@ static int CmdHF14AMfValue(const char *Cmd) { "hf mf value --blk 16 -k FFFFFFFFFFFF -b --get\n" "hf mf value --blk 16 -k FFFFFFFFFFFF --res --transfer 30 --tk FFFFFFFFFFFF --> transfer block 16 value to block 30 (even if block can't be incremented by ACL)\n" "hf mf value --get -d 87D612007829EDFF87D6120011EE11EE\n" - ); + ); void *argtable[] = { - arg_param_begin, - arg_str0("k", "key", "", "key, 6 hex bytes"), - arg_lit0("a", NULL, "input key type is key A (def)"), - arg_lit0("b", NULL, "input key type is key B"), - arg_u64_0(NULL, "inc", "", "Increment value by X (0 - 2147483647)"), - arg_u64_0(NULL, "dec", "", "Decrement value by X (0 - 2147483647)"), - arg_u64_0(NULL, "set", "", "Set value to X (-2147483647 - 2147483647)"), - arg_u64_0(NULL, "transfer", "", "Transfer value to other block (after inc/dec/restore)"), - arg_str0(NULL, "tkey", "", "transfer key, 6 hex bytes (if transfer is preformed to other sector)"), - arg_lit0(NULL, "ta", "transfer key type is key A (def)"), - arg_lit0(NULL, "tb", "transfer key type is key B"), - arg_lit0(NULL, "get", "Get value from block"), - arg_lit0(NULL, "res", "Restore (copy value to card buffer, should be used with --transfer)"), - arg_int0(NULL, "blk", "", "block number"), - arg_str0("d", "data", "", "block data to extract values from (16 hex bytes)"), - arg_param_end + arg_param_begin, + arg_str0("k", "key", "", "key, 6 hex bytes"), + arg_lit0("a", NULL, "input key type is key A (def)"), + arg_lit0("b", NULL, "input key type is key B"), + arg_u64_0(NULL, "inc", "", "Increment value by X (0 - 2147483647)"), + arg_u64_0(NULL, "dec", "", "Decrement value by X (0 - 2147483647)"), + arg_u64_0(NULL, "set", "", "Set value to X (-2147483647 - 2147483647)"), + arg_u64_0(NULL, "transfer", "", "Transfer value to other block (after inc/dec/restore)"), + arg_str0(NULL, "tkey", "", "transfer key, 6 hex bytes (if transfer is preformed to other sector)"), + arg_lit0(NULL, "ta", "transfer key type is key A (def)"), + arg_lit0(NULL, "tb", "transfer key type is key B"), + arg_lit0(NULL, "get", "Get value from block"), + arg_lit0(NULL, "res", "Restore (copy value to card buffer, should be used with --transfer)"), + arg_int0(NULL, "blk", "", "block number"), + arg_str0("d", "data", "", "block data to extract values from (16 hex bytes)"), + arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); @@ -8038,7 +8038,7 @@ static int CmdHF14AMfValue(const char *Cmd) { // Action: 0 Increment, 1 - Decrement, 2 - Restore, 3 - Set, 4 - Get, 5 - Decode from data // iceman: TODO - should be enum - uint8_t action = 4; + uint8_t action = 4; uint32_t value = 0; // Need to check we only have 1 of inc/dec/set and get the value from the selected option @@ -8109,10 +8109,10 @@ static int CmdHF14AMfValue(const char *Cmd) { } // don't want to write value data and break something - if ((blockno == 0) || - (mfIsSectorTrailer(blockno)) || - (trnval == 0) || - (trnval != -1 && mfIsSectorTrailer(trnval))) { + if ((blockno == 0) || + (mfIsSectorTrailer(blockno)) || + (trnval == 0) || + (trnval != -1 && mfIsSectorTrailer(trnval))) { PrintAndLogEx(WARNING, "invalid block number, should be a data block"); return PM3_EINVARG; } @@ -8130,7 +8130,7 @@ static int CmdHF14AMfValue(const char *Cmd) { memcpy(block, (uint8_t *)&value, 4); uint8_t cmddata[34]; - memcpy(cmddata, key, sizeof(key)); + memcpy(cmddata, key, sizeof(key)); // Key == 6 data went to 10, so lets offset 9 for inc/dec if (action == 0) { @@ -8141,13 +8141,13 @@ static int CmdHF14AMfValue(const char *Cmd) { } // 00 if increment, 01 if decrement, 02 if restore - cmddata[9] = action; - + cmddata[9] = action; + if (trnval != -1) { // transfer to block - cmddata[10] = trnval; - + cmddata[10] = trnval; + memcpy(cmddata + 27, transferkey, sizeof(transferkey)); if (mfSectorNum(trnval) != mfSectorNum(blockno)) { cmddata[33] = 1; // should send nested auth @@ -8200,7 +8200,7 @@ static int CmdHF14AMfValue(const char *Cmd) { if (isok) { PrintAndLogEx(SUCCESS, "Update ... : " _GREEN_("success")); - getval = true; + getval = true; // all ok so set flag to read current value } else { PrintAndLogEx(FAILED, "Update ... : " _RED_("failed")); diff --git a/client/src/cmdhfmfhard.c b/client/src/cmdhfmfhard.c index acbf32ea5..c885e41c9 100644 --- a/client/src/cmdhfmfhard.c +++ b/client/src/cmdhfmfhard.c @@ -510,7 +510,7 @@ static char failstr[250] = ""; #endif // the probability that a random nonce has a Sum Property K -static const float p_K0[NUM_SUMS] = { +static const float p_K0[NUM_SUMS] = { 0.0290, 0.0083, 0.0006, 0.0339, 0.0048, 0.0934, 0.0119, 0.0489, 0.0602, 0.4180, 0.0602, 0.0489, 0.0119, 0.0934, 0.0048, 0.0339, 0.0006, 0.0083, 0.0290 diff --git a/client/src/cmdhfmfp.c b/client/src/cmdhfmfp.c index b079e15c1..4f956d3af 100644 --- a/client/src/cmdhfmfp.c +++ b/client/src/cmdhfmfp.c @@ -1006,7 +1006,7 @@ static int MFPKeyCheck(uint8_t startSector, uint8_t endSector, uint8_t startKeyA for (uint8_t keyAB = startKeyAB; keyAB <= endKeyAB; keyAB++) { // main cycle with key check for (int i = 0; i < keyListLen; i++) { - + // allow client abort every iteration if (kbd_enter_pressed()) { PrintAndLogEx(WARNING, "\naborted via keyboard!\n"); @@ -1052,14 +1052,14 @@ static int MFPKeyCheck(uint8_t startSector, uint8_t endSector, uint8_t startKeyA selectCard = true; msleep(50); - // break out from keylist check loop, + // break out from keylist check loop, break; } if (verbose) PrintAndLogEx(WARNING, "\nsector %02d key %d [%s] res: %d", sector, keyAB, sprint_hex_inrow(keyList[i], 16), res); - // RES can be: + // RES can be: // PM3_ERFTRANS -7 // PM3_EWRONGANSWER -16 if (res == PM3_ERFTRANS) { diff --git a/client/src/cmdlfhitag.c b/client/src/cmdlfhitag.c index 23b8ac235..8cd28b842 100644 --- a/client/src/cmdlfhitag.c +++ b/client/src/cmdlfhitag.c @@ -338,7 +338,7 @@ static void printHitag2PaxtonDowngrade(const uint8_t *data) { bytes = (bytes * 0x100) + data[i]; } - for (int j = 0; j< 8; j++) { + for (int j = 0; j < 8; j++) { num = bytes & mask; skip -= 5; mask = mask >> 5; diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index 554658c9f..ffb90513b 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -4028,7 +4028,7 @@ static int CmdT55xxSniff(const char *Cmd) { if (use_graphbuf == false) { // make loop to call sniff with skip samples.. - // then build it up by adding + // then build it up by adding CmdLFSniff(""); } diff --git a/client/src/fileutils.c b/client/src/fileutils.c index d26470ed5..8fd06456e 100644 --- a/client/src/fileutils.c +++ b/client/src/fileutils.c @@ -316,9 +316,9 @@ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, s int saveFileJSONex(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen, bool verbose, void (*callback)(json_t *), savePaths_t e_save_path) { if (ftype != jsfCustom) { - if (data == NULL || datalen == 0) { - return PM3_EINVARG; - } + if (data == NULL || datalen == 0) { + return PM3_EINVARG; + } } char *fileName = newfilenamemcopyEx(preferredName, ".json", e_save_path); @@ -2032,8 +2032,8 @@ int searchFile(char **foundpath, const char *pm3dir, const char *searchname, con PrintAndLogEx(FAILED, "Error - can't find `" _YELLOW_("%s") "`", filename); } } - free(filename); - return res; + free(filename); + return res; } int pm3_load_dump(const char *fn, void **pdump, size_t *dumplen, size_t maxdumplen) { @@ -2067,7 +2067,7 @@ int pm3_load_dump(const char *fn, void **pdump, size_t *dumplen, size_t maxdumpl } case MCT: { res = loadFileMCT_safe(fn, pdump, dumplen); - break; + break; } } diff --git a/client/src/mifare/mad.c b/client/src/mifare/mad.c index 49d3de065..328c2e63c 100644 --- a/client/src/mifare/mad.c +++ b/client/src/mifare/mad.c @@ -424,8 +424,8 @@ int DetectHID(uint8_t *d, uint16_t manufacture) { int convert_mad_to_arr(uint8_t *in, uint16_t ilen, uint8_t *out, uint16_t *olen) { - if (in == NULL || out == NULL || ilen == 0 ) { - return PM3_EINVARG; + if (in == NULL || out == NULL || ilen == 0) { + return PM3_EINVARG; } // MAD detection @@ -464,8 +464,8 @@ int convert_mad_to_arr(uint8_t *in, uint16_t ilen, uint8_t *out, uint16_t *olen) // copy to out (skip ST) memcpy(out, tmp, sizeof(tmp) - MFBLOCK_SIZE); out += sizeof(tmp) - MFBLOCK_SIZE; - *olen += sizeof(tmp) -MFBLOCK_SIZE; + *olen += sizeof(tmp) - MFBLOCK_SIZE; } } return PM3_SUCCESS; -} \ No newline at end of file +} diff --git a/client/src/nfc/ndef.c b/client/src/nfc/ndef.c index 311615c2a..09ff31945 100644 --- a/client/src/nfc/ndef.c +++ b/client/src/nfc/ndef.c @@ -313,7 +313,7 @@ static int ndefDecodeSig1(uint8_t *sig, size_t siglen) { if (sigType == stECDSA_P256) { slen = 32; } - + PrintAndLogEx(SUCCESS, "\tSignature [%u]...", intsiglen); print_hex_noascii_break(&sig[indx], intsiglen, 32); @@ -508,7 +508,7 @@ static int ndefDecodePayloadHandoverRequest(uint8_t *payload, size_t len) { PrintAndLogEx(INFO, _CYAN_("Handover Request")); uint8_t *p = payload; uint8_t major = (*(p) >> 4) & 0x0F; - uint8_t minor = *(p) & 0x0F; + uint8_t minor = *(p) & 0x0F; p++; PrintAndLogEx(INFO, "Version....... " _YELLOW_("%u.%u"), major, minor); @@ -866,7 +866,7 @@ static int ndefDecodeMime_bt(NDEFHeader_t *ndef) { uint8_t rev[6] = {0}; reverse_array_copy(ndef->Payload + 2, 6, rev); PrintAndLogEx(INFO, "BT MAC.......... " _YELLOW_("%s"), sprint_hex(rev, sizeof(rev))); - + // Let's check payload[8]. Tells us a bit about the UUID's. If 0x07 then it tells us a service UUID is 128bit switch (ndef->Payload[8]) { case 0x02: @@ -903,29 +903,29 @@ static int ndefDecodeMime_bt(NDEFHeader_t *ndef) { return PM3_SUCCESS; } -// https://raw.githubusercontent.com/haldean/ndef/master/docs/NFCForum-TS-RTD_1.0.pdf +// https://raw.githubusercontent.com/haldean/ndef/master/docs/NFCForum-TS-RTD_1.0.pdf static int ndefDecodeExternal_record(NDEFHeader_t *ndef) { - + if (ndef->TypeLen == 0) { PrintAndLogEx(INFO, "no type"); return PM3_SUCCESS; } - + if (ndef->PayloadLen == 0) { PrintAndLogEx(INFO, "no payload"); return PM3_SUCCESS; } PrintAndLogEx(INFO - , " URN... " _GREEN_("urn:nfc:ext:%.*s") - , (int)ndef->TypeLen - , ndef->Type - ); + , " URN... " _GREEN_("urn:nfc:ext:%.*s") + , (int)ndef->TypeLen + , ndef->Type + ); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "Payload [%zu]...", ndef->PayloadLen); print_hex_noascii_break(ndef->Payload, ndef->PayloadLen, 32); - + // do a character check? if (!strncmp((char *)ndef->Type, "pilet.ee:ekaart:2", ndef->TypeLen)) { PrintAndLogEx(NORMAL, ""); diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index e6d6dc438..ffe9c66ff 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -360,7 +360,8 @@ const static vocabulory_t vocabulory[] = { { 0, "hf mf gsave" }, { 0, "hf mf gsetblk" }, { 0, "hf mf gview" }, - { 0, "hf mf gdmconfig" }, + { 0, "hf mf gdmcfg" }, + { 0, "hf mf gdmsetcfg" }, { 0, "hf mf gdmsetblk" }, { 0, "hf mf ndefformat" }, { 0, "hf mf ndefread" }, diff --git a/client/update_amiibo_tools_lua.py b/client/update_amiibo_tools_lua.py index 873a6e18d..8a31b9d60 100644 --- a/client/update_amiibo_tools_lua.py +++ b/client/update_amiibo_tools_lua.py @@ -8,15 +8,15 @@ Author: Cory Solovewicz Description: This is a python script to automate what the updating of the amiibo_tools.lua -file which holds a lua table of all known amiibos. Previously updating the +file which holds a lua table of all known amiibos. Previously updating the amiibo_tools.lua was a very manual process. -This script automates the following original command: +This script automates the following original command: curl https://raw.githubusercontent.com/N3evin/AmiiboAPI/master/database/amiibo.json | jq 'del(.amiibos[].release)' | jq 'del(.characters)' | pbcopy --> transform to table -And outputs the formatted file as amiibo_tools.lua -If everything goes well, this should be an updated copy of amiibo_tools.lua -which can then be placed in the /lualibs/ directory. -The temporary amiibo.json file is then deleted +And outputs the formatted file as amiibo_tools.lua +If everything goes well, this should be an updated copy of amiibo_tools.lua +which can then be placed in the /lualibs/ directory. +The temporary amiibo.json file is then deleted Dependencies: python3 -m pip install jq @@ -25,7 +25,7 @@ How to run: python update_amiibo_tools_lua.py The script will create the file amiibo_tools.lua -After running, manually backup the original /lualibs/amiibo_tools.lua and move the +After running, manually backup the original /lualibs/amiibo_tools.lua and move the updated amiibo_tools.lua to the /lualibs/ directory. ----------------------------------------------------------------------------- """ diff --git a/doc/commands.json b/doc/commands.json index f8712fc47..70b10c521 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -1354,9 +1354,10 @@ "offline": false, "options": [ "-h, --help This help", - "-f, --file (optional) filename, if no UID will be used as filename" + "-f, --file (optional) filename, if no UID will be used as filename", + "--ns no save to file" ], - "usage": "hf 14b dump [-h] [-f ]" + "usage": "hf 14b dump [-h] [-f ] [--ns]" }, "hf 14b help": { "command": "hf 14b help", @@ -4218,9 +4219,10 @@ "--mini MIFARE Classic Mini / S20", "--1k MIFARE Classic 1k / S50 (def)", "--2k MIFARE Classic/Plus 2k", - "--4k MIFARE Classic 4k / S70" + "--4k MIFARE Classic 4k / S70", + "--ns no save to file" ], - "usage": "hf mf dump [-h] [-f ] [-k ] [--mini] [--1k] [--2k] [--4k]" + "usage": "hf mf dump [-h] [-f ] [-k ] [--mini] [--1k] [--2k] [--4k] [--ns]" }, "hf mf ecfill": { "command": "hf mf ecfill", @@ -4368,9 +4370,10 @@ "--1k MIFARE Classic 1k / S50 (def)", "--2k MIFARE Classic/Plus 2k", "--4k MIFARE Classic 4k / S70", - "-v, --verbose verbose output" + "-v, --verbose verbose output", + "--sk Save extracted keys to file" ], - "usage": "hf mf eview [-hv] [--mini] [--1k] [--2k] [--4k]" + "usage": "hf mf eview [-hv] [--mini] [--1k] [--2k] [--4k] [--sk]" }, "hf mf fchk": { "command": "hf mf fchk", @@ -4400,18 +4403,18 @@ ], "usage": "hf mf fchk [-h] [-k ]... [--mini] [--1k] [--2k] [--4k] [--emu] [--dump] [--mem] [-f ]" }, - "hf mf gdmconfig": { - "command": "hf mf gdmconfig", + "hf mf gdmcfg": { + "command": "hf mf gdmcfg", "description": "Get configuration data from magic gen4 GDM card.", "notes": [ - "hf mf gdmconfig" + "hf mf gdmcfg" ], "offline": false, "options": [ "-h, --help This help", "-k, --key key 6 bytes" ], - "usage": "hf mf gdmconfig [-h] [-k ]" + "usage": "hf mf gdmcfg [-h] [-k ]" }, "hf mf gdmsetblk": { "command": "hf mf gdmsetblk", @@ -4431,6 +4434,19 @@ ], "usage": "hf mf gdmsetblk [-hab] --blk [-d ] [-k ] [--force]" }, + "hf mf gdmsetcfg": { + "command": "hf mf gdmsetcfg", + "description": "Set configuration data on a magic gen4 GDM card", + "notes": [ + "hf mf gdmsetcfg -d 850000000000000000005A5A00000008" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-d, --data bytes to write, 16 hex bytes" + ], + "usage": "hf mf gdmsetcfg [-h] -d " + }, "hf mf gen3blk": { "command": "hf mf gen3blk", "description": "Overwrite full manufacturer block for magic Gen3 card - You can specify part of manufacturer block as 4/7-bytes for UID change only", @@ -4902,6 +4918,7 @@ "hf mf value --blk 16 -k FFFFFFFFFFFF --inc 10", "hf mf value --blk 16 -k FFFFFFFFFFFF -b --dec 10", "hf mf value --blk 16 -k FFFFFFFFFFFF -b --get", + "hf mf value --blk 16 -k FFFFFFFFFFFF --res --transfer 30 --tk FFFFFFFFFFFF -> transfer block 16 value to block 30 (even if block can't be incremented by ACL)", "hf mf value --get -d 87D612007829EDFF87D6120011EE11EE" ], "offline": true, @@ -4910,14 +4927,19 @@ "-k, --key key, 6 hex bytes", "-a input key type is key A (def)", "-b input key type is key B", - "--inc Incremenet value by X (0 - 2147483647)", - "--dec Dcrement value by X (0 - 2147483647)", + "--inc Increment value by X (0 - 2147483647)", + "--dec Decrement value by X (0 - 2147483647)", "--set Set value to X (-2147483647 - 2147483647)", + "--transfer Transfer value to other block (after inc/dec/restore)", + "--tkey transfer key, 6 hex bytes (if transfer is preformed to other sector)", + "--ta transfer key type is key A (def)", + "--tb transfer key type is key B", "--get Get value from block", + "--res Restore (copy value to card buffer, should be used with --transfer)", "--blk block number", "-d, --data block data to extract values from (16 hex bytes)" ], - "usage": "hf mf value [-hab] [-k ] [--inc ] [--dec ] [--set ] [--get] [--blk ] [-d ]" + "usage": "hf mf value [-hab] [-k ] [--inc ] [--dec ] [--set ] [--transfer ] [--tkey ] [--ta] [--tb] [--get] [--res] [--blk ] [-d ]" }, "hf mf view": { "command": "hf mf view", @@ -4929,9 +4951,10 @@ "options": [ "-h, --help This help", "-f, --file filename of dump", - "-v, --verbose verbose output" + "-v, --verbose verbose output", + "--sk Save extracted keys to file" ], - "usage": "hf mf view [-hv] -f " + "usage": "hf mf view [-hv] -f [--sk]" }, "hf mf wipe": { "command": "hf mf wipe", @@ -6146,7 +6169,7 @@ }, "hf mfp commitp": { "command": "hf mfp commitp", - "description": "Executes Commit Perso command. Can be used in SL0 mode only.", + "description": "Executes Commit Perso command. Can be used in SL0 mode only. OBS! This command will not be executed if CardConfigKey, CardMasterKey and L3SwitchKey AES keys are not written.", "notes": [ "hf mfp commitp" ], @@ -6246,9 +6269,9 @@ "-b, --keyb Use key B (def: keyA)", "-p, --plain Plain communication mode between reader and card", "--blk <0..255> Block number", - "--key Key, 16 hex bytes" + "-k, --key Key, 16 hex bytes" ], - "usage": "hf mfp rdbl [-hvbp] [-n ] --blk <0..255> [--key ]" + "usage": "hf mfp rdbl [-hvbp] [-n ] --blk <0..255> [-k ]" }, "hf mfp rdsc": { "command": "hf mfp rdsc", @@ -6335,9 +6358,10 @@ "-k, --key Key for authentication (UL-C 16 bytes, EV1/NTAG 4 bytes)", "-l Swap entered key's endianness", "-p, --page Manually set start page number to start from", - "-q, --qty Manually set number of pages to dump" + "-q, --qty Manually set number of pages to dump", + "--ns no save to file" ], - "usage": "hf mfu dump [-hl] [-f ] [-k ] [-p ] [-q ]" + "usage": "hf mfu dump [-hl] [-f ] [-k ] [-p ] [-q ] [--ns]" }, "hf mfu eload": { "command": "hf mfu eload", @@ -6565,7 +6589,7 @@ }, "hf mfu tamper": { "command": "hf mfu tamper", - "description": "Set the congiguration of the NTAG 213TT tamper feature Supports: NTAG 213TT", + "description": "Set the configuration of the NTAG 213TT tamper feature Supports: NTAG 213TT", "notes": [ "hf mfu tamper -e -> enable tamper feature", "hf mfu tamper -d -> disable tamper feature", @@ -8039,15 +8063,19 @@ "command": "lf em 4x50 brute", "description": "Tries to bruteforce the password of a EM4x50 card. Function can be stopped by pressing pm3 button.", "notes": [ - "lf em 4x50 brute --first 12330000 --last 12340000 -> tries pwds from 0x12330000 to 0x1234000000" + "lf em 4x50 brute --mode range --begin 12330000 --end 12340000 -> tries pwds from 0x12330000 to 0x12340000", + "lf em 4x50 brute --mode charset --digits --uppercase -> tries all combinations of ASCII codes for digits and uppercase letters" ], "offline": false, "options": [ "-h, --help This help", - "--first first password (start), 4 bytes, lsb", - "--last last password (stop), 4 bytes, lsb" + "--mode Bruteforce mode (range|charset)", + "--begin Range mode - start of the key range", + "--end Range mode - end of the key range", + "--digits Charset mode - include ASCII codes for digits", + "--uppercase Charset mode - include ASCII codes for uppercase letters" ], - "usage": "lf em 4x50 brute [-h] --first --last " + "usage": "lf em 4x50 brute [-h] --mode [--begin ] [--end ] [--digits] [--uppercase]" }, "lf em 4x50 chk": { "command": "lf em 4x50 chk", @@ -10199,12 +10227,13 @@ "-f, --file filename (default is generated on blk 0)", "-o, --override override, force pwd read despite danger to card", "-p, --pwd password (4 hex bytes)", + "--ns no save", "--r0 downlink - fixed bit length", "--r1 downlink - long leading reference", "--r2 downlink - leading zero", "--r3 downlink - 1 of 4 coding reference" ], - "usage": "lf t55xx dump [-ho] [-f ] [-p ] [--r0] [--r1] [--r2] [--r3]" + "usage": "lf t55xx dump [-ho] [-f ] [-p ] [--ns] [--r0] [--r1] [--r2] [--r3]" }, "lf t55xx help": { "command": "lf t55xx help", @@ -10867,7 +10896,7 @@ "options": [ "-h, --help This help", "-f, --file SPIFFS file to view", - "-c, --cols column breaks (def 32)" + "-c, --cols column breaks (def 16)" ], "usage": "mem spiffs view [-h] -f [-c ]" }, @@ -11592,7 +11621,7 @@ }, "script help": { "command": "script help", - "description": "This is a feature to run Lua/Cmd/Python scripts. You can place scripts within the luascripts/cmdscripts/pyscripts folders. --------------------------------------------------------------------------------------- script list available offline: yes", + "description": "This is a feature to run Lua/Cmd scripts. You can place scripts within the luascripts/cmdscripts folders. --------------------------------------------------------------------------------------- script list available offline: yes", "notes": [], "offline": true, "options": [], @@ -11987,8 +12016,8 @@ } }, "metadata": { - "commands_extracted": 754, + "commands_extracted": 755, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2023-03-26T15:04:49" + "extracted_on": "2023-06-02T08:44:26" } -} +} \ No newline at end of file diff --git a/doc/commands.md b/doc/commands.md index 487cea0c9..938413fa8 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -523,7 +523,8 @@ Check column "offline" for their availability. |`hf mf gsave `|N |`Save dump from card into file or emulator` |`hf mf gsetblk `|N |`Write block to card` |`hf mf gview `|N |`View card` -|`hf mf gdmconfig `|N |`Read config block from card` +|`hf mf gdmcfg `|N |`Read config block from card` +|`hf mf gdmsetcfg `|N |`Write config block to card` |`hf mf gdmsetblk `|N |`Write block to card` |`hf mf ndefformat `|N |`Format MIFARE Classic Tag as NFC Tag` |`hf mf ndefread `|N |`Read and print NDEF records from card` @@ -568,7 +569,7 @@ Check column "offline" for their availability. |`hf mfu restore `|N |`Restore a dump onto a MFU MAGIC tag` |`hf mfu view `|Y |`Display content from tag dump file` |`hf mfu wrbl `|N |`Write block` -|`hf mfu tamper `|N |`Cofigure the tamper feature on an NTAG 213TT` +|`hf mfu tamper `|N |`Configure the tamper feature on an NTAG 213TT` |`hf mfu eload `|N |`Load Ultralight dump file into emulator memory` |`hf mfu esave `|N |`Save Ultralight dump file from emulator memory` |`hf mfu eview `|N |`View emulator memory` @@ -874,7 +875,7 @@ Check column "offline" for their availability. |command |offline |description |------- |------- |----------- |`lf em 4x50 help `|Y |`This help` -|`lf em 4x50 brute `|N |`Simple bruteforce attack to find password` +|`lf em 4x50 brute `|N |`Bruteforce attack to find password` |`lf em 4x50 chk `|N |`Check passwords from dictionary` |`lf em 4x50 dump `|N |`Dump EM4x50 tag` |`lf em 4x50 info `|N |`Tag information`