diff --git a/CHANGELOG.md b/CHANGELOG.md index c300c2d17..004c06cb5 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 `lf em 410x brute` - better filehandling and memory handling (@iceman1001) - Changed split PacketResponseNG status into status and reason(@douniwan5788) - add a helper script to decode JEDEC data `script run spi_flash_decode` (@ANTodorov) - show SPI flash JEDEC Manufacturer ID and Device ID in `hw status` output (@ANTodorov) diff --git a/client/src/cmdlfem410x.c b/client/src/cmdlfem410x.c index 8b051ade9..891773d4e 100644 --- a/client/src/cmdlfem410x.c +++ b/client/src/cmdlfem410x.c @@ -519,74 +519,34 @@ static int CmdEM410xBrute(const char *Cmd) { return PM3_EINVARG; } - uint32_t uidcnt = 0; - uint8_t stUidBlock = 20; - uint8_t *p = NULL; - uint8_t uid[5] = {0x00}; - - // open file - FILE *f = NULL; - if ((f = fopen(filename, "r")) == NULL) { - PrintAndLogEx(ERR, "Error: Could not open EM Tag IDs file ["_YELLOW_("%s")"]", filename); - return PM3_EFILE; + // get suffix. + char suffix[10] = {0}; + char *ext = strrchr(filename, '.'); + if (ext != NULL) { + strncpy(suffix, ext, sizeof(suffix) - 1); } - // allocate mem for file contents - uint8_t *uidblock = calloc(stUidBlock, 5); - if (uidblock == NULL) { - fclose(f); - PrintAndLogEx(ERR, "Error: can't allocate memory"); - return PM3_EMALLOC; + // load keys + uint8_t *uidblock = NULL; + uint32_t uidcount = 0; + int res = loadFileDICTIONARY_safe_ex(filename, suffix, (void**)&uidblock, 5, &uidcount, false); + if (res != PM3_SUCCESS) { + free(uidblock); + return res; } - // read file into memory - char buf[11]; - - while (fgets(buf, sizeof(buf), f)) { - if (strlen(buf) < 10 || buf[9] == '\n') continue; - while (fgetc(f) != '\n' && !feof(f)); //goto next line - - //The line start with # is comment, skip - if (buf[0] == '#') continue; - - int uidlen = 0; - if (param_gethex_ex(buf, 0, uid, &uidlen) && (uidlen != 10)) { - PrintAndLogEx(FAILED, "EM Tag IDs must include 5 hex bytes (10 hex symbols), got ( " _RED_("%d") " )", uidlen); - free(uidblock); - fclose(f); - return PM3_ESOFT; - } - - buf[10] = 0; - - if (stUidBlock - uidcnt < 2) { - p = realloc(uidblock, 5 * (stUidBlock += 10)); - if (!p) { - PrintAndLogEx(WARNING, "Cannot allocate memory for EM Tag IDs"); - free(uidblock); - fclose(f); - return PM3_ESOFT; - } - uidblock = p; - } - memset(uidblock + 5 * uidcnt, 0, 5); - num_to_bytes(strtoll(buf, NULL, 16), 5, uidblock + 5 * uidcnt); - uidcnt++; - memset(buf, 0, sizeof(buf)); - } - fclose(f); - - if (uidcnt == 0) { + if (uidcount == 0) { PrintAndLogEx(FAILED, "No EM Tag IDs found in file"); free(uidblock); - return PM3_ESOFT; + return PM3_EINVARG; } - PrintAndLogEx(SUCCESS, "Loaded "_YELLOW_("%d")" EM Tag IDs from "_YELLOW_("%s")", pause delay:"_YELLOW_("%d")" ms", uidcnt, filename, delay); + PrintAndLogEx(SUCCESS, "Loaded "_GREEN_("%d")" EM Tag IDs from `"_YELLOW_("%s")"` pause delay:"_YELLOW_("%d")" ms", uidcount, filename, delay); // loop uint8_t testuid[5]; - for (uint32_t c = 0; c < uidcnt; ++c) { + for (uint32_t i = 0; i < uidcount; ++i) { + if (kbd_enter_pressed()) { SendCommandNG(CMD_BREAK_LOOP, NULL, 0); PrintAndLogEx(WARNING, "aborted via keyboard!\n"); @@ -594,10 +554,12 @@ static int CmdEM410xBrute(const char *Cmd) { return PM3_EOPABORTED; } - memcpy(testuid, uidblock + 5 * c, 5); + memset(testuid, 0, sizeof(testuid)); + memcpy(testuid, uidblock + (5 * i), sizeof(testuid)); + PrintAndLogEx(INFO, "Bruteforce %d / %u: simulating EM Tag ID " _YELLOW_("%s") - , c + 1 - , uidcnt + , i + 1 + , uidcount , sprint_hex_inrow(testuid, sizeof(testuid)) ); @@ -614,7 +576,6 @@ static int CmdEM410xBrute(const char *Cmd) { clearCommandBuffer(); SendCommandNG(CMD_LF_SIMULATE, (uint8_t *)&payload, sizeof(payload)); - PacketResponseNG resp; if (WaitForResponseTimeout(CMD_LF_SIMULATE, &resp, delay)) { if (resp.status == PM3_EOPABORTED) { diff --git a/client/src/fileutils.c b/client/src/fileutils.c index a28ec1cfd..9f56dc52e 100644 --- a/client/src/fileutils.c +++ b/client/src/fileutils.c @@ -2267,12 +2267,17 @@ out: return retval; } + int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t keylen, uint32_t *keycnt) { + return loadFileDICTIONARY_safe_ex(preferredName, ".dic", pdata, keylen, keycnt, true); +} + +int loadFileDICTIONARY_safe_ex(const char *preferredName, const char* suffix, void **pdata, uint8_t keylen, uint32_t *keycnt, bool verbose) { int retval = PM3_SUCCESS; char *path; - if (searchFile(&path, DICTIONARIES_SUBDIR, preferredName, ".dic", false) != PM3_SUCCESS) { + if (searchFile(&path, DICTIONARIES_SUBDIR, preferredName, suffix, false) != PM3_SUCCESS) { return PM3_EFILE; } @@ -2282,7 +2287,7 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key // mf desfire == 3des3k 24 bytes // iclass == 8 bytes // default to 6 bytes. - if (keylen != 4 && keylen != 6 && keylen != 8 && keylen != 16 && keylen != 24) { + if (keylen != 4 && keylen != 5 && keylen != 6 && keylen != 8 && keylen != 16 && keylen != 24) { keylen = 6; } @@ -2340,7 +2345,7 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key continue; } - if (!CheckStringIsHEXValue(line)) { + if (CheckStringIsHEXValue(line) == false) { continue; } @@ -2357,7 +2362,9 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key } fclose(f); - PrintAndLogEx(SUCCESS, "Loaded " _GREEN_("%2d") " keys from dictionary file `" _YELLOW_("%s") "`", *keycnt, path); + if (verbose) { + PrintAndLogEx(SUCCESS, "Loaded " _GREEN_("%2d") " keys from dictionary file `" _YELLOW_("%s") "`", *keycnt, path); + } out: free(path); diff --git a/client/src/fileutils.h b/client/src/fileutils.h index c69185425..98e517b27 100644 --- a/client/src/fileutils.h +++ b/client/src/fileutils.h @@ -277,6 +277,8 @@ int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatale */ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t keylen, uint32_t *keycnt); +int loadFileDICTIONARY_safe_ex(const char *preferredName, const char* suffix, void **pdata, uint8_t keylen, uint32_t *keycnt, bool verbose); + int loadFileBinaryKey(const char *preferredName, const char *suffix, void **keya, void **keyb, size_t *alen, size_t *blen); /**