From bbd118760ba7c244d64b8380de0072c6f95a6113 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Fri, 24 Jun 2016 23:43:53 -0400 Subject: [PATCH] allow mf1k reader attack from file full of UIDs also add UID to stats.txt collection. --- client/cmdhfmf.c | 349 ++++++++++++++++++++++------------- client/nonce2key/nonce2key.c | 4 +- 2 files changed, 226 insertions(+), 127 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index c565a7cf..05202ac5 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1016,7 +1016,82 @@ int CmdHF14AMfChk(const char *Cmd) return 0; } -int usage_hf14_mf1ksim(void){ +void readerAttack(nonces_t ar_resp[], bool setEmulatorMem) { + #define ATTACK_KEY_COUNT 8 + uint64_t key = 0; + typedef struct { + uint64_t keyA; + uint32_t security; + 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("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) { + //PrintAndLog ("block %d, keyA:%04x%08x, keyb:%04x%08x",stSector[i]*4+3, (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)); + 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); + } + } + } + //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"); @@ -1025,157 +1100,181 @@ int usage_hf14_mf1ksim(void){ 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"); + PrintAndLog(" f (Optional) get UIDs to use for 'reader attack' from file 'f '"); PrintAndLog("samples:"); PrintAndLog(" hf mf sim u 0a0a0a0a"); PrintAndLog(" hf mf sim u 11223344556677"); - //PrintAndLog(" hf mf sim u 112233445566778899AA"); + PrintAndLog(" hf mf sim u 112233445566778899AA"); return 0; } -int CmdHF14AMf1kSim(const char *Cmd) -{ - #define ATTACK_KEY_COUNT 8 +int CmdHF14AMf1kSim(const char *Cmd) { 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 uidBuffer[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; + 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; + 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; + } + //Validations + if(errors) return usage_hf14_mf1ksim(); - char cmdp = param_getchar(Cmd, pnr); + // attack from file implies nr ar attack... + if (!(flags & FLAG_NR_AR_ATTACK) && attackFromFile) flags |= FLAG_NR_AR_ATTACK; - if (cmdp == 'h' || cmdp == 'H') return usage_hf14_mf1ksim(); + UsbCommand c = {CMD_SIMULATE_MIFARE_CARD, {flags, exitAfterNReads,0}}; + UsbCommand resp; - if (cmdp == 'u' || cmdp == 'U') { - param_gethex_ex(Cmd, pnr+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(); + //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; } - pnr +=2; - } - - cmdp = param_getchar(Cmd, pnr); - if (cmdp == 'n' || cmdp == 'N') { - exitAfterNReads = param_get8(Cmd, pnr+1); - pnr += 2; - } + while(!feof(f)){ + memset(buf, 0, sizeof(buf)); + memset(uidBuffer, 0, sizeof(uidBuffer)); - cmdp = param_getchar(Cmd, pnr); - if (cmdp == 'i' || cmdp == 'I' ) { - flags |= FLAG_INTERACTIVE; - pnr++; - } + if (fgets(buf, sizeof(buf), f) == NULL) { + if (count > 0) break; + + PrintAndLog("File reading error."); + fclose(f); + return 2; + } + + if (strlen(buf) < uidlen) { + if(strlen(buf) && feof(f)) + break; + PrintAndLog("File content error. Block data must include %d HEX symbols", uidlen); + fclose(f); + return 2; + } + + for (uint8_t i = 0; i < uidlen; i += 2) { + sscanf(&buf[i], "%02x", (unsigned int *)&uidBuffer[i / 2]); + } + + 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); + + memcpy(c.d.asBytes, uid, sizeof(uid)); + clearCommandBuffer(); + SendCommand(&c); - cmdp = param_getchar(Cmd, pnr); - if (cmdp == 'x' || cmdp == 'X') { - flags |= FLAG_NR_AR_ATTACK; - pnr++; - } + 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... " + } + //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); + } + } - cmdp = param_getchar(Cmd, pnr); - if (cmdp == 'e' || cmdp == 'E') { - setEmulatorMem = true; - } + count++; + } + fclose(f); + } else { - PrintAndLog(" uid:%s, numreads:%d, flags:%d (0x%02x) ", + 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): "N/A" - , exitAfterNReads, flags,flags); + 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); + memcpy(c.d.asBytes, uid, sizeof(uid)); + clearCommandBuffer(); + SendCommand(&c); - UsbCommand c = {CMD_SIMULATE_MIFARE_CARD, {flags, exitAfterNReads,0}}; - memcpy(c.d.asBytes, uid, sizeof(uid)); - clearCommandBuffer(); - SendCommand(&c); - - 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) { - nonces_t ar_resp[ATTACK_KEY_COUNT*2]; - uint64_t key = 0; - memcpy (ar_resp, resp.d.asBytes, sizeof(ar_resp)); - typedef struct { - uint64_t keyA; - uint32_t security; - 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("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) { - //PrintAndLog ("block %d, keyA:%04x%08x, keyb:%04x%08x",stSector[i]*4+3, (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)); - 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 1; - } - - UsbCommand c = {CMD_MIFARE_EML_MEMSET, {(stSector[i]*4+3), 1, 0}}; - memcpy(c.d.asBytes, memBlock, 16); - 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... " } - //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)); - } - } + //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; } diff --git a/client/nonce2key/nonce2key.c b/client/nonce2key/nonce2key.c index fcf34a73..942ef78b 100644 --- a/client/nonce2key/nonce2key.c +++ b/client/nonce2key/nonce2key.c @@ -192,7 +192,7 @@ bool mfkey32(nonces_t data, uint64_t *outputkey) { PrintAndLog("Could not create file name stats.txt"); return 1; } - fprintf(fout, "mfkey32,%d,%d,%s,%04x%08x,%.0Lf\r\n",counter,data.sector,(data.keytype) ? "B" : "A", (uint32_t)(outkey>>32) & 0xFFFF,(uint32_t)(outkey&0xFFFFFFFF),(long double)t1); + fprintf(fout, "mfkey32,%d,%08x,%d,%s,%04x%08x,%.0Lf\r\n", counter, data.cuid, data.sector, (data.keytype) ? "B" : "A", (uint32_t)(outkey>>32) & 0xFFFF,(uint32_t)(outkey&0xFFFFFFFF),(long double)t1); fclose(fout); return isSuccess; } @@ -243,7 +243,7 @@ bool tryMfk32_moebius(nonces_t data, uint64_t *outputkey) { PrintAndLog("Could not create file name stats.txt"); return 1; } - fprintf(fout, "moebius,%d,%d,%s,%04x%08x,%0.Lf\r\n",counter,data.sector, (data.keytype) ? "B" : "A", (uint32_t) (outkey>>32),(uint32_t)(outkey&0xFFFFFFFF),(long double)t1); + fprintf(fout, "moebius,%d,%08x,%d,%s,%04x%08x,%0.Lf\r\n", counter, data.cuid, data.sector, (data.keytype) ? "B" : "A", (uint32_t) (outkey>>32),(uint32_t)(outkey&0xFFFFFFFF),(long double)t1); fclose(fout); return isSuccess; } -- 2.39.2