From: marshmellow42 <marshmellowrf@gmail.com>
Date: Wed, 2 Dec 2015 22:27:12 +0000 (-0500)
Subject: icemans lf fixes & adjustments + lf t55xx bruteforce
X-Git-Tag: v2.3.0~13^2~6
X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/506672c48bdae1b045bb65c2939656806bc8be50

icemans lf fixes & adjustments + lf t55xx bruteforce

Fix small fskdemod clock bug
---

diff --git a/CHANGELOG.md b/CHANGELOG.md
index a3a0799e..6dfa6384 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,11 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
 ## [unreleased][unreleased]
 
 ### Added
+- `lf t55xx bruteforce <start password> <end password> [i <*.dic>]` - Simple bruteforce attack to find password - (iceman and others)
+- `lf viking clone`- clone viking tag to t55x7 or Q5 from 4byte hex ID input 
+- `lf viking sim`  - sim full viking tag from 4byte hex ID input
+- `lf viking read` - read viking tag and output ID
+- `lf t55xx wipe`  - sets t55xx back to factory defaults
 - Added viking demod to `lf search` (marshmellow)
 - `data askvikingdemod` demod viking id tag from graphbuffer (marshmellow)
 - `lf t55xx resetread` added reset then read command - should allow determining start
@@ -26,6 +31,11 @@ of stream transmissions (marshmellow)
 - Added option c to 'hf list' (mark CRC bytes) (piwi)
 
 ### Changed
+- Adjusted lf awid clone to optionally clone to Q5 tags
+- Adjusted lf t55xx detect to find Q5 tags (t5555) instead of just t55x7
+- Adjusted all lf NRZ demods - works more acurately and consistantly (as long as you have strong signal)
+- Adjusted lf pskindalademod to reduce false positive reads.
+- Small adjustments to psk, nrz, and ask clock detect routines - more reliable.
 - Adjusted lf em410x em410xsim to accept a clock argument
 - Adjusted lf t55xx dump to allow overriding the safety check and warning text (marshmellow)
 - Adjusted lf t55xx write input variables (marshmellow)
diff --git a/armsrc/lfops.c b/armsrc/lfops.c
index 5cdfe834..47fec7c2 100644
--- a/armsrc/lfops.c
+++ b/armsrc/lfops.c
@@ -17,7 +17,7 @@
 #include "lfdemod.h"
 #include "lfsampling.h"
 #include "protocols.h"
-#include "usb_cdc.h" //test
+#include "usb_cdc.h" // for usb_poll_validate_length
 
 /**
  * Function to do a modulation and then get samples.
diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c
index b6ca9209..ab7c79dd 100644
--- a/armsrc/lfsampling.c
+++ b/armsrc/lfsampling.c
@@ -10,7 +10,7 @@
 #include "apps.h"
 #include "util.h"
 #include "string.h"
-
+#include "usb_cdc.h" // for usb_poll_validate_length
 #include "lfsampling.h"
 
 sample_config config = { 1, 8, 1, 95, 0 } ;
@@ -272,7 +272,7 @@ void doT55x7Acquisition(size_t sample_size) {
 	uint8_t curSample = 0;
 	uint8_t lastSample = 0;
 	uint16_t skipCnt = 0;
-	while(!BUTTON_PRESS() && skipCnt<1000) {
+	while(!BUTTON_PRESS() && !usb_poll_validate_length() && skipCnt<1000 && i<bufsize ) {
 		WDT_HIT();
 		if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
 			AT91C_BASE_SSC->SSC_THR = 0x43;
@@ -311,7 +311,6 @@ void doT55x7Acquisition(size_t sample_size) {
 				}
 				// collect samples
 				dest[i++] = curSample;
-				if (i >= bufsize-1) break;
 			}
 		}
 	}
diff --git a/client/cmddata.c b/client/cmddata.c
index ca4fcafc..30546f11 100644
--- a/client/cmddata.c
+++ b/client/cmddata.c
@@ -934,14 +934,14 @@ char *GetFSKType(uint8_t fchigh, uint8_t fclow, uint8_t invert)
 int FSKrawDemod(const char *Cmd, bool verbose)
 {
 	//raw fsk demod  no manchester decoding no start bit finding just get binary from wave
-	//set defaults
-	int rfLen = 0;
-	int invert = 0;
-	int fchigh = 0;
-	int fclow = 0;
+	uint8_t rfLen, invert, fchigh, fclow;
 
+	//set defaults
 	//set options from parameters entered with the command
-	sscanf(Cmd, "%i %i %i %i", &rfLen, &invert, &fchigh, &fclow);
+	rfLen = param_get8ex(Cmd, 0, 0, 10);
+	invert = param_get8ex(Cmd, 1, 0, 10);
+	fchigh = param_get8ex(Cmd, 2, 0, 10);
+	fclow = param_get8ex(Cmd, 3, 0, 10);
 
 	if (strlen(Cmd)>0 && strlen(Cmd)<=2) {
 		 if (rfLen==1){
@@ -955,34 +955,34 @@ int FSKrawDemod(const char *Cmd, bool verbose)
 	if (BitLen==0) return 0;
 	//get field clock lengths
 	uint16_t fcs=0;
-	if (fchigh==0 || fclow == 0){
+	if (!fchigh || !fclow) {
 		fcs = countFC(BitStream, BitLen, 1);
-		if (fcs==0){
-			fchigh=10;
-			fclow=8;
-		}else{
-			fchigh = (fcs >> 8) & 0xFF;
-			fclow = fcs & 0xFF;
+		if (!fcs) {
+			fchigh = 10;
+			fclow = 8;
+		} else {
+			fchigh = (fcs >> 8) & 0x00FF;
+			fclow = fcs & 0x00FF;
 		}
 	}
 	//get bit clock length
-	if (rfLen==0){
+	if (!rfLen){
 		rfLen = detectFSKClk(BitStream, BitLen, fchigh, fclow);
-		if (rfLen == 0) rfLen = 50;
+		if (!rfLen) rfLen = 50;
 	}
-	int size = fskdemod(BitStream,BitLen,(uint8_t)rfLen,(uint8_t)invert,(uint8_t)fchigh,(uint8_t)fclow);
-	if (size>0){
+	int size = fskdemod(BitStream, BitLen, rfLen, invert, fchigh, fclow);
+	if (size > 0){
 		setDemodBuf(BitStream,size,0);
 
 		// Now output the bitstream to the scrollback by line of 16 bits
 		if (verbose || g_debugMode) {
-			PrintAndLog("\nUsing Clock:%d, invert:%d, fchigh:%d, fclow:%d", rfLen, invert, fchigh, fclow);
+			PrintAndLog("\nUsing Clock:%u, invert:%u, fchigh:%u, fclow:%u", rfLen, invert, fchigh, fclow);
 			PrintAndLog("%s decoded bitstream:",GetFSKType(fchigh,fclow,invert));
 			printDemodBuff();
 		}
 
 		return 1;
-	} else{
+	} else {
 		if (g_debugMode) PrintAndLog("no FSK data found");
 	}
 	return 0;
diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c
index 490850f8..7bf2c25c 100644
--- a/client/cmdlft55xx.c
+++ b/client/cmdlft55xx.c
@@ -29,6 +29,7 @@
 #define T55x7_CONFIGURATION_BLOCK 0x00
 #define T55x7_PAGE0 0x00
 #define T55x7_PAGE1 0x01
+#define T55x7_PWD	0x00000010
 #define REGULAR_READ_MODE_BLOCK 0xFF
 
 // Default configuration
@@ -148,11 +149,24 @@ int usage_t55xx_wakup(){
 		PrintAndLog("      lf t55xx wakeup p 11223344  - send wakeup password");
 	return 0;
 }
+int usage_t55xx_bruteforce(){
+	PrintAndLog("Usage: lf t55xx bruteforce <start password> <end password> [i <*.dic>]");
+	PrintAndLog("       password must be 4 bytes (8 hex symbols)");
+	PrintAndLog("Options:");
+	PrintAndLog("     h         - this help");
+	PrintAndLog("     i <*.dic> - loads a default keys dictionary file <*.dic>");
+	PrintAndLog("");
+	PrintAndLog("Examples:");
+	PrintAndLog("       lf t55xx bruteforce aaaaaaaa bbbbbbbb");
+	PrintAndLog("       lf t55xx bruteforce i mykeys.dic");
+	PrintAndLog("");
+	return 0;
+}
 
 static int CmdHelp(const char *Cmd);
 
 void printT5xxHeader(uint8_t page){
-	PrintAndLog("Reading Page %d:", page);	
+	PrintAndLog("Reading Page %d:", page);
 	PrintAndLog("blk | hex data | binary");
 	PrintAndLog("----+----------+---------------------------------");	
 }
@@ -442,7 +456,6 @@ bool tryDetectModulation(){
 	t55xx_conf_block_t tests[15];
 	int bitRate=0;
 	uint8_t fc1 = 0, fc2 = 0, clk=0;
-	save_restoreGB(1);
 
 	if (GetFskClock("", FALSE, FALSE)){ 
 		fskClocks(&fc1, &fc2, &clk, FALSE);
@@ -502,7 +515,7 @@ bool tryDetectModulation(){
 			}
 		}
 		//undo trim from ask
-		save_restoreGB(0);
+		//save_restoreGB(0);
 		clk = GetNrzClock("", FALSE, FALSE);
 		if (clk>0) {
 			if ( NRZrawDemod("0 0 1", FALSE)  && test(DEMOD_NRZ, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
@@ -522,9 +535,9 @@ bool tryDetectModulation(){
 			}
 		}
 		
-		//undo trim from nrz
-		save_restoreGB(0);
+		// allow undo
 		// skip first 160 samples to allow antenna to settle in (psk gets inverted occasionally otherwise)
+		save_restoreGB(1);
 		CmdLtrim("160");
 		clk = GetPskClock("", FALSE, FALSE);
 		if (clk>0) {
@@ -565,8 +578,9 @@ bool tryDetectModulation(){
 				}
 			} // inverse waves does not affect this demod
 		}
+		//undo trim samples
+		save_restoreGB(0);
 	}	
-	save_restoreGB(0);	
 	if ( hits == 1) {
 		config.modulation = tests[0].modulation;
 		config.bitrate = tests[0].bitrate;
@@ -1297,19 +1311,161 @@ int CmdT55xxWipe(const char *Cmd) {
 	return 0;
 }
 
+int CmdT55xxBruteForce(const char *Cmd) {
+
+	// load a default pwd file.
+	char buf[9];
+	char filename[FILE_PATH_SIZE]={0};
+	int keycnt = 0;
+	uint8_t stKeyBlock = 20;
+	uint8_t *keyBlock = NULL, *p;
+	keyBlock = calloc(stKeyBlock, 6);
+	if (keyBlock == NULL) return 1;
+
+	uint32_t start_password = 0x00000000; //start password
+	uint32_t end_password   = 0xFFFFFFFF; //end   password
+	bool found = false;
+
+	char cmdp = param_getchar(Cmd, 0);
+	if (cmdp == 'h' || cmdp == 'H') return usage_t55xx_bruteforce();
+
+	if (cmdp == 'i' || cmdp == 'I') {
+
+		int len = strlen(Cmd+2);
+		if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
+		memcpy(filename, Cmd+2, len);
+
+		FILE * f = fopen( filename , "r");
+
+		if ( !f ) {
+			PrintAndLog("File: %s: not found or locked.", filename);
+			free(keyBlock);
+			return 1;
+		}
+
+		while( fgets(buf, sizeof(buf), f) ){
+			if (strlen(buf) < 8 || buf[7] == '\n') continue;
+
+			while (fgetc(f) != '\n' && !feof(f)) ;  //goto next line
+
+			//The line start with # is comment, skip
+			if( buf[0]=='#' ) continue;
+
+			if (!isxdigit(buf[0])){
+				PrintAndLog("File content error. '%s' must include 8 HEX symbols", buf);
+				continue;
+			}
+			
+			buf[8] = 0;
+
+			if ( stKeyBlock - keycnt < 2) {
+				p = realloc(keyBlock, 6*(stKeyBlock+=10));
+				if (!p) {
+					PrintAndLog("Cannot allocate memory for defaultKeys");
+					free(keyBlock);
+					return 2;
+				}
+				keyBlock = p;
+			}
+			memset(keyBlock + 4 * keycnt, 0, 4);
+			num_to_bytes(strtoll(buf, NULL, 16), 4, keyBlock + 4*keycnt);
+			PrintAndLog("chk custom pwd[%2d] %08X", keycnt, bytes_to_num(keyBlock + 4*keycnt, 4));
+			keycnt++;
+			memset(buf, 0, sizeof(buf));
+		}
+		fclose(f);
+		
+		if (keycnt == 0) {
+			PrintAndLog("No keys found in file");
+			return 1;
+		}
+		PrintAndLog("Loaded %d keys", keycnt);
+		
+		// loop
+		uint64_t testpwd = 0x00;
+		for (uint16_t c = 0; c < keycnt; ++c ) {
+
+			if (ukbhit()) {
+				getchar();
+				printf("\naborted via keyboard!\n");
+				return 0;
+			}
+
+			testpwd = bytes_to_num(keyBlock + 4*c, 4);
+
+			PrintAndLog("Testing %08X", testpwd);
+
+			if ( !AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, TRUE, testpwd)) {
+				PrintAndLog("Aquireing data from device failed. Quitting");
+				return 0;
+			}
+
+			found = tryDetectModulation();
+
+			if ( found ) {
+				PrintAndLog("Found valid password: [%08X]", testpwd);
+				return 0;
+			}
+		}
+		PrintAndLog("Password NOT found.");
+		return 0;
+	}
+
+	// Try to read Block 7, first :)
+
+	// incremental pwd range search
+	start_password = param_get32ex(Cmd, 0, 0, 16);
+	end_password = param_get32ex(Cmd, 1, 0, 16);
+	
+	if ( start_password >= end_password ) return usage_t55xx_bruteforce();
+
+	PrintAndLog("Search password range [%08X -> %08X]", start_password, end_password);
+
+	uint32_t i = start_password;
+
+	while ((!found) && (i <= end_password)){
+
+	printf(".");
+	fflush(stdout);
+	if (ukbhit()) {
+		getchar();
+		printf("\naborted via keyboard!\n");
+		return 0;
+	}
+
+	if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, TRUE, i)) {
+		PrintAndLog("Aquireing data from device failed. Quitting");
+		return 0;
+	}
+	found = tryDetectModulation();
+	    
+	if (found) break;
+	i++;
+	}
+
+	PrintAndLog("");
+
+	if (found)
+	PrintAndLog("Found valid password: [%08x]", i);
+	else
+	PrintAndLog("Password NOT found. Last tried: [%08x]", --i);
+	return 0;
+}
+
 static command_t CommandTable[] = {
-  {"help",     CmdHelp,           1, "This help"},
-  {"config",   CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"},
-  {"detect",   CmdT55xxDetect,    1, "[1] Try detecting the tag modulation from reading the configuration block."},
-  {"read",     CmdT55xxReadBlock, 0, "b <block> p [password] [o] [1] -- Read T55xx block data. Optional [p password], [override], [page1]"},
-  {"resetread",CmdResetRead,      0, "Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)"},
-  {"write",    CmdT55xxWriteBlock,0, "b <block> d <data> p [password] [1] -- Write T55xx block data. Optional [p password], [page1]"},
-  {"trace",    CmdT55xxReadTrace, 1, "[1] Show T55x7 traceability data (page 1/ blk 0-1)"},
-  {"info",     CmdT55xxInfo,      1, "[1] Show T55x7 configuration data (page 0/ blk 0)"},
-  {"dump",     CmdT55xxDump,      0, "[password] [o] Dump T55xx card block 0-7. Optional [password], [override]"},
-  {"special",  special,           0, "Show block changes with 64 different offsets"},
-  {"wakeup",   CmdT55xxWakeUp,    0, "Send AOR wakeup command"},
-  {"wipe",     CmdT55xxWipe,      0, "Wipe a T55xx tag and set defaults (will destroy any data on tag)"},
+  {"help",      CmdHelp,           1, "This help"},
+	{"bruteforce",CmdT55xxBruteForce,0, "<start password> <end password> [i <*.dic>] Simple bruteforce attack to find password"},
+  {"config",    CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"},
+  {"detect",    CmdT55xxDetect,    1, "[1] Try detecting the tag modulation from reading the configuration block."},
+  {"read",      CmdT55xxReadBlock, 0, "b <block> p [password] [o] [1] -- Read T55xx block data. Optional [p password], [override], [page1]"},
+  {"resetread", CmdResetRead,      0, "Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)"},
+  {"write",     CmdT55xxWriteBlock,0, "b <block> d <data> p [password] [1] -- Write T55xx block data. Optional [p password], [page1]"},
+  {"trace",     CmdT55xxReadTrace, 1, "[1] Show T55x7 traceability data (page 1/ blk 0-1)"},
+  {"info",      CmdT55xxInfo,      1, "[1] Show T55x7 configuration data (page 0/ blk 0)"},
+  {"dump",      CmdT55xxDump,      0, "[password] [o] Dump T55xx card block 0-7. Optional [password], [override]"},
+  {"special",   special,           0, "Show block changes with 64 different offsets"},
+  {"wakeup",    CmdT55xxWakeUp,    0, "Send AOR wakeup command"},
+  {"wipe",      CmdT55xxWipe,      0, "Wipe a T55xx tag and set defaults (will destroy any data on tag)"},
   {NULL, NULL, 0, NULL}
 };
 
diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h
index 424e85ab..56b1b9b7 100644
--- a/client/cmdlft55xx.h
+++ b/client/cmdlft55xx.h
@@ -45,6 +45,7 @@ void Set_t55xx_Config(t55xx_conf_block_t conf);
 
 
 int CmdLFT55XX(const char *Cmd);
+int CmdT55xxBruteForce(const char *Cmd);
 int CmdT55xxSetConfig(const char *Cmd);
 int CmdT55xxReadBlock(const char *Cmd);
 int CmdT55xxWriteBlock(const char *Cmd);