X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/e6432f05795ba0eaf1e34bb47b2a7f87a762de29..99cf19d9e8b450422f61c467751e8570537ab718:/client/cmdhfmf.c

diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c
index aa3b66dc..58d2061a 100644
--- a/client/cmdhfmf.c
+++ b/client/cmdhfmf.c
@@ -9,6 +9,7 @@
 //-----------------------------------------------------------------------------
 
 #include "cmdhfmf.h"
+#include "nonce2key/nonce2key.h"
 
 static int CmdHelp(const char *Cmd);
 
@@ -17,7 +18,7 @@ int CmdHF14AMifare(const char *Cmd)
 	uint32_t uid = 0;
 	uint32_t nt = 0, nr = 0;
 	uint64_t par_list = 0, ks_list = 0, r_key = 0;
-	uint8_t isOK = 0;
+	int16_t isOK = 0;
 	uint8_t keyBlock[8] = {0};
 
 	UsbCommand c = {CMD_READER_MIFARE, {true, 0, 0}};
@@ -25,7 +26,7 @@ int CmdHF14AMifare(const char *Cmd)
 	// message
 	printf("-------------------------------------------------------------------------\n");
 	printf("Executing command. Expected execution time: 25sec on average  :-)\n");
-	printf("Press the key on the proxmark3 device to abort both proxmark3 and client.\n");
+	printf("Press button on the proxmark3 device to abort both proxmark3 and client.\n");
 	printf("-------------------------------------------------------------------------\n");
 
 	
@@ -48,14 +49,19 @@ start:
 		
 		UsbCommand resp;
 		if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
-			isOK  = resp.arg[0] & 0xff;
+			isOK  = resp.arg[0];
 			uid = (uint32_t)bytes_to_num(resp.d.asBytes +  0, 4);
 			nt =  (uint32_t)bytes_to_num(resp.d.asBytes +  4, 4);
 			par_list = bytes_to_num(resp.d.asBytes +  8, 8);
 			ks_list = bytes_to_num(resp.d.asBytes +  16, 8);
 			nr = bytes_to_num(resp.d.asBytes + 24, 4);
 			printf("\n\n");
-			if (!isOK) PrintAndLog("Proxmark can't get statistic info. Execution aborted.\n");
+			switch (isOK) {
+				case -1 : PrintAndLog("Button pressed. Aborted.\n"); break;
+				case -2 : PrintAndLog("Card is not vulnerable to Darkside attack (doesn't send NACK on authentication requests).\n"); break;
+				case -3 : PrintAndLog("Card is not vulnerable to Darkside attack (its random number generator is not predictable).\n"); break;
+				default: ;
+			}
 			break;
 		}
 	}	
@@ -622,8 +628,14 @@ int CmdHF14AMfNested(const char *Cmd)
 	
 	if (cmdp == 'o') {
 		PrintAndLog("--target block no:%3d, target key type:%c ", trgBlockNo, trgKeyType?'B':'A');
-		if (mfnested(blockNo, keyType, key, trgBlockNo, trgKeyType, keyBlock, true)) {
-			PrintAndLog("Nested error.");
+		int16_t isOK = mfnested(blockNo, keyType, key, trgBlockNo, trgKeyType, keyBlock, true);
+		if (isOK) {
+			switch (isOK) {
+				case -1 : PrintAndLog("Error: No response from Proxmark.\n"); break;
+				case -2 : PrintAndLog("Button pressed. Aborted.\n"); break;
+				case -3 : PrintAndLog("Tag isn't vulnerable to Nested Attack (random numbers are not predictable).\n"); break;
+				default : PrintAndLog("Unknown Error.\n");
+			}
 			return 2;
 		}
 		key64 = bytes_to_num(keyBlock, 6);
@@ -696,11 +708,17 @@ int CmdHF14AMfNested(const char *Cmd)
 				for (trgKeyType = 0; trgKeyType < 2; trgKeyType++) { 
 					if (e_sector[sectorNo].foundKey[trgKeyType]) continue;
 					PrintAndLog("-----------------------------------------------");
-					if(mfnested(blockNo, keyType, key, FirstBlockOfSector(sectorNo), trgKeyType, keyBlock, calibrate)) {
-						PrintAndLog("Nested error.\n");
+					int16_t isOK = mfnested(blockNo, keyType, key, FirstBlockOfSector(sectorNo), trgKeyType, keyBlock, calibrate);
+					if(isOK) {
+						switch (isOK) {
+							case -1 : PrintAndLog("Error: No response from Proxmark.\n"); break;
+							case -2 : PrintAndLog("Button pressed. Aborted.\n"); break;
+							case -3 : PrintAndLog("Tag isn't vulnerable to Nested Attack (random numbers are not predictable).\n"); break;
+							default : PrintAndLog("Unknown Error.\n");
+						}
 						free(e_sector);
-						return 2;					}
-					else {
+						return 2;
+					} else {
 						calibrate = false;
 					}
 					
@@ -781,8 +799,8 @@ int CmdHF14AMfChk(const char *Cmd)
 		PrintAndLog("Usage:  hf mf chk <block number>|<*card memory> <key type (A/B/?)> [t|d] [<key (12 hex symbols)>] [<dic (*.dic)>]");
 		PrintAndLog("          * - all sectors");
 		PrintAndLog("card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, <other> - 1K");
-		PrintAndLog("d - write keys to binary file\n");
-		PrintAndLog("t - write keys to emulator memory");
+		PrintAndLog("d - write keys to binary file");
+		PrintAndLog("t - write keys to emulator memory\n");
 		PrintAndLog("      sample: hf mf chk 0 A 1234567890ab keys.dic");
 		PrintAndLog("              hf mf chk *1 ? t");
 		PrintAndLog("              hf mf chk *1 ? d");
@@ -1011,8 +1029,10 @@ int CmdHF14AMf1kSim(const char *Cmd)
 	uint8_t uid[7] = {0, 0, 0, 0, 0, 0, 0};
 	uint8_t exitAfterNReads = 0;
 	uint8_t flags = 0;
-
+	
 	uint8_t cmdp = param_getchar(Cmd, 0);
+
+	clearCommandBuffer();
 	
 	if (cmdp == 'h' || cmdp == 'H') {
 		PrintAndLog("Usage:  hf mf sim  u <uid (8 hex symbols)> n <numreads> i x");
@@ -1063,15 +1083,42 @@ int CmdHF14AMf1kSim(const char *Cmd)
 	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... "
+		
+		uint8_t data[40];
+		uint8_t key[6];
+
+		UsbCommand resp;		
+		while(!ukbhit() ){
+			if ( WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
+				if ( (resp.arg[0] & 0xffff) == CMD_SIMULATE_MIFARE_CARD ){
+					memset(data, 0x00, sizeof(data));
+					memset(key, 0x00, sizeof(key));
+					int len = (resp.arg[1] > sizeof(data)) ? sizeof(data) : resp.arg[1];
+					
+					memcpy(data, resp.d.asBytes, len);
+					
+					uint64_t corr_uid = 0;
+					if ( memcmp(data, "\x00\x00\x00\x00", 4) == 0 ) {
+						corr_uid = (data[3] << 24) | (data[2] << 16) | (data[1] << 8) | data[0];
+					}
+					else {
+						corr_uid |= (uint64_t)data[2] << 48; 
+						corr_uid |= (uint64_t)data[1] << 40; 
+						corr_uid |= (uint64_t)data[0] << 32;
+						corr_uid |= data[7] << 24;
+						corr_uid |= data[6] << 16;
+						corr_uid |= data[5] << 8;
+						corr_uid |= data[4];
+					}
+					tryMfk32(corr_uid, data, key);
+					//tryMfk64(corr_uid, data, key);
+					PrintAndLog("--");
+				}
+			}
 		}
 	}
-	
 	return 0;
 }
 
@@ -1200,9 +1247,9 @@ int CmdHF14AMfELoad(const char *Cmd)
 
 	len = param_getstr(Cmd,nameParamNo,filename);
 	
-	if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
+	if (len > FILE_PATH_SIZE - 4) len = FILE_PATH_SIZE - 4;
 
-	fnameptr += len-4;
+	fnameptr += len;
 
 	sprintf(fnameptr, ".eml"); 
 	
@@ -1299,19 +1346,22 @@ int CmdHF14AMfESave(const char *Cmd)
 
 	len = param_getstr(Cmd,nameParamNo,filename);
 	
-	if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
+	if (len > FILE_PATH_SIZE - 4) len = FILE_PATH_SIZE - 4;
 	
 	// user supplied filename?
 	if (len < 1) {
 		// get filename (UID from memory)
 		if (mfEmlGetMem(buf, 0, 1)) {
 			PrintAndLog("Can\'t get UID from block: %d", 0);
-			sprintf(filename, "dump.eml"); 
+			len = sprintf(fnameptr, "dump");
+			fnameptr += len;
+		}
+		else {
+			for (j = 0; j < 7; j++, fnameptr += 2)
+				sprintf(fnameptr, "%02X", buf[j]);
 		}
-		for (j = 0; j < 7; j++, fnameptr += 2)
-			sprintf(fnameptr, "%02X", buf[j]); 
 	} else {
-		fnameptr += len-4;
+		fnameptr += len;
 	}
 
 	// add file extension
@@ -1572,10 +1622,10 @@ int CmdHF14AMfCLoad(const char *Cmd)
 		return 0;
 	} else {
 		len = strlen(Cmd);
-		if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
+		if (len > FILE_PATH_SIZE - 4) len = FILE_PATH_SIZE - 4;
 
 		memcpy(filename, Cmd, len);
-		fnameptr += len-4;
+		fnameptr += len;
 
 		sprintf(fnameptr, ".eml"); 
 	
@@ -1741,16 +1791,18 @@ int CmdHF14AMfCSave(const char *Cmd) {
 		return 0;
 	} else {
 		len = strlen(Cmd);
-		if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
+		if (len > FILE_PATH_SIZE - 4) len = FILE_PATH_SIZE - 4;
 	
 		if (len < 1) {
 			// get filename
 			if (mfCGetBlock(0, buf, CSETBLOCK_SINGLE_OPER)) {
 				PrintAndLog("Cant get block: %d", 0);
-				return 1;
+				len = sprintf(fnameptr, "dump");
+				fnameptr += len;
+			} else {
+				for (j = 0; j < 7; j++, fnameptr += 2)
+					sprintf(fnameptr, "%02x", buf[j]); 
 			}
-			for (j = 0; j < 7; j++, fnameptr += 2)
-				sprintf(fnameptr, "%02x", buf[j]); 
 		} else {
 			memcpy(filename, Cmd, len);
 			fnameptr += len;