mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 22:03:42 -07:00
added obsfuscation optionally for dump/restore/eload/esave, consider it wip. As of byte 22.
This commit is contained in:
parent
e0d27d0ea3
commit
45223ee5d5
1 changed files with 71 additions and 43 deletions
|
@ -104,23 +104,26 @@ static int usage_legic_dump(void) {
|
||||||
PrintAndLogEx(NORMAL, "Read all memory from LEGIC Prime MIM22, MIM256, MIM1024");
|
PrintAndLogEx(NORMAL, "Read all memory from LEGIC Prime MIM22, MIM256, MIM1024");
|
||||||
PrintAndLogEx(NORMAL, "and saves bin/eml/json dump file");
|
PrintAndLogEx(NORMAL, "and saves bin/eml/json dump file");
|
||||||
PrintAndLogEx(NORMAL, "It autodetects card type.\n");
|
PrintAndLogEx(NORMAL, "It autodetects card type.\n");
|
||||||
PrintAndLogEx(NORMAL, "Usage: hf legic dump [h] f <filename w/o .bin>\n");
|
PrintAndLogEx(NORMAL, "Usage: hf legic dump [h] [x] [f <filename w/o .bin>]\n");
|
||||||
PrintAndLogEx(NORMAL, "Options:");
|
PrintAndLogEx(NORMAL, "Options:");
|
||||||
PrintAndLogEx(NORMAL, " h : this help");
|
PrintAndLogEx(NORMAL, " h : this help");
|
||||||
PrintAndLogEx(NORMAL, " f <filename> : filename w/o '.bin' to dump bytes");
|
PrintAndLogEx(NORMAL, " f <filename> : filename w/o '.bin' to dump bytes");
|
||||||
|
PrintAndLogEx(NORMAL, " x : deobfuscate dump data");
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
PrintAndLogEx(NORMAL, _YELLOW_(" hf legic dump -- uses UID as filename"));
|
PrintAndLogEx(NORMAL, _YELLOW_(" hf legic dump -- uses UID as filename"));
|
||||||
PrintAndLogEx(NORMAL, _YELLOW_(" hf legic dump f myfile"));
|
PrintAndLogEx(NORMAL, _YELLOW_(" hf legic dump f myfile"));
|
||||||
|
PrintAndLogEx(NORMAL, _YELLOW_(" hf legic dump x"));
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
static int usage_legic_restore(void) {
|
static int usage_legic_restore(void) {
|
||||||
PrintAndLogEx(NORMAL, "Reads binary file and it autodetects card type and verifies that the file has the same size");
|
PrintAndLogEx(NORMAL, "Reads binary file and it autodetects card type and verifies that the file has the same size");
|
||||||
PrintAndLogEx(NORMAL, "Then write the data back to card. All bytes except the first 7bytes [UID(4) MCC(1) DCF(2)]\n");
|
PrintAndLogEx(NORMAL, "Then write the data back to card. All bytes except the first 7bytes [UID(4) MCC(1) DCF(2)]\n");
|
||||||
PrintAndLogEx(NORMAL, "Usage: hf legic restore [h] [f <filename w/o .bin>]\n");
|
PrintAndLogEx(NORMAL, "Usage: hf legic restore [h] [x] [f <filename w/o .bin>]\n");
|
||||||
PrintAndLogEx(NORMAL, "Options:");
|
PrintAndLogEx(NORMAL, "Options:");
|
||||||
PrintAndLogEx(NORMAL, " h : this help");
|
PrintAndLogEx(NORMAL, " h : this help");
|
||||||
PrintAndLogEx(NORMAL, " f <filename> : filename w/o '.bin' to restore bytes on to card from");
|
PrintAndLogEx(NORMAL, " f <filename> : filename w/o '.bin' to restore bytes on to card from");
|
||||||
|
PrintAndLogEx(NORMAL, " x : obfuscate dump data");
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
PrintAndLogEx(NORMAL, _YELLOW_(" hf legic restore f myfile"));
|
PrintAndLogEx(NORMAL, _YELLOW_(" hf legic restore f myfile"));
|
||||||
|
@ -166,6 +169,25 @@ static int usage_legic_wipe(void) {
|
||||||
PrintAndLogEx(NORMAL, _YELLOW_(" hf legic wipe"));
|
PrintAndLogEx(NORMAL, _YELLOW_(" hf legic wipe"));
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool legic_xor(uint8_t *data, uint8_t cardsize) {
|
||||||
|
bool ret = true;
|
||||||
|
uint8_t crc = data[4];
|
||||||
|
uint32_t calc_crc = CRC8Legic(data, 4);
|
||||||
|
if (crc != calc_crc) {
|
||||||
|
PrintAndLogEx(INFO, "Crc mismatch, obsfuscation not possible");
|
||||||
|
ret = false;
|
||||||
|
} else if (cardsize <= 22) {
|
||||||
|
PrintAndLogEx(INFO, "No obsfuscation such small dump");
|
||||||
|
} else {
|
||||||
|
for(uint16_t i = 22; i < cardsize - 22; i++) {
|
||||||
|
data[i] ^= crc;
|
||||||
|
}
|
||||||
|
PrintAndLogEx(SUCCESS, "Obsfuscation done");
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Output BigBuf and deobfuscate LEGIC RF tag data.
|
* Output BigBuf and deobfuscate LEGIC RF tag data.
|
||||||
* This is based on information given in the talk held
|
* This is based on information given in the talk held
|
||||||
|
@ -531,7 +553,6 @@ static int CmdLegicRdbl(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CmdLegicSim(const char *Cmd) {
|
static int CmdLegicSim(const char *Cmd) {
|
||||||
|
|
||||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||||
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_legic_sim();
|
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_legic_sim();
|
||||||
|
|
||||||
|
@ -869,7 +890,7 @@ static int CmdLegicDump(const char *Cmd) {
|
||||||
int fileNameLen = 0;
|
int fileNameLen = 0;
|
||||||
char filename[FILE_PATH_SIZE] = {0x00};
|
char filename[FILE_PATH_SIZE] = {0x00};
|
||||||
char *fptr = filename;
|
char *fptr = filename;
|
||||||
bool errors = false;
|
bool errors = false, shall_deobsfuscate = false;
|
||||||
uint16_t dumplen;
|
uint16_t dumplen;
|
||||||
uint8_t cmdp = 0;
|
uint8_t cmdp = 0;
|
||||||
|
|
||||||
|
@ -885,6 +906,10 @@ static int CmdLegicDump(const char *Cmd) {
|
||||||
fileNameLen = FILE_PATH_SIZE - 5;
|
fileNameLen = FILE_PATH_SIZE - 5;
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
break;
|
break;
|
||||||
|
case 'x':
|
||||||
|
shall_deobsfuscate = true;
|
||||||
|
cmdp++;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
errors = true;
|
errors = true;
|
||||||
|
@ -951,6 +976,10 @@ static int CmdLegicDump(const char *Cmd) {
|
||||||
FillFileNameByUID(fptr, data, "-dump", 4);
|
FillFileNameByUID(fptr, data, "-dump", 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (shall_deobsfuscate) {
|
||||||
|
legic_xor(data, card.cardsize);
|
||||||
|
}
|
||||||
|
|
||||||
saveFile(filename, ".bin", data, readlen);
|
saveFile(filename, ".bin", data, readlen);
|
||||||
saveFileEML(filename, data, readlen, 8);
|
saveFileEML(filename, data, readlen, 8);
|
||||||
saveFileJSON(filename, jsfLegic, data, readlen);
|
saveFileJSON(filename, jsfLegic, data, readlen);
|
||||||
|
@ -959,12 +988,10 @@ static int CmdLegicDump(const char *Cmd) {
|
||||||
|
|
||||||
static int CmdLegicRestore(const char *Cmd) {
|
static int CmdLegicRestore(const char *Cmd) {
|
||||||
|
|
||||||
FILE *f;
|
|
||||||
char filename[FILE_PATH_SIZE] = {0x00};
|
char filename[FILE_PATH_SIZE] = {0x00};
|
||||||
char *fnameptr = filename;
|
|
||||||
size_t fileNlen = 0;
|
size_t fileNlen = 0;
|
||||||
bool errors = false;
|
bool errors = false, shall_obsfuscate = false;
|
||||||
uint16_t numofbytes;
|
size_t numofbytes;
|
||||||
uint8_t cmdp = 0;
|
uint8_t cmdp = 0;
|
||||||
|
|
||||||
memset(filename, 0, sizeof(filename));
|
memset(filename, 0, sizeof(filename));
|
||||||
|
@ -974,7 +1001,7 @@ static int CmdLegicRestore(const char *Cmd) {
|
||||||
case 'h':
|
case 'h':
|
||||||
errors = true;
|
errors = true;
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'f':
|
||||||
fileNlen = param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE);
|
fileNlen = param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE);
|
||||||
if (!fileNlen)
|
if (!fileNlen)
|
||||||
errors = true;
|
errors = true;
|
||||||
|
@ -983,6 +1010,10 @@ static int CmdLegicRestore(const char *Cmd) {
|
||||||
fileNlen = FILE_PATH_SIZE - 5;
|
fileNlen = FILE_PATH_SIZE - 5;
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
break;
|
break;
|
||||||
|
case 'x':
|
||||||
|
shall_obsfuscate = true;
|
||||||
|
cmdp++;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
errors = true;
|
errors = true;
|
||||||
|
@ -998,48 +1029,30 @@ static int CmdLegicRestore(const char *Cmd) {
|
||||||
PrintAndLogEx(WARNING, "Failed to identify tagtype");
|
PrintAndLogEx(WARNING, "Failed to identify tagtype");
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
numofbytes = card.cardsize;
|
|
||||||
|
legic_print_type(card.cardsize, 0);
|
||||||
|
|
||||||
// set up buffer
|
// set up buffer
|
||||||
uint8_t *data = calloc(numofbytes, sizeof(uint8_t));
|
uint8_t *data = calloc(card.cardsize, sizeof(uint8_t));
|
||||||
if (!data) {
|
if (!data) {
|
||||||
PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
|
PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
|
||||||
return PM3_EMALLOC;
|
return PM3_EMALLOC;
|
||||||
}
|
}
|
||||||
|
|
||||||
legic_print_type(numofbytes, 0);
|
if (loadFile_safe(filename, ".bin", (void **)&data, &numofbytes) != PM3_SUCCESS) {
|
||||||
|
free(data);
|
||||||
|
PrintAndLogEx(WARNING, "Error, reading file");
|
||||||
|
return PM3_EFILE;
|
||||||
|
}
|
||||||
|
|
||||||
// set up file
|
if (card.cardsize != numofbytes) {
|
||||||
fnameptr += fileNlen;
|
PrintAndLogEx(WARNING, "Fail, filesize and cardsize is not equal. [%zu != %u]", card.cardsize, numofbytes);
|
||||||
sprintf(fnameptr, ".bin");
|
|
||||||
|
|
||||||
f = fopen(filename, "rb");
|
|
||||||
if (!f) {
|
|
||||||
PrintAndLogEx(WARNING, "File %s not found or locked", filename);
|
|
||||||
free(data);
|
free(data);
|
||||||
return PM3_EFILE;
|
return PM3_EFILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// verify size of dumpfile is the same as card.
|
if (shall_obsfuscate){
|
||||||
fseek(f, 0, SEEK_END); // seek to end of file
|
legic_xor(data, card.cardsize);
|
||||||
size_t filesize = ftell(f); // get current file pointer
|
|
||||||
fseek(f, 0, SEEK_SET); // seek back to beginning of file
|
|
||||||
|
|
||||||
if (filesize != numofbytes) {
|
|
||||||
PrintAndLogEx(WARNING, "Fail, filesize and cardsize is not equal. [%zu != %u]", filesize, numofbytes);
|
|
||||||
free(data);
|
|
||||||
fclose(f);
|
|
||||||
return PM3_EFILE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// load file
|
|
||||||
size_t bytes_read = fread(data, 1, numofbytes, f);
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
if (bytes_read == 0) {
|
|
||||||
PrintAndLogEx(ERR, "File reading error");
|
|
||||||
free(data);
|
|
||||||
return PM3_EFILE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "Restoring to card");
|
PrintAndLogEx(SUCCESS, "Restoring to card");
|
||||||
|
@ -1082,7 +1095,7 @@ static int CmdLegicRestore(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
free(data);
|
free(data);
|
||||||
PrintAndLogEx(SUCCESS, "\nWrote %d bytes to card from file %s", numofbytes, filename);
|
PrintAndLogEx(SUCCESS, "Done");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1091,7 +1104,7 @@ static int CmdLegicELoad(const char *Cmd) {
|
||||||
size_t numofbytes = 256;
|
size_t numofbytes = 256;
|
||||||
int fileNameLen = 0;
|
int fileNameLen = 0;
|
||||||
char filename[FILE_PATH_SIZE] = {0x00};
|
char filename[FILE_PATH_SIZE] = {0x00};
|
||||||
bool errors = false;
|
bool errors = false, shall_obsfuscate = false;
|
||||||
uint8_t cmdp = 0;
|
uint8_t cmdp = 0;
|
||||||
|
|
||||||
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||||
|
@ -1106,6 +1119,10 @@ static int CmdLegicELoad(const char *Cmd) {
|
||||||
fileNameLen = FILE_PATH_SIZE - 5;
|
fileNameLen = FILE_PATH_SIZE - 5;
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
break;
|
break;
|
||||||
|
case 'x':
|
||||||
|
shall_obsfuscate = true;
|
||||||
|
cmdp++;
|
||||||
|
break;
|
||||||
case '0' :
|
case '0' :
|
||||||
numofbytes = 22;
|
numofbytes = 22;
|
||||||
cmdp++;
|
cmdp++;
|
||||||
|
@ -1140,8 +1157,11 @@ static int CmdLegicELoad(const char *Cmd) {
|
||||||
return PM3_EFILE;
|
return PM3_EFILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "Uploading to emulator memory");
|
if (shall_obsfuscate) {
|
||||||
|
legic_xor(data, numofbytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintAndLogEx(SUCCESS, "Uploading to emulator memory");
|
||||||
legic_seteml(data, 0, numofbytes);
|
legic_seteml(data, 0, numofbytes);
|
||||||
|
|
||||||
free(data);
|
free(data);
|
||||||
|
@ -1155,7 +1175,7 @@ static int CmdLegicESave(const char *Cmd) {
|
||||||
char *fptr = filename;
|
char *fptr = filename;
|
||||||
int fileNameLen = 0;
|
int fileNameLen = 0;
|
||||||
size_t numofbytes = 256;
|
size_t numofbytes = 256;
|
||||||
bool errors = false;
|
bool errors = false, shall_deobsfuscate = false;
|
||||||
uint8_t cmdp = 0;
|
uint8_t cmdp = 0;
|
||||||
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||||
switch (tolower(param_getchar(Cmd, cmdp))) {
|
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||||
|
@ -1169,6 +1189,10 @@ static int CmdLegicESave(const char *Cmd) {
|
||||||
fileNameLen = FILE_PATH_SIZE - 5;
|
fileNameLen = FILE_PATH_SIZE - 5;
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
break;
|
break;
|
||||||
|
case 'x':
|
||||||
|
shall_deobsfuscate = true;
|
||||||
|
cmdp++;
|
||||||
|
break;
|
||||||
case '0' :
|
case '0' :
|
||||||
numofbytes = 22;
|
numofbytes = 22;
|
||||||
cmdp++;
|
cmdp++;
|
||||||
|
@ -1212,6 +1236,10 @@ static int CmdLegicESave(const char *Cmd) {
|
||||||
FillFileNameByUID(fptr, data, "-dump", 4);
|
FillFileNameByUID(fptr, data, "-dump", 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (shall_deobsfuscate) {
|
||||||
|
legic_xor(data, numofbytes);
|
||||||
|
}
|
||||||
|
|
||||||
saveFile(filename, ".bin", data, numofbytes);
|
saveFile(filename, ".bin", data, numofbytes);
|
||||||
saveFileEML(filename, data, numofbytes, 8);
|
saveFileEML(filename, data, numofbytes, 8);
|
||||||
saveFileJSON(filename, jsfLegic, data, numofbytes);
|
saveFileJSON(filename, jsfLegic, data, numofbytes);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue