X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/79dcb9e0900d51edf30d8cf863aca7be2f257ff4..refs/pull/193/head:/client/cmdhfmf.c diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index df504416..36c8e6c3 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1016,130 +1016,273 @@ int CmdHF14AMfChk(const char *Cmd) return 0; } -int CmdHF14AMf1kSim(const char *Cmd) -{ - uint8_t uid[7] = {0, 0, 0, 0, 0, 0, 0}; - uint8_t exitAfterNReads = 0; - uint8_t flags = 0; - - uint8_t cmdp = param_getchar(Cmd, 0); - - if (cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: hf mf sim u n i x"); - PrintAndLog(" h this help"); - PrintAndLog(" u (Optional) UID. If not specified, the UID from emulator memory will be used"); - PrintAndLog(" n (Optional) Automatically exit simulation after blocks have been read by reader. 0 = infinite"); - PrintAndLog(" i (Optional) Interactive, means that console will not be returned until simulation finishes or is aborted"); - PrintAndLog(" x (Optional) Crack, performs the 'reader attack', nr/ar attack against a legitimate reader, fishes out the key(s)"); - PrintAndLog(""); - PrintAndLog(" sample: hf mf sim u 0a0a0a0a "); - return 0; - } - uint8_t pnr = 0; - if (param_getchar(Cmd, pnr) == 'u') { - if(param_gethex(Cmd, pnr+1, uid, 8) == 0) - { - flags |= FLAG_4B_UID_IN_DATA; // UID from packet - } else if(param_gethex(Cmd,pnr+1,uid,14) == 0) { - flags |= FLAG_7B_UID_IN_DATA;// UID from packet - } else { - PrintAndLog("UID, if specified, must include 8 or 14 HEX symbols"); - return 1; +void readerAttack(nonces_t ar_resp[], bool setEmulatorMem) { + #define ATTACK_KEY_COUNT 8 // keep same as define in iso14443a.c -> Mifare1ksim() + uint64_t key = 0; + typedef struct { + uint64_t keyA; + uint64_t keyB; + } st_t; + st_t sector_trailer[ATTACK_KEY_COUNT]; + memset(sector_trailer, 0x00, sizeof(sector_trailer)); + + uint8_t stSector[ATTACK_KEY_COUNT]; + memset(stSector, 0x00, sizeof(stSector)); + uint8_t key_cnt[ATTACK_KEY_COUNT]; + memset(key_cnt, 0x00, sizeof(key_cnt)); + + for (uint8_t i = 0; i 0) { + //PrintAndLog("DEBUG: Trying sector %d, cuid %08x, nt %08x, ar %08x, nr %08x, ar2 %08x, nr2 %08x",ar_resp[i].sector, ar_resp[i].cuid,ar_resp[i].nonce,ar_resp[i].ar,ar_resp[i].nr,ar_resp[i].ar2,ar_resp[i].nr2); + if (mfkey32(ar_resp[i], &key)) { + PrintAndLog(" Found Key%s for sector %02d: [%04x%08x]", (ar_resp[i].keytype) ? "B" : "A", ar_resp[i].sector, (uint32_t) (key>>32), (uint32_t) (key &0xFFFFFFFF)); + + for (uint8_t ii = 0; ii0) { + uint8_t memBlock[16]; + memset(memBlock, 0x00, sizeof(memBlock)); + char cmd1[36]; + memset(cmd1,0x00,sizeof(cmd1)); + snprintf(cmd1,sizeof(cmd1),"%04x%08xFF078069%04x%08x",(uint32_t) (sector_trailer[i].keyA>>32), (uint32_t) (sector_trailer[i].keyA &0xFFFFFFFF),(uint32_t) (sector_trailer[i].keyB>>32), (uint32_t) (sector_trailer[i].keyB &0xFFFFFFFF)); + PrintAndLog("Setting Emulator Memory Block %02d: [%s]",stSector[i]*4+3, cmd1); + if (param_gethex(cmd1, 0, memBlock, 32)) { + PrintAndLog("block data must include 32 HEX symbols"); + return; + } + + UsbCommand c = {CMD_MIFARE_EML_MEMSET, {(stSector[i]*4+3), 1, 0}}; + memcpy(c.d.asBytes, memBlock, 16); + clearCommandBuffer(); + SendCommand(&c); + } + } } + /* + //un-comment to use as well moebius attack + for (uint8_t i = ATTACK_KEY_COUNT; i 0) { + if (tryMfk32_moebius(ar_resp[i], &key)) { + PrintAndLog("M-Found Key%s for sector %02d: [%04x%08x]", (ar_resp[i].keytype) ? "B" : "A", ar_resp[i].sector, (uint32_t) (key>>32), (uint32_t) (key &0xFFFFFFFF)); + } + } + }*/ +} + +int usage_hf14_mf1ksim(void) { + PrintAndLog("Usage: hf mf sim h u n i x"); + PrintAndLog("options:"); + PrintAndLog(" h this help"); + PrintAndLog(" u (Optional) UID 4,7 or 10 bytes. If not specified, the UID 4B from emulator memory will be used"); + PrintAndLog(" n (Optional) Automatically exit simulation after blocks have been read by reader. 0 = infinite"); + PrintAndLog(" i (Optional) Interactive, means that console will not be returned until simulation finishes or is aborted"); + PrintAndLog(" x (Optional) Crack, performs the 'reader attack', nr/ar attack against a legitimate reader, fishes out the key(s)"); + PrintAndLog(" e (Optional) set keys found from 'reader attack' to emulator memory (implies x and i)"); + PrintAndLog(" f (Optional) get UIDs to use for 'reader attack' from file 'f ' (implies x and i)"); + PrintAndLog("samples:"); + PrintAndLog(" hf mf sim u 0a0a0a0a"); + PrintAndLog(" hf mf sim u 11223344556677"); + PrintAndLog(" hf mf sim u 112233445566778899AA"); + PrintAndLog(" hf mf sim f uids.txt"); + PrintAndLog(" hf mf sim u 0a0a0a0a e"); + + return 0; +} - if (param_getchar(Cmd, pnr) == 'x' ) { - //Using a flag to signal interactiveness, least significant bit - flags |= FLAG_NR_AR_ATTACK; +int CmdHF14AMf1kSim(const char *Cmd) { + UsbCommand resp; + uint8_t uid[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + uint8_t exitAfterNReads = 0; + uint8_t flags = 0; + int uidlen = 0; + uint8_t pnr = 0; + bool setEmulatorMem = false; + bool attackFromFile = false; + FILE *f; + char filename[FILE_PATH_SIZE]; + memset(filename, 0x00, sizeof(filename)); + int len = 0; + char buf[64]; + + uint8_t cmdp = 0; + bool errors = false; + + while(param_getchar(Cmd, cmdp) != 0x00) { + switch(param_getchar(Cmd, cmdp)) { + case 'e': + case 'E': + setEmulatorMem = true; + //implies x and i + flags |= FLAG_INTERACTIVE; + flags |= FLAG_NR_AR_ATTACK; + cmdp++; + break; + case 'f': + case 'F': + len = param_getstr(Cmd, cmdp+1, filename); + if (len < 1) { + PrintAndLog("error no filename found"); + return 0; + } + attackFromFile = true; + //implies x and i + flags |= FLAG_INTERACTIVE; + flags |= FLAG_NR_AR_ATTACK; + cmdp += 2; + break; + case 'h': + case 'H': + return usage_hf14_mf1ksim(); + case 'i': + case 'I': + flags |= FLAG_INTERACTIVE; + cmdp++; + break; + case 'n': + case 'N': + exitAfterNReads = param_get8(Cmd, pnr+1); + cmdp += 2; + break; + case 'u': + case 'U': + param_gethex_ex(Cmd, cmdp+1, uid, &uidlen); + switch(uidlen) { + case 20: flags = FLAG_10B_UID_IN_DATA; break; //not complete + case 14: flags = FLAG_7B_UID_IN_DATA; break; + case 8: flags = FLAG_4B_UID_IN_DATA; break; + default: return usage_hf14_mf1ksim(); + } + cmdp += 2; + break; + case 'x': + case 'X': + flags |= FLAG_NR_AR_ATTACK; + cmdp++; + break; + default: + PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + if(errors) break; } - PrintAndLog(" uid:%s, numreads:%d, flags:%d (0x%02x) ", - flags & FLAG_4B_UID_IN_DATA ? sprint_hex(uid,4): - flags & FLAG_7B_UID_IN_DATA ? sprint_hex(uid,7): "N/A" - , exitAfterNReads, flags,flags); + //Validations + if(errors) return usage_hf14_mf1ksim(); + //get uid from file + if (attackFromFile) { + int count = 0; + // open file + f = fopen(filename, "r"); + if (f == NULL) { + PrintAndLog("File %s not found or locked", filename); + return 1; + } + PrintAndLog("Loading file and simulating. Press keyboard to abort"); + while(!feof(f) && !ukbhit()){ + memset(buf, 0, sizeof(buf)); + memset(uid, 0, sizeof(uid)); - UsbCommand c = {CMD_SIMULATE_MIFARE_CARD, {flags, exitAfterNReads,0}}; - memcpy(c.d.asBytes, uid, sizeof(uid)); - SendCommand(&c); + if (fgets(buf, sizeof(buf), f) == NULL) { + if (count > 0) break; + + PrintAndLog("File reading error."); + fclose(f); + return 2; + } + if(!strlen(buf) && feof(f)) break; + + uidlen = strlen(buf)-1; + switch(uidlen) { + case 20: flags |= FLAG_10B_UID_IN_DATA; break; //not complete + case 14: flags |= FLAG_7B_UID_IN_DATA; break; + case 8: flags |= FLAG_4B_UID_IN_DATA; break; + default: + PrintAndLog("uid in file wrong length at %d (length: %d) [%s]",count, uidlen, buf); + fclose(f); + return 2; + } - if(flags & FLAG_INTERACTIVE) - { - UsbCommand resp; - PrintAndLog("Press pm3-button 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... " - } - //got a response - if (flags & FLAG_NR_AR_ATTACK) { - typedef struct { - uint32_t cuid; - uint8_t sector; - uint8_t keytype; - uint32_t nonce; - uint32_t ar; - uint32_t nr; - uint32_t nonce2; - uint32_t ar2; - uint32_t nr2; - } nonces_t; - nonces_t ar_resp[4]; - //uint32_t ar_responses[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - uint64_t key = 0; - //uint64_t keyB = 0; - //uint8_t arnr_len = 8; - memcpy (ar_resp, resp.d.asBytes, sizeof(ar_resp)); + for (uint8_t i = 0; i < uidlen; i += 2) { + sscanf(&buf[i], "%02x", (unsigned int *)&uid[i / 2]); + } - for (uint8_t i = 0; i<4; i++) { - if (ar_resp[i].ar2 > 0) { - key = mfkey32(ar_resp[i].cuid,ar_resp[i].nonce,ar_resp[i].ar,ar_resp[i].nr,ar_resp[i].ar2,ar_resp[i].nr2); - if (key>0) { - PrintAndLog("\nFound Key%s for sector %d: [%04x%08x]", (i<2) ? "A" : "B", ar_resp[i].sector, (uint32_t) (key>>32), (uint32_t) (key &0xFFFFFFFF)); - //set emulator memory for key - } - } + PrintAndLog("mf 1k sim uid: %s, numreads:%d, flags:%d (0x%02x) - press button to abort", + flags & FLAG_4B_UID_IN_DATA ? sprint_hex(uid,4): + flags & FLAG_7B_UID_IN_DATA ? sprint_hex(uid,7): + flags & FLAG_10B_UID_IN_DATA ? sprint_hex(uid,10): "N/A" + , exitAfterNReads, flags, flags); + + UsbCommand c = {CMD_SIMULATE_MIFARE_CARD, {flags, exitAfterNReads,0}}; + memcpy(c.d.asBytes, uid, sizeof(uid)); + clearCommandBuffer(); + SendCommand(&c); + + 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... " } - /* - if (ar_resp[1] && ar_responses[2] && ar_responses[3] && ar_responses[6] && ar_responses[7]) { - keyA = mfkey32(ar_responses[0],ar_responses[1],ar_responses[2],ar_responses[3],ar_responses[6],ar_responses[7]); - if (keyA>0) { - PrintAndLog("\nFound KeyA: [%04x%08x]\n\n", (uint32_t) (keyA>>32), (uint32_t) (keyA &0xFFFFFFFF)); - //set emulator memory for key - } else { - keyA = mfkey32(ar_responses[0],ar_responses[1],ar_responses[2],ar_responses[3],ar_responses[6],ar_responses[7]); - if (keyA>0) { - PrintAndLog("\nFound KeyA: [%04x%08x]\n\n", (uint32_t) (keyA>>32), (uint32_t) (keyA &0xFFFFFFFF)); - //set emulator memory for key - } - } - } else { - PrintAndLog("keyA response error: %d %d %d %d %d",ar_responses[1] , ar_responses[2] , ar_responses[3] , ar_responses[6] , ar_responses[7]); + //got a response + nonces_t ar_resp[ATTACK_KEY_COUNT*2]; + memcpy(ar_resp, resp.d.asBytes, sizeof(ar_resp)); + readerAttack(ar_resp, setEmulatorMem); + if ((bool)resp.arg[1]) { + PrintAndLog("Device button pressed - quitting"); + fclose(f); + return 4; } - if (ar_responses[1] && ar_responses[2+arnr_len] && ar_responses[3+arnr_len] && ar_responses[6+arnr_len] && ar_responses[7+arnr_len]) { - keyB = mfkey32(ar_responses[0],ar_responses[1],ar_responses[2+arnr_len],ar_responses[3+arnr_len],ar_responses[6+arnr_len],ar_responses[7+arnr_len]); - if (keyB>0) { - PrintAndLog("\nFound KeyB: [%04x%08x]\n\n", (uint32_t) (keyB>>32), (uint32_t) (keyB & 0xFFFFFFFF)); - //set emulator memory for key - } + count++; + } + fclose(f); + } else { //not from file + + PrintAndLog("mf 1k sim uid: %s, numreads:%d, flags:%d (0x%02x) ", + flags & FLAG_4B_UID_IN_DATA ? sprint_hex(uid,4): + flags & FLAG_7B_UID_IN_DATA ? sprint_hex(uid,7): + flags & FLAG_10B_UID_IN_DATA ? sprint_hex(uid,10): "N/A" + , exitAfterNReads, flags, flags); + + UsbCommand c = {CMD_SIMULATE_MIFARE_CARD, {flags, exitAfterNReads,0}}; + memcpy(c.d.asBytes, uid, sizeof(uid)); + clearCommandBuffer(); + SendCommand(&c); + + if(flags & FLAG_INTERACTIVE) { + PrintAndLog("Press pm3-button 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... " } - if (keyA || keyB) { - //TODO retry sim with new keys in emulator memory? (somehow flag to check that to see if new key has successful auth now?) - // to validate key is correct + //got a response + if (flags & FLAG_NR_AR_ATTACK) { + nonces_t ar_resp[ATTACK_KEY_COUNT*2]; + memcpy(ar_resp, resp.d.asBytes, sizeof(ar_resp)); + readerAttack(ar_resp, setEmulatorMem); } - */ } } - + return 0; }