]> git.zerfleddert.de Git - proxmark3-svn/blob - client/cmdhficlass.c
Applied Holiman's fixes for iclass.c and CSNs
[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 "../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
47 bool ShowWaitCycles = false;
48 char param = param_getchar(Cmd, 0);
49
50 if (param != 0) {
51 PrintAndLog("List data in trace buffer.");
52 PrintAndLog("Usage: hf iclass list");
53 PrintAndLog("h - help");
54 PrintAndLog("sample: hf iclass list");
55 return 0;
56 }
57
58 uint8_t got[TRACE_BUFFER_SIZE];
59 GetFromBigBuf(got,sizeof(got),0);
60 WaitForResponse(CMD_ACK,NULL);
61
62 PrintAndLog("Recorded Activity");
63 PrintAndLog("");
64 PrintAndLog("Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer");
65 PrintAndLog("All times are in carrier periods (1/13.56Mhz)");
66 PrintAndLog("");
67 PrintAndLog(" Start | End | Src | Data");
68 PrintAndLog("-----------|-----------|-----|--------");
69
70 int i;
71 uint32_t first_timestamp = 0;
72 uint32_t timestamp;
73 bool tagToReader;
74 uint32_t parityBits;
75 uint8_t len;
76 uint8_t *frame;
77 uint32_t EndOfTransmissionTimestamp = 0;
78
79
80 for( i=0; i < TRACE_BUFFER_SIZE;)
81 {
82 //First 32 bits contain
83 // isResponse (1 bit)
84 // timestamp (remaining)
85 //Then paritybits
86 //Then length
87 timestamp = *((uint32_t *)(got+i));
88 parityBits = *((uint32_t *)(got+i+4));
89 len = got[i+8];
90 frame = (got+i+9);
91 uint32_t next_timestamp = (*((uint32_t *)(got+i+9))) & 0x7fffffff;
92
93 tagToReader = timestamp & 0x80000000;
94 timestamp &= 0x7fffffff;
95
96 if(i==0) {
97 first_timestamp = timestamp;
98 }
99
100 // Break and stick with current result idf buffer was not completely full
101 if (frame[0] == 0x44 && frame[1] == 0x44 && frame[2] == 0x44 && frame[3] == 0x44) break;
102
103 char line[1000] = "";
104
105 if(len)//We have some data to display
106 {
107 int j,oddparity;
108
109 for(j = 0; j < len ; j++)
110 {
111 oddparity = 0x01 ^ xorbits_8(frame[j] & 0xFF);
112
113 if (tagToReader && (oddparity != ((parityBits >> (len - j - 1)) & 0x01))) {
114 sprintf(line+(j*4), "%02x! ", frame[j]);
115 } else {
116 sprintf(line+(j*4), "%02x ", frame[j]);
117 }
118 }
119 }else
120 {
121 if (ShowWaitCycles) {
122 sprintf(line, "fdt (Frame Delay Time): %d", (next_timestamp - timestamp));
123 }
124 }
125
126 char *crc = "";
127
128 if(len > 2)
129 {
130 uint8_t b1, b2;
131 if(!tagToReader && len == 4) {
132 // Rough guess that this is a command from the reader
133 // For iClass the command byte is not part of the CRC
134 ComputeCrc14443(CRC_ICLASS, &frame[1], len-3, &b1, &b2);
135 }
136 else {
137 // For other data.. CRC might not be applicable (UPDATE commands etc.)
138 ComputeCrc14443(CRC_ICLASS, frame, len-2, &b1, &b2);
139 }
140
141 if (b1 != frame[len-2] || b2 != frame[len-1]) {
142 crc = (tagToReader & (len < 8)) ? "" : " !crc";
143 }
144 }
145
146 i += (len + 9);
147 EndOfTransmissionTimestamp = (*((uint32_t *)(got+i))) & 0x7fffffff;
148
149 // Not implemented for iclass on the ARM-side
150 //if (!ShowWaitCycles) i += 9;
151
152 PrintAndLog(" %9d | %9d | %s | %s %s",
153 (timestamp - first_timestamp),
154 (EndOfTransmissionTimestamp - first_timestamp),
155 (len?(tagToReader ? "Tag" : "Rdr"):" "),
156 line, crc);
157 }
158 return 0;
159 }
160
161 int CmdHFiClassListOld(const char *Cmd)
162 {
163 uint8_t got[1920];
164 GetFromBigBuf(got,sizeof(got),0);
165
166 PrintAndLog("recorded activity:");
167 PrintAndLog(" ETU :rssi: who bytes");
168 PrintAndLog("---------+----+----+-----------");
169
170 int i = 0;
171 int prev = -1;
172
173 for (;;) {
174 if(i >= 1900) {
175 break;
176 }
177
178 bool isResponse;
179 int timestamp = *((uint32_t *)(got+i));
180 if (timestamp & 0x80000000) {
181 timestamp &= 0x7fffffff;
182 isResponse = 1;
183 } else {
184 isResponse = 0;
185 }
186
187
188 int metric = 0;
189
190 int parityBits = *((uint32_t *)(got+i+4));
191 // 4 bytes of additional information...
192 // maximum of 32 additional parity bit information
193 //
194 // TODO:
195 // at each quarter bit period we can send power level (16 levels)
196 // or each half bit period in 256 levels.
197
198
199 int len = got[i+8];
200
201 if (len > 100) {
202 break;
203 }
204 if (i + len >= 1900) {
205 break;
206 }
207
208 uint8_t *frame = (got+i+9);
209
210 // Break and stick with current result if buffer was not completely full
211 if (frame[0] == 0x44 && frame[1] == 0x44 && frame[3] == 0x44) { break; }
212
213 char line[1000] = "";
214 int j;
215 for (j = 0; j < len; j++) {
216 int oddparity = 0x01;
217 int k;
218
219 for (k=0;k<8;k++) {
220 oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
221 }
222
223 //if((parityBits >> (len - j - 1)) & 0x01) {
224 if (isResponse && (oddparity != ((parityBits >> (len - j - 1)) & 0x01))) {
225 sprintf(line+(j*4), "%02x! ", frame[j]);
226 }
227 else {
228 sprintf(line+(j*4), "%02x ", frame[j]);
229 }
230 }
231
232 char *crc;
233 crc = "";
234 if (len > 2) {
235 uint8_t b1, b2;
236 for (j = 0; j < (len - 1); j++) {
237 // gives problems... search for the reason..
238 /*if(frame[j] == 0xAA) {
239 switch(frame[j+1]) {
240 case 0x01:
241 crc = "[1] Two drops close after each other";
242 break;
243 case 0x02:
244 crc = "[2] Potential SOC with a drop in second half of bitperiod";
245 break;
246 case 0x03:
247 crc = "[3] Segment Z after segment X is not possible";
248 break;
249 case 0x04:
250 crc = "[4] Parity bit of a fully received byte was wrong";
251 break;
252 default:
253 crc = "[?] Unknown error";
254 break;
255 }
256 break;
257 }*/
258 }
259
260 if (strlen(crc)==0) {
261 if(!isResponse && len == 4) {
262 // Rough guess that this is a command from the reader
263 // For iClass the command byte is not part of the CRC
264 ComputeCrc14443(CRC_ICLASS, &frame[1], len-3, &b1, &b2);
265 }
266 else {
267 // For other data.. CRC might not be applicable (UPDATE commands etc.)
268 ComputeCrc14443(CRC_ICLASS, frame, len-2, &b1, &b2);
269 }
270 //printf("%1x %1x",(unsigned)b1,(unsigned)b2);
271 if (b1 != frame[len-2] || b2 != frame[len-1]) {
272 crc = (isResponse & (len < 8)) ? "" : " !crc";
273 } else {
274 crc = "";
275 }
276 }
277 } else {
278 crc = ""; // SHORT
279 }
280
281 char metricString[100];
282 if (isResponse) {
283 sprintf(metricString, "%3d", metric);
284 } else {
285 strcpy(metricString, " ");
286 }
287
288 PrintAndLog(" +%7d: %s: %s %s %s",
289 (prev < 0 ? 0 : (timestamp - prev)),
290 metricString,
291 (isResponse ? "TAG" : " "), line, crc);
292
293 prev = timestamp;
294 i += (len + 9);
295 }
296 return 0;
297 }
298
299 int CmdHFiClassSnoop(const char *Cmd)
300 {
301 UsbCommand c = {CMD_SNOOP_ICLASS};
302 SendCommand(&c);
303 return 0;
304 }
305 #define NUM_CSNS 15
306 int CmdHFiClassSim(const char *Cmd)
307 {
308 uint8_t simType = 0;
309 uint8_t CSN[8] = {0, 0, 0, 0, 0, 0, 0, 0};
310
311 if (strlen(Cmd)<1) {
312 PrintAndLog("Usage: hf iclass sim [0 <CSN>] | x");
313 PrintAndLog(" options");
314 PrintAndLog(" 0 <CSN> simulate the given CSN");
315 PrintAndLog(" 1 simulate default CSN");
316 PrintAndLog(" 2 iterate CSNs, gather MACs");
317 PrintAndLog(" sample: hf iclass sim 0 031FEC8AF7FF12E0");
318 PrintAndLog(" sample: hf iclass sim 2");
319 return 0;
320 }
321
322 simType = param_get8(Cmd, 0);
323
324 if(simType == 0)
325 {
326 if (param_gethex(Cmd, 1, CSN, 16)) {
327 PrintAndLog("A CSN should consist of 16 HEX symbols");
328 return 1;
329 }
330 PrintAndLog("--simtype:%02x csn:%s", simType, sprint_hex(CSN, 8));
331
332 }
333 if(simType > 2)
334 {
335 PrintAndLog("Undefined simptype %d", simType);
336 return 1;
337 }
338 uint8_t numberOfCSNs=0;
339
340 if(simType == 2)
341 {
342 UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType,NUM_CSNS}};
343 UsbCommand resp = {0};
344
345 uint8_t csns[8*NUM_CSNS] = {
346 0x00, 0x0B, 0x0F, 0xFF, 0xF7, 0xFF, 0x12, 0xE0,
347 0x00, 0x04, 0x0E, 0x08, 0xF7, 0xFF, 0x12, 0xE0,
348 0x00, 0x09, 0x0D, 0x05, 0xF7, 0xFF, 0x12, 0xE0,
349 0x00, 0x0A, 0x0C, 0x06, 0xF7, 0xFF, 0x12, 0xE0,
350 0x00, 0x0F, 0x0B, 0x03, 0xF7, 0xFF, 0x12, 0xE0,
351 0x00, 0x08, 0x0A, 0x0C, 0xF7, 0xFF, 0x12, 0xE0,
352 0x00, 0x0D, 0x09, 0x09, 0xF7, 0xFF, 0x12, 0xE0,
353 0x00, 0x0E, 0x08, 0x0A, 0xF7, 0xFF, 0x12, 0xE0,
354 0x00, 0x03, 0x07, 0x17, 0xF7, 0xFF, 0x12, 0xE0,
355 0x00, 0x3C, 0x06, 0xE0, 0xF7, 0xFF, 0x12, 0xE0,
356 0x00, 0x01, 0x05, 0x1D, 0xF7, 0xFF, 0x12, 0xE0,
357 0x00, 0x02, 0x04, 0x1E, 0xF7, 0xFF, 0x12, 0xE0,
358 0x00, 0x07, 0x03, 0x1B, 0xF7, 0xFF, 0x12, 0xE0,
359 0x00, 0x00, 0x02, 0x24, 0xF7, 0xFF, 0x12, 0xE0,
360 0x00, 0x05, 0x01, 0x21, 0xF7, 0xFF, 0x12, 0xE0 };
361
362 memcpy(c.d.asBytes, csns, 8*NUM_CSNS);
363
364 SendCommand(&c);
365 if (!WaitForResponseTimeout(CMD_ACK, &resp, -1)) {
366 PrintAndLog("Command timed out");
367 return 0;
368 }
369
370 uint8_t num_mac_responses = resp.arg[1];
371 PrintAndLog("Mac responses: %d MACs obtained (should be %d)", num_mac_responses, NUM_CSNS);
372
373 size_t datalen = NUM_CSNS*24;
374 /*
375 * Now, time to dump to file. We'll use this format:
376 * <8-byte CSN><8-byte CC><4 byte NR><4 byte MAC>....
377 * So, it should wind up as
378 * 8 * 24 bytes.
379 *
380 * The returndata from the pm3 is on the following format
381 * <4 byte NR><4 byte MAC>
382 * CC are all zeroes, CSN is the same as was sent in
383 **/
384 void* dump = malloc(datalen);
385 memset(dump,0,datalen);//<-- Need zeroes for the CC-field
386 uint8_t i = 0;
387 for(i = 0 ; i < NUM_CSNS ; i++)
388 {
389 memcpy(dump+i*24, csns+i*8,8); //CSN
390 //8 zero bytes here...
391 //Then comes NR_MAC (eight bytes from the response)
392 memcpy(dump+i*24+16,resp.d.asBytes+i*8,8);
393
394 }
395 /** Now, save to dumpfile **/
396 saveFile("iclass_mac_attack", "bin", dump,datalen);
397 free(dump);
398 }else
399 {
400 UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType,numberOfCSNs}};
401 memcpy(c.d.asBytes, CSN, 8);
402 SendCommand(&c);
403 }
404
405 return 0;
406 }
407
408 int CmdHFiClassReader(const char *Cmd)
409 {
410 UsbCommand c = {CMD_READER_ICLASS, {0}};
411 SendCommand(&c);
412 UsbCommand resp;
413 while(!ukbhit()){
414 if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) {
415 uint8_t isOK = resp.arg[0] & 0xff;
416 uint8_t * data = resp.d.asBytes;
417
418 PrintAndLog("isOk:%02x", isOK);
419
420 if(isOK > 0)
421 {
422 PrintAndLog("CSN: %s",sprint_hex(data,8));
423 }
424 if(isOK >= 1)
425 {
426 PrintAndLog("CC: %s",sprint_hex(data+8,8));
427 }else{
428 PrintAndLog("No CC obtained");
429 }
430 } else {
431 PrintAndLog("Command execute timeout");
432 }
433 }
434
435 return 0;
436 }
437
438 int CmdHFiClassReader_Replay(const char *Cmd)
439 {
440 uint8_t readerType = 0;
441 uint8_t MAC[4]={0x00, 0x00, 0x00, 0x00};
442
443 if (strlen(Cmd)<1) {
444 PrintAndLog("Usage: hf iclass replay <MAC>");
445 PrintAndLog(" sample: hf iclass replay 00112233");
446 return 0;
447 }
448
449 if (param_gethex(Cmd, 0, MAC, 8)) {
450 PrintAndLog("MAC must include 8 HEX symbols");
451 return 1;
452 }
453
454 UsbCommand c = {CMD_READER_ICLASS_REPLAY, {readerType}};
455 memcpy(c.d.asBytes, MAC, 4);
456 SendCommand(&c);
457
458 return 0;
459 }
460
461 int CmdHFiClassReader_Dump(const char *Cmd)
462 {
463 uint8_t readerType = 0;
464 uint8_t MAC[4]={0x00,0x00,0x00,0x00};
465 uint8_t KEY[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
466 uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
467 uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
468 //uint8_t CC_temp[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
469 uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
470 uint8_t keytable[128] = {0};
471 int elite = 0;
472 uint8_t *used_key;
473 int i;
474 if (strlen(Cmd)<1)
475 {
476 PrintAndLog("Usage: hf iclass dump <Key> [e]");
477 PrintAndLog(" Key - A 16 byte master key");
478 PrintAndLog(" e - If 'e' is specified, the key is interpreted as the 16 byte");
479 PrintAndLog(" Custom Key (KCus), which can be obtained via reader-attack");
480 PrintAndLog(" See 'hf iclass sim 2'. This key should be on iclass-format");
481 PrintAndLog(" sample: hf iclass dump 0011223344556677");
482
483
484 return 0;
485 }
486
487 if (param_gethex(Cmd, 0, KEY, 16))
488 {
489 PrintAndLog("KEY must include 16 HEX symbols");
490 return 1;
491 }
492
493 if (param_getchar(Cmd, 1) == 'e')
494 {
495 PrintAndLog("Elite switch on");
496 elite = 1;
497
498 //calc h2
499 hash2(KEY, keytable);
500 printarr_human_readable("keytable", keytable, 128);
501
502 }
503
504
505 UsbCommand c = {CMD_READER_ICLASS, {0}};
506 c.arg[0] = FLAG_ICLASS_READER_ONLY_ONCE;
507
508 SendCommand(&c);
509
510 UsbCommand resp;
511 uint8_t key_sel[8] = {0x00};
512 uint8_t key_sel_p[8] = {0x00};
513
514 if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) {
515 uint8_t isOK = resp.arg[0] & 0xff;
516 uint8_t * data = resp.d.asBytes;
517
518 memcpy(CSN,data,8);
519 memcpy(CCNR,data+8,8);
520
521 PrintAndLog("isOk:%02x", isOK);
522
523 if(isOK > 0)
524 {
525 PrintAndLog("CSN: %s",sprint_hex(CSN,8));
526 }
527 if(isOK > 1)
528 {
529 if(elite)
530 {
531
532 //Get the key index (hash1)
533 uint8_t key_index[8] = {0};
534
535 hash1(CSN, key_index);
536 printvar("hash1", key_index,8);
537 for(i = 0; i < 8 ; i++)
538 key_sel[i] = keytable[key_index[i]] & 0xFF;
539 printvar("k_sel", key_sel,8);
540 //Permute from iclass format to standard format
541 permutekey_rev(key_sel,key_sel_p);
542 used_key = key_sel_p;
543 }else{
544 //Perhaps this should also be permuted to std format?
545 // Something like the code below? I have no std system
546 // to test this with /Martin
547
548 //uint8_t key_sel_p[8] = { 0 };
549 //permutekey_rev(KEY,key_sel_p);
550 //used_key = key_sel_p;
551
552 used_key = KEY;
553
554 }
555 printvar("Used key",used_key,8);
556 diversifyKey(CSN,used_key, div_key);
557 printvar("Div key", div_key, 8);
558 printvar("CC_NR:",CCNR,12);
559 doMAC(CCNR,12,div_key, MAC);
560 printvar("MAC", MAC, 4);
561
562 UsbCommand d = {CMD_READER_ICLASS_REPLAY, {readerType}};
563 memcpy(d.d.asBytes, MAC, 4);
564 SendCommand(&d);
565
566 }else{
567 PrintAndLog("Failed to obtain CC! Aborting");
568 }
569 } else {
570 PrintAndLog("Command execute timeout");
571 }
572
573 return 0;
574 }
575
576 int CmdHFiClass_iso14443A_write(const char *Cmd)
577 {
578 uint8_t readerType = 0;
579 uint8_t MAC[4]={0x00,0x00,0x00,0x00};
580 uint8_t KEY[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
581 uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
582 uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
583 uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
584
585 uint8_t blockNo=0;
586 uint8_t bldata[8]={0};
587
588 if (strlen(Cmd)<3)
589 {
590 PrintAndLog("Usage: hf iclass write <Key> <Block> <Data>");
591 PrintAndLog(" sample: hf iclass write 0011223344556677 10 AAAAAAAAAAAAAAAA");
592 return 0;
593 }
594
595 if (param_gethex(Cmd, 0, KEY, 16))
596 {
597 PrintAndLog("KEY must include 16 HEX symbols");
598 return 1;
599 }
600
601 blockNo = param_get8(Cmd, 1);
602 if (blockNo>32)
603 {
604 PrintAndLog("Error: Maximum number of blocks is 32 for iClass 2K Cards!");
605 return 1;
606 }
607 if (param_gethex(Cmd, 2, bldata, 8))
608 {
609 PrintAndLog("Block data must include 8 HEX symbols");
610 return 1;
611 }
612
613 UsbCommand c = {CMD_ICLASS_ISO14443A_WRITE, {0}};
614 SendCommand(&c);
615 UsbCommand resp;
616
617 if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) {
618 uint8_t isOK = resp.arg[0] & 0xff;
619 uint8_t * data = resp.d.asBytes;
620
621 memcpy(CSN,data,8);
622 memcpy(CCNR,data+8,8);
623 PrintAndLog("DEBUG: %s",sprint_hex(CSN,8));
624 PrintAndLog("DEBUG: %s",sprint_hex(CCNR,8));
625 PrintAndLog("isOk:%02x", isOK);
626 } else {
627 PrintAndLog("Command execute timeout");
628 }
629
630 diversifyKey(CSN,KEY, div_key);
631
632 PrintAndLog("Div Key: %s",sprint_hex(div_key,8));
633 doMAC(CCNR, 12,div_key, MAC);
634
635 UsbCommand c2 = {CMD_ICLASS_ISO14443A_WRITE, {readerType,blockNo}};
636 memcpy(c2.d.asBytes, bldata, 8);
637 memcpy(c2.d.asBytes+8, MAC, 4);
638 SendCommand(&c2);
639
640 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
641 uint8_t isOK = resp.arg[0] & 0xff;
642 uint8_t * data = resp.d.asBytes;
643
644 if (isOK)
645 PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 4));
646 else
647 PrintAndLog("isOk:%02x", isOK);
648 } else {
649 PrintAndLog("Command execute timeout");
650 }
651 return 0;
652 }
653
654
655 static command_t CommandTable[] =
656 {
657 {"help", CmdHelp, 1, "This help"},
658 {"list", CmdHFiClassList, 0, "List iClass history"},
659 {"snoop", CmdHFiClassSnoop, 0, "Eavesdrop iClass communication"},
660 {"sim", CmdHFiClassSim, 0, "Simulate iClass tag"},
661 {"reader",CmdHFiClassReader, 0, "Read an iClass tag"},
662 {"replay",CmdHFiClassReader_Replay, 0, "Read an iClass tag via Reply Attack"},
663 {"dump", CmdHFiClassReader_Dump, 0, "Authenticate and Dump iClass tag"},
664 {"write", CmdHFiClass_iso14443A_write, 0, "Authenticate and Write iClass block"},
665 {"replay", CmdHFiClassReader_Replay, 0, "Read an iClass tag via Reply Attack"},
666 {"dump", CmdHFiClassReader_Dump, 0, "Authenticate and Dump iClass tag"},
667 {"write", CmdHFiClass_iso14443A_write, 0, "Authenticate and Write iClass block"},
668 {NULL, NULL, 0, NULL}
669 };
670
671 int CmdHFiClass(const char *Cmd)
672 {
673 CmdsParse(CommandTable, Cmd);
674 return 0;
675 }
676
677 int CmdHelp(const char *Cmd)
678 {
679 CmdsHelp(CommandTable);
680 return 0;
681 }
Impressum, Datenschutz