ADD: @marshmellow42 's changes to "hf mfu *" ,
ADD: @marshmellow42 's changes to "hf mf sim", ADD: @pwpiwi 's parity files was missing.
This commit is contained in:
@@ -1195,15 +1195,21 @@ int CmdHF14AMf1kSim(const char *Cmd)
|
||||
|
||||
if(flags & FLAG_INTERACTIVE)
|
||||
{
|
||||
PrintAndLog("Press pm3-button to abort simulation");
|
||||
|
||||
uint8_t data[40];
|
||||
uint8_t key[6];
|
||||
|
||||
UsbCommand resp;
|
||||
PrintAndLog("Press pm3-button or send another cmd to abort simulation");
|
||||
//while(! WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
|
||||
//We're waiting only 1.5 s at a time, otherwise we get the
|
||||
// annoying message about "Waiting for a response... "
|
||||
//}
|
||||
while(!ukbhit() ){
|
||||
if ( WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
|
||||
if ( (resp.arg[0] & 0xffff) == CMD_SIMULATE_MIFARE_CARD ){
|
||||
if (!WaitForResponseTimeout(CMD_ACK,&resp,1500) ) continue;
|
||||
|
||||
if ( !(flags & FLAG_NR_AR_ATTACK) ) break;
|
||||
if ( (resp.arg[0] & 0xffff) != CMD_SIMULATE_MIFARE_CARD ) break;
|
||||
|
||||
memset(data, 0x00, sizeof(data));
|
||||
memset(key, 0x00, sizeof(key));
|
||||
int len = (resp.arg[1] > sizeof(data)) ? sizeof(data) : resp.arg[1];
|
||||
@@ -1213,8 +1219,8 @@ int CmdHF14AMf1kSim(const char *Cmd)
|
||||
uint64_t corr_uid = 0;
|
||||
if ( memcmp(data, "\x00\x00\x00\x00", 4) == 0 ) {
|
||||
corr_uid = (data[3] << 24) | (data[2] << 16) | (data[1] << 8) | data[0];
|
||||
}
|
||||
else {
|
||||
tryMfk32(corr_uid, data, key);
|
||||
} else {
|
||||
corr_uid |= (uint64_t)data[2] << 48;
|
||||
corr_uid |= (uint64_t)data[1] << 40;
|
||||
corr_uid |= (uint64_t)data[0] << 32;
|
||||
@@ -1222,14 +1228,12 @@ int CmdHF14AMf1kSim(const char *Cmd)
|
||||
corr_uid |= data[6] << 16;
|
||||
corr_uid |= data[5] << 8;
|
||||
corr_uid |= data[4];
|
||||
tryMfk64(corr_uid, data, key);
|
||||
}
|
||||
tryMfk32(corr_uid, data, key);
|
||||
//tryMfk64(corr_uid, data, key);
|
||||
PrintAndLog("--");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1334,7 +1338,7 @@ int CmdHF14AMfELoad(const char *Cmd)
|
||||
|
||||
if ( ctmp == 'h' || ctmp == 'H' || ctmp == 0x00) {
|
||||
PrintAndLog("It loads emul dump from the file `filename.eml`");
|
||||
PrintAndLog("Usage: hf mf eload [card memory] <file name w/o `.eml`>");
|
||||
PrintAndLog("Usage: hf mf eload [card memory] <file name w/o `.eml`> [numblocks]");
|
||||
PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K, u = UL");
|
||||
PrintAndLog("");
|
||||
PrintAndLog(" sample: hf mf eload filename");
|
||||
@@ -1348,13 +1352,15 @@ int CmdHF14AMfELoad(const char *Cmd)
|
||||
case '\0': numBlocks = 16*4; break;
|
||||
case '2' : numBlocks = 32*4; break;
|
||||
case '4' : numBlocks = 256; break;
|
||||
case 'U' : // fall through , NTAG 215 has 135blocks a 540 bytes.
|
||||
case 'u' : numBlocks = 135; blockWidth = 8; break;
|
||||
case 'U' : // fall through
|
||||
case 'u' : numBlocks = 255; blockWidth = 8; break;
|
||||
default: {
|
||||
numBlocks = 16*4;
|
||||
nameParamNo = 0;
|
||||
}
|
||||
}
|
||||
uint32_t numblk2 = param_get32ex(Cmd,2,0,10);
|
||||
if (numblk2 > 0) numBlocks = numblk2;
|
||||
|
||||
len = param_getstr(Cmd,nameParamNo,filename);
|
||||
|
||||
@@ -1816,7 +1822,7 @@ int CmdHF14AMfCGetBlk(const char *Cmd) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
PrintAndLog("data:%s", sprint_hex(data, sizeof(data)));
|
||||
PrintAndLog("data: %s", sprint_hex(data, sizeof(data)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,5 +54,6 @@ int CmdHF14AMfCGetBlk(const char* cmd);
|
||||
int CmdHF14AMfCGetSc(const char* cmd);
|
||||
int CmdHF14AMfCLoad(const char* cmd);
|
||||
int CmdHF14AMfCSave(const char* cmd);
|
||||
int GetCardSize();
|
||||
int CmdHf14MfDecryptBytes(const char *Cmd);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1210,7 +1210,6 @@ int usage_hf_mfu_dump(void) {
|
||||
PrintAndLog(" n <FN > : filename w/o .bin to save the dump as");
|
||||
PrintAndLog(" p <Pg > : starting Page number to manually set a page to start the dump at");
|
||||
PrintAndLog(" q <qty> : number of Pages to manually set how many pages to dump");
|
||||
|
||||
PrintAndLog("");
|
||||
PrintAndLog(" sample : hf mfu dump");
|
||||
PrintAndLog(" : hf mfu dump n myfile");
|
||||
@@ -1248,14 +1247,29 @@ int usage_hf_mfu_wrbl(void) {
|
||||
}
|
||||
|
||||
int usage_hf_mfu_eload(void) {
|
||||
PrintAndLog("It loads emulator dump from the file `filename.eml`\n");
|
||||
PrintAndLog("Usage: hf mfu eload t <card memory> i <file name w/o `.eml`>\n");
|
||||
PrintAndLog(" Options:");
|
||||
PrintAndLog(" t <card memory> : Tag memorysize/type");
|
||||
PrintAndLog(" i <file> : file name w/o `.eml`");
|
||||
PrintAndLog("It loads emul dump from the file `filename.eml`");
|
||||
PrintAndLog("Hint: See script dumptoemul-mfu.lua to convert the .bin to the eml");
|
||||
PrintAndLog("Usage: hf mfu eload u <file name w/o `.eml`> [numblocks]");
|
||||
PrintAndLog(" Options:");
|
||||
PrintAndLog(" h : this help");
|
||||
PrintAndLog(" u : UL");
|
||||
PrintAndLog(" numblocks : number of blocks to load from eml file");
|
||||
PrintAndLog("");
|
||||
PrintAndLog(" sample : hf mfu eload filename");
|
||||
PrintAndLog(" : hf mfu eload 4 filename");
|
||||
PrintAndLog(" sample: hf mfu eload u filename");
|
||||
PrintAndLog(" hf mfu eload u filename 57");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usage_hf_mfu_sim(void) {
|
||||
PrintAndLog("\nEmulating Ultralight tag from emulator memory\n");
|
||||
PrintAndLog("\nBe sure to load the emulator memory first!\n");
|
||||
PrintAndLog("Usage: hf mfu sim t 7 u <uid>");
|
||||
PrintAndLog(" Options : ");
|
||||
PrintAndLog(" h : this help");
|
||||
PrintAndLog(" t : 7 = NTAG or Ultralight sim");
|
||||
PrintAndLog(" u : 4 or 7 byte UID");
|
||||
PrintAndLog("\n sample : hf mfu sim t 7");
|
||||
PrintAndLog(" : hf mfu sim t 7 u 1122344556677\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1300,8 +1314,8 @@ int usage_hf_mfu_gendiverse(void){
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define DUMP_PREFIX_LENGTH 48
|
||||
//
|
||||
|
||||
// Mifare Ultralight / Ultralight-C / Ultralight-EV1
|
||||
// Read and Dump Card Contents, using auto detection of tag size.
|
||||
int CmdHF14AMfUDump(const char *Cmd){
|
||||
@@ -1365,7 +1379,7 @@ int CmdHF14AMfUDump(const char *Cmd){
|
||||
cmdp += 2;
|
||||
break;
|
||||
case 'p':
|
||||
case 'P':
|
||||
case 'P': //set start page
|
||||
startPage = param_get8(Cmd, cmdp+1);
|
||||
manualPages = true;
|
||||
cmdp += 2;
|
||||
@@ -1469,6 +1483,71 @@ int CmdHF14AMfUDump(const char *Cmd){
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t get_pack[] = {0,0};
|
||||
iso14a_card_select_t card;
|
||||
//attempt to read pack
|
||||
if (!ul_auth_select( &card, tagtype, true, authKeyPtr, get_pack, sizeof(get_pack))) {
|
||||
//reset pack
|
||||
get_pack[0]=0;
|
||||
get_pack[1]=0;
|
||||
}
|
||||
ul_switch_off_field();
|
||||
// add pack to block read
|
||||
memcpy(data + (Pages*4) - 4, get_pack, sizeof(get_pack));
|
||||
|
||||
uint8_t dump_file_data[1024+DUMP_PREFIX_LENGTH] = {0x00};
|
||||
uint8_t get_version[] = {0,0,0,0,0,0,0,0,0};
|
||||
uint8_t get_tearing[] = {0,0,0};
|
||||
uint8_t get_counter[] = {0,0,0};
|
||||
uint8_t dummy_pack[] = {0,0};
|
||||
uint8_t get_signature[32];
|
||||
memset( get_signature, 0, sizeof(get_signature) );
|
||||
|
||||
if ( hasAuthKey )
|
||||
ul_auth_select( &card, tagtype, hasAuthKey, authKeyPtr, dummy_pack, sizeof(dummy_pack));
|
||||
else
|
||||
ul_select(&card);
|
||||
|
||||
ulev1_getVersion( get_version, sizeof(get_version) );
|
||||
for ( uint8_t i = 0; i<3; ++i) {
|
||||
ulev1_readTearing(i, get_tearing+i, 1);
|
||||
ulev1_readCounter(i, get_counter, sizeof(get_counter) );
|
||||
}
|
||||
ul_switch_off_field();
|
||||
if ( hasAuthKey )
|
||||
ul_auth_select( &card, tagtype, hasAuthKey, authKeyPtr, dummy_pack, sizeof(dummy_pack));
|
||||
else
|
||||
ul_select(&card);
|
||||
ulev1_readSignature( get_signature, sizeof(get_signature));
|
||||
ul_switch_off_field();
|
||||
//get version
|
||||
memcpy(dump_file_data, get_version, sizeof(get_version));
|
||||
//tearing
|
||||
memcpy(dump_file_data+10, get_tearing, sizeof(get_tearing));
|
||||
//pack
|
||||
memcpy(dump_file_data+13, get_pack, sizeof(get_pack));
|
||||
//signature
|
||||
memcpy(dump_file_data+16, get_signature, sizeof(get_signature));
|
||||
//block read data
|
||||
memcpy(dump_file_data+DUMP_PREFIX_LENGTH, data, Pages*4);
|
||||
|
||||
PrintAndLog("\nDataType| Data | | Ascii");
|
||||
PrintAndLog("---------------------------------");
|
||||
PrintAndLog("GetVer-1| %s| | %.4s", sprint_hex(dump_file_data, 4), dump_file_data);
|
||||
PrintAndLog("GetVer-2| %s| | %.4s", sprint_hex(dump_file_data+4, 4), dump_file_data+4);
|
||||
PrintAndLog("TBD | 00 00 | | ");
|
||||
PrintAndLog("Tearing | %s| | %.3s", sprint_hex(dump_file_data+10, 3), dump_file_data+10);
|
||||
PrintAndLog("Pack | %s | | %.2s", sprint_hex(dump_file_data+13, 2), dump_file_data+13);
|
||||
PrintAndLog("TBD | 00 | | ");
|
||||
PrintAndLog("Sig-1 | %s| | %.4s", sprint_hex(dump_file_data+16, 4), dump_file_data+16);
|
||||
PrintAndLog("Sig-2 | %s| | %.4s", sprint_hex(dump_file_data+20, 4), dump_file_data+20);
|
||||
PrintAndLog("Sig-3 | %s| | %.4s", sprint_hex(dump_file_data+24, 4), dump_file_data+24);
|
||||
PrintAndLog("Sig-4 | %s| | %.4s", sprint_hex(dump_file_data+28, 4), dump_file_data+28);
|
||||
PrintAndLog("Sig-5 | %s| | %.4s", sprint_hex(dump_file_data+32, 4), dump_file_data+32);
|
||||
PrintAndLog("Sig-6 | %s| | %.4s", sprint_hex(dump_file_data+36, 4), dump_file_data+36);
|
||||
PrintAndLog("Sig-7 | %s| | %.4s", sprint_hex(dump_file_data+40, 4), dump_file_data+40);
|
||||
PrintAndLog("Sig-8 | %s| | %.4s", sprint_hex(dump_file_data+44, 4), dump_file_data+44);
|
||||
|
||||
PrintAndLog("\nBlock# | Data |lck| Ascii");
|
||||
PrintAndLog("---------------------------------");
|
||||
for (i = 0; i < Pages; ++i) {
|
||||
@@ -1537,10 +1616,10 @@ int CmdHF14AMfUDump(const char *Cmd){
|
||||
PrintAndLog("Could not create file name %s", filename);
|
||||
return 1;
|
||||
}
|
||||
fwrite( data, 1, Pages*4, fout );
|
||||
fwrite( dump_file_data, 1, Pages*4 + DUMP_PREFIX_LENGTH, fout );
|
||||
fclose(fout);
|
||||
|
||||
PrintAndLog("Dumped %d pages, wrote %d bytes to %s", Pages, Pages*4, filename);
|
||||
PrintAndLog("Dumped %d pages, wrote %d bytes to %s", Pages+12, (Pages+12)*4, filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1548,7 +1627,6 @@ int CmdHF14AMfUDump(const char *Cmd){
|
||||
// Ultralight C Methods
|
||||
//-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
//
|
||||
// Ultralight C Authentication Demo {currently uses hard-coded key}
|
||||
//
|
||||
@@ -1874,113 +1952,34 @@ int CmdHF14AMfuGenDiverseKeys(const char *Cmd){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// static void GenerateUIDe( uint8_t *uid, uint8_t len){
|
||||
// for (int i=0; i<len; ++i){
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
|
||||
int CmdHF14AMfuELoad(const char *Cmd)
|
||||
{
|
||||
//FILE * f;
|
||||
//char filename[FILE_PATH_SIZE];
|
||||
//char *fnameptr = filename;
|
||||
//char buf[64] = {0x00};
|
||||
//uint8_t buf8[64] = {0x00};
|
||||
//int i, len, blockNum, numBlocks;
|
||||
//int nameParamNo = 1;
|
||||
|
||||
int CmdHF14AMfUeLoad(const char *Cmd) {
|
||||
char ctmp = param_getchar(Cmd, 0);
|
||||
|
||||
if ( ctmp == 'h' || ctmp == 0x00) return usage_hf_mfu_eload();
|
||||
|
||||
/*
|
||||
switch (ctmp) {
|
||||
case '0' : numBlocks = 5*4; break;
|
||||
case '1' :
|
||||
case '\0': numBlocks = 16*4; break;
|
||||
case '2' : numBlocks = 32*4; break;
|
||||
case '4' : numBlocks = 256; break;
|
||||
default: {
|
||||
numBlocks = 16*4;
|
||||
nameParamNo = 0;
|
||||
}
|
||||
}
|
||||
|
||||
len = param_getstr(Cmd,nameParamNo,filename);
|
||||
|
||||
if (len > FILE_PATH_SIZE - 4) len = FILE_PATH_SIZE - 4;
|
||||
|
||||
fnameptr += len;
|
||||
|
||||
sprintf(fnameptr, ".eml");
|
||||
|
||||
// open file
|
||||
f = fopen(filename, "r");
|
||||
if (f == NULL) {
|
||||
PrintAndLog("File %s not found or locked", filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
blockNum = 0;
|
||||
while(!feof(f)){
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
if (fgets(buf, sizeof(buf), f) == NULL) {
|
||||
|
||||
if (blockNum >= numBlocks) break;
|
||||
|
||||
PrintAndLog("File reading error.");
|
||||
fclose(f);
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (strlen(buf) < 32){
|
||||
if(strlen(buf) && feof(f))
|
||||
break;
|
||||
PrintAndLog("File content error. Block data must include 32 HEX symbols");
|
||||
fclose(f);
|
||||
return 2;
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; i += 2) {
|
||||
sscanf(&buf[i], "%02x", (unsigned int *)&buf8[i / 2]);
|
||||
}
|
||||
|
||||
if (mfEmlSetMem(buf8, blockNum, 1)) {
|
||||
PrintAndLog("Cant set emul block: %3d", blockNum);
|
||||
fclose(f);
|
||||
return 3;
|
||||
}
|
||||
printf(".");
|
||||
blockNum++;
|
||||
|
||||
if (blockNum >= numBlocks) break;
|
||||
}
|
||||
fclose(f);
|
||||
printf("\n");
|
||||
|
||||
if ((blockNum != numBlocks)) {
|
||||
PrintAndLog("File content error. Got %d must be %d blocks.",blockNum, numBlocks);
|
||||
return 4;
|
||||
}
|
||||
PrintAndLog("Loaded %d blocks from file: %s", blockNum, filename);
|
||||
*/
|
||||
return 0;
|
||||
if ( ctmp == 'h' || ctmp == 'H' || ctmp == 0x00) return usage_hf_mfu_eload();
|
||||
return CmdHF14AMfELoad(Cmd);
|
||||
}
|
||||
|
||||
int CmdHF14AMfUSim(const char *Cmd) {
|
||||
char ctmp = param_getchar(Cmd, 0);
|
||||
if ( ctmp == 'h' || ctmp == 'H' || ctmp == 0x00) return usage_hf_mfu_sim();
|
||||
return CmdHF14ASim(Cmd);
|
||||
}
|
||||
|
||||
//------------------------------------
|
||||
// Menu Stuff
|
||||
//------------------------------------
|
||||
static command_t CommandTable[] =
|
||||
{
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
{"dbg", CmdHF14AMfDbg, 0, "Set default debug mode"},
|
||||
{"info", CmdHF14AMfUInfo, 0, "Tag information"},
|
||||
{"dump", CmdHF14AMfUDump, 0, "Dump Ultralight / Ultralight-C / NTAG tag to binary file"},
|
||||
{"eload", CmdHF14AMfUeLoad, 0, "load Ultralight .eml dump file into emulator memory"},
|
||||
{"rdbl", CmdHF14AMfURdBl, 0, "Read block"},
|
||||
{"wrbl", CmdHF14AMfUWrBl, 0, "Write block"},
|
||||
{"eload", CmdHF14AMfuELoad, 0, "<not implemented> Load from file emulator dump"},
|
||||
{"cauth", CmdHF14AMfucAuth, 0, "Authentication - Ultralight C"},
|
||||
{"setpwd", CmdHF14AMfucSetPwd, 1, "Set 3des password - Ultralight-C"},
|
||||
{"setuid", CmdHF14AMfucSetUid, 1, "Set UID - MAGIC tags only"},
|
||||
{"setpwd", CmdHF14AMfucSetPwd, 0, "Set 3des password - Ultralight-C"},
|
||||
{"setuid", CmdHF14AMfucSetUid, 0, "Set UID - MAGIC tags only"},
|
||||
{"sim", CmdHF14AMfUSim, 0, "Simulate Ultralight from emulator memory"},
|
||||
{"gen", CmdHF14AMfuGenDiverseKeys , 1, "Generate 3des mifare diversified keys"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
@@ -9,22 +9,30 @@ int CmdHF14AMfURdBl(const char *Cmd);
|
||||
|
||||
//Crypto Cards
|
||||
int CmdHF14AMfucAuth(const char *Cmd);
|
||||
int CmdHF14AMfucSetPwd(const char *Cmd);
|
||||
int CmdHF14AMfucSetUid(const char *Cmd);
|
||||
int CmdHF14AMfuGenDiverseKeys(const char *Cmd);
|
||||
|
||||
//general stuff
|
||||
int CmdHF14AMfUDump(const char *Cmd);
|
||||
int CmdHF14AMfUInfo(const char *Cmd);
|
||||
|
||||
int CmdHF14AMfuELoad(const char *Cmd);
|
||||
int CmdHF14AMfUeLoad(const char *Cmd);
|
||||
int CmdHF14AMfUSim(const char *Cmd);
|
||||
|
||||
uint32_t GetHF14AMfU_Type(void);
|
||||
int ul_print_type(uint32_t tagtype, uint8_t spacer);
|
||||
void ul_switch_off_field(void);
|
||||
|
||||
int usage_hf_mfu_dump(void);
|
||||
int usage_hf_mfu_info(void);
|
||||
int usage_hf_mfu_dump(void);
|
||||
int usage_hf_mfu_rdbl(void);
|
||||
int usage_hf_mfu_wrbl(void);
|
||||
int usage_hf_mfu_eload(void);
|
||||
int usage_hf_mfu_sim(void);
|
||||
int usage_hf_mfu_ucauth(void);
|
||||
int usage_hf_mfu_ucsetpwd(void);
|
||||
int usage_hf_mfu_ucsetuid(void);
|
||||
int usage_hf_mfu_gendiverse(void);
|
||||
|
||||
int CmdHFMFUltra(const char *Cmd);
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@ getopt = require('getopt')
|
||||
bin = require('bin')
|
||||
example = "script run dumptoemul-mfu -i dumpdata-foobar.bin"
|
||||
author = "Martin Holst Swende \n @Marshmellow"
|
||||
usage = "script run dumptoemul [-i <file>] [-o <file>]"
|
||||
usage = "script run dumptoemul-mfu [-i <file>] [-o <file>]"
|
||||
desc =[[
|
||||
This script takes a dumpfile from 'hf mf dump' and converts it to a format that can be used
|
||||
This script takes a dumpfile from 'hf mfu dump' and converts it to a format that can be used
|
||||
by the emulator
|
||||
|
||||
Arguments:
|
||||
@@ -91,7 +91,7 @@ local function main(args)
|
||||
-- The hex-data is now in ascii-format,
|
||||
|
||||
-- But first, check the uid
|
||||
local uid = string.sub(dumpdata,1,8)
|
||||
local uid = string.sub(dumpdata,1+48,8)
|
||||
output = output or (uid .. ".eml")
|
||||
|
||||
-- Format some linebreaks
|
||||
|
||||
Reference in New Issue
Block a user