Merge pull request #523 from Proxmark/iceman1001-patch-2

ADD: 'hf iclass chk'
This commit is contained in:
marshmellow42 2017-12-16 11:09:48 -05:00 committed by GitHub
commit 5421396e7e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -14,6 +14,7 @@
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <ctype.h>
#include "iso14443crc.h" // Can also be used for iClass, using 0xE012 as CRC-type
#include "data.h"
#include "proxmark3.h"
@ -32,6 +33,7 @@
#include "protocols.h"
#include "usb_cmd.h"
#include "cmdhfmfu.h"
#include "util_posix.h"
static int CmdHelp(const char *Cmd);
@ -51,6 +53,14 @@ typedef struct iclass_block {
uint8_t d[8];
} iclass_block_t;
int usage_hf_iclass_chk(void) {
PrintAndLog("Usage: hf iclass chk [h] <f (*.dic)>");
PrintAndLog("Options:");
PrintAndLog("h Show this help");
PrintAndLog("f <filename> Dictionary file with default iclass keys");
return 0;
}
int xorbits_8(uint8_t val) {
uint8_t res = val ^ (val >> 1); //1st pass
res = res ^ (res >> 1); // 2nd pass
@ -531,7 +541,7 @@ static bool select_and_auth(uint8_t *KEY, uint8_t *MAC, uint8_t *div_key, bool u
memcpy(div_key, KEY, 8);
else
HFiClassCalcDivKey(CSN, KEY, div_key, elite);
PrintAndLog("Authing with %s: %02x%02x%02x%02x%02x%02x%02x%02x", rawkey ? "raw key" : "diversified key", div_key[0],div_key[1],div_key[2],div_key[3],div_key[4],div_key[5],div_key[6],div_key[7]);
if (verbose) PrintAndLog("Authing with %s: %02x%02x%02x%02x%02x%02x%02x%02x", rawkey ? "raw key" : "diversified key", div_key[0],div_key[1],div_key[2],div_key[3],div_key[4],div_key[5],div_key[6],div_key[7]);
doMAC(CCNR, div_key, MAC);
UsbCommand resp;
@ -541,12 +551,12 @@ static bool select_and_auth(uint8_t *KEY, uint8_t *MAC, uint8_t *div_key, bool u
SendCommand(&d);
if (!WaitForResponseTimeout(CMD_ACK,&resp,4500))
{
PrintAndLog("Auth Command execute timeout");
if (verbose) PrintAndLog("Auth Command execute timeout");
return false;
}
uint8_t isOK = resp.arg[0] & 0xff;
if (!isOK) {
PrintAndLog("Authentication error");
if (verbose) PrintAndLog("Authentication error");
return false;
}
return true;
@ -1699,10 +1709,131 @@ int CmdHFiClassManageKeys(const char *Cmd) {
return 0;
}
int CmdHFiClassCheckKeys(const char *Cmd) {
char ctmp = 0x00;
ctmp = param_getchar(Cmd, 0);
if (ctmp == 'h' || ctmp == 'H') return usage_hf_iclass_chk();
uint8_t mac[4] = {0x00,0x00,0x00,0x00};
uint8_t key[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
uint8_t div_key[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
// elite key, raw key, standard key
bool elite = false;
bool rawkey = false;
bool found_debit = false;
bool found_credit = false;
FILE * f;
char filename[FILE_PATH_SIZE] = {0};
char buf[17];
uint8_t *keyBlock = NULL, *p;
int keyitems = 0, keycnt = 0;
// May be a dictionary file
if ( param_getstr(Cmd, 1, filename, sizeof(filename)) >= FILE_PATH_SIZE ) {
PrintAndLog("File name too long");
free(keyBlock);
return 2;
}
if ( !(f = fopen( filename , "r")) ) {
PrintAndLog("File: %s: not found or locked.", filename);
free(keyBlock);
return 1;
}
while( fgets(buf, sizeof(buf), f) ){
if (strlen(buf) < 16 || buf[15] == '\n')
continue;
while (fgetc(f) != '\n' && !feof(f)) ; //goto next line
if( buf[0]=='#' ) continue; //The line start with # is comment, skip
if (!isxdigit(buf[0])){
PrintAndLog("File content error. '%s' must include 16 HEX symbols",buf);
continue;
}
buf[16] = 0;
p = realloc(keyBlock, 8 * (keyitems += 64));
if (!p) {
PrintAndLog("Cannot allocate memory for default keys");
free(keyBlock);
fclose(f);
return 2;
}
keyBlock = p;
memset(keyBlock + 8 * keycnt, 0, 8);
num_to_bytes(strtoull(buf, NULL, 16), 8, keyBlock + 8 * keycnt);
//PrintAndLog("check key[%2d] %016" PRIx64, keycnt, bytes_to_num(keyBlock + 8*keycnt, 8));
keycnt++;
memset(buf, 0, sizeof(buf));
}
fclose(f);
PrintAndLog("Loaded %2d keys from %s", keycnt, filename);
// time
uint64_t t1 = msclock();
for (uint32_t c = 0; c < keycnt; c += 1) {
printf("."); fflush(stdout);
if (ukbhit()) {
int gc = getchar(); (void)gc;
printf("\naborted via keyboard!\n");
break;
}
memcpy(key, keyBlock + 8 * c , 8);
// debit key. try twice
for (int foo = 0; foo < 2 && !found_debit; foo++) {
if (!select_and_auth(key, mac, div_key, false, elite, rawkey, false))
continue;
// key found.
PrintAndLog("\n--------------------------------------------------------");
PrintAndLog(" Found AA1 debit key\t\t[%s]", sprint_hex(key, 8));
found_debit = true;
}
// credit key. try twice
for (int foo = 0; foo < 2 && !found_credit; foo++) {
if (!select_and_auth(key, mac, div_key, true, elite, rawkey, false))
continue;
// key found
PrintAndLog("\n--------------------------------------------------------");
PrintAndLog(" Found AA2 credit key\t\t[%s]", sprint_hex(key, 8));
found_credit = true;
}
// both keys found.
if ( found_debit && found_credit )
break;
}
t1 = msclock() - t1;
PrintAndLog("\nTime in iclass checkkeys: %.0f seconds\n", (float)t1/1000.0);
DropField();
free(keyBlock);
PrintAndLog("");
return 0;
}
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"calcnewkey", CmdHFiClassCalcNewKey, 1, "[options..] Calc Diversified keys (blocks 3 & 4) to write new keys"},
{"chk", CmdHFiClassCheckKeys, 0, " Check keys"},
{"clone", CmdHFiClassCloneTag, 0, "[options..] Authenticate and Clone from iClass bin file"},
{"decrypt", CmdHFiClassDecrypt, 1, "[f <fname>] Decrypt tagdump" },
{"dump", CmdHFiClassReader_Dump, 0, "[options..] Authenticate and Dump iClass tag's AA1"},
@ -1723,6 +1854,7 @@ static command_t CommandTable[] =
int CmdHFiClass(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}