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:
iceman1001 2015-12-15 09:34:55 +01:00
commit 2b1f4228c2
8 changed files with 293 additions and 173 deletions

View file

@ -977,6 +977,15 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data)
response8[0] = 0x80; response8[0] = 0x80;
response8[1] = 0x80; response8[1] = 0x80;
ComputeCrc14443(CRC_14443_A, response8, 2, &response8[2], &response8[3]); ComputeCrc14443(CRC_14443_A, response8, 2, &response8[2], &response8[3]);
// uid not supplied then get from emulator memory
if (data[0]==0) {
uint16_t start = 4 * (0+12);
uint8_t emdata[8];
emlGetMemBt( emdata, start, sizeof(emdata));
memcpy(data, emdata, 3); //uid bytes 0-2
memcpy(data+3, emdata+4, 4); //uid bytes 3-7
flags |= FLAG_7B_UID_IN_DATA;
}
} break; } break;
default: { default: {
Dbprintf("Error: unkown tagtype (%d)",tagType); Dbprintf("Error: unkown tagtype (%d)",tagType);
@ -1034,12 +1043,12 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data)
// TC(1) = 0x02: CID supported, NAD not supported // TC(1) = 0x02: CID supported, NAD not supported
ComputeCrc14443(CRC_14443_A, response6, 4, &response6[4], &response6[5]); ComputeCrc14443(CRC_14443_A, response6, 4, &response6[4], &response6[5]);
// Prepare GET_VERSION (different for EV-1 / NTAG) // Prepare GET_VERSION (different for UL EV-1 / NTAG)
//uint8_t response7_EV1[] = {0x00, 0x04, 0x03, 0x01, 0x01, 0x00, 0x0b, 0x03, 0xfd, 0xf7}; //EV1 48bytes VERSION. //uint8_t response7_EV1[] = {0x00, 0x04, 0x03, 0x01, 0x01, 0x00, 0x0b, 0x03, 0xfd, 0xf7}; //EV1 48bytes VERSION.
uint8_t response7_NTAG[] = {0x00, 0x04, 0x04, 0x02, 0x01, 0x00, 0x11, 0x03, 0x01, 0x9e}; //NTAG 215 //uint8_t response7_NTAG[] = {0x00, 0x04, 0x04, 0x02, 0x01, 0x00, 0x11, 0x03, 0x01, 0x9e}; //NTAG 215
// Prepare CHK_TEARING // Prepare CHK_TEARING
uint8_t response9[] = {0xBD,0x90,0x3f}; //uint8_t response9[] = {0xBD,0x90,0x3f};
#define TAG_RESPONSE_COUNT 10 #define TAG_RESPONSE_COUNT 10
tag_response_info_t responses[TAG_RESPONSE_COUNT] = { tag_response_info_t responses[TAG_RESPONSE_COUNT] = {
@ -1050,9 +1059,9 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data)
{ .response = response3a, .response_n = sizeof(response3a) }, // Acknowledge select - cascade 2 { .response = response3a, .response_n = sizeof(response3a) }, // Acknowledge select - cascade 2
{ .response = response5, .response_n = sizeof(response5) }, // Authentication answer (random nonce) { .response = response5, .response_n = sizeof(response5) }, // Authentication answer (random nonce)
{ .response = response6, .response_n = sizeof(response6) }, // dummy ATS (pseudo-ATR), answer to RATS { .response = response6, .response_n = sizeof(response6) }, // dummy ATS (pseudo-ATR), answer to RATS
{ .response = response7_NTAG, .response_n = sizeof(response7_NTAG) }, // EV1/NTAG GET_VERSION response //{ .response = response7_NTAG, .response_n = sizeof(response7_NTAG)}, // EV1/NTAG GET_VERSION response
{ .response = response8, .response_n = sizeof(response8) }, // EV1/NTAG PACK response { .response = response8, .response_n = sizeof(response8) }, // EV1/NTAG PACK response
{ .response = response9, .response_n = sizeof(response9) } // EV1/NTAG CHK_TEAR response //{ .response = response9, .response_n = sizeof(response9) } // EV1/NTAG CHK_TEAR response
}; };
// Allocate 512 bytes for the dynamic modulation, created when the reader queries for it // Allocate 512 bytes for the dynamic modulation, created when the reader queries for it
@ -1105,7 +1114,6 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data)
LED_A_ON(); LED_A_ON();
for(;;) { for(;;) {
// Clean receive command buffer // Clean receive command buffer
if(!GetIso14443aCommandFromReader(receivedCmd, receivedCmdPar, &len)) { if(!GetIso14443aCommandFromReader(receivedCmd, receivedCmdPar, &len)) {
DbpString("Button press"); DbpString("Button press");
break; break;
@ -1129,33 +1137,18 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data)
p_response = &responses[4]; order = 30; p_response = &responses[4]; order = 30;
} else if(receivedCmd[0] == 0x30) { // Received a (plain) READ } else if(receivedCmd[0] == 0x30) { // Received a (plain) READ
uint8_t block = receivedCmd[1]; uint8_t block = receivedCmd[1];
if ( tagType == 7 ) { // if Ultralight or NTAG (4 byte blocks)
uint16_t start = 4 * block; if ( tagType == 7 || tagType == 2 ) {
//first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature]
/*if ( block < 4 ) { uint16_t start = 4 * (block+12);
//NTAG 215
uint8_t blockdata[50] = {
data[0],data[1],data[2], 0x88 ^ data[0] ^ data[1] ^ data[2],
data[3],data[4],data[5],data[6],
data[3] ^ data[4] ^ data[5] ^ data[6],0x48,0x0f,0xe0,
0xe1,0x10,0x12,0x00,
0x03,0x00,0xfe,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00};
AppendCrc14443a(blockdata+start, 16);
EmSendCmdEx( blockdata+start, MAX_MIFARE_FRAME_SIZE, false);
} else {*/
uint8_t emdata[MAX_MIFARE_FRAME_SIZE]; uint8_t emdata[MAX_MIFARE_FRAME_SIZE];
emlGetMemBt( emdata, start, 16); emlGetMemBt( emdata, start, 16);
AppendCrc14443a(emdata, 16); AppendCrc14443a(emdata, 16);
EmSendCmdEx(emdata, sizeof(emdata), false); EmSendCmdEx(emdata, sizeof(emdata), false);
//} // We already responded, do not send anything with the EmSendCmd14443aRaw() that is called below
p_response = NULL; p_response = NULL;
} else { // all other tags (16 byte block tags)
} else { EmSendCmdEx(data+(4*receivedCmd[1]),16,false);
EmSendCmdEx(data+(4*block),16,false);
// Dbprintf("Read request from reader: %x %x",receivedCmd[0],receivedCmd[1]); // Dbprintf("Read request from reader: %x %x",receivedCmd[0],receivedCmd[1]);
// We already responded, do not send anything with the EmSendCmd14443aRaw() that is called below // We already responded, do not send anything with the EmSendCmd14443aRaw() that is called below
p_response = NULL; p_response = NULL;
@ -1163,7 +1156,8 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data)
} else if(receivedCmd[0] == 0x3A) { // Received a FAST READ (ranged read) } else if(receivedCmd[0] == 0x3A) { // Received a FAST READ (ranged read)
uint8_t emdata[MAX_FRAME_SIZE]; uint8_t emdata[MAX_FRAME_SIZE];
int start = receivedCmd[1] * 4; //first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature]
int start = (receivedCmd[1]+12) * 4;
int len = (receivedCmd[2] - receivedCmd[1] + 1) * 4; int len = (receivedCmd[2] - receivedCmd[1] + 1) * 4;
emlGetMemBt( emdata, start, len); emlGetMemBt( emdata, start, len);
AppendCrc14443a(emdata, len); AppendCrc14443a(emdata, len);
@ -1172,13 +1166,19 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data)
} else if(receivedCmd[0] == 0x3C && tagType == 7) { // Received a READ SIGNATURE -- } else if(receivedCmd[0] == 0x3C && tagType == 7) { // Received a READ SIGNATURE --
// ECC data, taken from a NTAG215 amiibo token. might work. LEN: 32, + 2 crc // ECC data, taken from a NTAG215 amiibo token. might work. LEN: 32, + 2 crc
uint8_t data[] = {0x56,0x06,0xa6,0x4f,0x43,0x32,0x53,0x6f, //first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature]
0x43,0xda,0x45,0xd6,0x61,0x38,0xaa,0x1e, uint16_t start = 4 * 4;
0xcf,0xd3,0x61,0x36,0xca,0x5f,0xbb,0x05, uint8_t emdata[34];
0xce,0x21,0x24,0x5b,0xa6,0x7a,0x79,0x07, emlGetMemBt( emdata, start, 32);
0x00,0x00}; AppendCrc14443a(emdata, 32);
AppendCrc14443a(data, sizeof(data)-2); EmSendCmdEx(emdata, sizeof(emdata), false);
EmSendCmdEx(data,sizeof(data),false); //uint8_t data[] = {0x56,0x06,0xa6,0x4f,0x43,0x32,0x53,0x6f,
// 0x43,0xda,0x45,0xd6,0x61,0x38,0xaa,0x1e,
// 0xcf,0xd3,0x61,0x36,0xca,0x5f,0xbb,0x05,
// 0xce,0x21,0x24,0x5b,0xa6,0x7a,0x79,0x07,
// 0x00,0x00};
//AppendCrc14443a(data, sizeof(data)-2);
//EmSendCmdEx(data,sizeof(data),false);
p_response = NULL; p_response = NULL;
} else if (receivedCmd[0] == 0x39 && tagType == 7) { // Received a READ COUNTER -- } else if (receivedCmd[0] == 0x39 && tagType == 7) { // Received a READ COUNTER --
uint8_t index = receivedCmd[1]; uint8_t index = receivedCmd[1];
@ -1201,7 +1201,16 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data)
p_response = NULL; p_response = NULL;
} else if(receivedCmd[0] == 0x3E && tagType == 7) { // Received a CHECK_TEARING_EVENT -- } else if(receivedCmd[0] == 0x3E && tagType == 7) { // Received a CHECK_TEARING_EVENT --
p_response = &responses[9]; //first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature]
uint8_t emdata[3];
uint8_t counter=0;
if (receivedCmd[1]<3) counter = receivedCmd[1];
emlGetMemBt( emdata, 10+counter, 1);
AppendCrc14443a(emdata, sizeof(emdata)-2);
EmSendCmdEx(emdata, sizeof(emdata), false);
p_response = NULL;
//p_response = &responses[9];
} else if(receivedCmd[0] == 0x50) { // Received a HALT } else if(receivedCmd[0] == 0x50) { // Received a HALT
if (tracing) { if (tracing) {
@ -1211,7 +1220,12 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data)
} else if(receivedCmd[0] == 0x60 || receivedCmd[0] == 0x61) { // Received an authentication request } else if(receivedCmd[0] == 0x60 || receivedCmd[0] == 0x61) { // Received an authentication request
if ( tagType == 7 ) { // IF NTAG /EV1 0x60 == GET_VERSION, not a authentication request. if ( tagType == 7 ) { // IF NTAG /EV1 0x60 == GET_VERSION, not a authentication request.
p_response = &responses[7]; uint8_t emdata[10];
emlGetMemBt( emdata, 0, 8 );
AppendCrc14443a(emdata, sizeof(emdata)-2);
EmSendCmdEx(emdata, sizeof(emdata), false);
p_response = NULL;
//p_response = &responses[7];
} else { } else {
p_response = &responses[5]; order = 7; p_response = &responses[5]; order = 7;
} }
@ -1282,13 +1296,18 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data)
else if (receivedCmd[0] == 0x1b) // NTAG / EV-1 authentication else if (receivedCmd[0] == 0x1b) // NTAG / EV-1 authentication
{ {
if ( tagType == 7 ) { if ( tagType == 7 ) {
p_response = &responses[8]; // PACK response uint16_t start = 13; //first 4 blocks of emu are [getversion answer - check tearing - pack - 0x00]
uint8_t emdata[4];
emlGetMemBt( emdata, start, 2);
AppendCrc14443a(emdata, 2);
EmSendCmdEx(emdata, sizeof(emdata), false);
p_response = NULL;
//p_response = &responses[8]; // PACK response
uint32_t pwd = bytes_to_num(receivedCmd+1,4); uint32_t pwd = bytes_to_num(receivedCmd+1,4);
if ( MF_DBGLEVEL >= 3) Dbprintf("Auth attempt: %08x", pwd); if ( MF_DBGLEVEL >= 3) Dbprintf("Auth attempt: %08x", pwd);
} }
} } else {
else {
// Check for ISO 14443A-4 compliant commands, look at left nibble // Check for ISO 14443A-4 compliant commands, look at left nibble
switch (receivedCmd[0]) { switch (receivedCmd[0]) {
case 0x02: case 0x02:
@ -2545,7 +2564,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
uint8_t rAUTH_NT[] = {0x01, 0x01, 0x01, 0x01}; uint8_t rAUTH_NT[] = {0x01, 0x01, 0x01, 0x01};
uint8_t rAUTH_AT[] = {0x00, 0x00, 0x00, 0x00}; uint8_t rAUTH_AT[] = {0x00, 0x00, 0x00, 0x00};
//Here, we collect UID,NT,AR,NR,UID2,NT2,AR2,NR2 //Here, we collect UID1,UID2,NT,AR,NR,0,0,NT2,AR2,NR2
// This can be used in a reader-only attack. // This can be used in a reader-only attack.
// (it can also be retrieved via 'hf 14a list', but hey... // (it can also be retrieved via 'hf 14a list', but hey...
uint32_t ar_nr_responses[] = {0,0,0,0,0,0,0,0,0,0}; uint32_t ar_nr_responses[] = {0,0,0,0,0,0,0,0,0,0};
@ -2620,7 +2639,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
bool finished = FALSE; bool finished = FALSE;
while (!BUTTON_PRESS() && !finished) { while (!BUTTON_PRESS() && !finished && !usb_poll_validate_length()) {
WDT_HIT(); WDT_HIT();
// find reader field // find reader field
@ -3017,7 +3036,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
} else { } else {
Dbprintf("Failed to obtain two AR/NR pairs!"); Dbprintf("Failed to obtain two AR/NR pairs!");
if(ar_nr_collected > 0 ) { if(ar_nr_collected > 0 ) {
Dbprintf("Only got these: UID=%07x%08x, nonce=%08x, AR1=%08x, NR1=%08x", Dbprintf("Only got these: UID=%06x%08x, nonce=%08x, AR1=%08x, NR1=%08x",
ar_nr_responses[0], // UID1 ar_nr_responses[0], // UID1
ar_nr_responses[1], // UID2 ar_nr_responses[1], // UID2
ar_nr_responses[2], // NT ar_nr_responses[2], // NT

View file

@ -1195,15 +1195,21 @@ int CmdHF14AMf1kSim(const char *Cmd)
if(flags & FLAG_INTERACTIVE) if(flags & FLAG_INTERACTIVE)
{ {
PrintAndLog("Press pm3-button to abort simulation");
uint8_t data[40]; uint8_t data[40];
uint8_t key[6]; uint8_t key[6];
UsbCommand resp; 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() ){ while(!ukbhit() ){
if ( WaitForResponseTimeout(CMD_ACK,&resp,1500) ) { if (!WaitForResponseTimeout(CMD_ACK,&resp,1500) ) continue;
if ( (resp.arg[0] & 0xffff) == CMD_SIMULATE_MIFARE_CARD ){
if ( !(flags & FLAG_NR_AR_ATTACK) ) break;
if ( (resp.arg[0] & 0xffff) != CMD_SIMULATE_MIFARE_CARD ) break;
memset(data, 0x00, sizeof(data)); memset(data, 0x00, sizeof(data));
memset(key, 0x00, sizeof(key)); memset(key, 0x00, sizeof(key));
int len = (resp.arg[1] > sizeof(data)) ? sizeof(data) : resp.arg[1]; 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; uint64_t corr_uid = 0;
if ( memcmp(data, "\x00\x00\x00\x00", 4) == 0 ) { if ( memcmp(data, "\x00\x00\x00\x00", 4) == 0 ) {
corr_uid = (data[3] << 24) | (data[2] << 16) | (data[1] << 8) | data[0]; corr_uid = (data[3] << 24) | (data[2] << 16) | (data[1] << 8) | data[0];
} tryMfk32(corr_uid, data, key);
else { } else {
corr_uid |= (uint64_t)data[2] << 48; corr_uid |= (uint64_t)data[2] << 48;
corr_uid |= (uint64_t)data[1] << 40; corr_uid |= (uint64_t)data[1] << 40;
corr_uid |= (uint64_t)data[0] << 32; corr_uid |= (uint64_t)data[0] << 32;
@ -1222,14 +1228,12 @@ int CmdHF14AMf1kSim(const char *Cmd)
corr_uid |= data[6] << 16; corr_uid |= data[6] << 16;
corr_uid |= data[5] << 8; corr_uid |= data[5] << 8;
corr_uid |= data[4]; corr_uid |= data[4];
tryMfk64(corr_uid, data, key);
} }
tryMfk32(corr_uid, data, key);
//tryMfk64(corr_uid, data, key);
PrintAndLog("--"); PrintAndLog("--");
} }
} }
}
}
return 0; return 0;
} }
@ -1334,7 +1338,7 @@ int CmdHF14AMfELoad(const char *Cmd)
if ( ctmp == 'h' || ctmp == 'H' || ctmp == 0x00) { if ( ctmp == 'h' || ctmp == 'H' || ctmp == 0x00) {
PrintAndLog("It loads emul dump from the file `filename.eml`"); 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(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K, u = UL");
PrintAndLog(""); PrintAndLog("");
PrintAndLog(" sample: hf mf eload filename"); PrintAndLog(" sample: hf mf eload filename");
@ -1348,13 +1352,15 @@ int CmdHF14AMfELoad(const char *Cmd)
case '\0': numBlocks = 16*4; break; case '\0': numBlocks = 16*4; break;
case '2' : numBlocks = 32*4; break; case '2' : numBlocks = 32*4; break;
case '4' : numBlocks = 256; break; case '4' : numBlocks = 256; break;
case 'U' : // fall through , NTAG 215 has 135blocks a 540 bytes. case 'U' : // fall through
case 'u' : numBlocks = 135; blockWidth = 8; break; case 'u' : numBlocks = 255; blockWidth = 8; break;
default: { default: {
numBlocks = 16*4; numBlocks = 16*4;
nameParamNo = 0; nameParamNo = 0;
} }
} }
uint32_t numblk2 = param_get32ex(Cmd,2,0,10);
if (numblk2 > 0) numBlocks = numblk2;
len = param_getstr(Cmd,nameParamNo,filename); len = param_getstr(Cmd,nameParamNo,filename);
@ -1816,7 +1822,7 @@ int CmdHF14AMfCGetBlk(const char *Cmd) {
return 1; return 1;
} }
PrintAndLog("data:%s", sprint_hex(data, sizeof(data))); PrintAndLog("data: %s", sprint_hex(data, sizeof(data)));
return 0; return 0;
} }

View file

@ -54,5 +54,6 @@ int CmdHF14AMfCGetBlk(const char* cmd);
int CmdHF14AMfCGetSc(const char* cmd); int CmdHF14AMfCGetSc(const char* cmd);
int CmdHF14AMfCLoad(const char* cmd); int CmdHF14AMfCLoad(const char* cmd);
int CmdHF14AMfCSave(const char* cmd); int CmdHF14AMfCSave(const char* cmd);
int GetCardSize(); int CmdHf14MfDecryptBytes(const char *Cmd);
#endif #endif

View file

@ -1210,7 +1210,6 @@ int usage_hf_mfu_dump(void) {
PrintAndLog(" n <FN > : filename w/o .bin to save the dump as"); 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(" 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(" q <qty> : number of Pages to manually set how many pages to dump");
PrintAndLog(""); PrintAndLog("");
PrintAndLog(" sample : hf mfu dump"); PrintAndLog(" sample : hf mfu dump");
PrintAndLog(" : hf mfu dump n myfile"); PrintAndLog(" : hf mfu dump n myfile");
@ -1248,14 +1247,29 @@ int usage_hf_mfu_wrbl(void) {
} }
int usage_hf_mfu_eload(void) { int usage_hf_mfu_eload(void) {
PrintAndLog("It loads emulator dump from the file `filename.eml`\n"); PrintAndLog("It loads emul dump from the file `filename.eml`");
PrintAndLog("Usage: hf mfu eload t <card memory> i <file name w/o `.eml`>\n"); PrintAndLog("Hint: See script dumptoemul-mfu.lua to convert the .bin to the eml");
PrintAndLog(" Options:"); PrintAndLog("Usage: hf mfu eload u <file name w/o `.eml`> [numblocks]");
PrintAndLog(" t <card memory> : Tag memorysize/type"); PrintAndLog(" Options:");
PrintAndLog(" i <file> : file name w/o `.eml`"); PrintAndLog(" h : this help");
PrintAndLog(" u : UL");
PrintAndLog(" numblocks : number of blocks to load from eml file");
PrintAndLog(""); PrintAndLog("");
PrintAndLog(" sample : hf mfu eload filename"); PrintAndLog(" sample: hf mfu eload u filename");
PrintAndLog(" : hf mfu eload 4 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; return 0;
} }
@ -1300,8 +1314,8 @@ int usage_hf_mfu_gendiverse(void){
return 0; return 0;
} }
#define DUMP_PREFIX_LENGTH 48
// //
// Mifare Ultralight / Ultralight-C / Ultralight-EV1 // Mifare Ultralight / Ultralight-C / Ultralight-EV1
// Read and Dump Card Contents, using auto detection of tag size. // Read and Dump Card Contents, using auto detection of tag size.
int CmdHF14AMfUDump(const char *Cmd){ int CmdHF14AMfUDump(const char *Cmd){
@ -1365,7 +1379,7 @@ int CmdHF14AMfUDump(const char *Cmd){
cmdp += 2; cmdp += 2;
break; break;
case 'p': case 'p':
case 'P': case 'P': //set start page
startPage = param_get8(Cmd, cmdp+1); startPage = param_get8(Cmd, cmdp+1);
manualPages = true; manualPages = true;
cmdp += 2; 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("\nBlock# | Data |lck| Ascii");
PrintAndLog("---------------------------------"); PrintAndLog("---------------------------------");
for (i = 0; i < Pages; ++i) { for (i = 0; i < Pages; ++i) {
@ -1537,10 +1616,10 @@ int CmdHF14AMfUDump(const char *Cmd){
PrintAndLog("Could not create file name %s", filename); PrintAndLog("Could not create file name %s", filename);
return 1; return 1;
} }
fwrite( data, 1, Pages*4, fout ); fwrite( dump_file_data, 1, Pages*4 + DUMP_PREFIX_LENGTH, fout );
fclose(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; return 0;
} }
@ -1548,7 +1627,6 @@ int CmdHF14AMfUDump(const char *Cmd){
// Ultralight C Methods // Ultralight C Methods
//------------------------------------------------------------------------------- //-------------------------------------------------------------------------------
// //
// Ultralight C Authentication Demo {currently uses hard-coded key} // Ultralight C Authentication Demo {currently uses hard-coded key}
// //
@ -1874,113 +1952,34 @@ int CmdHF14AMfuGenDiverseKeys(const char *Cmd){
return 0; return 0;
} }
// static void GenerateUIDe( uint8_t *uid, uint8_t len){ int CmdHF14AMfUeLoad(const char *Cmd) {
// 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;
char ctmp = param_getchar(Cmd, 0); char ctmp = param_getchar(Cmd, 0);
if ( ctmp == 'h' || ctmp == 'H' || ctmp == 0x00) return usage_hf_mfu_eload();
if ( ctmp == 'h' || ctmp == 0x00) return usage_hf_mfu_eload(); return CmdHF14AMfELoad(Cmd);
/*
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;
} }
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[] = static command_t CommandTable[] =
{ {
{"help", CmdHelp, 1, "This help"}, {"help", CmdHelp, 1, "This help"},
{"dbg", CmdHF14AMfDbg, 0, "Set default debug mode"}, {"dbg", CmdHF14AMfDbg, 0, "Set default debug mode"},
{"info", CmdHF14AMfUInfo, 0, "Tag information"}, {"info", CmdHF14AMfUInfo, 0, "Tag information"},
{"dump", CmdHF14AMfUDump, 0, "Dump Ultralight / Ultralight-C / NTAG tag to binary file"}, {"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"}, {"rdbl", CmdHF14AMfURdBl, 0, "Read block"},
{"wrbl", CmdHF14AMfUWrBl, 0, "Write block"}, {"wrbl", CmdHF14AMfUWrBl, 0, "Write block"},
{"eload", CmdHF14AMfuELoad, 0, "<not implemented> Load from file emulator dump"},
{"cauth", CmdHF14AMfucAuth, 0, "Authentication - Ultralight C"}, {"cauth", CmdHF14AMfucAuth, 0, "Authentication - Ultralight C"},
{"setpwd", CmdHF14AMfucSetPwd, 1, "Set 3des password - Ultralight-C"}, {"setpwd", CmdHF14AMfucSetPwd, 0, "Set 3des password - Ultralight-C"},
{"setuid", CmdHF14AMfucSetUid, 1, "Set UID - MAGIC tags only"}, {"setuid", CmdHF14AMfucSetUid, 0, "Set UID - MAGIC tags only"},
{"sim", CmdHF14AMfUSim, 0, "Simulate Ultralight from emulator memory"},
{"gen", CmdHF14AMfuGenDiverseKeys , 1, "Generate 3des mifare diversified keys"}, {"gen", CmdHF14AMfuGenDiverseKeys , 1, "Generate 3des mifare diversified keys"},
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };

View file

@ -9,22 +9,30 @@ int CmdHF14AMfURdBl(const char *Cmd);
//Crypto Cards //Crypto Cards
int CmdHF14AMfucAuth(const char *Cmd); int CmdHF14AMfucAuth(const char *Cmd);
int CmdHF14AMfucSetPwd(const char *Cmd);
int CmdHF14AMfucSetUid(const char *Cmd);
int CmdHF14AMfuGenDiverseKeys(const char *Cmd);
//general stuff //general stuff
int CmdHF14AMfUDump(const char *Cmd); int CmdHF14AMfUDump(const char *Cmd);
int CmdHF14AMfUInfo(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); uint32_t GetHF14AMfU_Type(void);
int ul_print_type(uint32_t tagtype, uint8_t spacer); int ul_print_type(uint32_t tagtype, uint8_t spacer);
void ul_switch_off_field(void); void ul_switch_off_field(void);
int usage_hf_mfu_dump(void);
int usage_hf_mfu_info(void); int usage_hf_mfu_info(void);
int usage_hf_mfu_dump(void);
int usage_hf_mfu_rdbl(void); int usage_hf_mfu_rdbl(void);
int usage_hf_mfu_wrbl(void); int usage_hf_mfu_wrbl(void);
int usage_hf_mfu_eload(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); int CmdHFMFUltra(const char *Cmd);

View file

@ -4,9 +4,9 @@ getopt = require('getopt')
bin = require('bin') bin = require('bin')
example = "script run dumptoemul-mfu -i dumpdata-foobar.bin" example = "script run dumptoemul-mfu -i dumpdata-foobar.bin"
author = "Martin Holst Swende \n @Marshmellow" author = "Martin Holst Swende \n @Marshmellow"
usage = "script run dumptoemul [-i <file>] [-o <file>]" usage = "script run dumptoemul-mfu [-i <file>] [-o <file>]"
desc =[[ 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 by the emulator
Arguments: Arguments:
@ -91,7 +91,7 @@ local function main(args)
-- The hex-data is now in ascii-format, -- The hex-data is now in ascii-format,
-- But first, check the uid -- 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") output = output or (uid .. ".eml")
-- Format some linebreaks -- Format some linebreaks

49
common/parity.c Normal file
View file

@ -0,0 +1,49 @@
//-----------------------------------------------------------------------------
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// parity functions
//-----------------------------------------------------------------------------
#include <stdint.h>
const uint8_t OddByteParity[256] = {
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
};
const uint8_t EvenByteParity[256] = {
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0
};

38
common/parity.h Normal file
View file

@ -0,0 +1,38 @@
//-----------------------------------------------------------------------------
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// Generic CRC calculation code.
//-----------------------------------------------------------------------------
#ifndef __PARITY_H
#define __PARITY_H
#include <stdint.h>
extern const uint8_t OddByteParity[256];
static inline uint8_t oddparity8(uint8_t bt)
{
return OddByteParity[bt];
}
extern const uint8_t EvenByteParity[256];
static inline uint8_t evenparity8(const uint8_t bt)
{
return EvenByteParity[bt];
}
static inline uint32_t evenparity32(uint32_t x)
{
x ^= x >> 16;
x ^= x >> 8;
return EvenByteParity[x & 0xff];
}
#endif /* __PARITY_H */