From 2b1f4228c2987459445d30443f92038f9ea080c6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 15 Dec 2015 09:34:55 +0100 Subject: [PATCH] ADD: @marshmellow42 's changes to "hf mfu *" , ADD: @marshmellow42 's changes to "hf mf sim", ADD: @pwpiwi 's parity files was missing. --- armsrc/iso14443a.c | 107 +++++++++------ client/cmdhfmf.c | 34 +++-- client/cmdhfmf.h | 3 +- client/cmdhfmfu.c | 213 +++++++++++++++--------------- client/cmdhfmfu.h | 14 +- client/scripts/dumptoemul-mfu.lua | 6 +- common/parity.c | 49 +++++++ common/parity.h | 38 ++++++ 8 files changed, 292 insertions(+), 172 deletions(-) create mode 100644 common/parity.c create mode 100644 common/parity.h diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 2eb280e1..bfbc70c7 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -977,6 +977,15 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data) response8[0] = 0x80; response8[1] = 0x80; 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; default: { 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 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_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 - uint8_t response9[] = {0xBD,0x90,0x3f}; + //uint8_t response9[] = {0xBD,0x90,0x3f}; #define TAG_RESPONSE_COUNT 10 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 = response5, .response_n = sizeof(response5) }, // Authentication answer (random nonce) { .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 = 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 @@ -1105,7 +1114,6 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data) LED_A_ON(); for(;;) { // Clean receive command buffer - if(!GetIso14443aCommandFromReader(receivedCmd, receivedCmdPar, &len)) { DbpString("Button press"); break; @@ -1129,33 +1137,18 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data) p_response = &responses[4]; order = 30; } else if(receivedCmd[0] == 0x30) { // Received a (plain) READ uint8_t block = receivedCmd[1]; - if ( tagType == 7 ) { - uint16_t start = 4 * block; - - /*if ( block < 4 ) { - //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 {*/ + // if Ultralight or NTAG (4 byte blocks) + if ( tagType == 7 || tagType == 2 ) { + //first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature] + uint16_t start = 4 * (block+12); uint8_t emdata[MAX_MIFARE_FRAME_SIZE]; emlGetMemBt( emdata, start, 16); AppendCrc14443a(emdata, 16); EmSendCmdEx(emdata, sizeof(emdata), false); - //} + // We already responded, do not send anything with the EmSendCmd14443aRaw() that is called below p_response = NULL; - - } else { - EmSendCmdEx(data+(4*block),16,false); + } else { // all other tags (16 byte block tags) + EmSendCmdEx(data+(4*receivedCmd[1]),16,false); // 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 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) 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; emlGetMemBt( emdata, start, 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 -- // 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, - 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); + //first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature] + uint16_t start = 4 * 4; + uint8_t emdata[34]; + emlGetMemBt( emdata, start, 32); + AppendCrc14443a(emdata, 32); + EmSendCmdEx(emdata, sizeof(emdata), 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; } else if (receivedCmd[0] == 0x39 && tagType == 7) { // Received a READ COUNTER -- uint8_t index = receivedCmd[1]; @@ -1201,7 +1201,16 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data) p_response = NULL; } 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 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 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 { 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 { 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); if ( MF_DBGLEVEL >= 3) Dbprintf("Auth attempt: %08x", pwd); } - } - else { + } else { // Check for ISO 14443A-4 compliant commands, look at left nibble switch (receivedCmd[0]) { 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_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. // (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}; @@ -2620,7 +2639,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * bool finished = FALSE; - while (!BUTTON_PRESS() && !finished) { + while (!BUTTON_PRESS() && !finished && !usb_poll_validate_length()) { WDT_HIT(); // find reader field @@ -3017,7 +3036,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * } else { Dbprintf("Failed to obtain two AR/NR pairs!"); 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[1], // UID2 ar_nr_responses[2], // NT diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index d43a0ef2..b2d5494f 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -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] "); + PrintAndLog("Usage: hf mf eload [card memory] [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; } diff --git a/client/cmdhfmf.h b/client/cmdhfmf.h index 31c84dc4..6c0b206c 100644 --- a/client/cmdhfmf.h +++ b/client/cmdhfmf.h @@ -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 diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 19dc7547..82289d5b 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -1210,7 +1210,6 @@ int usage_hf_mfu_dump(void) { PrintAndLog(" n : filename w/o .bin to save the dump as"); PrintAndLog(" p : starting Page number to manually set a page to start the dump at"); PrintAndLog(" q : 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 i \n"); - PrintAndLog(" Options:"); - PrintAndLog(" t : Tag memorysize/type"); - PrintAndLog(" i : 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 [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 "); + 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 FILE_PATH_SIZE - 4) len = FILE_PATH_SIZE - 4; - - fnameptr += len; + if ( ctmp == 'h' || ctmp == 'H' || ctmp == 0x00) return usage_hf_mfu_eload(); + return CmdHF14AMfELoad(Cmd); +} - 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[] = { {"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, " 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} }; diff --git a/client/cmdhfmfu.h b/client/cmdhfmfu.h index 2fc55ae9..621d5c0b 100644 --- a/client/cmdhfmfu.h +++ b/client/cmdhfmfu.h @@ -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); diff --git a/client/scripts/dumptoemul-mfu.lua b/client/scripts/dumptoemul-mfu.lua index b901a2ba..1236f173 100644 --- a/client/scripts/dumptoemul-mfu.lua +++ b/client/scripts/dumptoemul-mfu.lua @@ -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 ] [-o ]" +usage = "script run dumptoemul-mfu [-i ] [-o ]" 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 diff --git a/common/parity.c b/common/parity.c new file mode 100644 index 00000000..b783b1e9 --- /dev/null +++ b/common/parity.c @@ -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 + +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 +}; + + diff --git a/common/parity.h b/common/parity.h new file mode 100644 index 00000000..6adfdb30 --- /dev/null +++ b/common/parity.h @@ -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 + +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 */ -- 2.39.5