]> git.zerfleddert.de Git - proxmark3-svn/blame - client/cmdhficlass.c
Save iclass dumps to file, like mifare-dump functionality works
[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
cee5a30d 45int CmdHFiClassList(const char *Cmd)
17cba269 46{
4c3de57a 47 PrintAndLog("Deprecated command, use 'hf list iclass' instead");
17cba269
MHS
48 return 0;
49}
50
cee5a30d 51int CmdHFiClassSnoop(const char *Cmd)
52{
53 UsbCommand c = {CMD_SNOOP_ICLASS};
54 SendCommand(&c);
55 return 0;
56}
6116c796 57#define NUM_CSNS 15
1e262141 58int CmdHFiClassSim(const char *Cmd)
59{
60 uint8_t simType = 0;
61 uint8_t CSN[8] = {0, 0, 0, 0, 0, 0, 0, 0};
62
17cba269
MHS
63 if (strlen(Cmd)<1) {
64 PrintAndLog("Usage: hf iclass sim [0 <CSN>] | x");
65 PrintAndLog(" options");
66 PrintAndLog(" 0 <CSN> simulate the given CSN");
67 PrintAndLog(" 1 simulate default CSN");
68 PrintAndLog(" 2 iterate CSNs, gather MACs");
1e262141 69 PrintAndLog(" sample: hf iclass sim 0 031FEC8AF7FF12E0");
17cba269 70 PrintAndLog(" sample: hf iclass sim 2");
1e262141 71 return 0;
72 }
73
74 simType = param_get8(Cmd, 0);
17cba269
MHS
75
76 if(simType == 0)
77 {
78 if (param_gethex(Cmd, 1, CSN, 16)) {
79 PrintAndLog("A CSN should consist of 16 HEX symbols");
80 return 1;
81 }
82 PrintAndLog("--simtype:%02x csn:%s", simType, sprint_hex(CSN, 8));
83
84 }
77abe781 85 if(simType > 2)
17cba269
MHS
86 {
87 PrintAndLog("Undefined simptype %d", simType);
88 return 1;
1e262141 89 }
17cba269 90 uint8_t numberOfCSNs=0;
1e262141 91
9f6e9d15
MHS
92 if(simType == 2)
93 {
6116c796 94 UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType,NUM_CSNS}};
9f6e9d15 95 UsbCommand resp = {0};
17cba269 96
6116c796 97 /*uint8_t csns[8 * NUM_CSNS] = {
77abe781
MHS
98 0x00,0x0B,0x0F,0xFF,0xF7,0xFF,0x12,0xE0 ,
99 0x00,0x13,0x94,0x7e,0x76,0xff,0x12,0xe0 ,
100 0x2a,0x99,0xac,0x79,0xec,0xff,0x12,0xe0 ,
101 0x17,0x12,0x01,0xfd,0xf7,0xff,0x12,0xe0 ,
102 0xcd,0x56,0x01,0x7c,0x6f,0xff,0x12,0xe0 ,
103 0x4b,0x5e,0x0b,0x72,0xef,0xff,0x12,0xe0 ,
104 0x00,0x73,0xd8,0x75,0x58,0xff,0x12,0xe0 ,
105 0x0c,0x90,0x32,0xf3,0x5d,0xff,0x12,0xe0 };
6116c796
MHS
106*/
107
108 uint8_t csns[8*NUM_CSNS] = {
109 0x00, 0x0B, 0x0F, 0xFF, 0xF7, 0xFF, 0x12, 0xE0,
110 0x00, 0x04, 0x0E, 0x08, 0xF7, 0xFF, 0x12, 0xE0,
111 0x00, 0x09, 0x0D, 0x05, 0xF7, 0xFF, 0x12, 0xE0,
112 0x00, 0x0A, 0x0C, 0x06, 0xF7, 0xFF, 0x12, 0xE0,
113 0x00, 0x0F, 0x0B, 0x03, 0xF7, 0xFF, 0x12, 0xE0,
114 0x00, 0x08, 0x0A, 0x0C, 0xF7, 0xFF, 0x12, 0xE0,
115 0x00, 0x0D, 0x09, 0x09, 0xF7, 0xFF, 0x12, 0xE0,
116 0x00, 0x0E, 0x08, 0x0A, 0xF7, 0xFF, 0x12, 0xE0,
117 0x00, 0x03, 0x07, 0x17, 0xF7, 0xFF, 0x12, 0xE0,
118 0x00, 0x3C, 0x06, 0xE0, 0xF7, 0xFF, 0x12, 0xE0,
119 0x00, 0x01, 0x05, 0x1D, 0xF7, 0xFF, 0x12, 0xE0,
120 0x00, 0x02, 0x04, 0x1E, 0xF7, 0xFF, 0x12, 0xE0,
121 0x00, 0x07, 0x03, 0x1B, 0xF7, 0xFF, 0x12, 0xE0,
122 0x00, 0x00, 0x02, 0x24, 0xF7, 0xFF, 0x12, 0xE0,
123 0x00, 0x05, 0x01, 0x21, 0xF7, 0xFF, 0x12, 0xE0 };
124
125 memcpy(c.d.asBytes, csns, 8*NUM_CSNS);
9f6e9d15
MHS
126
127 SendCommand(&c);
128 if (!WaitForResponseTimeout(CMD_ACK, &resp, -1)) {
129 PrintAndLog("Command timed out");
130 return 0;
131 }
1e262141 132
77abe781 133 uint8_t num_mac_responses = resp.arg[1];
6116c796 134 PrintAndLog("Mac responses: %d MACs obtained (should be %d)", num_mac_responses,NUM_CSNS);
9f6e9d15 135
6116c796 136 size_t datalen = NUM_CSNS*24;
9f6e9d15
MHS
137 /*
138 * Now, time to dump to file. We'll use this format:
77abe781 139 * <8-byte CSN><8-byte CC><4 byte NR><4 byte MAC>....
9f6e9d15 140 * So, it should wind up as
77abe781
MHS
141 * 8 * 24 bytes.
142 *
143 * The returndata from the pm3 is on the following format
144 * <4 byte NR><4 byte MAC>
145 * CC are all zeroes, CSN is the same as was sent in
9f6e9d15 146 **/
77abe781
MHS
147 void* dump = malloc(datalen);
148 memset(dump,0,datalen);//<-- Need zeroes for the CC-field
9f6e9d15 149 uint8_t i = 0;
6116c796 150 for(i = 0 ; i < NUM_CSNS ; i++)
9f6e9d15 151 {
77abe781
MHS
152 memcpy(dump+i*24, csns+i*8,8); //CSN
153 //8 zero bytes here...
154 //Then comes NR_MAC (eight bytes from the response)
155 memcpy(dump+i*24+16,resp.d.asBytes+i*8,8);
1e262141 156
9f6e9d15
MHS
157 }
158 /** Now, save to dumpfile **/
77abe781
MHS
159 saveFile("iclass_mac_attack", "bin", dump,datalen);
160 free(dump);
9f6e9d15
MHS
161 }else
162 {
163 UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType,numberOfCSNs}};
164 memcpy(c.d.asBytes, CSN, 8);
165 SendCommand(&c);
166 }
1e262141 167
1e262141 168 return 0;
169}
170
171int CmdHFiClassReader(const char *Cmd)
172{
aa41c605 173 UsbCommand c = {CMD_READER_ICLASS, {0}};
1e262141 174 SendCommand(&c);
aa41c605
MHS
175 UsbCommand resp;
176 while(!ukbhit()){
177 if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) {
178 uint8_t isOK = resp.arg[0] & 0xff;
179 uint8_t * data = resp.d.asBytes;
180
181 PrintAndLog("isOk:%02x", isOK);
2e9d4b3f
MHS
182 if( isOK == 0){
183 //Aborted
184 PrintAndLog("Quitting...");
185 return 0;
186 }
aa41c605
MHS
187 if(isOK > 0)
188 {
189 PrintAndLog("CSN: %s",sprint_hex(data,8));
190 }
191 if(isOK >= 1)
192 {
193 PrintAndLog("CC: %s",sprint_hex(data+8,8));
194 }else{
195 PrintAndLog("No CC obtained");
196 }
197 } else {
198 PrintAndLog("Command execute timeout");
199 }
200 }
1e262141 201
c3963755 202 return 0;
203}
204
205int CmdHFiClassReader_Replay(const char *Cmd)
206{
207 uint8_t readerType = 0;
208 uint8_t MAC[4]={0x00, 0x00, 0x00, 0x00};
209
210 if (strlen(Cmd)<1) {
211 PrintAndLog("Usage: hf iclass replay <MAC>");
212 PrintAndLog(" sample: hf iclass replay 00112233");
213 return 0;
214 }
215
216 if (param_gethex(Cmd, 0, MAC, 8)) {
217 PrintAndLog("MAC must include 8 HEX symbols");
218 return 1;
219 }
220
221 UsbCommand c = {CMD_READER_ICLASS_REPLAY, {readerType}};
222 memcpy(c.d.asBytes, MAC, 4);
223 SendCommand(&c);
1e262141 224
225 return 0;
226}
227
a66fca86
AD
228int CmdHFiClassReader_Dump(const char *Cmd)
229{
230 uint8_t readerType = 0;
231 uint8_t MAC[4]={0x00,0x00,0x00,0x00};
232 uint8_t KEY[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
233 uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
234 uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
fecd8202 235 //uint8_t CC_temp[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
a66fca86 236 uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
9b82de75
MHS
237 uint8_t keytable[128] = {0};
238 int elite = 0;
239 uint8_t *used_key;
240 int i;
fecd8202 241 if (strlen(Cmd)<1)
242 {
9b82de75
MHS
243 PrintAndLog("Usage: hf iclass dump <Key> [e]");
244 PrintAndLog(" Key - A 16 byte master key");
245 PrintAndLog(" e - If 'e' is specified, the key is interpreted as the 16 byte");
246 PrintAndLog(" Custom Key (KCus), which can be obtained via reader-attack");
247 PrintAndLog(" See 'hf iclass sim 2'. This key should be on iclass-format");
fecd8202 248 PrintAndLog(" sample: hf iclass dump 0011223344556677");
9b82de75
MHS
249
250
a66fca86
AD
251 return 0;
252 }
253
fecd8202 254 if (param_gethex(Cmd, 0, KEY, 16))
255 {
a66fca86
AD
256 PrintAndLog("KEY must include 16 HEX symbols");
257 return 1;
258 }
9b82de75
MHS
259
260 if (param_getchar(Cmd, 1) == 'e')
261 {
262 PrintAndLog("Elite switch on");
263 elite = 1;
264
265 //calc h2
266 hash2(KEY, keytable);
9e28ee9f 267 printarr_human_readable("keytable", keytable, 128);
9b82de75
MHS
268
269 }
270
0eea34a2
MHS
271 UsbCommand resp;
272 uint8_t key_sel[8] = {0};
273 uint8_t key_sel_p[8] = { 0 };
274
aa41c605 275 UsbCommand c = {CMD_READER_ICLASS, {0}};
c8dd9b09 276 c.arg[0] = FLAG_ICLASS_READER_ONLY_ONCE| FLAG_ICLASS_READER_GET_CC;
cb29e00a 277 SendCommand(&c);
fecd8202 278
26c0d833 279
0eea34a2 280
cb29e00a
MHS
281 if (!WaitForResponseTimeout(CMD_ACK,&resp,4500))
282 {
283 PrintAndLog("Command execute timeout");
284 return 0;
285 }
26c0d833 286
cb29e00a
MHS
287 uint8_t isOK = resp.arg[0] & 0xff;
288 uint8_t * data = resp.d.asBytes;
3ad48540 289
cb29e00a
MHS
290 memcpy(CSN,data,8);
291 memcpy(CCNR,data+8,8);
a66fca86 292
cb29e00a 293 PrintAndLog("isOk:%02x", isOK);
9e28ee9f 294
cb29e00a
MHS
295 if(isOK > 0)
296 {
297 PrintAndLog("CSN: %s",sprint_hex(CSN,8));
298 }
299 if(isOK <= 1){
300 PrintAndLog("Failed to obtain CC! Aborting");
301 return 0;
302 }
303 //Status 2 or higher
9e28ee9f 304
cb29e00a
MHS
305 if(elite)
306 {
307 //Get the key index (hash1)
308 uint8_t key_index[8] = {0};
309
310 hash1(CSN, key_index);
311 printvar("hash1", key_index,8);
312 for(i = 0; i < 8 ; i++)
313 key_sel[i] = keytable[key_index[i]] & 0xFF;
314 PrintAndLog("Pre-fortified 'permuted' HS key that would be needed by an iclass reader to talk to above CSN:");
315 printvar("k_sel", key_sel,8);
316 //Permute from iclass format to standard format
317 permutekey_rev(key_sel,key_sel_p);
318 used_key = key_sel_p;
319 }else{
320 used_key = KEY;
321 }
9b82de75 322
cb29e00a
MHS
323 PrintAndLog("Pre-fortified key that would be needed by the OmniKey reader to talk to above CSN:");
324 printvar("Used key",used_key,8);
325 diversifyKey(CSN,used_key, div_key);
326 PrintAndLog("Hash0, a.k.a diversified key, that is computed using Ksel and stored in the card (Block 3):");
327 printvar("Div key", div_key, 8);
328 printvar("CC_NR:",CCNR,12);
329 doMAC(CCNR,12,div_key, MAC);
330 printvar("MAC", MAC, 4);
331
332 uint8_t iclass_data[32000] = {0};
333 uint8_t iclass_datalen = 0;
334 uint8_t iclass_blocksFailed = 0;//Set to 1 if dump was incomplete
335
336 UsbCommand d = {CMD_READER_ICLASS_REPLAY, {readerType}};
337 memcpy(d.d.asBytes, MAC, 4);
338 clearCommandBuffer();
339 SendCommand(&d);
340 PrintAndLog("Waiting for device to dump data. Press button on device and key on keyboard to abort...");
341 while (true) {
342 printf(".");
343 if (ukbhit()) {
344 getchar();
345 printf("\naborted via keyboard!\n");
346 break;
347 }
348 if(WaitForResponseTimeout(CMD_ACK,&resp,4500))
349 {
350 uint64_t dataLength = resp.arg[0];
351 iclass_blocksFailed |= resp.arg[1];
352
353 if(dataLength > 0)
354 {
355 memcpy(iclass_data, resp.d.asBytes,dataLength);
356 iclass_datalen += dataLength;
357 }else
358 {//Last transfer, datalength 0 means the dump is finished
359 PrintAndLog("Dumped %d bytes of data from tag. ", iclass_datalen);
360 if(iclass_blocksFailed)
361 {
362 PrintAndLog("OBS! Some blocks failed to be dumped correctly!");
363 }
364 if(iclass_datalen > 0)
365 {
366 char filename[100] = {0};
367 //create a preferred filename
368 snprintf(filename, 100,"iclass_tagdump-%02x%02x%02x%02x%02x%02x%02x%02x",
369 CSN[0],CSN[1],CSN[2],CSN[3],
370 CSN[4],CSN[5],CSN[6],CSN[7]);
371 saveFile(filename,"bin",iclass_data, iclass_datalen );
372
373 }
374 //Aaaand we're finished
375 return 0;
376 }
377 }
378 }
0eea34a2 379
1e262141 380
381 return 0;
382}
383
fecd8202 384int CmdHFiClass_iso14443A_write(const char *Cmd)
385{
386 uint8_t readerType = 0;
387 uint8_t MAC[4]={0x00,0x00,0x00,0x00};
388 uint8_t KEY[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
389 uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
390 uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
fecd8202 391 uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
3ad48540 392
fecd8202 393 uint8_t blockNo=0;
394 uint8_t bldata[8]={0};
395
396 if (strlen(Cmd)<3)
397 {
398 PrintAndLog("Usage: hf iclass write <Key> <Block> <Data>");
399 PrintAndLog(" sample: hf iclass write 0011223344556677 10 AAAAAAAAAAAAAAAA");
400 return 0;
401 }
402
403 if (param_gethex(Cmd, 0, KEY, 16))
404 {
405 PrintAndLog("KEY must include 16 HEX symbols");
406 return 1;
407 }
408
409 blockNo = param_get8(Cmd, 1);
410 if (blockNo>32)
411 {
412 PrintAndLog("Error: Maximum number of blocks is 32 for iClass 2K Cards!");
413 return 1;
414 }
415 if (param_gethex(Cmd, 2, bldata, 8))
416 {
417 PrintAndLog("Block data must include 8 HEX symbols");
418 return 1;
419 }
420
aa41c605 421 UsbCommand c = {CMD_ICLASS_ISO14443A_WRITE, {0}};
fecd8202 422 SendCommand(&c);
fecd8202 423 UsbCommand resp;
3ad48540 424
fecd8202 425 if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) {
426 uint8_t isOK = resp.arg[0] & 0xff;
427 uint8_t * data = resp.d.asBytes;
428
429 memcpy(CSN,data,8);
430 memcpy(CCNR,data+8,8);
431 PrintAndLog("DEBUG: %s",sprint_hex(CSN,8));
432 PrintAndLog("DEBUG: %s",sprint_hex(CCNR,8));
433 PrintAndLog("isOk:%02x", isOK);
434 } else {
435 PrintAndLog("Command execute timeout");
436 }
3ad48540
MHS
437
438 diversifyKey(CSN,KEY, div_key);
439
fecd8202 440 PrintAndLog("Div Key: %s",sprint_hex(div_key,8));
74a38802 441 doMAC(CCNR, 12,div_key, MAC);
fecd8202 442
3ad48540
MHS
443 UsbCommand c2 = {CMD_ICLASS_ISO14443A_WRITE, {readerType,blockNo}};
444 memcpy(c2.d.asBytes, bldata, 8);
445 memcpy(c2.d.asBytes+8, MAC, 4);
446 SendCommand(&c2);
a66fca86 447
fecd8202 448 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
449 uint8_t isOK = resp.arg[0] & 0xff;
450 uint8_t * data = resp.d.asBytes;
451
452 if (isOK)
453 PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 4));
454 else
455 PrintAndLog("isOk:%02x", isOK);
456 } else {
457 PrintAndLog("Command execute timeout");
458 }
a66fca86
AD
459 return 0;
460}
6f101995
MHS
461int CmdHFiClass_loclass(const char *Cmd)
462{
463 char opt = param_getchar(Cmd, 0);
464
465 if (strlen(Cmd)<1 || opt == 'h') {
466 PrintAndLog("Usage: hf iclass loclass [options]");
467 PrintAndLog("Options:");
468 PrintAndLog("h Show this help");
469 PrintAndLog("t Perform self-test");
470 PrintAndLog("f <filename> Bruteforce iclass dumpfile");
471 PrintAndLog(" An iclass dumpfile is assumed to consist of an arbitrary number of");
472 PrintAndLog(" malicious CSNs, and their protocol responses");
473 PrintAndLog(" The the binary format of the file is expected to be as follows: ");
474 PrintAndLog(" <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>");
475 PrintAndLog(" <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>");
476 PrintAndLog(" <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>");
477 PrintAndLog(" ... totalling N*24 bytes");
478 return 0;
479 }
480 char fileName[255] = {0};
481 if(opt == 'f')
482 {
483 if(param_getstr(Cmd, 1, fileName) > 0)
484 {
485 return bruteforceFileNoKeys(fileName);
486 }else
487 {
488 PrintAndLog("You must specify a filename");
489 }
490 }
491 else if(opt == 't')
492 {
493 int errors = testCipherUtils();
494 errors += testMAC();
495 errors += doKeyTests(0);
496 errors += testElite();
497 if(errors)
498 {
499 prnlog("OBS! There were errors!!!");
500 }
501 return errors;
502 }
a66fca86 503
6f101995
MHS
504 return 0;
505}
c3963755 506
cee5a30d 507static command_t CommandTable[] =
508{
6f101995
MHS
509 {"help", CmdHelp, 1, "This help"},
510 {"list", CmdHFiClassList, 0, "[Deprecated] List iClass history"},
511 {"snoop", CmdHFiClassSnoop, 0, "Eavesdrop iClass communication"},
512 {"sim", CmdHFiClassSim, 0, "Simulate iClass tag"},
513 {"reader",CmdHFiClassReader, 0, "Read an iClass tag"},
514 {"replay",CmdHFiClassReader_Replay, 0, "Read an iClass tag via Reply Attack"},
515 {"dump", CmdHFiClassReader_Dump, 0, "Authenticate and Dump iClass tag"},
516 {"write", CmdHFiClass_iso14443A_write, 0, "Authenticate and Write iClass block"},
517 {"loclass", CmdHFiClass_loclass, 1, "Use loclass to perform bruteforce of reader attack dump"},
518 {NULL, NULL, 0, NULL}
cee5a30d 519};
520
521int CmdHFiClass(const char *Cmd)
522{
523 CmdsParse(CommandTable, Cmd);
524 return 0;
525}
526
527int CmdHelp(const char *Cmd)
528{
529 CmdsHelp(CommandTable);
530 return 0;
531}
Impressum, Datenschutz