update hf mf sim x attack mode - start 10byte uid..

..support  (some from @iceman1001)
(sim reader attack currently testing std mfkey32 vs mfkey32_moebius
version...)  possibly will remove one later.
This commit is contained in:
marshmellow42 2016-06-24 01:31:27 -04:00
commit c872d8c177
9 changed files with 513 additions and 198 deletions

View file

@ -1016,64 +1016,81 @@ int CmdHF14AMfChk(const char *Cmd)
return 0;
}
int usage_hf14_mf1ksim(void){
PrintAndLog("Usage: hf mf sim [h] u <uid (8,14 hex symbols)> n <numreads> i x");
PrintAndLog("options:");
PrintAndLog(" h this help");
PrintAndLog(" u (Optional) UID 4,7 bytes. If not specified, the UID 4b from emulator memory will be used");
PrintAndLog(" n (Optional) Automatically exit simulation after <numreads> 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");
PrintAndLog("samples:");
PrintAndLog(" hf mf sim u 0a0a0a0a");
PrintAndLog(" hf mf sim u 11223344556677");
//PrintAndLog(" hf mf sim u 112233445566778899AA");
return 0;
}
int CmdHF14AMf1kSim(const char *Cmd)
{
uint8_t uid[7] = {0, 0, 0, 0, 0, 0, 0};
#define ATTACK_KEY_COUNT 8
uint8_t uid[10] = {0, 0, 0, 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 <uid (8 hex symbols)> n <numreads> 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 <numreads> 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;
}
int uidlen = 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;
bool setEmulatorMem = false;
char cmdp = param_getchar(Cmd, pnr);
if (cmdp == 'h' || cmdp == 'H') return usage_hf14_mf1ksim();
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();
}
pnr +=2;
}
if (param_getchar(Cmd, pnr) == 'n') {
exitAfterNReads = param_get8(Cmd,pnr+1);
cmdp = param_getchar(Cmd, pnr);
if (cmdp == 'n' || cmdp == 'N') {
exitAfterNReads = param_get8(Cmd, pnr+1);
pnr += 2;
}
if (param_getchar(Cmd, pnr) == 'i' ) {
//Using a flag to signal interactiveness, least significant bit
cmdp = param_getchar(Cmd, pnr);
if (cmdp == 'i' || cmdp == 'I' ) {
flags |= FLAG_INTERACTIVE;
pnr++;
}
if (param_getchar(Cmd, pnr) == 'x' ) {
//Using a flag to signal interactiveness, least significant bit
cmdp = param_getchar(Cmd, pnr);
if (cmdp == 'x' || cmdp == 'X') {
flags |= FLAG_NR_AR_ATTACK;
}
cmdp = param_getchar(Cmd, pnr);
if (cmdp == 'e' || cmdp == 'E') {
setEmulatorMem = true;
}
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"
flags & FLAG_7B_UID_IN_DATA ? sprint_hex(uid,7): "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)
{
if(flags & FLAG_INTERACTIVE) {
UsbCommand resp;
PrintAndLog("Press pm3-button to abort simulation");
while(! WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
@ -1082,61 +1099,79 @@ int CmdHF14AMf1kSim(const char *Cmd)
}
//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};
nonces_t ar_resp[ATTACK_KEY_COUNT*2];
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<4; i++) {
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<ATTACK_KEY_COUNT; 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
}
}
}
/*
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
//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 %d: [%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; ii<ATTACK_KEY_COUNT; ii++) {
if (key_cnt[ii]==0 || stSector[ii]==ar_resp[i].sector) {
if (ar_resp[i].keytype==0) {
//keyA
sector_trailer[ii].keyA = key;
stSector[ii] = ar_resp[i].sector;
key_cnt[ii]++;
break;
} else {
//keyB
sector_trailer[ii].keyB = key;
stSector[ii] = ar_resp[i].sector;
key_cnt[ii]++;
break;
}
}
}
}
}
} 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]);
}
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
//set emulator memory for keys
if (setEmulatorMem) {
for (uint8_t i = 0; i<ATTACK_KEY_COUNT; i++) {
if (key_cnt[i]>0) {
//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("%s",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 (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
//moebius attack
for (uint8_t i = ATTACK_KEY_COUNT; i<ATTACK_KEY_COUNT*2; i++) {
if (ar_resp[i].ar2 > 0) {
if (tryMfk32_moebius(ar_resp[i], &key)) {
PrintAndLog("M-Found Key%s for sector %d: [%04x%08x]", (ar_resp[i].keytype) ? "B" : "A", ar_resp[i].sector, (uint32_t) (key>>32), (uint32_t) (key &0xFFFFFFFF));
}
}
}
*/
}
}