mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
Implemented a function to safely load dictionaries.
This commit is contained in:
parent
ab095cb39d
commit
225b18d5fc
4 changed files with 91 additions and 14 deletions
|
@ -1591,7 +1591,6 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||||
uint8_t sectors_cnt = MIFARE_1K_MAXSECTOR;
|
uint8_t sectors_cnt = MIFARE_1K_MAXSECTOR;
|
||||||
int block_cnt = MIFARE_1K_MAXBLOCK;
|
int block_cnt = MIFARE_1K_MAXBLOCK;
|
||||||
uint8_t tmp_key[6] = {0};
|
uint8_t tmp_key[6] = {0};
|
||||||
size_t data_length = 0;
|
|
||||||
bool know_target_key = false;
|
bool know_target_key = false;
|
||||||
// For the timier
|
// For the timier
|
||||||
uint64_t t1;
|
uint64_t t1;
|
||||||
|
@ -1613,7 +1612,6 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||||
bool legacy_mfchk = false;
|
bool legacy_mfchk = false;
|
||||||
bool prng_type = false;
|
bool prng_type = false;
|
||||||
bool verbose = false;
|
bool verbose = false;
|
||||||
int max_dictionary_size = 2000;
|
|
||||||
|
|
||||||
// Parse the options given by the user
|
// Parse the options given by the user
|
||||||
ctmp = tolower(param_getchar(Cmd, 0));
|
ctmp = tolower(param_getchar(Cmd, 0));
|
||||||
|
@ -1788,17 +1786,14 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||||
|
|
||||||
// Load the dictionary
|
// Load the dictionary
|
||||||
if (strlen(filename) != 0) {
|
if (strlen(filename) != 0) {
|
||||||
keyBlock = calloc(6 * max_dictionary_size, sizeof(uint8_t));
|
int res = loadFileDICTIONARY_safe(filename, &keyBlock, 6, &key_cnt);
|
||||||
loadFileDICTIONARY(filename, keyBlock, &data_length, 6, &key_cnt);
|
if (res != PM3_SUCCESS || key_cnt <= 0) {
|
||||||
if ((data_length / 6) > max_dictionary_size) {
|
PrintAndLogEx(FAILED, "An error occurred while loading the dictionary! (we will use the default keys now)");
|
||||||
// This is not a good solution (loadFileDICTIONARY needs a maxdatalen)!
|
free(keyBlock); // free the memory, just in case an allocation happened
|
||||||
// loadfiledictionary will reallocate to correct size.
|
goto useDefaultKeys;
|
||||||
PrintAndLogEx(FAILED, "Dictionary is too large: %d (allowed: %d)", data_length, max_dictionary_size);
|
|
||||||
free(keyBlock);
|
|
||||||
free(e_sector);
|
|
||||||
return PM3_EMALLOC;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
useDefaultKeys:
|
||||||
keyBlock = calloc(ARRAYLEN(g_mifare_default_keys), 6);
|
keyBlock = calloc(ARRAYLEN(g_mifare_default_keys), 6);
|
||||||
if (keyBlock == NULL) {
|
if (keyBlock == NULL) {
|
||||||
free(e_sector);
|
free(e_sector);
|
||||||
|
|
|
@ -2127,7 +2127,6 @@ static int CmdT55xxChkPwds(const char *Cmd) {
|
||||||
|
|
||||||
if (use_pwd_file) {
|
if (use_pwd_file) {
|
||||||
uint16_t keycount = 0;
|
uint16_t keycount = 0;
|
||||||
size_t datalen = 0;
|
|
||||||
|
|
||||||
// TODO, a way of reallocating memory if file was larger
|
// TODO, a way of reallocating memory if file was larger
|
||||||
keyBlock = calloc(4 * 200, sizeof(uint8_t));
|
keyBlock = calloc(4 * 200, sizeof(uint8_t));
|
||||||
|
@ -2136,7 +2135,7 @@ static int CmdT55xxChkPwds(const char *Cmd) {
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
int res = loadFileDICTIONARY(filename, keyBlock, &datalen, 4, &keycount);
|
int res = loadFileDICTIONARY_safe(filename, &keyBlock, 4, &keycount);
|
||||||
if (res || keycount == 0) {
|
if (res || keycount == 0) {
|
||||||
PrintAndLogEx(WARNING, "No keys found in file");
|
PrintAndLogEx(WARNING, "No keys found in file");
|
||||||
free(keyBlock);
|
free(keyBlock);
|
||||||
|
|
|
@ -649,6 +649,79 @@ out:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int loadFileDICTIONARY_safe(const char *preferredName, uint8_t **data, uint8_t keylen, uint16_t *keycnt) {
|
||||||
|
|
||||||
|
int block_size = 512;
|
||||||
|
int allocation_size = block_size;
|
||||||
|
size_t counter = 0;
|
||||||
|
int retval = PM3_SUCCESS;
|
||||||
|
char *path;
|
||||||
|
if (searchFile(&path, DICTIONARIES_SUBDIR, preferredName, ".dic") != PM3_SUCCESS)
|
||||||
|
return PM3_EFILE;
|
||||||
|
|
||||||
|
// t5577 == 4bytes
|
||||||
|
// mifare == 6 bytes
|
||||||
|
// iclass == 8 bytes
|
||||||
|
// default to 6 bytes.
|
||||||
|
if (keylen != 4 && keylen != 6 && keylen != 8) {
|
||||||
|
keylen = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
// double up since its chars
|
||||||
|
keylen <<= 1;
|
||||||
|
|
||||||
|
char line[255];
|
||||||
|
|
||||||
|
// allocate some space for the dictionary
|
||||||
|
*data = (uint8_t*) malloc(keylen * allocation_size * sizeof(uint8_t));
|
||||||
|
if (*data == NULL) return PM3_EFILE;
|
||||||
|
|
||||||
|
FILE *f = fopen(path, "r");
|
||||||
|
if (!f) {
|
||||||
|
PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", path);
|
||||||
|
retval = PM3_EFILE;
|
||||||
|
goto out; }
|
||||||
|
|
||||||
|
// read file
|
||||||
|
while (fgets(line, sizeof(line), f)) {
|
||||||
|
// check if we have enough space (if not allocate more)
|
||||||
|
if ((*keycnt) >= allocation_size) {
|
||||||
|
allocation_size += block_size;
|
||||||
|
*data = (uint8_t*) realloc((void*) *data, keylen * allocation_size * sizeof(uint8_t));
|
||||||
|
if (*data == NULL) return PM3_EFILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add null terminator
|
||||||
|
line[keylen] = 0;
|
||||||
|
|
||||||
|
// smaller keys than expected is skipped
|
||||||
|
if (strlen(line) < keylen)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// The line start with # is comment, skip
|
||||||
|
if (line[0] == '#')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!isxdigit(line[0])) {
|
||||||
|
PrintAndLogEx(FAILED, "file content error. '%s' must include " _BLUE_("%2d") "HEX symbols", line, keylen);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t key = strtoull(line, NULL, 16);
|
||||||
|
|
||||||
|
num_to_bytes(key, keylen >> 1, *data + counter);
|
||||||
|
(*keycnt)++;
|
||||||
|
memset(line, 0, sizeof(line));
|
||||||
|
counter += (keylen >> 1);
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") "keys from dictionary file " _YELLOW_("%s"), *keycnt, path);
|
||||||
|
|
||||||
|
out:
|
||||||
|
free(path);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
int convertOldMfuDump(uint8_t **dump, size_t *dumplen) {
|
int convertOldMfuDump(uint8_t **dump, size_t *dumplen) {
|
||||||
if (!dump || !dumplen || *dumplen < OLD_MFU_DUMP_PREFIX_LENGTH)
|
if (!dump || !dumplen || *dumplen < OLD_MFU_DUMP_PREFIX_LENGTH)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -149,7 +149,6 @@ int loadFileEML(const char *preferredName, void *data, size_t *datalen);
|
||||||
*/
|
*/
|
||||||
int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen);
|
int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Utility function to load data from a DICTIONARY textfile. This method takes a preferred name.
|
* @brief Utility function to load data from a DICTIONARY textfile. This method takes a preferred name.
|
||||||
* E.g. mfc_default_keys.dic
|
* E.g. mfc_default_keys.dic
|
||||||
|
@ -163,6 +162,17 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_
|
||||||
*/
|
*/
|
||||||
int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt);
|
int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Utility function to load data from a DICTIONARY safely into a textfile. This method takes a preferred name.
|
||||||
|
* E.g. mfc_default_keys.dic
|
||||||
|
*
|
||||||
|
* @param preferredName
|
||||||
|
* @param data The data array to store the loaded bytes from file
|
||||||
|
* @param keylen the number of bytes a key per row is
|
||||||
|
* @return 0 for ok, 1 for failz
|
||||||
|
*/
|
||||||
|
int loadFileDICTIONARY_safe(const char *preferredName, uint8_t **data, uint8_t keylen, uint16_t *keycnt);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Utility function to check and convert old mfu dump format to new
|
* @brief Utility function to check and convert old mfu dump format to new
|
||||||
*
|
*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue