X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/bce5d24494997238052d7f3fa7a3b89df43bce9f..3d83b58b50a328b2bedd63cb102158a8c43c07ef:/client/cmdhficlass.c?ds=inline diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 03b39021..31f7ba97 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -29,16 +29,17 @@ #include "loclass/ikeys.h" #include "loclass/elite_crack.h" #include "loclass/fileutils.h" +#include "protocols.h" static int CmdHelp(const char *Cmd); int xorbits_8(uint8_t val) { - uint8_t res = val ^ (val >> 1); //1st pass - res = res ^ (res >> 1); // 2nd pass - res = res ^ (res >> 2); // 3rd pass - res = res ^ (res >> 4); // 4th pass - return res & 1; + uint8_t res = val ^ (val >> 1); //1st pass + res = res ^ (res >> 1); // 2nd pass + res = res ^ (res >> 2); // 3rd pass + res = res ^ (res >> 4); // 4th pass + return res & 1; } int CmdHFiClassList(const char *Cmd) @@ -49,77 +50,73 @@ int CmdHFiClassList(const char *Cmd) int CmdHFiClassSnoop(const char *Cmd) { - UsbCommand c = {CMD_SNOOP_ICLASS}; - SendCommand(&c); - return 0; + UsbCommand c = {CMD_SNOOP_ICLASS}; + SendCommand(&c); + return 0; } -#define NUM_CSNS 15 -int CmdHFiClassSim(const char *Cmd) +int usage_hf_iclass_sim() { - uint8_t simType = 0; - uint8_t CSN[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - - if (strlen(Cmd)<1) { - PrintAndLog("Usage: hf iclass sim [0 <CSN>] | x"); + PrintAndLog("Usage: hf iclass sim <option> [CSN]"); PrintAndLog(" options"); PrintAndLog(" 0 <CSN> simulate the given CSN"); PrintAndLog(" 1 simulate default CSN"); - PrintAndLog(" 2 iterate CSNs, gather MACs"); - PrintAndLog(" sample: hf iclass sim 0 031FEC8AF7FF12E0"); - PrintAndLog(" sample: hf iclass sim 2"); + PrintAndLog(" 2 Reader-attack, gather reader responses to extract elite key"); + PrintAndLog(" 3 Full simulation using emulator memory (see 'hf iclass eload')"); + PrintAndLog(" example: hf iclass sim 0 031FEC8AF7FF12E0"); + PrintAndLog(" example: hf iclass sim 2"); + PrintAndLog(" example: hf iclass eload 'tagdump.bin'"); + PrintAndLog(" hf iclass sim 3"); return 0; - } - - simType = param_get8(Cmd, 0); - - if(simType == 0) - { - if (param_gethex(Cmd, 1, CSN, 16)) { - PrintAndLog("A CSN should consist of 16 HEX symbols"); - return 1; - } - PrintAndLog("--simtype:%02x csn:%s", simType, sprint_hex(CSN, 8)); - - } - if(simType > 2) - { - PrintAndLog("Undefined simptype %d", simType); - return 1; - } - uint8_t numberOfCSNs=0; +} +#define NUM_CSNS 15 +int CmdHFiClassSim(const char *Cmd) +{ + uint8_t simType = 0; + uint8_t CSN[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + + if (strlen(Cmd)<1) { + return usage_hf_iclass_sim(); + } + simType = param_get8ex(Cmd, 0, 0, 10); + + if(simType == 0) + { + if (param_gethex(Cmd, 1, CSN, 16)) { + PrintAndLog("A CSN should consist of 16 HEX symbols"); + return usage_hf_iclass_sim(); + } + + PrintAndLog("--simtype:%02x csn:%s", simType, sprint_hex(CSN, 8)); + } + if(simType > 3) + { + PrintAndLog("Undefined simptype %d", simType); + return usage_hf_iclass_sim(); + } + + uint8_t numberOfCSNs=0; if(simType == 2) { UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType,NUM_CSNS}}; UsbCommand resp = {0}; - /*uint8_t csns[8 * NUM_CSNS] = { - 0x00,0x0B,0x0F,0xFF,0xF7,0xFF,0x12,0xE0 , - 0x00,0x13,0x94,0x7e,0x76,0xff,0x12,0xe0 , - 0x2a,0x99,0xac,0x79,0xec,0xff,0x12,0xe0 , - 0x17,0x12,0x01,0xfd,0xf7,0xff,0x12,0xe0 , - 0xcd,0x56,0x01,0x7c,0x6f,0xff,0x12,0xe0 , - 0x4b,0x5e,0x0b,0x72,0xef,0xff,0x12,0xe0 , - 0x00,0x73,0xd8,0x75,0x58,0xff,0x12,0xe0 , - 0x0c,0x90,0x32,0xf3,0x5d,0xff,0x12,0xe0 }; -*/ - - uint8_t csns[8*NUM_CSNS] = { - 0x00, 0x0B, 0x0F, 0xFF, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x04, 0x0E, 0x08, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x09, 0x0D, 0x05, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x0A, 0x0C, 0x06, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x0F, 0x0B, 0x03, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x08, 0x0A, 0x0C, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x0D, 0x09, 0x09, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x0E, 0x08, 0x0A, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x03, 0x07, 0x17, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x3C, 0x06, 0xE0, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x01, 0x05, 0x1D, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x02, 0x04, 0x1E, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x07, 0x03, 0x1B, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x00, 0x02, 0x24, 0xF7, 0xFF, 0x12, 0xE0, - 0x00, 0x05, 0x01, 0x21, 0xF7, 0xFF, 0x12, 0xE0 }; + uint8_t csns[8*NUM_CSNS] = { + 0x00, 0x0B, 0x0F, 0xFF, 0xF7, 0xFF, 0x12, 0xE0, + 0x00, 0x04, 0x0E, 0x08, 0xF7, 0xFF, 0x12, 0xE0, + 0x00, 0x09, 0x0D, 0x05, 0xF7, 0xFF, 0x12, 0xE0, + 0x00, 0x0A, 0x0C, 0x06, 0xF7, 0xFF, 0x12, 0xE0, + 0x00, 0x0F, 0x0B, 0x03, 0xF7, 0xFF, 0x12, 0xE0, + 0x00, 0x08, 0x0A, 0x0C, 0xF7, 0xFF, 0x12, 0xE0, + 0x00, 0x0D, 0x09, 0x09, 0xF7, 0xFF, 0x12, 0xE0, + 0x00, 0x0E, 0x08, 0x0A, 0xF7, 0xFF, 0x12, 0xE0, + 0x00, 0x03, 0x07, 0x17, 0xF7, 0xFF, 0x12, 0xE0, + 0x00, 0x3C, 0x06, 0xE0, 0xF7, 0xFF, 0x12, 0xE0, + 0x00, 0x01, 0x05, 0x1D, 0xF7, 0xFF, 0x12, 0xE0, + 0x00, 0x02, 0x04, 0x1E, 0xF7, 0xFF, 0x12, 0xE0, + 0x00, 0x07, 0x03, 0x1B, 0xF7, 0xFF, 0x12, 0xE0, + 0x00, 0x00, 0x02, 0x24, 0xF7, 0xFF, 0x12, 0xE0, + 0x00, 0x05, 0x01, 0x21, 0xF7, 0xFF, 0x12, 0xE0 }; memcpy(c.d.asBytes, csns, 8*NUM_CSNS); @@ -164,124 +161,124 @@ int CmdHFiClassSim(const char *Cmd) SendCommand(&c); } - return 0; + return 0; } int CmdHFiClassReader(const char *Cmd) { - UsbCommand c = {CMD_READER_ICLASS, {0}}; - SendCommand(&c); - UsbCommand resp; - while(!ukbhit()){ - if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) { - uint8_t isOK = resp.arg[0] & 0xff; - uint8_t * data = resp.d.asBytes; - - PrintAndLog("isOk:%02x", isOK); - if( isOK == 0){ - //Aborted - PrintAndLog("Quitting..."); - return 0; - } - if(isOK > 0) - { - PrintAndLog("CSN: %s",sprint_hex(data,8)); - } - if(isOK >= 1) - { - PrintAndLog("CC: %s",sprint_hex(data+8,8)); - }else{ - PrintAndLog("No CC obtained"); - } - } else { - PrintAndLog("Command execute timeout"); - } - } - - return 0; + UsbCommand c = {CMD_READER_ICLASS, {0}}; + SendCommand(&c); + UsbCommand resp; + while(!ukbhit()){ + if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) { + uint8_t isOK = resp.arg[0] & 0xff; + uint8_t * data = resp.d.asBytes; + + PrintAndLog("isOk:%02x", isOK); + if( isOK == 0){ + //Aborted + PrintAndLog("Quitting..."); + return 0; + } + if(isOK > 0) + { + PrintAndLog("CSN: %s",sprint_hex(data,8)); + } + if(isOK >= 1) + { + PrintAndLog("CC: %s",sprint_hex(data+8,8)); + }else{ + PrintAndLog("No CC obtained"); + } + } else { + PrintAndLog("Command execute timeout"); + } + } + + return 0; } int CmdHFiClassReader_Replay(const char *Cmd) { - uint8_t readerType = 0; - uint8_t MAC[4]={0x00, 0x00, 0x00, 0x00}; + uint8_t readerType = 0; + uint8_t MAC[4]={0x00, 0x00, 0x00, 0x00}; - if (strlen(Cmd)<1) { - PrintAndLog("Usage: hf iclass replay <MAC>"); - PrintAndLog(" sample: hf iclass replay 00112233"); - return 0; - } + if (strlen(Cmd)<1) { + PrintAndLog("Usage: hf iclass replay <MAC>"); + PrintAndLog(" sample: hf iclass replay 00112233"); + return 0; + } - if (param_gethex(Cmd, 0, MAC, 8)) { - PrintAndLog("MAC must include 8 HEX symbols"); - return 1; - } + if (param_gethex(Cmd, 0, MAC, 8)) { + PrintAndLog("MAC must include 8 HEX symbols"); + return 1; + } - UsbCommand c = {CMD_READER_ICLASS_REPLAY, {readerType}}; - memcpy(c.d.asBytes, MAC, 4); - SendCommand(&c); + UsbCommand c = {CMD_READER_ICLASS_REPLAY, {readerType}}; + memcpy(c.d.asBytes, MAC, 4); + SendCommand(&c); - return 0; + return 0; } int CmdHFiClassReader_Dump(const char *Cmd) { - uint8_t readerType = 0; - uint8_t MAC[4]={0x00,0x00,0x00,0x00}; - uint8_t KEY[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - //uint8_t CC_temp[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - uint8_t keytable[128] = {0}; - int elite = 0; - uint8_t *used_key; - int i; - if (strlen(Cmd)<1) - { - PrintAndLog("Usage: hf iclass dump <Key> [e]"); - PrintAndLog(" Key - A 16 byte master key"); - PrintAndLog(" e - If 'e' is specified, the key is interpreted as the 16 byte"); - PrintAndLog(" Custom Key (KCus), which can be obtained via reader-attack"); - PrintAndLog(" See 'hf iclass sim 2'. This key should be on iclass-format"); - PrintAndLog(" sample: hf iclass dump 0011223344556677"); - - - return 0; - } - - if (param_gethex(Cmd, 0, KEY, 16)) - { - PrintAndLog("KEY must include 16 HEX symbols"); - return 1; - } - - if (param_getchar(Cmd, 1) == 'e') - { - PrintAndLog("Elite switch on"); - elite = 1; - - //calc h2 - hash2(KEY, keytable); - printarr_human_readable("keytable", keytable, 128); - - } - - UsbCommand resp; - uint8_t key_sel[8] = {0}; - uint8_t key_sel_p[8] = { 0 }; - - UsbCommand c = {CMD_READER_ICLASS, {0}}; - c.arg[0] = FLAG_ICLASS_READER_ONLY_ONCE| FLAG_ICLASS_READER_GET_CC; - SendCommand(&c); - - - - if (!WaitForResponseTimeout(CMD_ACK,&resp,4500)) - { - PrintAndLog("Command execute timeout"); - return 0; - } + uint8_t readerType = 0; + uint8_t MAC[4]={0x00,0x00,0x00,0x00}; + uint8_t KEY[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + //uint8_t CC_temp[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + uint8_t keytable[128] = {0}; + int elite = 0; + uint8_t *used_key; + int i; + if (strlen(Cmd)<1) + { + PrintAndLog("Usage: hf iclass dump <Key> [e]"); + PrintAndLog(" Key - A 16 byte master key"); + PrintAndLog(" e - If 'e' is specified, the key is interpreted as the 16 byte"); + PrintAndLog(" Custom Key (KCus), which can be obtained via reader-attack"); + PrintAndLog(" See 'hf iclass sim 2'. This key should be on iclass-format"); + PrintAndLog(" sample: hf iclass dump 0011223344556677"); + + + return 0; + } + + if (param_gethex(Cmd, 0, KEY, 16)) + { + PrintAndLog("KEY must include 16 HEX symbols"); + return 1; + } + + if (param_getchar(Cmd, 1) == 'e') + { + PrintAndLog("Elite switch on"); + elite = 1; + + //calc h2 + hash2(KEY, keytable); + printarr_human_readable("keytable", keytable, 128); + + } + + UsbCommand resp; + uint8_t key_sel[8] = {0}; + uint8_t key_sel_p[8] = { 0 }; + + UsbCommand c = {CMD_READER_ICLASS, {0}}; + c.arg[0] = FLAG_ICLASS_READER_ONLY_ONCE| FLAG_ICLASS_READER_GET_CC; + SendCommand(&c); + + + + if (!WaitForResponseTimeout(CMD_ACK,&resp,4500)) + { + PrintAndLog("Command execute timeout"); + return 0; + } uint8_t isOK = resp.arg[0] & 0xff; uint8_t * data = resp.d.asBytes; @@ -325,12 +322,12 @@ int CmdHFiClassReader_Dump(const char *Cmd) PrintAndLog("Hash0, a.k.a diversified key, that is computed using Ksel and stored in the card (Block 3):"); printvar("Div key", div_key, 8); printvar("CC_NR:",CCNR,12); - doMAC(CCNR,12,div_key, MAC); + doMAC(CCNR,div_key, MAC); printvar("MAC", MAC, 4); uint8_t iclass_data[32000] = {0}; - uint8_t iclass_datalen = 0; - uint8_t iclass_blocksFailed = 0;//Set to 1 if dump was incomplete + uint32_t iclass_datalen = 0; + uint32_t iclass_blocksFailed = 0;//Set to 1 if dump was incomplete UsbCommand d = {CMD_READER_ICLASS_REPLAY, {readerType}}; memcpy(d.d.asBytes, MAC, 4); @@ -346,11 +343,11 @@ int CmdHFiClassReader_Dump(const char *Cmd) } if(WaitForResponseTimeout(CMD_ACK,&resp,4500)) { - uint64_t dataLength = resp.arg[0]; + uint32_t dataLength = resp.arg[0]; iclass_blocksFailed |= resp.arg[1]; - if(dataLength > 0) { + PrintAndLog("Got %d bytes data (total so far %d)" ,dataLength,iclass_datalen); memcpy(iclass_data, resp.d.asBytes,dataLength); iclass_datalen += dataLength; }else @@ -366,9 +363,10 @@ int CmdHFiClassReader_Dump(const char *Cmd) //create a preferred filename snprintf(filename, 100,"iclass_tagdump-%02x%02x%02x%02x%02x%02x%02x%02x", CSN[0],CSN[1],CSN[2],CSN[3], - CSN[4],CSN[5],CSN[6],CSN[7]); + CSN[4],CSN[5],CSN[6],CSN[7]); + //Place the div_key in block 3 + memcpy(iclass_data+(3*8), div_key, 8); saveFile(filename,"bin",iclass_data, iclass_datalen ); - } //Aaaand we're finished return 0; @@ -377,85 +375,257 @@ int CmdHFiClassReader_Dump(const char *Cmd) } - return 0; + return 0; +} + +int hf_iclass_eload_usage() +{ + PrintAndLog("Loads iclass tag-dump into emulator memory on device"); + PrintAndLog("Usage: hf iclass eload f <filename>"); + PrintAndLog(""); + PrintAndLog("Example: hf iclass eload f iclass_tagdump-aa162d30f8ff12f1.bin"); + return 0; + +} + +int iclassEmlSetMem(uint8_t *data, int blockNum, int blocksCount) { + UsbCommand c = {CMD_MIFARE_EML_MEMSET, {blockNum, blocksCount, 0}}; + memcpy(c.d.asBytes, data, blocksCount * 16); + SendCommand(&c); + return 0; +} +int CmdHFiClassELoad(const char *Cmd) +{ + + char opt = param_getchar(Cmd, 0); + if (strlen(Cmd)<1 || opt == 'h') + return hf_iclass_eload_usage(); + + //File handling and reading + FILE *f; + char filename[FILE_PATH_SIZE]; + if(opt == 'f' && param_getstr(Cmd, 1, filename) > 0) + { + f = fopen(filename, "rb"); + }else{ + return hf_iclass_eload_usage(); + } + + if(!f) { + PrintAndLog("Failed to read from file '%s'", filename); + return 1; + } + + fseek(f, 0, SEEK_END); + long fsize = ftell(f); + fseek(f, 0, SEEK_SET); + + uint8_t *dump = malloc(fsize); + + + size_t bytes_read = fread(dump, 1, fsize, f); + fclose(f); + + printIclassDumpInfo(dump); + //Validate + + if (bytes_read < fsize) + { + prnlog("Error, could only read %d bytes (should be %d)",bytes_read, fsize ); + free(dump); + return 1; + } + //Send to device + uint32_t bytes_sent = 0; + uint32_t bytes_remaining = bytes_read; + + while(bytes_remaining > 0){ + uint32_t bytes_in_packet = MIN(USB_CMD_DATA_SIZE, bytes_remaining); + UsbCommand c = {CMD_ICLASS_EML_MEMSET, {bytes_sent,bytes_in_packet,0}}; + memcpy(c.d.asBytes, dump, bytes_in_packet); + SendCommand(&c); + bytes_remaining -= bytes_in_packet; + bytes_sent += bytes_in_packet; + } + free(dump); + PrintAndLog("Sent %d bytes of data to device emulator memory", bytes_sent); + return 0; +} + +int usage_hf_iclass_decrypt() +{ + PrintAndLog("Usage: hf iclass decrypt f <tagdump> o "); + PrintAndLog(""); + PrintAndLog("OBS! In order to use this function, the file 'iclass_decryptionkey.bin' must reside"); + PrintAndLog("in the working directory. The file should be 16 bytes binary data"); + PrintAndLog(""); + PrintAndLog("example: hf iclass decrypt f tagdump_12312342343.bin"); + PrintAndLog(""); + PrintAndLog("OBS! This is pretty stupid implementation, it tries to decrypt every block after block 6. "); + PrintAndLog("Correct behaviour would be to decrypt only the application areas where the key is valid,"); + PrintAndLog("which is defined by the configuration block."); + return 1; +} + +int readKeyfile(const char *filename, size_t len, uint8_t* buffer) +{ + FILE *f = fopen(filename, "rb"); + if(!f) { + PrintAndLog("Failed to read from file '%s'", filename); + return 1; + } + fseek(f, 0, SEEK_END); + long fsize = ftell(f); + fseek(f, 0, SEEK_SET); + size_t bytes_read = fread(buffer, 1, len, f); + fclose(f); + if(fsize != len) + { + PrintAndLog("Warning, file size is %d, expected %d", fsize, len); + return 1; + } + if(bytes_read != len) + { + PrintAndLog("Warning, could only read %d bytes, expected %d" ,bytes_read, len); + return 1; + } + return 0; +} + +int CmdHFiClassDecrypt(const char *Cmd) +{ + uint8_t key[16] = { 0 }; + if(readKeyfile("iclass_decryptionkey.bin", 16, key)) + { + usage_hf_iclass_decrypt(); + return 1; + } + PrintAndLog("Decryption file found... "); + char opt = param_getchar(Cmd, 0); + if (strlen(Cmd)<1 || opt == 'h') + return usage_hf_iclass_decrypt(); + + //Open the tagdump-file + FILE *f; + char filename[FILE_PATH_SIZE]; + if(opt == 'f' && param_getstr(Cmd, 1, filename) > 0) + { + f = fopen(filename, "rb"); + }else{ + return usage_hf_iclass_decrypt(); + } + + fseek(f, 0, SEEK_END); + long fsize = ftell(f); + fseek(f, 0, SEEK_SET); + uint8_t enc_dump[8] = {0}; + uint8_t *decrypted = malloc(fsize); + des3_context ctx = { DES_DECRYPT ,{ 0 } }; + des3_set2key_dec( &ctx, key); + size_t bytes_read = fread(enc_dump, 1, 8, f); + + //Use the first block (CSN) for filename + char outfilename[FILE_PATH_SIZE] = { 0 }; + snprintf(outfilename,FILE_PATH_SIZE,"iclass_tagdump-%02x%02x%02x%02x%02x%02x%02x%02x-decrypted", + enc_dump[0],enc_dump[1],enc_dump[2],enc_dump[3], + enc_dump[4],enc_dump[5],enc_dump[6],enc_dump[7]); + + size_t blocknum =0; + while(bytes_read == 8) + { + if(blocknum < 7) + { + memcpy(decrypted+(blocknum*8), enc_dump, 8); + }else{ + des3_crypt_ecb(&ctx, enc_dump,decrypted +(blocknum*8) ); + } + printvar("decrypted block", decrypted +(blocknum*8), 8); + bytes_read = fread(enc_dump, 1, 8, f); + blocknum++; + } + fclose(f); + + saveFile(outfilename,"bin", decrypted, blocknum*8); + + return 0; } int CmdHFiClass_iso14443A_write(const char *Cmd) { - uint8_t readerType = 0; - uint8_t MAC[4]={0x00,0x00,0x00,0x00}; - uint8_t KEY[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - - uint8_t blockNo=0; - uint8_t bldata[8]={0}; - - if (strlen(Cmd)<3) - { - PrintAndLog("Usage: hf iclass write <Key> <Block> <Data>"); - PrintAndLog(" sample: hf iclass write 0011223344556677 10 AAAAAAAAAAAAAAAA"); - return 0; - } - - if (param_gethex(Cmd, 0, KEY, 16)) - { - PrintAndLog("KEY must include 16 HEX symbols"); - return 1; - } - - blockNo = param_get8(Cmd, 1); - if (blockNo>32) - { - PrintAndLog("Error: Maximum number of blocks is 32 for iClass 2K Cards!"); - return 1; - } - if (param_gethex(Cmd, 2, bldata, 8)) - { - PrintAndLog("Block data must include 8 HEX symbols"); - return 1; - } - - UsbCommand c = {CMD_ICLASS_ISO14443A_WRITE, {0}}; - SendCommand(&c); - UsbCommand resp; - - if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) { - uint8_t isOK = resp.arg[0] & 0xff; - uint8_t * data = resp.d.asBytes; - - memcpy(CSN,data,8); - memcpy(CCNR,data+8,8); - PrintAndLog("DEBUG: %s",sprint_hex(CSN,8)); - PrintAndLog("DEBUG: %s",sprint_hex(CCNR,8)); - PrintAndLog("isOk:%02x", isOK); - } else { - PrintAndLog("Command execute timeout"); - } - - diversifyKey(CSN,KEY, div_key); - - PrintAndLog("Div Key: %s",sprint_hex(div_key,8)); - doMAC(CCNR, 12,div_key, MAC); - - UsbCommand c2 = {CMD_ICLASS_ISO14443A_WRITE, {readerType,blockNo}}; - memcpy(c2.d.asBytes, bldata, 8); - memcpy(c2.d.asBytes+8, MAC, 4); - SendCommand(&c2); - - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - uint8_t isOK = resp.arg[0] & 0xff; - uint8_t * data = resp.d.asBytes; - - if (isOK) - PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 4)); - else - PrintAndLog("isOk:%02x", isOK); - } else { - PrintAndLog("Command execute timeout"); - } - return 0; + uint8_t readerType = 0; + uint8_t MAC[4]={0x00,0x00,0x00,0x00}; + uint8_t KEY[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + + uint8_t blockNo=0; + uint8_t bldata[8]={0}; + + if (strlen(Cmd)<3) + { + PrintAndLog("Usage: hf iclass write <Key> <Block> <Data>"); + PrintAndLog(" sample: hf iclass write 0011223344556677 10 AAAAAAAAAAAAAAAA"); + return 0; + } + + if (param_gethex(Cmd, 0, KEY, 16)) + { + PrintAndLog("KEY must include 16 HEX symbols"); + return 1; + } + + blockNo = param_get8(Cmd, 1); + if (blockNo>32) + { + PrintAndLog("Error: Maximum number of blocks is 32 for iClass 2K Cards!"); + return 1; + } + if (param_gethex(Cmd, 2, bldata, 8)) + { + PrintAndLog("Block data must include 8 HEX symbols"); + return 1; + } + + UsbCommand c = {CMD_ICLASS_ISO14443A_WRITE, {0}}; + SendCommand(&c); + UsbCommand resp; + + if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) { + uint8_t isOK = resp.arg[0] & 0xff; + uint8_t * data = resp.d.asBytes; + + memcpy(CSN,data,8); + memcpy(CCNR,data+8,8); + PrintAndLog("DEBUG: %s",sprint_hex(CSN,8)); + PrintAndLog("DEBUG: %s",sprint_hex(CCNR,8)); + PrintAndLog("isOk:%02x", isOK); + } else { + PrintAndLog("Command execute timeout"); + } + + diversifyKey(CSN,KEY, div_key); + + PrintAndLog("Div Key: %s",sprint_hex(div_key,8)); + doMAC(CCNR, div_key, MAC); + + UsbCommand c2 = {CMD_ICLASS_ISO14443A_WRITE, {readerType,blockNo}}; + memcpy(c2.d.asBytes, bldata, 8); + memcpy(c2.d.asBytes+8, MAC, 4); + SendCommand(&c2); + + if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { + uint8_t isOK = resp.arg[0] & 0xff; + uint8_t * data = resp.d.asBytes; + + if (isOK) + PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 4)); + else + PrintAndLog("isOk:%02x", isOK); + } else { + PrintAndLog("Command execute timeout"); + } + return 0; } int CmdHFiClass_loclass(const char *Cmd) { @@ -479,13 +649,13 @@ int CmdHFiClass_loclass(const char *Cmd) char fileName[255] = {0}; if(opt == 'f') { - if(param_getstr(Cmd, 1, fileName) > 0) - { - return bruteforceFileNoKeys(fileName); - }else - { - PrintAndLog("You must specify a filename"); - } + if(param_getstr(Cmd, 1, fileName) > 0) + { + return bruteforceFileNoKeys(fileName); + }else + { + PrintAndLog("You must specify a filename"); + } } else if(opt == 't') { @@ -512,19 +682,21 @@ static command_t CommandTable[] = {"reader",CmdHFiClassReader, 0, "Read an iClass tag"}, {"replay",CmdHFiClassReader_Replay, 0, "Read an iClass tag via Reply Attack"}, {"dump", CmdHFiClassReader_Dump, 0, "Authenticate and Dump iClass tag"}, - {"write", CmdHFiClass_iso14443A_write, 0, "Authenticate and Write iClass block"}, +// {"write", CmdHFiClass_iso14443A_write, 0, "Authenticate and Write iClass block"}, {"loclass", CmdHFiClass_loclass, 1, "Use loclass to perform bruteforce of reader attack dump"}, + {"eload", CmdHFiClassELoad, 0, "[experimental] Load data into iclass emulator memory"}, + {"decrypt", CmdHFiClassDecrypt, 1, "Decrypt tagdump" }, {NULL, NULL, 0, NULL} }; int CmdHFiClass(const char *Cmd) { - CmdsParse(CommandTable, Cmd); - return 0; + CmdsParse(CommandTable, Cmd); + return 0; } int CmdHelp(const char *Cmd) { - CmdsHelp(CommandTable); - return 0; + CmdsHelp(CommandTable); + return 0; }