]> git.zerfleddert.de Git - proxmark3-svn/blame - client/cmdhficlass.c
update changelog
[proxmark3-svn] / client / cmdhficlass.c
CommitLineData
cee5a30d 1//-----------------------------------------------------------------------------
2// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>, Hagen Fritsch
3// Copyright (C) 2011 Gerhard de Koning Gans
26c0d833 4// Copyright (C) 2014 Midnitesnake & Andy Davies & Martin Holst Swende
cee5a30d 5//
6// This code is licensed to you under the terms of the GNU GPL, version 2 or,
7// at your option, any later version. See the LICENSE.txt file for the text of
8// the license.
9//-----------------------------------------------------------------------------
10// High frequency iClass commands
11//-----------------------------------------------------------------------------
12
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
9f6e9d15 16#include <sys/stat.h>
cee5a30d 17#include "iso14443crc.h" // Can also be used for iClass, using 0xE012 as CRC-type
18#include "data.h"
902cb3c0 19#include "proxmark3.h"
cee5a30d 20#include "ui.h"
21#include "cmdparser.h"
22#include "cmdhficlass.h"
23#include "common.h"
14006804 24#include "util.h"
17cba269 25#include "cmdmain.h"
a66fca86
AD
26#include "loclass/des.h"
27#include "loclass/cipherutils.h"
28#include "loclass/cipher.h"
29#include "loclass/ikeys.h"
3ad48540
MHS
30#include "loclass/elite_crack.h"
31#include "loclass/fileutils.h"
1defcf60 32#include "protocols.h"
caaf9618 33#include "usb_cmd.h"
cee5a30d 34
35static int CmdHelp(const char *Cmd);
36
17cba269
MHS
37int xorbits_8(uint8_t val)
38{
53444513
MHS
39 uint8_t res = val ^ (val >> 1); //1st pass
40 res = res ^ (res >> 1); // 2nd pass
41 res = res ^ (res >> 2); // 3rd pass
42 res = res ^ (res >> 4); // 4th pass
43 return res & 1;
17cba269
MHS
44}
45
cee5a30d 46int CmdHFiClassList(const char *Cmd)
17cba269 47{
4c3de57a 48 PrintAndLog("Deprecated command, use 'hf list iclass' instead");
17cba269
MHS
49 return 0;
50}
51
cee5a30d 52int CmdHFiClassSnoop(const char *Cmd)
53{
53444513
MHS
54 UsbCommand c = {CMD_SNOOP_ICLASS};
55 SendCommand(&c);
56 return 0;
cee5a30d 57}
41524d8a
MHS
58int usage_hf_iclass_sim()
59{
60 PrintAndLog("Usage: hf iclass sim <option> [CSN]");
61 PrintAndLog(" options");
62 PrintAndLog(" 0 <CSN> simulate the given CSN");
63 PrintAndLog(" 1 simulate default CSN");
64 PrintAndLog(" 2 Reader-attack, gather reader responses to extract elite key");
65 PrintAndLog(" 3 Full simulation using emulator memory (see 'hf iclass eload')");
66 PrintAndLog(" example: hf iclass sim 0 031FEC8AF7FF12E0");
67 PrintAndLog(" example: hf iclass sim 2");
68 PrintAndLog(" example: hf iclass eload 'tagdump.bin'");
69 PrintAndLog(" hf iclass sim 3");
70 return 0;
71}
72
6116c796 73#define NUM_CSNS 15
1e262141 74int CmdHFiClassSim(const char *Cmd)
75{
53444513
MHS
76 uint8_t simType = 0;
77 uint8_t CSN[8] = {0, 0, 0, 0, 0, 0, 0, 0};
78
79 if (strlen(Cmd)<1) {
1defcf60 80 return usage_hf_iclass_sim();
53444513 81 }
1defcf60 82 simType = param_get8ex(Cmd, 0, 0, 10);
53444513
MHS
83
84 if(simType == 0)
85 {
86 if (param_gethex(Cmd, 1, CSN, 16)) {
87 PrintAndLog("A CSN should consist of 16 HEX symbols");
41524d8a 88 return usage_hf_iclass_sim();
53444513 89 }
53444513 90
41524d8a 91 PrintAndLog("--simtype:%02x csn:%s", simType, sprint_hex(CSN, 8));
53444513 92 }
41524d8a 93 if(simType > 3)
53444513
MHS
94 {
95 PrintAndLog("Undefined simptype %d", simType);
41524d8a 96 return usage_hf_iclass_sim();
53444513 97 }
1e262141 98
41524d8a 99 uint8_t numberOfCSNs=0;
9f6e9d15
MHS
100 if(simType == 2)
101 {
6116c796 102 UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType,NUM_CSNS}};
9f6e9d15 103 UsbCommand resp = {0};
17cba269 104
53444513
MHS
105 uint8_t csns[8*NUM_CSNS] = {
106 0x00, 0x0B, 0x0F, 0xFF, 0xF7, 0xFF, 0x12, 0xE0,
107 0x00, 0x04, 0x0E, 0x08, 0xF7, 0xFF, 0x12, 0xE0,
108 0x00, 0x09, 0x0D, 0x05, 0xF7, 0xFF, 0x12, 0xE0,
109 0x00, 0x0A, 0x0C, 0x06, 0xF7, 0xFF, 0x12, 0xE0,
110 0x00, 0x0F, 0x0B, 0x03, 0xF7, 0xFF, 0x12, 0xE0,
111 0x00, 0x08, 0x0A, 0x0C, 0xF7, 0xFF, 0x12, 0xE0,
112 0x00, 0x0D, 0x09, 0x09, 0xF7, 0xFF, 0x12, 0xE0,
113 0x00, 0x0E, 0x08, 0x0A, 0xF7, 0xFF, 0x12, 0xE0,
114 0x00, 0x03, 0x07, 0x17, 0xF7, 0xFF, 0x12, 0xE0,
115 0x00, 0x3C, 0x06, 0xE0, 0xF7, 0xFF, 0x12, 0xE0,
116 0x00, 0x01, 0x05, 0x1D, 0xF7, 0xFF, 0x12, 0xE0,
117 0x00, 0x02, 0x04, 0x1E, 0xF7, 0xFF, 0x12, 0xE0,
118 0x00, 0x07, 0x03, 0x1B, 0xF7, 0xFF, 0x12, 0xE0,
119 0x00, 0x00, 0x02, 0x24, 0xF7, 0xFF, 0x12, 0xE0,
120 0x00, 0x05, 0x01, 0x21, 0xF7, 0xFF, 0x12, 0xE0 };
6116c796
MHS
121
122 memcpy(c.d.asBytes, csns, 8*NUM_CSNS);
9f6e9d15
MHS
123
124 SendCommand(&c);
125 if (!WaitForResponseTimeout(CMD_ACK, &resp, -1)) {
126 PrintAndLog("Command timed out");
127 return 0;
128 }
1e262141 129
77abe781 130 uint8_t num_mac_responses = resp.arg[1];
6116c796 131 PrintAndLog("Mac responses: %d MACs obtained (should be %d)", num_mac_responses,NUM_CSNS);
9f6e9d15 132
6116c796 133 size_t datalen = NUM_CSNS*24;
9f6e9d15
MHS
134 /*
135 * Now, time to dump to file. We'll use this format:
77abe781 136 * <8-byte CSN><8-byte CC><4 byte NR><4 byte MAC>....
9f6e9d15 137 * So, it should wind up as
77abe781
MHS
138 * 8 * 24 bytes.
139 *
140 * The returndata from the pm3 is on the following format
141 * <4 byte NR><4 byte MAC>
142 * CC are all zeroes, CSN is the same as was sent in
9f6e9d15 143 **/
77abe781
MHS
144 void* dump = malloc(datalen);
145 memset(dump,0,datalen);//<-- Need zeroes for the CC-field
9f6e9d15 146 uint8_t i = 0;
6116c796 147 for(i = 0 ; i < NUM_CSNS ; i++)
9f6e9d15 148 {
77abe781
MHS
149 memcpy(dump+i*24, csns+i*8,8); //CSN
150 //8 zero bytes here...
151 //Then comes NR_MAC (eight bytes from the response)
152 memcpy(dump+i*24+16,resp.d.asBytes+i*8,8);
1e262141 153
9f6e9d15
MHS
154 }
155 /** Now, save to dumpfile **/
77abe781
MHS
156 saveFile("iclass_mac_attack", "bin", dump,datalen);
157 free(dump);
9f6e9d15
MHS
158 }else
159 {
160 UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType,numberOfCSNs}};
161 memcpy(c.d.asBytes, CSN, 8);
162 SendCommand(&c);
163 }
1e262141 164
53444513 165 return 0;
1e262141 166}
167
168int CmdHFiClassReader(const char *Cmd)
169{
caaf9618
MHS
170 UsbCommand c = {CMD_READER_ICLASS, {FLAG_ICLASS_READER_CSN|
171 FLAG_ICLASS_READER_CONF|FLAG_ICLASS_READER_AA}};
53444513
MHS
172 SendCommand(&c);
173 UsbCommand resp;
174 while(!ukbhit()){
175 if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) {
caaf9618 176 uint8_t readStatus = resp.arg[0] & 0xff;
53444513
MHS
177 uint8_t * data = resp.d.asBytes;
178
caaf9618
MHS
179 PrintAndLog("Readstatus:%02x", readStatus);
180 if( readStatus == 0){
53444513
MHS
181 //Aborted
182 PrintAndLog("Quitting...");
183 return 0;
184 }
caaf9618
MHS
185 if( readStatus & FLAG_ICLASS_READER_CSN) PrintAndLog("CSN: %s",sprint_hex(data,8));
186 if( readStatus & FLAG_ICLASS_READER_CC) PrintAndLog("CC: %s",sprint_hex(data+16,8));
187 if( readStatus & FLAG_ICLASS_READER_CONF){
188 printIclassDumpInfo(data);
53444513
MHS
189 }
190 } else {
191 PrintAndLog("Command execute timeout");
192 }
193 }
194
195 return 0;
c3963755 196}
197
198int CmdHFiClassReader_Replay(const char *Cmd)
199{
53444513
MHS
200 uint8_t readerType = 0;
201 uint8_t MAC[4]={0x00, 0x00, 0x00, 0x00};
c3963755 202
53444513
MHS
203 if (strlen(Cmd)<1) {
204 PrintAndLog("Usage: hf iclass replay <MAC>");
205 PrintAndLog(" sample: hf iclass replay 00112233");
206 return 0;
207 }
c3963755 208
53444513
MHS
209 if (param_gethex(Cmd, 0, MAC, 8)) {
210 PrintAndLog("MAC must include 8 HEX symbols");
211 return 1;
212 }
c3963755 213
53444513
MHS
214 UsbCommand c = {CMD_READER_ICLASS_REPLAY, {readerType}};
215 memcpy(c.d.asBytes, MAC, 4);
216 SendCommand(&c);
1e262141 217
53444513 218 return 0;
1e262141 219}
220
a66fca86
AD
221int CmdHFiClassReader_Dump(const char *Cmd)
222{
53444513
MHS
223 uint8_t readerType = 0;
224 uint8_t MAC[4]={0x00,0x00,0x00,0x00};
225 uint8_t KEY[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
226 uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
227 uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
228 //uint8_t CC_temp[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
229 uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
230 uint8_t keytable[128] = {0};
231 int elite = 0;
232 uint8_t *used_key;
233 int i;
234 if (strlen(Cmd)<1)
235 {
236 PrintAndLog("Usage: hf iclass dump <Key> [e]");
237 PrintAndLog(" Key - A 16 byte master key");
238 PrintAndLog(" e - If 'e' is specified, the key is interpreted as the 16 byte");
239 PrintAndLog(" Custom Key (KCus), which can be obtained via reader-attack");
240 PrintAndLog(" See 'hf iclass sim 2'. This key should be on iclass-format");
241 PrintAndLog(" sample: hf iclass dump 0011223344556677");
242
243
244 return 0;
245 }
246
247 if (param_gethex(Cmd, 0, KEY, 16))
248 {
249 PrintAndLog("KEY must include 16 HEX symbols");
250 return 1;
251 }
252
253 if (param_getchar(Cmd, 1) == 'e')
254 {
255 PrintAndLog("Elite switch on");
256 elite = 1;
257
258 //calc h2
259 hash2(KEY, keytable);
260 printarr_human_readable("keytable", keytable, 128);
261
262 }
263
264 UsbCommand resp;
265 uint8_t key_sel[8] = {0};
266 uint8_t key_sel_p[8] = { 0 };
267
268 UsbCommand c = {CMD_READER_ICLASS, {0}};
caaf9618 269 c.arg[0] = FLAG_ICLASS_READER_ONLY_ONCE| FLAG_ICLASS_READER_CC;
53444513
MHS
270 SendCommand(&c);
271
272
273
274 if (!WaitForResponseTimeout(CMD_ACK,&resp,4500))
275 {
276 PrintAndLog("Command execute timeout");
277 return 0;
278 }
26c0d833 279
cb29e00a
MHS
280 uint8_t isOK = resp.arg[0] & 0xff;
281 uint8_t * data = resp.d.asBytes;
3ad48540 282
cb29e00a 283 memcpy(CSN,data,8);
caaf9618 284 memcpy(CCNR,data+16,8);
a66fca86 285
cb29e00a 286 PrintAndLog("isOk:%02x", isOK);
9e28ee9f 287
cb29e00a
MHS
288 if(isOK > 0)
289 {
290 PrintAndLog("CSN: %s",sprint_hex(CSN,8));
291 }
292 if(isOK <= 1){
293 PrintAndLog("Failed to obtain CC! Aborting");
294 return 0;
295 }
296 //Status 2 or higher
9e28ee9f 297
cb29e00a
MHS
298 if(elite)
299 {
300 //Get the key index (hash1)
301 uint8_t key_index[8] = {0};
302
303 hash1(CSN, key_index);
304 printvar("hash1", key_index,8);
305 for(i = 0; i < 8 ; i++)
306 key_sel[i] = keytable[key_index[i]] & 0xFF;
307 PrintAndLog("Pre-fortified 'permuted' HS key that would be needed by an iclass reader to talk to above CSN:");
308 printvar("k_sel", key_sel,8);
309 //Permute from iclass format to standard format
310 permutekey_rev(key_sel,key_sel_p);
311 used_key = key_sel_p;
312 }else{
313 used_key = KEY;
314 }
9b82de75 315
cb29e00a
MHS
316 PrintAndLog("Pre-fortified key that would be needed by the OmniKey reader to talk to above CSN:");
317 printvar("Used key",used_key,8);
318 diversifyKey(CSN,used_key, div_key);
319 PrintAndLog("Hash0, a.k.a diversified key, that is computed using Ksel and stored in the card (Block 3):");
320 printvar("Div key", div_key, 8);
321 printvar("CC_NR:",CCNR,12);
1defcf60 322 doMAC(CCNR,div_key, MAC);
cb29e00a
MHS
323 printvar("MAC", MAC, 4);
324
325 uint8_t iclass_data[32000] = {0};
428d6221
MHS
326 uint32_t iclass_datalen = 0;
327 uint32_t iclass_blocksFailed = 0;//Set to 1 if dump was incomplete
cb29e00a
MHS
328
329 UsbCommand d = {CMD_READER_ICLASS_REPLAY, {readerType}};
330 memcpy(d.d.asBytes, MAC, 4);
331 clearCommandBuffer();
332 SendCommand(&d);
333 PrintAndLog("Waiting for device to dump data. Press button on device and key on keyboard to abort...");
334 while (true) {
335 printf(".");
336 if (ukbhit()) {
337 getchar();
338 printf("\naborted via keyboard!\n");
339 break;
340 }
341 if(WaitForResponseTimeout(CMD_ACK,&resp,4500))
342 {
428d6221 343 uint32_t dataLength = resp.arg[0];
cb29e00a 344 iclass_blocksFailed |= resp.arg[1];
cb29e00a
MHS
345 if(dataLength > 0)
346 {
428d6221 347 PrintAndLog("Got %d bytes data (total so far %d)" ,dataLength,iclass_datalen);
cb29e00a
MHS
348 memcpy(iclass_data, resp.d.asBytes,dataLength);
349 iclass_datalen += dataLength;
350 }else
351 {//Last transfer, datalength 0 means the dump is finished
352 PrintAndLog("Dumped %d bytes of data from tag. ", iclass_datalen);
353 if(iclass_blocksFailed)
354 {
355 PrintAndLog("OBS! Some blocks failed to be dumped correctly!");
356 }
357 if(iclass_datalen > 0)
358 {
359 char filename[100] = {0};
360 //create a preferred filename
361 snprintf(filename, 100,"iclass_tagdump-%02x%02x%02x%02x%02x%02x%02x%02x",
362 CSN[0],CSN[1],CSN[2],CSN[3],
53444513 363 CSN[4],CSN[5],CSN[6],CSN[7]);
b67f7ec3
MHS
364 //Place the div_key in block 3
365 memcpy(iclass_data+(3*8), div_key, 8);
cb29e00a 366 saveFile(filename,"bin",iclass_data, iclass_datalen );
cb29e00a
MHS
367 }
368 //Aaaand we're finished
369 return 0;
370 }
371 }
372 }
0eea34a2 373
1e262141 374
53444513 375 return 0;
1e262141 376}
377
7781a656
MHS
378int hf_iclass_eload_usage()
379{
380 PrintAndLog("Loads iclass tag-dump into emulator memory on device");
381 PrintAndLog("Usage: hf iclass eload f <filename>");
382 PrintAndLog("");
383 PrintAndLog("Example: hf iclass eload f iclass_tagdump-aa162d30f8ff12f1.bin");
384 return 0;
385
386}
387
388int iclassEmlSetMem(uint8_t *data, int blockNum, int blocksCount) {
389 UsbCommand c = {CMD_MIFARE_EML_MEMSET, {blockNum, blocksCount, 0}};
390 memcpy(c.d.asBytes, data, blocksCount * 16);
391 SendCommand(&c);
392 return 0;
393}
394int CmdHFiClassELoad(const char *Cmd)
395{
396
397 char opt = param_getchar(Cmd, 0);
398 if (strlen(Cmd)<1 || opt == 'h')
399 return hf_iclass_eload_usage();
400
401 //File handling and reading
402 FILE *f;
403 char filename[FILE_PATH_SIZE];
404 if(opt == 'f' && param_getstr(Cmd, 1, filename) > 0)
405 {
406 f = fopen(filename, "rb");
407 }else{
408 return hf_iclass_eload_usage();
409 }
410
411 if(!f) {
412 PrintAndLog("Failed to read from file '%s'", filename);
413 return 1;
414 }
415
416 fseek(f, 0, SEEK_END);
417 long fsize = ftell(f);
418 fseek(f, 0, SEEK_SET);
419
420 uint8_t *dump = malloc(fsize);
1defcf60
MHS
421
422
7781a656
MHS
423 size_t bytes_read = fread(dump, 1, fsize, f);
424 fclose(f);
425
1defcf60 426 printIclassDumpInfo(dump);
7781a656
MHS
427 //Validate
428
429 if (bytes_read < fsize)
430 {
431 prnlog("Error, could only read %d bytes (should be %d)",bytes_read, fsize );
432 free(dump);
433 return 1;
434 }
435 //Send to device
436 uint32_t bytes_sent = 0;
437 uint32_t bytes_remaining = bytes_read;
438
439 while(bytes_remaining > 0){
440 uint32_t bytes_in_packet = MIN(USB_CMD_DATA_SIZE, bytes_remaining);
441 UsbCommand c = {CMD_ICLASS_EML_MEMSET, {bytes_sent,bytes_in_packet,0}};
442 memcpy(c.d.asBytes, dump, bytes_in_packet);
443 SendCommand(&c);
444 bytes_remaining -= bytes_in_packet;
445 bytes_sent += bytes_in_packet;
446 }
447 free(dump);
448 PrintAndLog("Sent %d bytes of data to device emulator memory", bytes_sent);
449 return 0;
450}
451
41524d8a
MHS
452int usage_hf_iclass_decrypt()
453{
454 PrintAndLog("Usage: hf iclass decrypt f <tagdump> o ");
455 PrintAndLog("");
9a9bcea8 456 PrintAndLog("OBS! In order to use this function, the file 'iclass_decryptionkey.bin' must reside");
41524d8a 457 PrintAndLog("in the working directory. The file should be 16 bytes binary data");
9a9bcea8 458 PrintAndLog("");
1defcf60 459 PrintAndLog("example: hf iclass decrypt f tagdump_12312342343.bin");
41524d8a 460 PrintAndLog("");
9a9bcea8 461 PrintAndLog("OBS! This is pretty stupid implementation, it tries to decrypt every block after block 6. ");
41524d8a
MHS
462 PrintAndLog("Correct behaviour would be to decrypt only the application areas where the key is valid,");
463 PrintAndLog("which is defined by the configuration block.");
464 return 1;
465}
466
467int readKeyfile(const char *filename, size_t len, uint8_t* buffer)
468{
469 FILE *f = fopen(filename, "rb");
470 if(!f) {
471 PrintAndLog("Failed to read from file '%s'", filename);
472 return 1;
473 }
474 fseek(f, 0, SEEK_END);
475 long fsize = ftell(f);
476 fseek(f, 0, SEEK_SET);
477 size_t bytes_read = fread(buffer, 1, len, f);
478 fclose(f);
479 if(fsize != len)
480 {
481 PrintAndLog("Warning, file size is %d, expected %d", fsize, len);
482 return 1;
483 }
484 if(bytes_read != len)
485 {
486 PrintAndLog("Warning, could only read %d bytes, expected %d" ,bytes_read, len);
487 return 1;
488 }
489 return 0;
490}
491
492int CmdHFiClassDecrypt(const char *Cmd)
493{
494 uint8_t key[16] = { 0 };
495 if(readKeyfile("iclass_decryptionkey.bin", 16, key))
496 {
497 usage_hf_iclass_decrypt();
498 return 1;
499 }
500 PrintAndLog("Decryption file found... ");
501 char opt = param_getchar(Cmd, 0);
502 if (strlen(Cmd)<1 || opt == 'h')
503 return usage_hf_iclass_decrypt();
504
505 //Open the tagdump-file
506 FILE *f;
507 char filename[FILE_PATH_SIZE];
508 if(opt == 'f' && param_getstr(Cmd, 1, filename) > 0)
509 {
510 f = fopen(filename, "rb");
511 }else{
512 return usage_hf_iclass_decrypt();
513 }
514
515 fseek(f, 0, SEEK_END);
516 long fsize = ftell(f);
517 fseek(f, 0, SEEK_SET);
518 uint8_t enc_dump[8] = {0};
519 uint8_t *decrypted = malloc(fsize);
520 des3_context ctx = { DES_DECRYPT ,{ 0 } };
521 des3_set2key_dec( &ctx, key);
522 size_t bytes_read = fread(enc_dump, 1, 8, f);
523
524 //Use the first block (CSN) for filename
525 char outfilename[FILE_PATH_SIZE] = { 0 };
526 snprintf(outfilename,FILE_PATH_SIZE,"iclass_tagdump-%02x%02x%02x%02x%02x%02x%02x%02x-decrypted",
527 enc_dump[0],enc_dump[1],enc_dump[2],enc_dump[3],
528 enc_dump[4],enc_dump[5],enc_dump[6],enc_dump[7]);
529
530 size_t blocknum =0;
531 while(bytes_read == 8)
532 {
9a9bcea8 533 if(blocknum < 7)
41524d8a
MHS
534 {
535 memcpy(decrypted+(blocknum*8), enc_dump, 8);
536 }else{
537 des3_crypt_ecb(&ctx, enc_dump,decrypted +(blocknum*8) );
538 }
539 printvar("decrypted block", decrypted +(blocknum*8), 8);
540 bytes_read = fread(enc_dump, 1, 8, f);
541 blocknum++;
542 }
543 fclose(f);
544
545 saveFile(outfilename,"bin", decrypted, blocknum*8);
546
547 return 0;
548}
7781a656 549
fecd8202 550int CmdHFiClass_iso14443A_write(const char *Cmd)
551{
53444513
MHS
552 uint8_t readerType = 0;
553 uint8_t MAC[4]={0x00,0x00,0x00,0x00};
554 uint8_t KEY[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
555 uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
556 uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
557 uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
558
559 uint8_t blockNo=0;
560 uint8_t bldata[8]={0};
561
562 if (strlen(Cmd)<3)
563 {
564 PrintAndLog("Usage: hf iclass write <Key> <Block> <Data>");
565 PrintAndLog(" sample: hf iclass write 0011223344556677 10 AAAAAAAAAAAAAAAA");
566 return 0;
567 }
568
569 if (param_gethex(Cmd, 0, KEY, 16))
570 {
571 PrintAndLog("KEY must include 16 HEX symbols");
572 return 1;
573 }
574
575 blockNo = param_get8(Cmd, 1);
576 if (blockNo>32)
577 {
578 PrintAndLog("Error: Maximum number of blocks is 32 for iClass 2K Cards!");
579 return 1;
580 }
581 if (param_gethex(Cmd, 2, bldata, 8))
582 {
583 PrintAndLog("Block data must include 8 HEX symbols");
584 return 1;
585 }
586
587 UsbCommand c = {CMD_ICLASS_ISO14443A_WRITE, {0}};
588 SendCommand(&c);
589 UsbCommand resp;
590
591 if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) {
592 uint8_t isOK = resp.arg[0] & 0xff;
593 uint8_t * data = resp.d.asBytes;
594
595 memcpy(CSN,data,8);
596 memcpy(CCNR,data+8,8);
597 PrintAndLog("DEBUG: %s",sprint_hex(CSN,8));
598 PrintAndLog("DEBUG: %s",sprint_hex(CCNR,8));
599 PrintAndLog("isOk:%02x", isOK);
600 } else {
601 PrintAndLog("Command execute timeout");
602 }
603
604 diversifyKey(CSN,KEY, div_key);
605
606 PrintAndLog("Div Key: %s",sprint_hex(div_key,8));
1defcf60 607 doMAC(CCNR, div_key, MAC);
53444513
MHS
608
609 UsbCommand c2 = {CMD_ICLASS_ISO14443A_WRITE, {readerType,blockNo}};
610 memcpy(c2.d.asBytes, bldata, 8);
611 memcpy(c2.d.asBytes+8, MAC, 4);
612 SendCommand(&c2);
613
614 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
615 uint8_t isOK = resp.arg[0] & 0xff;
616 uint8_t * data = resp.d.asBytes;
617
618 if (isOK)
619 PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 4));
620 else
621 PrintAndLog("isOk:%02x", isOK);
622 } else {
623 PrintAndLog("Command execute timeout");
624 }
625 return 0;
a66fca86 626}
6f101995
MHS
627int CmdHFiClass_loclass(const char *Cmd)
628{
629 char opt = param_getchar(Cmd, 0);
630
631 if (strlen(Cmd)<1 || opt == 'h') {
632 PrintAndLog("Usage: hf iclass loclass [options]");
633 PrintAndLog("Options:");
634 PrintAndLog("h Show this help");
635 PrintAndLog("t Perform self-test");
636 PrintAndLog("f <filename> Bruteforce iclass dumpfile");
637 PrintAndLog(" An iclass dumpfile is assumed to consist of an arbitrary number of");
638 PrintAndLog(" malicious CSNs, and their protocol responses");
639 PrintAndLog(" The the binary format of the file is expected to be as follows: ");
640 PrintAndLog(" <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>");
641 PrintAndLog(" <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>");
642 PrintAndLog(" <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>");
643 PrintAndLog(" ... totalling N*24 bytes");
644 return 0;
645 }
646 char fileName[255] = {0};
647 if(opt == 'f')
648 {
53444513
MHS
649 if(param_getstr(Cmd, 1, fileName) > 0)
650 {
651 return bruteforceFileNoKeys(fileName);
652 }else
653 {
654 PrintAndLog("You must specify a filename");
655 }
6f101995
MHS
656 }
657 else if(opt == 't')
658 {
659 int errors = testCipherUtils();
660 errors += testMAC();
661 errors += doKeyTests(0);
662 errors += testElite();
663 if(errors)
664 {
665 prnlog("OBS! There were errors!!!");
666 }
667 return errors;
668 }
a66fca86 669
6f101995
MHS
670 return 0;
671}
c3963755 672
cee5a30d 673static command_t CommandTable[] =
674{
6f101995
MHS
675 {"help", CmdHelp, 1, "This help"},
676 {"list", CmdHFiClassList, 0, "[Deprecated] List iClass history"},
677 {"snoop", CmdHFiClassSnoop, 0, "Eavesdrop iClass communication"},
678 {"sim", CmdHFiClassSim, 0, "Simulate iClass tag"},
679 {"reader",CmdHFiClassReader, 0, "Read an iClass tag"},
680 {"replay",CmdHFiClassReader_Replay, 0, "Read an iClass tag via Reply Attack"},
681 {"dump", CmdHFiClassReader_Dump, 0, "Authenticate and Dump iClass tag"},
a4749080 682// {"write", CmdHFiClass_iso14443A_write, 0, "Authenticate and Write iClass block"},
6f101995 683 {"loclass", CmdHFiClass_loclass, 1, "Use loclass to perform bruteforce of reader attack dump"},
7781a656 684 {"eload", CmdHFiClassELoad, 0, "[experimental] Load data into iclass emulator memory"},
41524d8a 685 {"decrypt", CmdHFiClassDecrypt, 1, "Decrypt tagdump" },
6f101995 686 {NULL, NULL, 0, NULL}
cee5a30d 687};
688
689int CmdHFiClass(const char *Cmd)
690{
53444513
MHS
691 CmdsParse(CommandTable, Cmd);
692 return 0;
cee5a30d 693}
694
695int CmdHelp(const char *Cmd)
696{
53444513
MHS
697 CmdsHelp(CommandTable);
698 return 0;
cee5a30d 699}
Impressum, Datenschutz