]> git.zerfleddert.de Git - proxmark3-svn/blame - client/cmdhficlass.c
Some work on iclass dump and iclass list, now the dumping is a lot more stable. I...
[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"
28fdb04f 19//#include "proxusb.h"
902cb3c0 20#include "proxmark3.h"
cee5a30d 21#include "ui.h"
22#include "cmdparser.h"
23#include "cmdhficlass.h"
24#include "common.h"
14006804 25#include "util.h"
17cba269 26#include "cmdmain.h"
a66fca86
AD
27#include "loclass/des.h"
28#include "loclass/cipherutils.h"
29#include "loclass/cipher.h"
30#include "loclass/ikeys.h"
3ad48540
MHS
31#include "loclass/elite_crack.h"
32#include "loclass/fileutils.h"
cee5a30d 33
34static int CmdHelp(const char *Cmd);
35
17cba269
MHS
36int xorbits_8(uint8_t val)
37{
3ad48540
MHS
38 uint8_t res = val ^ (val >> 1); //1st pass
39 res = res ^ (res >> 1); // 2nd pass
40 res = res ^ (res >> 2); // 3rd pass
41 res = res ^ (res >> 4); // 4th pass
42 return res & 1;
17cba269
MHS
43}
44
c8dd9b09
MHS
45#define ICLASS_CMD_ACTALL 0x0A
46#define ICLASS_CMD_IDENTIFY 0x0C
47#define ICLASS_CMD_READ 0x0C
48
49#define ICLASS_CMD_SELECT 0x81
50#define ICLASS_CMD_PAGESEL 0x84
51#define ICLASS_CMD_READCHECK 0x88
52#define ICLASS_CMD_CHECK 0x05
53#define ICLASS_CMD_SOF 0x0F
54#define ICLASS_CMD_HALT 0x00
55
56
2e9d4b3f
MHS
57void explain(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
58{
59
c8dd9b09
MHS
60 if(cmdsize > 1 && cmd[0] == ICLASS_CMD_READ)
61 {
62 snprintf(exp,size,"READ(%d)",cmd[1]);
63 return;
64 }
65
2e9d4b3f
MHS
66 switch(cmd[0])
67 {
c8dd9b09
MHS
68 case ICLASS_CMD_ACTALL: snprintf(exp,size,"ACTALL"); break;
69 case ICLASS_CMD_IDENTIFY: snprintf(exp,size,"IDENTIFY"); break;
70 case ICLASS_CMD_SELECT: snprintf(exp,size,"SELECT"); break;
71 case ICLASS_CMD_PAGESEL: snprintf(exp,size,"PAGESEL"); break;
72 case ICLASS_CMD_READCHECK: snprintf(exp,size,"READCHECK"); break;
73 case ICLASS_CMD_CHECK: snprintf(exp,size,"CHECK"); break;
74 case ICLASS_CMD_SOF: snprintf(exp,size,"SOF"); break;
75 case ICLASS_CMD_HALT: snprintf(exp,size,"HALT"); break;
76 default: snprintf(exp,size,"?"); break;
2e9d4b3f
MHS
77 }
78 return;
79}
80
cee5a30d 81int CmdHFiClassList(const char *Cmd)
17cba269 82{
17cba269
MHS
83 bool ShowWaitCycles = false;
84 char param = param_getchar(Cmd, 0);
545f2038 85
17cba269
MHS
86 if (param != 0) {
87 PrintAndLog("List data in trace buffer.");
88 PrintAndLog("Usage: hf iclass list");
89 PrintAndLog("h - help");
90 PrintAndLog("sample: hf iclass list");
91 return 0;
92 }
93
545f2038 94// for the time being. Need better Bigbuf handling.
95#define TRACE_SIZE 3000
96
97 uint8_t trace[TRACE_SIZE];
98 GetFromBigBuf(trace, TRACE_SIZE, 0);
99 WaitForResponse(CMD_ACK, NULL);
17cba269
MHS
100
101 PrintAndLog("Recorded Activity");
102 PrintAndLog("");
103 PrintAndLog("Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer");
104 PrintAndLog("All times are in carrier periods (1/13.56Mhz)");
105 PrintAndLog("");
2e9d4b3f
MHS
106 PrintAndLog(" Start | End | Src | Data (! denotes parity error) | CRC | Explanation|");
107 PrintAndLog("-----------|-----------|-----|-------------------------------------------------------------------------------------");
545f2038 108
109 uint16_t tracepos = 0;
110 uint16_t duration;
111 uint16_t data_len;
112 uint16_t parity_len;
113 bool isResponse;
17cba269 114 uint32_t timestamp;
545f2038 115 uint32_t first_timestamp;
116 uint32_t EndOfTransmissionTimestamp;
2e9d4b3f 117 char explanation[20] = {0};
545f2038 118 for (;;) {
17cba269 119
545f2038 120 if(tracepos >= TRACE_SIZE) {
121 break;
122 }
17cba269 123
545f2038 124 timestamp = *((uint32_t *)(trace + tracepos));
125 if(tracepos == 0) {
17cba269
MHS
126 first_timestamp = timestamp;
127 }
128
545f2038 129 // Break and stick with current result if buffer was not completely full
130 if (timestamp == 0x44444444) break;
131
132 tracepos += 4;
133 duration = *((uint16_t *)(trace + tracepos));
134 tracepos += 2;
135 data_len = *((uint16_t *)(trace + tracepos));
136 tracepos += 2;
137
138 if (data_len & 0x8000) {
139 data_len &= 0x7fff;
140 isResponse = true;
141 } else {
142 isResponse = false;
143 }
17cba269 144
545f2038 145 parity_len = (data_len-1)/8 + 1;
17cba269 146
545f2038 147 if (tracepos + data_len + parity_len >= TRACE_SIZE) {
148 break;
149 }
150
151 uint8_t *frame = trace + tracepos;
152 tracepos += data_len;
153 uint8_t *parityBytes = trace + tracepos;
154 tracepos += parity_len;
155
156 char line[16][110];
157 for (int j = 0; j < data_len; j++) {
158 int oddparity = 0x01;
159 int k;
160
161 for (k=0;k<8;k++) {
162 oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
17cba269 163 }
545f2038 164
165 uint8_t parityBits = parityBytes[j>>3];
166 if (isResponse && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
167 sprintf(line[j/16]+((j%16)*4), "%02x! ", frame[j]);
168 } else {
169 sprintf(line[j/16]+((j%16)*4), "%02x ", frame[j]);
17cba269 170 }
17cba269 171
545f2038 172 }
17cba269 173
2e9d4b3f 174 char *crc = " ";
545f2038 175 if (data_len > 2) {
17cba269 176 uint8_t b1, b2;
545f2038 177 if(!isResponse && data_len == 4 ) {
17cba269
MHS
178 // Rough guess that this is a command from the reader
179 // For iClass the command byte is not part of the CRC
545f2038 180 ComputeCrc14443(CRC_ICLASS, &frame[1], data_len-3, &b1, &b2);
181 if (b1 != frame[data_len-2] || b2 != frame[data_len-1]) {
182 crc = "!crc";
183 }
17cba269
MHS
184 }
185 else {
545f2038 186 // For other data.. CRC might not be applicable (UPDATE commands etc.)
187 ComputeCrc14443(CRC_ICLASS, frame, data_len-2, &b1, &b2);
188 if (b1 != frame[data_len-2] || b2 != frame[data_len-1]) {
189 crc = "!crc";
190 }
17cba269 191 }
545f2038 192 }
17cba269 193
545f2038 194 EndOfTransmissionTimestamp = timestamp + duration;
2e9d4b3f 195 explain(explanation,sizeof(explanation),frame,data_len);
545f2038 196 int num_lines = (data_len - 1)/16 + 1;
197 for (int j = 0; j < num_lines; j++) {
198 if (j == 0) {
2e9d4b3f 199 PrintAndLog(" %9d | %9d | %s | %-64s| %s| %s",
545f2038 200 (timestamp - first_timestamp),
201 (EndOfTransmissionTimestamp - first_timestamp),
202 (isResponse ? "Tag" : "Rdr"),
203 line[j],
2e9d4b3f
MHS
204 (j == num_lines-1)?crc:" ",
205 explanation);
545f2038 206 } else {
207 PrintAndLog(" | | | %-64s| %s",
208 line[j],
2e9d4b3f 209 (j == num_lines-1)?crc:" ");
545f2038 210 }
211 }
212
213 bool next_isResponse = *((uint16_t *)(trace + tracepos + 6)) & 0x8000;
214
215 if (ShowWaitCycles && !isResponse && next_isResponse) {
216 uint32_t next_timestamp = *((uint32_t *)(trace + tracepos));
217 if (next_timestamp != 0x44444444) {
218 PrintAndLog(" %9d | %9d | %s | fdt (Frame Delay Time): %d",
219 (EndOfTransmissionTimestamp - first_timestamp),
220 (next_timestamp - first_timestamp),
221 " ",
222 (next_timestamp - EndOfTransmissionTimestamp));
17cba269
MHS
223 }
224 }
545f2038 225
17cba269 226 }
545f2038 227
17cba269
MHS
228 return 0;
229}
230
cee5a30d 231int CmdHFiClassSnoop(const char *Cmd)
232{
233 UsbCommand c = {CMD_SNOOP_ICLASS};
234 SendCommand(&c);
235 return 0;
236}
6116c796 237#define NUM_CSNS 15
1e262141 238int CmdHFiClassSim(const char *Cmd)
239{
240 uint8_t simType = 0;
241 uint8_t CSN[8] = {0, 0, 0, 0, 0, 0, 0, 0};
242
17cba269
MHS
243 if (strlen(Cmd)<1) {
244 PrintAndLog("Usage: hf iclass sim [0 <CSN>] | x");
245 PrintAndLog(" options");
246 PrintAndLog(" 0 <CSN> simulate the given CSN");
247 PrintAndLog(" 1 simulate default CSN");
248 PrintAndLog(" 2 iterate CSNs, gather MACs");
1e262141 249 PrintAndLog(" sample: hf iclass sim 0 031FEC8AF7FF12E0");
17cba269 250 PrintAndLog(" sample: hf iclass sim 2");
1e262141 251 return 0;
252 }
253
254 simType = param_get8(Cmd, 0);
17cba269
MHS
255
256 if(simType == 0)
257 {
258 if (param_gethex(Cmd, 1, CSN, 16)) {
259 PrintAndLog("A CSN should consist of 16 HEX symbols");
260 return 1;
261 }
262 PrintAndLog("--simtype:%02x csn:%s", simType, sprint_hex(CSN, 8));
263
264 }
77abe781 265 if(simType > 2)
17cba269
MHS
266 {
267 PrintAndLog("Undefined simptype %d", simType);
268 return 1;
1e262141 269 }
17cba269 270 uint8_t numberOfCSNs=0;
1e262141 271
9f6e9d15
MHS
272 if(simType == 2)
273 {
6116c796 274 UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType,NUM_CSNS}};
9f6e9d15 275 UsbCommand resp = {0};
17cba269 276
6116c796 277 /*uint8_t csns[8 * NUM_CSNS] = {
77abe781
MHS
278 0x00,0x0B,0x0F,0xFF,0xF7,0xFF,0x12,0xE0 ,
279 0x00,0x13,0x94,0x7e,0x76,0xff,0x12,0xe0 ,
280 0x2a,0x99,0xac,0x79,0xec,0xff,0x12,0xe0 ,
281 0x17,0x12,0x01,0xfd,0xf7,0xff,0x12,0xe0 ,
282 0xcd,0x56,0x01,0x7c,0x6f,0xff,0x12,0xe0 ,
283 0x4b,0x5e,0x0b,0x72,0xef,0xff,0x12,0xe0 ,
284 0x00,0x73,0xd8,0x75,0x58,0xff,0x12,0xe0 ,
285 0x0c,0x90,0x32,0xf3,0x5d,0xff,0x12,0xe0 };
6116c796
MHS
286*/
287
288 uint8_t csns[8*NUM_CSNS] = {
289 0x00, 0x0B, 0x0F, 0xFF, 0xF7, 0xFF, 0x12, 0xE0,
290 0x00, 0x04, 0x0E, 0x08, 0xF7, 0xFF, 0x12, 0xE0,
291 0x00, 0x09, 0x0D, 0x05, 0xF7, 0xFF, 0x12, 0xE0,
292 0x00, 0x0A, 0x0C, 0x06, 0xF7, 0xFF, 0x12, 0xE0,
293 0x00, 0x0F, 0x0B, 0x03, 0xF7, 0xFF, 0x12, 0xE0,
294 0x00, 0x08, 0x0A, 0x0C, 0xF7, 0xFF, 0x12, 0xE0,
295 0x00, 0x0D, 0x09, 0x09, 0xF7, 0xFF, 0x12, 0xE0,
296 0x00, 0x0E, 0x08, 0x0A, 0xF7, 0xFF, 0x12, 0xE0,
297 0x00, 0x03, 0x07, 0x17, 0xF7, 0xFF, 0x12, 0xE0,
298 0x00, 0x3C, 0x06, 0xE0, 0xF7, 0xFF, 0x12, 0xE0,
299 0x00, 0x01, 0x05, 0x1D, 0xF7, 0xFF, 0x12, 0xE0,
300 0x00, 0x02, 0x04, 0x1E, 0xF7, 0xFF, 0x12, 0xE0,
301 0x00, 0x07, 0x03, 0x1B, 0xF7, 0xFF, 0x12, 0xE0,
302 0x00, 0x00, 0x02, 0x24, 0xF7, 0xFF, 0x12, 0xE0,
303 0x00, 0x05, 0x01, 0x21, 0xF7, 0xFF, 0x12, 0xE0 };
304
305 memcpy(c.d.asBytes, csns, 8*NUM_CSNS);
9f6e9d15
MHS
306
307 SendCommand(&c);
308 if (!WaitForResponseTimeout(CMD_ACK, &resp, -1)) {
309 PrintAndLog("Command timed out");
310 return 0;
311 }
1e262141 312
77abe781 313 uint8_t num_mac_responses = resp.arg[1];
6116c796 314 PrintAndLog("Mac responses: %d MACs obtained (should be %d)", num_mac_responses,NUM_CSNS);
9f6e9d15 315
6116c796 316 size_t datalen = NUM_CSNS*24;
9f6e9d15
MHS
317 /*
318 * Now, time to dump to file. We'll use this format:
77abe781 319 * <8-byte CSN><8-byte CC><4 byte NR><4 byte MAC>....
9f6e9d15 320 * So, it should wind up as
77abe781
MHS
321 * 8 * 24 bytes.
322 *
323 * The returndata from the pm3 is on the following format
324 * <4 byte NR><4 byte MAC>
325 * CC are all zeroes, CSN is the same as was sent in
9f6e9d15 326 **/
77abe781
MHS
327 void* dump = malloc(datalen);
328 memset(dump,0,datalen);//<-- Need zeroes for the CC-field
9f6e9d15 329 uint8_t i = 0;
6116c796 330 for(i = 0 ; i < NUM_CSNS ; i++)
9f6e9d15 331 {
77abe781
MHS
332 memcpy(dump+i*24, csns+i*8,8); //CSN
333 //8 zero bytes here...
334 //Then comes NR_MAC (eight bytes from the response)
335 memcpy(dump+i*24+16,resp.d.asBytes+i*8,8);
1e262141 336
9f6e9d15
MHS
337 }
338 /** Now, save to dumpfile **/
77abe781
MHS
339 saveFile("iclass_mac_attack", "bin", dump,datalen);
340 free(dump);
9f6e9d15
MHS
341 }else
342 {
343 UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType,numberOfCSNs}};
344 memcpy(c.d.asBytes, CSN, 8);
345 SendCommand(&c);
346 }
1e262141 347
1e262141 348 return 0;
349}
350
351int CmdHFiClassReader(const char *Cmd)
352{
aa41c605 353 UsbCommand c = {CMD_READER_ICLASS, {0}};
1e262141 354 SendCommand(&c);
aa41c605
MHS
355 UsbCommand resp;
356 while(!ukbhit()){
357 if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) {
358 uint8_t isOK = resp.arg[0] & 0xff;
359 uint8_t * data = resp.d.asBytes;
360
361 PrintAndLog("isOk:%02x", isOK);
2e9d4b3f
MHS
362 if( isOK == 0){
363 //Aborted
364 PrintAndLog("Quitting...");
365 return 0;
366 }
aa41c605
MHS
367 if(isOK > 0)
368 {
369 PrintAndLog("CSN: %s",sprint_hex(data,8));
370 }
371 if(isOK >= 1)
372 {
373 PrintAndLog("CC: %s",sprint_hex(data+8,8));
374 }else{
375 PrintAndLog("No CC obtained");
376 }
377 } else {
378 PrintAndLog("Command execute timeout");
379 }
380 }
1e262141 381
c3963755 382 return 0;
383}
384
385int CmdHFiClassReader_Replay(const char *Cmd)
386{
387 uint8_t readerType = 0;
388 uint8_t MAC[4]={0x00, 0x00, 0x00, 0x00};
389
390 if (strlen(Cmd)<1) {
391 PrintAndLog("Usage: hf iclass replay <MAC>");
392 PrintAndLog(" sample: hf iclass replay 00112233");
393 return 0;
394 }
395
396 if (param_gethex(Cmd, 0, MAC, 8)) {
397 PrintAndLog("MAC must include 8 HEX symbols");
398 return 1;
399 }
400
401 UsbCommand c = {CMD_READER_ICLASS_REPLAY, {readerType}};
402 memcpy(c.d.asBytes, MAC, 4);
403 SendCommand(&c);
1e262141 404
405 return 0;
406}
407
a66fca86
AD
408int CmdHFiClassReader_Dump(const char *Cmd)
409{
410 uint8_t readerType = 0;
411 uint8_t MAC[4]={0x00,0x00,0x00,0x00};
412 uint8_t KEY[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
413 uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
414 uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
fecd8202 415 //uint8_t CC_temp[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
a66fca86 416 uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
9b82de75
MHS
417 uint8_t keytable[128] = {0};
418 int elite = 0;
419 uint8_t *used_key;
420 int i;
fecd8202 421 if (strlen(Cmd)<1)
422 {
9b82de75
MHS
423 PrintAndLog("Usage: hf iclass dump <Key> [e]");
424 PrintAndLog(" Key - A 16 byte master key");
425 PrintAndLog(" e - If 'e' is specified, the key is interpreted as the 16 byte");
426 PrintAndLog(" Custom Key (KCus), which can be obtained via reader-attack");
427 PrintAndLog(" See 'hf iclass sim 2'. This key should be on iclass-format");
fecd8202 428 PrintAndLog(" sample: hf iclass dump 0011223344556677");
9b82de75
MHS
429
430
a66fca86
AD
431 return 0;
432 }
433
fecd8202 434 if (param_gethex(Cmd, 0, KEY, 16))
435 {
a66fca86
AD
436 PrintAndLog("KEY must include 16 HEX symbols");
437 return 1;
438 }
9b82de75
MHS
439
440 if (param_getchar(Cmd, 1) == 'e')
441 {
442 PrintAndLog("Elite switch on");
443 elite = 1;
444
445 //calc h2
446 hash2(KEY, keytable);
9e28ee9f 447 printarr_human_readable("keytable", keytable, 128);
9b82de75
MHS
448
449 }
450
0eea34a2
MHS
451 UsbCommand resp;
452 uint8_t key_sel[8] = {0};
453 uint8_t key_sel_p[8] = { 0 };
454
455 //HACK -- Below is for testing without access to a tag
0eea34a2 456 uint8_t fake_dummy_test = false;
8e976839
MHS
457 if(fake_dummy_test)
458 {
459 uint8_t xdata[16] = {0x01,0x02,0x03,0x04,0xF7,0xFF,0x12,0xE0, //CSN from http://www.proxmark.org/forum/viewtopic.php?pid=11230#p11230
460 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; // Just a random CC. Would be good to add a real testcase here
461 memcpy(resp.d.asBytes,xdata, 16);
462 resp.arg[0] = 2;
463 }
464
0eea34a2
MHS
465 //End hack
466
9b82de75 467
aa41c605 468 UsbCommand c = {CMD_READER_ICLASS, {0}};
c8dd9b09 469 c.arg[0] = FLAG_ICLASS_READER_ONLY_ONCE| FLAG_ICLASS_READER_GET_CC;
0eea34a2
MHS
470 if(!fake_dummy_test)
471 SendCommand(&c);
fecd8202 472
26c0d833 473
0eea34a2
MHS
474
475 if (fake_dummy_test || WaitForResponseTimeout(CMD_ACK,&resp,4500)) {
26c0d833
MHS
476 uint8_t isOK = resp.arg[0] & 0xff;
477 uint8_t * data = resp.d.asBytes;
478
26c0d833
MHS
479 memcpy(CSN,data,8);
480 memcpy(CCNR,data+8,8);
3ad48540 481
26c0d833 482 PrintAndLog("isOk:%02x", isOK);
a66fca86 483
aa41c605 484 if(isOK > 0)
26c0d833
MHS
485 {
486 PrintAndLog("CSN: %s",sprint_hex(CSN,8));
487 }
9b82de75 488 if(isOK > 1)
26c0d833 489 {
9b82de75
MHS
490 if(elite)
491 {
9b82de75
MHS
492 //Get the key index (hash1)
493 uint8_t key_index[8] = {0};
494
495 hash1(CSN, key_index);
496 printvar("hash1", key_index,8);
497 for(i = 0; i < 8 ; i++)
498 key_sel[i] = keytable[key_index[i]] & 0xFF;
0eea34a2 499 PrintAndLog("Pre-fortified 'permuted' HS key that would be needed by an iclass reader to talk to above CSN:");
9b82de75
MHS
500 printvar("k_sel", key_sel,8);
501 //Permute from iclass format to standard format
502 permutekey_rev(key_sel,key_sel_p);
503 used_key = key_sel_p;
504 }else{
9e28ee9f
MHS
505 //Perhaps this should also be permuted to std format?
506 // Something like the code below? I have no std system
507 // to test this with /Martin
508
509 //uint8_t key_sel_p[8] = { 0 };
510 //permutekey_rev(KEY,key_sel_p);
511 //used_key = key_sel_p;
512
9b82de75
MHS
513 used_key = KEY;
514
515 }
0eea34a2
MHS
516
517 PrintAndLog("Pre-fortified key that would be needed by the OmniKey reader to talk to above CSN:");
9b82de75
MHS
518 printvar("Used key",used_key,8);
519 diversifyKey(CSN,used_key, div_key);
0eea34a2 520 PrintAndLog("Hash0, a.k.a diversified key, that is computed using Ksel and stored in the card (Block 3):");
9b82de75 521 printvar("Div key", div_key, 8);
9e28ee9f 522 printvar("CC_NR:",CCNR,12);
74a38802 523 doMAC(CCNR,12,div_key, MAC);
9b82de75
MHS
524 printvar("MAC", MAC, 4);
525
26c0d833
MHS
526 UsbCommand d = {CMD_READER_ICLASS_REPLAY, {readerType}};
527 memcpy(d.d.asBytes, MAC, 4);
0eea34a2 528 if(!fake_dummy_test) SendCommand(&d);
26c0d833
MHS
529
530 }else{
531 PrintAndLog("Failed to obtain CC! Aborting");
532 }
533 } else {
534 PrintAndLog("Command execute timeout");
535 }
1e262141 536
537 return 0;
538}
539
fecd8202 540int CmdHFiClass_iso14443A_write(const char *Cmd)
541{
542 uint8_t readerType = 0;
543 uint8_t MAC[4]={0x00,0x00,0x00,0x00};
544 uint8_t KEY[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
545 uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
546 uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
fecd8202 547 uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
3ad48540 548
fecd8202 549 uint8_t blockNo=0;
550 uint8_t bldata[8]={0};
551
552 if (strlen(Cmd)<3)
553 {
554 PrintAndLog("Usage: hf iclass write <Key> <Block> <Data>");
555 PrintAndLog(" sample: hf iclass write 0011223344556677 10 AAAAAAAAAAAAAAAA");
556 return 0;
557 }
558
559 if (param_gethex(Cmd, 0, KEY, 16))
560 {
561 PrintAndLog("KEY must include 16 HEX symbols");
562 return 1;
563 }
564
565 blockNo = param_get8(Cmd, 1);
566 if (blockNo>32)
567 {
568 PrintAndLog("Error: Maximum number of blocks is 32 for iClass 2K Cards!");
569 return 1;
570 }
571 if (param_gethex(Cmd, 2, bldata, 8))
572 {
573 PrintAndLog("Block data must include 8 HEX symbols");
574 return 1;
575 }
576
aa41c605 577 UsbCommand c = {CMD_ICLASS_ISO14443A_WRITE, {0}};
fecd8202 578 SendCommand(&c);
fecd8202 579 UsbCommand resp;
3ad48540 580
fecd8202 581 if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) {
582 uint8_t isOK = resp.arg[0] & 0xff;
583 uint8_t * data = resp.d.asBytes;
584
585 memcpy(CSN,data,8);
586 memcpy(CCNR,data+8,8);
587 PrintAndLog("DEBUG: %s",sprint_hex(CSN,8));
588 PrintAndLog("DEBUG: %s",sprint_hex(CCNR,8));
589 PrintAndLog("isOk:%02x", isOK);
590 } else {
591 PrintAndLog("Command execute timeout");
592 }
3ad48540
MHS
593
594 diversifyKey(CSN,KEY, div_key);
595
fecd8202 596 PrintAndLog("Div Key: %s",sprint_hex(div_key,8));
74a38802 597 doMAC(CCNR, 12,div_key, MAC);
fecd8202 598
3ad48540
MHS
599 UsbCommand c2 = {CMD_ICLASS_ISO14443A_WRITE, {readerType,blockNo}};
600 memcpy(c2.d.asBytes, bldata, 8);
601 memcpy(c2.d.asBytes+8, MAC, 4);
602 SendCommand(&c2);
a66fca86 603
fecd8202 604 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
605 uint8_t isOK = resp.arg[0] & 0xff;
606 uint8_t * data = resp.d.asBytes;
607
608 if (isOK)
609 PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 4));
610 else
611 PrintAndLog("isOk:%02x", isOK);
612 } else {
613 PrintAndLog("Command execute timeout");
614 }
a66fca86
AD
615 return 0;
616}
617
c3963755 618
cee5a30d 619static command_t CommandTable[] =
620{
fecd8202 621 {"help", CmdHelp, 1, "This help"},
622 {"list", CmdHFiClassList, 0, "List iClass history"},
623 {"snoop", CmdHFiClassSnoop, 0, "Eavesdrop iClass communication"},
624 {"sim", CmdHFiClassSim, 0, "Simulate iClass tag"},
625 {"reader",CmdHFiClassReader, 0, "Read an iClass tag"},
626 {"replay",CmdHFiClassReader_Replay, 0, "Read an iClass tag via Reply Attack"},
627 {"dump", CmdHFiClassReader_Dump, 0, "Authenticate and Dump iClass tag"},
628 {"write", CmdHFiClass_iso14443A_write, 0, "Authenticate and Write iClass block"},
cee5a30d 629 {NULL, NULL, 0, NULL}
630};
631
632int CmdHFiClass(const char *Cmd)
633{
634 CmdsParse(CommandTable, Cmd);
635 return 0;
636}
637
638int CmdHelp(const char *Cmd)
639{
640 CmdsHelp(CommandTable);
641 return 0;
642}
Impressum, Datenschutz