FIX: 'hf 14a sim x' - this fixes the error with using moebius attack and sim. Updating the nonce variable doesn't change the premodulated response. And it should update everytime it gets a command. One concering issue is that this takes time. Successfully works with two PM3. One acting reader, another sim.

This commit is contained in:
iceman1001 2017-01-29 11:29:15 +01:00
commit 7e735c1398
3 changed files with 70 additions and 64 deletions

View file

@ -1058,12 +1058,7 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data) {
if(!GetIso14443aCommandFromReader(receivedCmd, receivedCmdPar, &len)) { if(!GetIso14443aCommandFromReader(receivedCmd, receivedCmdPar, &len)) {
DbpString("Button press"); DbpString("Button press");
break; break;
} }
// incease nonce at every command recieved
nonce = prand();
num_to_bytes(nonce, 4, response5);
p_response = NULL; p_response = NULL;
// Okay, look at the command now. // Okay, look at the command now.
@ -1158,6 +1153,12 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data) {
EmSendCmdEx(emdata, sizeof(emdata), false); EmSendCmdEx(emdata, sizeof(emdata), false);
p_response = NULL; p_response = NULL;
} else { } else {
// incease nonce at every command recieved. this is time consuming.
nonce = prand();
num_to_bytes(nonce, 4, response5);
prepare_tag_modulation(&responses[5], DYNAMIC_MODULATION_BUFFER_SIZE);
cardAUTHSC = receivedCmd[1] / 4; // received block num cardAUTHSC = receivedCmd[1] / 4; // received block num
cardAUTHKEY = receivedCmd[0] - 0x60; cardAUTHKEY = receivedCmd[0] - 0x60;
p_response = &responses[5]; order = 7; p_response = &responses[5]; order = 7;
@ -1173,7 +1174,7 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data) {
LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE); LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
uint32_t nr = bytes_to_num(receivedCmd,4); uint32_t nr = bytes_to_num(receivedCmd,4);
uint32_t ar = bytes_to_num(receivedCmd+4,4); uint32_t ar = bytes_to_num(receivedCmd+4,4);
// Collect AR/NR per keytype & sector // Collect AR/NR per keytype & sector
if ( (flags & FLAG_NR_AR_ATTACK) == FLAG_NR_AR_ATTACK ) { if ( (flags & FLAG_NR_AR_ATTACK) == FLAG_NR_AR_ATTACK ) {
@ -1279,8 +1280,8 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data) {
dynamic_response_info.response_n = 2; dynamic_response_info.response_n = 2;
} break; } break;
case 0xaa: case 0xAA:
case 0xbb: { case 0xBB: {
dynamic_response_info.response[0] = receivedCmd[0] ^ 0x11; dynamic_response_info.response[0] = receivedCmd[0] ^ 0x11;
dynamic_response_info.response_n = 2; dynamic_response_info.response_n = 2;
} break; } break;
@ -1313,7 +1314,7 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data) {
dynamic_response_info.response[1] = receivedCmd[1]; dynamic_response_info.response[1] = receivedCmd[1];
// Add CRC bytes, always used in ISO 14443A-4 compliant cards // Add CRC bytes, always used in ISO 14443A-4 compliant cards
AppendCrc14443a(dynamic_response_info.response,dynamic_response_info.response_n); AppendCrc14443a(dynamic_response_info.response, dynamic_response_info.response_n);
dynamic_response_info.response_n += 2; dynamic_response_info.response_n += 2;
if (prepare_tag_modulation(&dynamic_response_info,DYNAMIC_MODULATION_BUFFER_SIZE) == false) { if (prepare_tag_modulation(&dynamic_response_info,DYNAMIC_MODULATION_BUFFER_SIZE) == false) {
@ -1333,7 +1334,7 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data) {
// comment this limit if you want to simulation longer // comment this limit if you want to simulation longer
if (!tracing) { if (!tracing) {
Dbprintf("Trace Full. Simulation stopped."); DbpString("Trace Full. Simulation stopped.");
break; break;
} }
// comment this limit if you want to simulation longer // comment this limit if you want to simulation longer
@ -1366,9 +1367,10 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data) {
set_tracing(FALSE); set_tracing(FALSE);
BigBuf_free_keep_EM(); BigBuf_free_keep_EM();
LED_A_OFF(); LED_A_OFF();
/*
if(flags & FLAG_NR_AR_ATTACK && MF_DBGLEVEL >= 1) { if(flags & FLAG_NR_AR_ATTACK && MF_DBGLEVEL >= 1) {
/*
for ( uint8_t i = 0; i < ATTACK_KEY_COUNT; i++) { for ( uint8_t i = 0; i < ATTACK_KEY_COUNT; i++) {
if (ar_nr_collected[i] == 2) { if (ar_nr_collected[i] == 2) {
Dbprintf("Collected two pairs of AR/NR which can be used to extract %s from reader for sector %d:", (i<ATTACK_KEY_COUNT/2) ? "keyA" : "keyB", ar_nr_resp[i].sector); Dbprintf("Collected two pairs of AR/NR which can be used to extract %s from reader for sector %d:", (i<ATTACK_KEY_COUNT/2) ? "keyA" : "keyB", ar_nr_resp[i].sector);
@ -1382,7 +1384,7 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data) {
); );
} }
} }
*/
for ( uint8_t i = ATTACK_KEY_COUNT; i < ATTACK_KEY_COUNT*2; i++) { for ( uint8_t i = ATTACK_KEY_COUNT; i < ATTACK_KEY_COUNT*2; i++) {
if (ar_nr_collected[i] == 2) { if (ar_nr_collected[i] == 2) {
Dbprintf("Collected two pairs of AR/NR which can be used to extract %s from reader for sector %d:", (i<ATTACK_KEY_COUNT/2) ? "keyA" : "keyB", ar_nr_resp[i].sector); Dbprintf("Collected two pairs of AR/NR which can be used to extract %s from reader for sector %d:", (i<ATTACK_KEY_COUNT/2) ? "keyA" : "keyB", ar_nr_resp[i].sector);
@ -1398,7 +1400,8 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data) {
} }
} }
} }
*/
if (MF_DBGLEVEL >= 4){ if (MF_DBGLEVEL >= 4){
Dbprintf("-[ Wake ups after halt [%d]", happened); Dbprintf("-[ Wake ups after halt [%d]", happened);
Dbprintf("-[ Messages after halt [%d]", happened2); Dbprintf("-[ Messages after halt [%d]", happened2);

View file

@ -1383,62 +1383,64 @@ void readerAttack(nonces_t data[], bool setEmulatorMem, bool verbose) {
printf("enter reader attack\n"); printf("enter reader attack\n");
for (uint8_t i = 0; i < ATTACK_KEY_COUNT; ++i) { for (uint8_t i = 0; i < ATTACK_KEY_COUNT; ++i) {
if (data[i].ar2 > 0) {
// if no-collected data
if (data[i].ar2 == 0) continue;
// We can probably skip this, mfkey32v2 is more reliable. // We can probably skip this, mfkey32v2 is more reliable.
#ifdef HFMF_TRYMFK32 #ifdef HFMF_TRYMFK32
if (tryMfk32(data[i], &key, verbose)) { if (tryMfk32(data[i], &key, verbose)) {
PrintAndLog("Found Key%s for sector %02d: [%012"llx"]" PrintAndLog("Found Key%s for sector %02d: [%012"llx"]"
, (data[i].keytype) ? "B" : "A" , (data[i].keytype) ? "B" : "A"
, data[i].sector , data[i].sector
, key , key
); );
k_sector[i].Key[data[i].keytype] = key; k_sector[i].Key[data[i].keytype] = key;
k_sector[i].foundKey[data[i].keytype] = TRUE; k_sector[i].foundKey[data[i].keytype] = TRUE;
//set emulator memory for keys //set emulator memory for keys
if (setEmulatorMem) { if (setEmulatorMem) {
uint8_t memBlock[16] = {0,0,0,0,0,0, 0xff, 0x0F, 0x80, 0x69, 0,0,0,0,0,0}; uint8_t memBlock[16] = {0,0,0,0,0,0, 0xff, 0x0F, 0x80, 0x69, 0,0,0,0,0,0};
num_to_bytes( k_sector[i].Key[0], 6, memBlock); num_to_bytes( k_sector[i].Key[0], 6, memBlock);
num_to_bytes( k_sector[i].Key[1], 6, memBlock+10); num_to_bytes( k_sector[i].Key[1], 6, memBlock+10);
PrintAndLog("Setting Emulator Memory Block %02d: [%s]" PrintAndLog("Setting Emulator Memory Block %02d: [%s]"
, ((data[i].sector)*4) + 3 , ((data[i].sector)*4) + 3
, sprint_hex( memBlock, sizeof(memBlock)) , sprint_hex( memBlock, sizeof(memBlock))
); );
mfEmlSetMem( memBlock, ((data[i].sector)*4) + 3, 1); mfEmlSetMem( memBlock, ((data[i].sector)*4) + 3, 1);
}
continue;
} }
continue;
}
#endif #endif
//moebius attack
if (tryMfk32_moebius(data[i+ATTACK_KEY_COUNT], &key, verbose)) { //moebius attack
uint8_t sectorNum = data[i+ATTACK_KEY_COUNT].sector; if (tryMfk32_moebius(data[i+ATTACK_KEY_COUNT], &key, verbose)) {
uint8_t keyType = data[i+ATTACK_KEY_COUNT].keytype; uint8_t sectorNum = data[i+ATTACK_KEY_COUNT].sector;
uint8_t keyType = data[i+ATTACK_KEY_COUNT].keytype;
PrintAndLog("M-Found Key%s for sector %02d: [%012"llx"]" PrintAndLog("Found Key%s for sector %02d: [%012"llx"]"
, keyType ? "B" : "A" , keyType ? "B" : "A"
, sectorNum , sectorNum
, key , key
); );
k_sector[sectorNum].Key[keyType] = key; k_sector[sectorNum].Key[keyType] = key;
k_sector[sectorNum].foundKey[keyType] = TRUE; k_sector[sectorNum].foundKey[keyType] = TRUE;
//set emulator memory for keys //set emulator memory for keys
if (setEmulatorMem) { if (setEmulatorMem) {
uint8_t memBlock[16] = {0,0,0,0,0,0, 0xff, 0x0F, 0x80, 0x69, 0,0,0,0,0,0}; uint8_t memBlock[16] = {0,0,0,0,0,0, 0xff, 0x0F, 0x80, 0x69, 0,0,0,0,0,0};
num_to_bytes( k_sector[sectorNum].Key[0], 6, memBlock); num_to_bytes( k_sector[sectorNum].Key[0], 6, memBlock);
num_to_bytes( k_sector[sectorNum].Key[1], 6, memBlock+10); num_to_bytes( k_sector[sectorNum].Key[1], 6, memBlock+10);
PrintAndLog("Setting Emulator Memory Block %02d: [%s]" //iceman, guessing this will not work so well for 4K tags.
, (sectorNum*4) + 3 PrintAndLog("Setting Emulator Memory Block %02d: [%s]"
, sprint_hex( memBlock, sizeof(memBlock)) , (sectorNum*4) + 3
); , sprint_hex( memBlock, sizeof(memBlock))
mfEmlSetMem( memBlock, (sectorNum*4) + 3, 1); );
} mfEmlSetMem( memBlock, (sectorNum*4) + 3, 1);
continue;
} }
continue;
} }
} }
} }

View file

@ -280,8 +280,9 @@ bool tryMfk32_moebius(nonces_t data, uint64_t *outputkey, bool verbose) {
} }
isSuccess = (counter > 0); isSuccess = (counter > 0);
t1 = clock() - t1; t1 = clock() - t1;
if ( t1 > 0 ) PrintAndLog("Time in mfkey32_moebius: %.0f ticks - possible keys %d", (float)t1, counter); if (verbose) {
if ( t1 > 0 ) PrintAndLog("Time in mfkey32_moebius: %.0f ticks - possible keys %d", (float)t1, counter);
}
*outputkey = ( isSuccess ) ? outkey : 0; *outputkey = ( isSuccess ) ? outkey : 0;
crypto1_destroy(s); crypto1_destroy(s);
return isSuccess; return isSuccess;