mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-08-20 13:23:25 -07:00
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:
parent
7314995a5a
commit
c872d8c177
9 changed files with 513 additions and 198 deletions
193
client/cmdhfmf.c
193
client/cmdhfmf.c
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue