when you need to add too much changes at the same time...
fix: 'hf mf hardnested' test cases doesn't need to verify key. add: 'hf mf ' - collect nonces from classic tag. chg: switch_off on armside, a more unified way, so we don't forget to turn of the antenna ... chg: renamed 'hf iclass snoop' into 'hf iclass sniff' in an attempt to make all sniff/snoop commands only SNIFF chg: 'standalone' -> starting the work of moving all standalone mods into a plugin kind of style, in its own folder.
This commit is contained in:
@@ -193,7 +193,7 @@ int usage_hf_iclass_replay(void) {
|
||||
PrintAndLog(" hf iclass replay 00112233");
|
||||
return 0;
|
||||
}
|
||||
int usage_hf_iclass_snoop(void) {
|
||||
int usage_hf_iclass_sniff(void) {
|
||||
PrintAndLog("HELP: Snoops the communication between reader and tag");
|
||||
PrintAndLog("Usage: hf iclass snoop [h]");
|
||||
PrintAndLog("Samples:");
|
||||
@@ -230,10 +230,9 @@ int CmdHFiClassList(const char *Cmd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHFiClassSnoop(const char *Cmd) {
|
||||
int CmdHFiClassSniff(const char *Cmd) {
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
if (cmdp == 'h' || cmdp == 'H') return usage_hf_iclass_snoop();
|
||||
|
||||
if (cmdp == 'h' || cmdp == 'H') return usage_hf_iclass_sniff();
|
||||
UsbCommand c = {CMD_SNOOP_ICLASS};
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
@@ -263,7 +262,7 @@ int CmdHFiClassSim(const char *Cmd) {
|
||||
|
||||
uint8_t numberOfCSNs = 0;
|
||||
if (simType == 2) {
|
||||
UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType,NUM_CSNS}};
|
||||
UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType, NUM_CSNS}};
|
||||
UsbCommand resp = {0};
|
||||
|
||||
/*
|
||||
@@ -325,7 +324,7 @@ int CmdHFiClassSim(const char *Cmd) {
|
||||
}
|
||||
|
||||
uint8_t num_mac_responses = resp.arg[1];
|
||||
PrintAndLog("Mac responses: %d MACs obtained (should be %d)", num_mac_responses,NUM_CSNS);
|
||||
PrintAndLog("Mac responses: %d MACs obtained (should be %d)", num_mac_responses, NUM_CSNS);
|
||||
|
||||
size_t datalen = NUM_CSNS*24;
|
||||
/*
|
||||
@@ -351,7 +350,7 @@ int CmdHFiClassSim(const char *Cmd) {
|
||||
saveFile("iclass_mac_attack", "bin", dump, datalen);
|
||||
free(dump);
|
||||
} else {
|
||||
UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType,numberOfCSNs}};
|
||||
UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType, numberOfCSNs}};
|
||||
memcpy(c.d.asBytes, CSN, 8);
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
@@ -392,7 +391,10 @@ int HFiClassReader(const char *Cmd, bool loop, bool verbose) {
|
||||
}
|
||||
if (readStatus & FLAG_ICLASS_READER_AA) {
|
||||
bool legacy = true;
|
||||
PrintAndLog(" AppIA: %s",sprint_hex(data+8*5,8));
|
||||
PrintAndLog(" AppIA: %s", sprint_hex(data+8*5,8));
|
||||
|
||||
//if ( memcmp(data+8*5, '\xff\xff\xff\xff\xff\xff\xff\xff',8) != 0 )
|
||||
// legacy = false;
|
||||
for (int i = 0; i<8; i++) {
|
||||
if (data[8*5+i] != 0xFF) {
|
||||
legacy = false;
|
||||
@@ -1731,7 +1733,7 @@ static command_t CommandTable[] = {
|
||||
{"readtagfile", CmdHFiClassReadTagFile, 1, "[options..] Display Content from tagfile"},
|
||||
{"replay", CmdHFiClassReader_Replay, 0, "<mac> Read an iClass tag via Reply Attack"},
|
||||
{"sim", CmdHFiClassSim, 0, "[options..] Simulate iClass tag"},
|
||||
{"snoop", CmdHFiClassSnoop, 0, " Eavesdrop iClass communication"},
|
||||
{"sniff", CmdHFiClassSniff, 0, " Eavesdrop iClass communication"},
|
||||
{"writeblk", CmdHFiClass_WriteBlock, 0, "[options..] Authenticate and Write iClass block"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// High frequency iClass support
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef CMDHFICLASS_H__
|
||||
#define CMDHFICLASS_H__
|
||||
|
||||
@@ -55,10 +54,11 @@ extern int CmdHFiClass_ReadBlock(const char *Cmd);
|
||||
extern int CmdHFiClass_TestMac(const char *Cmd);
|
||||
extern int CmdHFiClassManageKeys(const char *Cmd);
|
||||
extern int CmdHFiClass_loclass(const char *Cmd);
|
||||
extern int CmdHFiClassSnoop(const char *Cmd);
|
||||
extern int CmdHFiClassSniff(const char *Cmd);
|
||||
extern int CmdHFiClassSim(const char *Cmd);
|
||||
extern int CmdHFiClassWriteKeyFile(const char *Cmd);
|
||||
extern int CmdHFiClass_WriteBlock(const char *Cmd);
|
||||
|
||||
void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t endblock, size_t filesize);
|
||||
void HFiClassCalcDivKey(uint8_t *CSN, uint8_t *KEY, uint8_t *div_key, bool elite);
|
||||
#endif
|
||||
|
||||
100
client/cmdhfmf.c
100
client/cmdhfmf.c
@@ -1100,14 +1100,16 @@ int CmdHF14AMfNestedHard(const char *Cmd) {
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t key64 = 0;
|
||||
// check if we can authenticate to sector
|
||||
int res = mfCheckKeys(blockNo, keyType, true, 1, key, &key64);
|
||||
if (res) {
|
||||
PrintAndLog("Key is wrong. Can't authenticate to block:%3d key type:%c", blockNo, keyType ? 'B' : 'A');
|
||||
return 3;
|
||||
}
|
||||
|
||||
if ( !know_target_key ) {
|
||||
uint64_t key64 = 0;
|
||||
// check if we can authenticate to sector
|
||||
int res = mfCheckKeys(blockNo, keyType, true, 1, key, &key64);
|
||||
if (res) {
|
||||
PrintAndLog("Key is wrong. Can't authenticate to block:%3d key type:%c", blockNo, keyType ? 'B' : 'A');
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
PrintAndLog("--target block no:%3d, target key type:%c, known target key: 0x%02x%02x%02x%02x%02x%02x%s, file action: %s, Slow: %s, Tests: %d ",
|
||||
trgBlockNo,
|
||||
trgKeyType?'B':'A',
|
||||
@@ -2444,7 +2446,7 @@ int CmdHF14AMfCSave(const char *Cmd) {
|
||||
}
|
||||
|
||||
//needs nt, ar, at, Data to decrypt
|
||||
int CmdHf14MfDecryptBytes(const char *Cmd){
|
||||
int CmdHf14AMfDecryptBytes(const char *Cmd){
|
||||
uint8_t data[50];
|
||||
uint32_t nt = param_get32ex(Cmd,0,0,16);
|
||||
uint32_t ar_enc = param_get32ex(Cmd,1,0,16);
|
||||
@@ -2498,6 +2500,83 @@ int CmdHf14AMfSetMod(const char *Cmd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHF14AMfice(const char *Cmd) {
|
||||
|
||||
uint8_t blockNo = 0;
|
||||
uint8_t keyType = 0;
|
||||
uint8_t trgBlockNo = 0;
|
||||
uint8_t trgKeyType = 1;
|
||||
bool slow = false;
|
||||
bool initialize = true;
|
||||
bool acquisition_completed = false;
|
||||
uint32_t flags = 0;
|
||||
uint32_t total_num_nonces = 0;
|
||||
FILE *fnonces = NULL;
|
||||
UsbCommand resp;
|
||||
|
||||
uint32_t part_limit = 3000;
|
||||
uint32_t limit = param_get32ex(Cmd, 0, 50000, 10);
|
||||
|
||||
printf("Collecting %u nonces \n", limit);
|
||||
|
||||
if ((fnonces = fopen("nonces.bin","wb")) == NULL) {
|
||||
PrintAndLog("Could not create file nonces.bin");
|
||||
return 3;
|
||||
}
|
||||
|
||||
clearCommandBuffer();
|
||||
|
||||
uint64_t t1 = msclock();
|
||||
|
||||
do {
|
||||
if (ukbhit()) {
|
||||
int gc = getchar(); (void)gc;
|
||||
printf("\naborted via keyboard!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
flags = 0;
|
||||
flags |= initialize ? 0x0001 : 0;
|
||||
flags |= slow ? 0x0002 : 0;
|
||||
UsbCommand c = {CMD_MIFARE_ACQUIRE_NONCES, {blockNo + keyType * 0x100, trgBlockNo + trgKeyType * 0x100, flags}};
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 3000)) goto out;
|
||||
if (resp.arg[0]) goto out;
|
||||
|
||||
uint32_t items = resp.arg[2];
|
||||
if (fnonces) {
|
||||
fwrite(resp.d.asBytes, 1, items*4, fnonces);
|
||||
fflush(fnonces);
|
||||
}
|
||||
|
||||
total_num_nonces += items;
|
||||
if ( total_num_nonces > part_limit ) {
|
||||
printf("Total nonces %u\n", total_num_nonces);
|
||||
part_limit += 3000;
|
||||
}
|
||||
|
||||
acquisition_completed = ( total_num_nonces > limit);
|
||||
|
||||
initialize = false;
|
||||
|
||||
} while (!acquisition_completed);
|
||||
|
||||
out:
|
||||
printf("time: %" PRIu64 " seconds\n", (msclock()-t1)/1000);
|
||||
|
||||
if ( fnonces ) {
|
||||
fflush(fnonces);
|
||||
fclose(fnonces);
|
||||
}
|
||||
|
||||
UsbCommand c = {CMD_MIFARE_ACQUIRE_NONCES, {blockNo + keyType * 0x100, trgBlockNo + trgKeyType * 0x100, 4}};
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
{"dbg", CmdHF14AMfDbg, 0, "Set default debug mode"},
|
||||
@@ -2526,8 +2605,9 @@ static command_t CommandTable[] = {
|
||||
{"cgetsc", CmdHF14AMfCGetSc, 0, "Read sector - Magic Chinese card"},
|
||||
{"cload", CmdHF14AMfCLoad, 0, "Load dump into magic Chinese card"},
|
||||
{"csave", CmdHF14AMfCSave, 0, "Save dump from magic Chinese card into file or emulator"},
|
||||
{"decrypt", CmdHf14MfDecryptBytes, 1, "[nt] [ar_enc] [at_enc] [data] - to decrypt snoop or trace"},
|
||||
{"decrypt", CmdHf14AMfDecryptBytes, 1, "[nt] [ar_enc] [at_enc] [data] - to decrypt snoop or trace"},
|
||||
{"setmod", CmdHf14AMfSetMod, 0, "Set MIFARE Classic EV1 load modulation strength"},
|
||||
{"ice", CmdHF14AMfice, 0, "collect Mifare Classic nonces to file"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ void hardnested_print_progress(uint32_t nonces, char *activity, float brute_forc
|
||||
} else {
|
||||
sprintf(brute_force_time_string, "%2.0fd", brute_force_time/(60*60*24));
|
||||
}
|
||||
PrintAndLog(" %7.0f | %7d | %-55s | %15.0f | %5s", (float)total_time/1000.0, nonces, activity, brute_force, brute_force_time_string);
|
||||
PrintAndLog(" %7.0f | %7u | %-55s | %15.0f | %5s", (float)total_time/1000.0, nonces, activity, brute_force, brute_force_time_string);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user