]> git.zerfleddert.de Git - proxmark3-svn/blob - client/cmdhficlass.c
Further implementation of iclass 'fullsim'. Moved protocol definitions to shared...
[proxmark3-svn] / client / cmdhficlass.c
1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2010 iZsh <izsh at fail0verflow.com>, Hagen Fritsch
3 // Copyright (C) 2011 Gerhard de Koning Gans
4 // Copyright (C) 2014 Midnitesnake & Andy Davies & Martin Holst Swende
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>
16 #include <sys/stat.h>
17 #include "iso14443crc.h" // Can also be used for iClass, using 0xE012 as CRC-type
18 #include "data.h"
19 #include "proxmark3.h"
20 #include "ui.h"
21 #include "cmdparser.h"
22 #include "cmdhficlass.h"
23 #include "common.h"
24 #include "util.h"
25 #include "cmdmain.h"
26 #include "loclass/des.h"
27 #include "loclass/cipherutils.h"
28 #include "loclass/cipher.h"
29 #include "loclass/ikeys.h"
30 #include "loclass/elite_crack.h"
31 #include "loclass/fileutils.h"
32
33 static int CmdHelp(const char *Cmd);
34
35 int xorbits_8(uint8_t val)
36 {
37 uint8_t res = val ^ (val >> 1); //1st pass
38 res = res ^ (res >> 1); // 2nd pass
39 res = res ^ (res >> 2); // 3rd pass
40 res = res ^ (res >> 4); // 4th pass
41 return res & 1;
42 }
43
44 int CmdHFiClassList(const char *Cmd)
45 {
46 PrintAndLog("Deprecated command, use 'hf list iclass' instead");
47 return 0;
48 }
49
50 int CmdHFiClassSnoop(const char *Cmd)
51 {
52 UsbCommand c = {CMD_SNOOP_ICLASS};
53 SendCommand(&c);
54 return 0;
55 }
56 int usage_hf_iclass_sim()
57 {
58 PrintAndLog("Usage: hf iclass sim <option> [CSN]");
59 PrintAndLog(" options");
60 PrintAndLog(" 0 <CSN> simulate the given CSN");
61 PrintAndLog(" 1 simulate default CSN");
62 PrintAndLog(" 2 Reader-attack, gather reader responses to extract elite key");
63 PrintAndLog(" 3 Full simulation using emulator memory (see 'hf iclass eload')");
64 PrintAndLog(" example: hf iclass sim 0 031FEC8AF7FF12E0");
65 PrintAndLog(" example: hf iclass sim 2");
66 PrintAndLog(" example: hf iclass eload 'tagdump.bin'");
67 PrintAndLog(" hf iclass sim 3");
68 return 0;
69 }
70
71 #define NUM_CSNS 15
72 int CmdHFiClassSim(const char *Cmd)
73 {
74 uint8_t simType = 0;
75 uint8_t CSN[8] = {0, 0, 0, 0, 0, 0, 0, 0};
76
77 if (strlen(Cmd)<1) {
78 usage_hf_iclass_sim();
79 }
80
81 simType = param_get8(Cmd, 0);
82
83 if(simType == 0)
84 {
85 if (param_gethex(Cmd, 1, CSN, 16)) {
86 PrintAndLog("A CSN should consist of 16 HEX symbols");
87 return usage_hf_iclass_sim();
88 }
89
90 PrintAndLog("--simtype:%02x csn:%s", simType, sprint_hex(CSN, 8));
91 }
92 if(simType > 3)
93 {
94 PrintAndLog("Undefined simptype %d", simType);
95 return usage_hf_iclass_sim();
96 }
97
98 uint8_t numberOfCSNs=0;
99 if(simType == 2)
100 {
101 UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType,NUM_CSNS}};
102 UsbCommand resp = {0};
103
104 uint8_t csns[8*NUM_CSNS] = {
105 0x00, 0x0B, 0x0F, 0xFF, 0xF7, 0xFF, 0x12, 0xE0,
106 0x00, 0x04, 0x0E, 0x08, 0xF7, 0xFF, 0x12, 0xE0,
107 0x00, 0x09, 0x0D, 0x05, 0xF7, 0xFF, 0x12, 0xE0,
108 0x00, 0x0A, 0x0C, 0x06, 0xF7, 0xFF, 0x12, 0xE0,
109 0x00, 0x0F, 0x0B, 0x03, 0xF7, 0xFF, 0x12, 0xE0,
110 0x00, 0x08, 0x0A, 0x0C, 0xF7, 0xFF, 0x12, 0xE0,
111 0x00, 0x0D, 0x09, 0x09, 0xF7, 0xFF, 0x12, 0xE0,
112 0x00, 0x0E, 0x08, 0x0A, 0xF7, 0xFF, 0x12, 0xE0,
113 0x00, 0x03, 0x07, 0x17, 0xF7, 0xFF, 0x12, 0xE0,
114 0x00, 0x3C, 0x06, 0xE0, 0xF7, 0xFF, 0x12, 0xE0,
115 0x00, 0x01, 0x05, 0x1D, 0xF7, 0xFF, 0x12, 0xE0,
116 0x00, 0x02, 0x04, 0x1E, 0xF7, 0xFF, 0x12, 0xE0,
117 0x00, 0x07, 0x03, 0x1B, 0xF7, 0xFF, 0x12, 0xE0,
118 0x00, 0x00, 0x02, 0x24, 0xF7, 0xFF, 0x12, 0xE0,
119 0x00, 0x05, 0x01, 0x21, 0xF7, 0xFF, 0x12, 0xE0 };
120
121 memcpy(c.d.asBytes, csns, 8*NUM_CSNS);
122
123 SendCommand(&c);
124 if (!WaitForResponseTimeout(CMD_ACK, &resp, -1)) {
125 PrintAndLog("Command timed out");
126 return 0;
127 }
128
129 uint8_t num_mac_responses = resp.arg[1];
130 PrintAndLog("Mac responses: %d MACs obtained (should be %d)", num_mac_responses,NUM_CSNS);
131
132 size_t datalen = NUM_CSNS*24;
133 /*
134 * Now, time to dump to file. We'll use this format:
135 * <8-byte CSN><8-byte CC><4 byte NR><4 byte MAC>....
136 * So, it should wind up as
137 * 8 * 24 bytes.
138 *
139 * The returndata from the pm3 is on the following format
140 * <4 byte NR><4 byte MAC>
141 * CC are all zeroes, CSN is the same as was sent in
142 **/
143 void* dump = malloc(datalen);
144 memset(dump,0,datalen);//<-- Need zeroes for the CC-field
145 uint8_t i = 0;
146 for(i = 0 ; i < NUM_CSNS ; i++)
147 {
148 memcpy(dump+i*24, csns+i*8,8); //CSN
149 //8 zero bytes here...
150 //Then comes NR_MAC (eight bytes from the response)
151 memcpy(dump+i*24+16,resp.d.asBytes+i*8,8);
152
153 }
154 /** Now, save to dumpfile **/
155 saveFile("iclass_mac_attack", "bin", dump,datalen);
156 free(dump);
157 }else
158 {
159 UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType,numberOfCSNs}};
160 memcpy(c.d.asBytes, CSN, 8);
161 SendCommand(&c);
162 }
163
164 return 0;
165 }
166
167 int CmdHFiClassReader(const char *Cmd)
168 {
169 UsbCommand c = {CMD_READER_ICLASS, {0}};
170 SendCommand(&c);
171 UsbCommand resp;
172 while(!ukbhit()){
173 if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) {
174 uint8_t isOK = resp.arg[0] & 0xff;
175 uint8_t * data = resp.d.asBytes;
176
177 PrintAndLog("isOk:%02x", isOK);
178 if( isOK == 0){
179 //Aborted
180 PrintAndLog("Quitting...");
181 return 0;
182 }
183 if(isOK > 0)
184 {
185 PrintAndLog("CSN: %s",sprint_hex(data,8));
186 }
187 if(isOK >= 1)
188 {
189 PrintAndLog("CC: %s",sprint_hex(data+8,8));
190 }else{
191 PrintAndLog("No CC obtained");
192 }
193 } else {
194 PrintAndLog("Command execute timeout");
195 }
196 }
197
198 return 0;
199 }
200
201 int CmdHFiClassReader_Replay(const char *Cmd)
202 {
203 uint8_t readerType = 0;
204 uint8_t MAC[4]={0x00, 0x00, 0x00, 0x00};
205
206 if (strlen(Cmd)<1) {
207 PrintAndLog("Usage: hf iclass replay <MAC>");
208 PrintAndLog(" sample: hf iclass replay 00112233");
209 return 0;
210 }
211
212 if (param_gethex(Cmd, 0, MAC, 8)) {
213 PrintAndLog("MAC must include 8 HEX symbols");
214 return 1;
215 }
216
217 UsbCommand c = {CMD_READER_ICLASS_REPLAY, {readerType}};
218 memcpy(c.d.asBytes, MAC, 4);
219 SendCommand(&c);
220
221 return 0;
222 }
223
224 int CmdHFiClassReader_Dump(const char *Cmd)
225 {
226 uint8_t readerType = 0;
227 uint8_t MAC[4]={0x00,0x00,0x00,0x00};
228 uint8_t KEY[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
229 uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
230 uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
231 //uint8_t CC_temp[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
232 uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
233 uint8_t keytable[128] = {0};
234 int elite = 0;
235 uint8_t *used_key;
236 int i;
237 if (strlen(Cmd)<1)
238 {
239 PrintAndLog("Usage: hf iclass dump <Key> [e]");
240 PrintAndLog(" Key - A 16 byte master key");
241 PrintAndLog(" e - If 'e' is specified, the key is interpreted as the 16 byte");
242 PrintAndLog(" Custom Key (KCus), which can be obtained via reader-attack");
243 PrintAndLog(" See 'hf iclass sim 2'. This key should be on iclass-format");
244 PrintAndLog(" sample: hf iclass dump 0011223344556677");
245
246
247 return 0;
248 }
249
250 if (param_gethex(Cmd, 0, KEY, 16))
251 {
252 PrintAndLog("KEY must include 16 HEX symbols");
253 return 1;
254 }
255
256 if (param_getchar(Cmd, 1) == 'e')
257 {
258 PrintAndLog("Elite switch on");
259 elite = 1;
260
261 //calc h2
262 hash2(KEY, keytable);
263 printarr_human_readable("keytable", keytable, 128);
264
265 }
266
267 UsbCommand resp;
268 uint8_t key_sel[8] = {0};
269 uint8_t key_sel_p[8] = { 0 };
270
271 UsbCommand c = {CMD_READER_ICLASS, {0}};
272 c.arg[0] = FLAG_ICLASS_READER_ONLY_ONCE| FLAG_ICLASS_READER_GET_CC;
273 SendCommand(&c);
274
275
276
277 if (!WaitForResponseTimeout(CMD_ACK,&resp,4500))
278 {
279 PrintAndLog("Command execute timeout");
280 return 0;
281 }
282
283 uint8_t isOK = resp.arg[0] & 0xff;
284 uint8_t * data = resp.d.asBytes;
285
286 memcpy(CSN,data,8);
287 memcpy(CCNR,data+8,8);
288
289 PrintAndLog("isOk:%02x", isOK);
290
291 if(isOK > 0)
292 {
293 PrintAndLog("CSN: %s",sprint_hex(CSN,8));
294 }
295 if(isOK <= 1){
296 PrintAndLog("Failed to obtain CC! Aborting");
297 return 0;
298 }
299 //Status 2 or higher
300
301 if(elite)
302 {
303 //Get the key index (hash1)
304 uint8_t key_index[8] = {0};
305
306 hash1(CSN, key_index);
307 printvar("hash1", key_index,8);
308 for(i = 0; i < 8 ; i++)
309 key_sel[i] = keytable[key_index[i]] & 0xFF;
310 PrintAndLog("Pre-fortified 'permuted' HS key that would be needed by an iclass reader to talk to above CSN:");
311 printvar("k_sel", key_sel,8);
312 //Permute from iclass format to standard format
313 permutekey_rev(key_sel,key_sel_p);
314 used_key = key_sel_p;
315 }else{
316 used_key = KEY;
317 }
318
319 PrintAndLog("Pre-fortified key that would be needed by the OmniKey reader to talk to above CSN:");
320 printvar("Used key",used_key,8);
321 diversifyKey(CSN,used_key, div_key);
322 PrintAndLog("Hash0, a.k.a diversified key, that is computed using Ksel and stored in the card (Block 3):");
323 printvar("Div key", div_key, 8);
324 printvar("CC_NR:",CCNR,12);
325 doMAC(CCNR,12,div_key, MAC);
326 printvar("MAC", MAC, 4);
327
328 uint8_t iclass_data[32000] = {0};
329 uint32_t iclass_datalen = 0;
330 uint32_t iclass_blocksFailed = 0;//Set to 1 if dump was incomplete
331
332 UsbCommand d = {CMD_READER_ICLASS_REPLAY, {readerType}};
333 memcpy(d.d.asBytes, MAC, 4);
334 clearCommandBuffer();
335 SendCommand(&d);
336 PrintAndLog("Waiting for device to dump data. Press button on device and key on keyboard to abort...");
337 while (true) {
338 printf(".");
339 if (ukbhit()) {
340 getchar();
341 printf("\naborted via keyboard!\n");
342 break;
343 }
344 if(WaitForResponseTimeout(CMD_ACK,&resp,4500))
345 {
346 uint32_t dataLength = resp.arg[0];
347 iclass_blocksFailed |= resp.arg[1];
348 if(dataLength > 0)
349 {
350 PrintAndLog("Got %d bytes data (total so far %d)" ,dataLength,iclass_datalen);
351 memcpy(iclass_data, resp.d.asBytes,dataLength);
352 iclass_datalen += dataLength;
353 }else
354 {//Last transfer, datalength 0 means the dump is finished
355 PrintAndLog("Dumped %d bytes of data from tag. ", iclass_datalen);
356 if(iclass_blocksFailed)
357 {
358 PrintAndLog("OBS! Some blocks failed to be dumped correctly!");
359 }
360 if(iclass_datalen > 0)
361 {
362 char filename[100] = {0};
363 //create a preferred filename
364 snprintf(filename, 100,"iclass_tagdump-%02x%02x%02x%02x%02x%02x%02x%02x",
365 CSN[0],CSN[1],CSN[2],CSN[3],
366 CSN[4],CSN[5],CSN[6],CSN[7]);
367 //Place the div_key in block 3
368 memcpy(iclass_data+(3*8), div_key, 8);
369 saveFile(filename,"bin",iclass_data, iclass_datalen );
370 }
371 //Aaaand we're finished
372 return 0;
373 }
374 }
375 }
376
377
378 return 0;
379 }
380
381 int hf_iclass_eload_usage()
382 {
383 PrintAndLog("Loads iclass tag-dump into emulator memory on device");
384 PrintAndLog("Usage: hf iclass eload f <filename>");
385 PrintAndLog("");
386 PrintAndLog("Example: hf iclass eload f iclass_tagdump-aa162d30f8ff12f1.bin");
387 return 0;
388
389 }
390
391 int iclassEmlSetMem(uint8_t *data, int blockNum, int blocksCount) {
392 UsbCommand c = {CMD_MIFARE_EML_MEMSET, {blockNum, blocksCount, 0}};
393 memcpy(c.d.asBytes, data, blocksCount * 16);
394 SendCommand(&c);
395 return 0;
396 }
397 int CmdHFiClassELoad(const char *Cmd)
398 {
399
400 char opt = param_getchar(Cmd, 0);
401 if (strlen(Cmd)<1 || opt == 'h')
402 return hf_iclass_eload_usage();
403
404 //File handling and reading
405 FILE *f;
406 char filename[FILE_PATH_SIZE];
407 if(opt == 'f' && param_getstr(Cmd, 1, filename) > 0)
408 {
409 f = fopen(filename, "rb");
410 }else{
411 return hf_iclass_eload_usage();
412 }
413
414 if(!f) {
415 PrintAndLog("Failed to read from file '%s'", filename);
416 return 1;
417 }
418
419 fseek(f, 0, SEEK_END);
420 long fsize = ftell(f);
421 fseek(f, 0, SEEK_SET);
422
423 uint8_t *dump = malloc(fsize);
424 size_t bytes_read = fread(dump, 1, fsize, f);
425 fclose(f);
426
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
452 int usage_hf_iclass_decrypt()
453 {
454 PrintAndLog("Usage: hf iclass decrypt f <tagdump> o ");
455 PrintAndLog("");
456 PrintAndLog("OBS! In order to use this function, the file 'iclass_decryptionkey.bin' must reside");
457 PrintAndLog("in the working directory. The file should be 16 bytes binary data");
458 PrintAndLog("");
459 PrintAndLog("example: hf iclass decrypt tagdump_12312342343.bin");
460 PrintAndLog("");
461 PrintAndLog("OBS! This is pretty stupid implementation, it tries to decrypt every block after block 6. ");
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
467 int 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
492 int 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 {
533 if(blocknum < 7)
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 }
549
550 int CmdHFiClass_iso14443A_write(const char *Cmd)
551 {
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));
607 doMAC(CCNR, 12,div_key, MAC);
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;
626 }
627 int 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 {
649 if(param_getstr(Cmd, 1, fileName) > 0)
650 {
651 return bruteforceFileNoKeys(fileName);
652 }else
653 {
654 PrintAndLog("You must specify a filename");
655 }
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 }
669
670 return 0;
671 }
672
673 static command_t CommandTable[] =
674 {
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"},
682 // {"write", CmdHFiClass_iso14443A_write, 0, "Authenticate and Write iClass block"},
683 {"loclass", CmdHFiClass_loclass, 1, "Use loclass to perform bruteforce of reader attack dump"},
684 {"eload", CmdHFiClassELoad, 0, "[experimental] Load data into iclass emulator memory"},
685 {"decrypt", CmdHFiClassDecrypt, 1, "Decrypt tagdump" },
686 {NULL, NULL, 0, NULL}
687 };
688
689 int CmdHFiClass(const char *Cmd)
690 {
691 CmdsParse(CommandTable, Cmd);
692 return 0;
693 }
694
695 int CmdHelp(const char *Cmd)
696 {
697 CmdsHelp(CommandTable);
698 return 0;
699 }
Impressum, Datenschutz