]> cvs.zerfleddert.de Git - proxmark3-svn/blob - client/cmdhfmf.c
Fixed bug in HID clone short format. Added EM4xxx block read/write commands
[proxmark3-svn] / client / cmdhfmf.c
1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2011,2012 Merlok
3 //
4 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
5 // at your option, any later version. See the LICENSE.txt file for the text of
6 // the license.
7 //-----------------------------------------------------------------------------
8 // High frequency MIFARE commands
9 //-----------------------------------------------------------------------------
10
11 #include "cmdhfmf.h"
12 #include "proxmark3.h"
13
14 static int CmdHelp(const char *Cmd);
15
16 int CmdHF14AMifare(const char *Cmd)
17 {
18 uint32_t uid = 0;
19 uint32_t nt = 0;
20 uint64_t par_list = 0, ks_list = 0, r_key = 0;
21 uint8_t isOK = 0;
22 uint8_t keyBlock[8] = {0};
23
24 if (param_getchar(Cmd, 0) && param_gethex(Cmd, 0, keyBlock, 8)) {
25 PrintAndLog("Nt must include 8 HEX symbols");
26 return 1;
27 }
28
29
30 UsbCommand c = {CMD_READER_MIFARE, {(uint32_t)bytes_to_num(keyBlock, 4), 0, 0}};
31 start:
32 SendCommand(&c);
33
34 //flush queue
35 while (ukbhit()) getchar();
36
37 // message
38 printf("-------------------------------------------------------------------------\n");
39 printf("Executing command. It may take up to 30 min.\n");
40 printf("Press the key on the proxmark3 device to abort both proxmark3 and client.\n");
41 printf("-------------------------------------------------------------------------\n");
42
43 // wait cycle
44 while (true) {
45 printf(".");
46 fflush(stdout);
47 if (ukbhit()) {
48 getchar();
49 printf("\naborted via keyboard!\n");
50 break;
51 }
52
53 UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 2000);
54 if (resp != NULL) {
55 isOK = resp->arg[0] & 0xff;
56
57 uid = (uint32_t)bytes_to_num(resp->d.asBytes + 0, 4);
58 nt = (uint32_t)bytes_to_num(resp->d.asBytes + 4, 4);
59 par_list = bytes_to_num(resp->d.asBytes + 8, 8);
60 ks_list = bytes_to_num(resp->d.asBytes + 16, 8);
61
62 printf("\n\n");
63 PrintAndLog("isOk:%02x", isOK);
64 if (!isOK) PrintAndLog("Proxmark can't get statistic info. Execution aborted.\n");
65 break;
66 }
67 }
68 printf("\n");
69
70 // error
71 if (isOK != 1) return 1;
72
73 // execute original function from util nonce2key
74 if (nonce2key(uid, nt, par_list, ks_list, &r_key))
75 {
76 isOK = 2;
77 PrintAndLog("Key not found (lfsr_common_prefix list is null). Nt=%08x", nt);
78 } else {
79 printf("------------------------------------------------------------------\n");
80 PrintAndLog("Key found:%012I64x \n", r_key);
81
82 num_to_bytes(r_key, 6, keyBlock);
83 isOK = mfCheckKeys(0, 0, 1, keyBlock, &r_key);
84 }
85 if (!isOK)
86 PrintAndLog("Found valid key:%012I64x", r_key);
87 else
88 {
89 if (isOK != 2) PrintAndLog("Found invalid key. ( Nt=%08x ,Trying use it to run again...", nt);
90 c.arg[0] = nt;
91 goto start;
92 }
93
94 return 0;
95 }
96
97 int CmdHF14AMfWrBl(const char *Cmd)
98 {
99 uint8_t blockNo = 0;
100 uint8_t keyType = 0;
101 uint8_t key[6] = {0, 0, 0, 0, 0, 0};
102 uint8_t bldata[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
103
104 char cmdp = 0x00;
105
106 if (strlen(Cmd)<3) {
107 PrintAndLog("Usage: hf mf wrbl <block number> <key A/B> <key (12 hex symbols)> <block data (32 hex symbols)>");
108 PrintAndLog(" sample: hf mf wrbl 0 A FFFFFFFFFFFF 000102030405060708090A0B0C0D0E0F");
109 return 0;
110 }
111
112 blockNo = param_get8(Cmd, 0);
113 cmdp = param_getchar(Cmd, 1);
114 if (cmdp == 0x00) {
115 PrintAndLog("Key type must be A or B");
116 return 1;
117 }
118 if (cmdp != 'A' && cmdp != 'a') keyType = 1;
119 if (param_gethex(Cmd, 2, key, 12)) {
120 PrintAndLog("Key must include 12 HEX symbols");
121 return 1;
122 }
123 if (param_gethex(Cmd, 3, bldata, 32)) {
124 PrintAndLog("Block data must include 32 HEX symbols");
125 return 1;
126 }
127 PrintAndLog("--block no:%02x key type:%02x key:%s", blockNo, keyType, sprint_hex(key, 6));
128 PrintAndLog("--data: %s", sprint_hex(bldata, 16));
129
130 UsbCommand c = {CMD_MIFARE_WRITEBL, {blockNo, keyType, 0}};
131 memcpy(c.d.asBytes, key, 6);
132 memcpy(c.d.asBytes + 10, bldata, 16);
133 SendCommand(&c);
134 UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
135
136 if (resp != NULL) {
137 uint8_t isOK = resp->arg[0] & 0xff;
138
139 PrintAndLog("isOk:%02x", isOK);
140 } else {
141 PrintAndLog("Command execute timeout");
142 }
143
144 return 0;
145 }
146
147 int CmdHF14AMfRdBl(const char *Cmd)
148 {
149 uint8_t blockNo = 0;
150 uint8_t keyType = 0;
151 uint8_t key[6] = {0, 0, 0, 0, 0, 0};
152
153 char cmdp = 0x00;
154
155
156 if (strlen(Cmd)<3) {
157 PrintAndLog("Usage: hf mf rdbl <block number> <key A/B> <key (12 hex symbols)>");
158 PrintAndLog(" sample: hf mf rdbl 0 A FFFFFFFFFFFF ");
159 return 0;
160 }
161
162 blockNo = param_get8(Cmd, 0);
163 cmdp = param_getchar(Cmd, 1);
164 if (cmdp == 0x00) {
165 PrintAndLog("Key type must be A or B");
166 return 1;
167 }
168 if (cmdp != 'A' && cmdp != 'a') keyType = 1;
169 if (param_gethex(Cmd, 2, key, 12)) {
170 PrintAndLog("Key must include 12 HEX symbols");
171 return 1;
172 }
173 PrintAndLog("--block no:%02x key type:%02x key:%s ", blockNo, keyType, sprint_hex(key, 6));
174
175 UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}};
176 memcpy(c.d.asBytes, key, 6);
177 SendCommand(&c);
178 UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
179
180 if (resp != NULL) {
181 uint8_t isOK = resp->arg[0] & 0xff;
182 uint8_t * data = resp->d.asBytes;
183
184 if (isOK)
185 PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 16));
186 else
187 PrintAndLog("isOk:%02x", isOK);
188 } else {
189 PrintAndLog("Command execute timeout");
190 }
191
192 return 0;
193 }
194
195 int CmdHF14AMfRdSc(const char *Cmd)
196 {
197 int i;
198 uint8_t sectorNo = 0;
199 uint8_t keyType = 0;
200 uint8_t key[6] = {0, 0, 0, 0, 0, 0};
201
202 uint8_t isOK = 0;
203 uint8_t * data = NULL;
204
205 char cmdp = 0x00;
206
207 if (strlen(Cmd)<3) {
208 PrintAndLog("Usage: hf mf rdsc <sector number> <key A/B> <key (12 hex symbols)>");
209 PrintAndLog(" sample: hf mf rdsc 0 A FFFFFFFFFFFF ");
210 return 0;
211 }
212
213 sectorNo = param_get8(Cmd, 0);
214 if (sectorNo > 63) {
215 PrintAndLog("Sector number must be less than 64");
216 return 1;
217 }
218 cmdp = param_getchar(Cmd, 1);
219 if (cmdp == 0x00) {
220 PrintAndLog("Key type must be A or B");
221 return 1;
222 }
223 if (cmdp != 'A' && cmdp != 'a') keyType = 1;
224 if (param_gethex(Cmd, 2, key, 12)) {
225 PrintAndLog("Key must include 12 HEX symbols");
226 return 1;
227 }
228 PrintAndLog("--sector no:%02x key type:%02x key:%s ", sectorNo, keyType, sprint_hex(key, 6));
229
230 UsbCommand c = {CMD_MIFARE_READSC, {sectorNo, keyType, 0}};
231 memcpy(c.d.asBytes, key, 6);
232 SendCommand(&c);
233 UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
234 PrintAndLog(" ");
235
236 if (resp != NULL) {
237 isOK = resp->arg[0] & 0xff;
238 data = resp->d.asBytes;
239
240 PrintAndLog("isOk:%02x", isOK);
241 if (isOK)
242 for (i = 0; i < 2; i++) {
243 PrintAndLog("data:%s", sprint_hex(data + i * 16, 16));
244 }
245 } else {
246 PrintAndLog("Command1 execute timeout");
247 }
248
249 // response2
250 resp = WaitForResponseTimeout(CMD_ACK, 500);
251 PrintAndLog(" ");
252
253 if (resp != NULL) {
254 isOK = resp->arg[0] & 0xff;
255 data = resp->d.asBytes;
256
257 if (isOK)
258 for (i = 0; i < 2; i++) {
259 PrintAndLog("data:%s", sprint_hex(data + i * 16, 16));
260 }
261 } else {
262 PrintAndLog("Command2 execute timeout");
263 }
264
265 return 0;
266 }
267
268 int CmdHF14AMfDump(const char *Cmd)
269 {
270 int i, j;
271
272 uint8_t keyA[40][6];
273 uint8_t keyB[40][6];
274 uint8_t rights[40][4];
275
276 FILE *fin;
277 FILE *fout;
278
279 UsbCommand *resp;
280
281 if ((fin = fopen("dumpkeys.bin","rb")) == NULL) {
282 PrintAndLog("Could not find file dumpkeys.bin");
283 return 1;
284 }
285
286 if ((fout = fopen("dumpdata.bin","wb")) == NULL) {
287 PrintAndLog("Could not create file name dumpdata.bin");
288 return 1;
289 }
290
291 // Read key file
292
293 for (i=0 ; i<16 ; i++) {
294 fread ( keyA[i], 1, 6, fin );
295 }
296 for (i=0 ; i<16 ; i++) {
297 fread ( keyB[i], 1, 6, fin );
298 }
299
300 // Read access rights to sectors
301
302 PrintAndLog("|-----------------------------------------|");
303 PrintAndLog("|------ Reading sector access bits...-----|");
304 PrintAndLog("|-----------------------------------------|");
305
306 for (i = 0 ; i < 16 ; i++) {
307 UsbCommand c = {CMD_MIFARE_READBL, {4*i + 3, 0, 0}};
308 memcpy(c.d.asBytes, keyA[i], 6);
309 SendCommand(&c);
310 resp = WaitForResponseTimeout(CMD_ACK, 1500);
311
312 if (resp != NULL) {
313 uint8_t isOK = resp->arg[0] & 0xff;
314 uint8_t *data = resp->d.asBytes;
315 if (isOK){
316 rights[i][0] = ((data[7] & 0x10)>>4) | ((data[8] & 0x1)<<1) | ((data[8] & 0x10)>>2);
317 rights[i][1] = ((data[7] & 0x20)>>5) | ((data[8] & 0x2)<<0) | ((data[8] & 0x20)>>3);
318 rights[i][2] = ((data[7] & 0x40)>>6) | ((data[8] & 0x4)>>1) | ((data[8] & 0x40)>>4);
319 rights[i][3] = ((data[7] & 0x80)>>7) | ((data[8] & 0x8)>>2) | ((data[8] & 0x80)>>5);
320 }
321 else{
322 PrintAndLog("Could not get access rights for block %d", i);
323 }
324 }
325 else {
326 PrintAndLog("Command execute timeout");
327 }
328 }
329
330 // Read blocks and print to file
331
332 PrintAndLog("|-----------------------------------------|");
333 PrintAndLog("|----- Dumping all blocks to file... -----|");
334 PrintAndLog("|-----------------------------------------|");
335
336 for (i=0 ; i<16 ; i++) {
337 for (j=0 ; j<4 ; j++) {
338 if (j == 3){
339 UsbCommand c = {CMD_MIFARE_READBL, {i*4 + j, 0, 0}};
340 memcpy(c.d.asBytes, keyA[i], 6);
341 SendCommand(&c);
342 resp = WaitForResponseTimeout(CMD_ACK, 1500);
343 }
344 else{
345 if ((rights[i][j] == 6) | (rights[i][j] == 5)) {
346 UsbCommand c = {CMD_MIFARE_READBL, {i*4+j, 1, 0}};
347 memcpy(c.d.asBytes, keyB[i], 6);
348 SendCommand(&c);
349 resp = WaitForResponseTimeout(CMD_ACK, 1500);
350 }
351 else if (rights[i][j] == 7) {
352 PrintAndLog("Access rights do not allow reading of sector %d block %d",i,j);
353 }
354 else {
355 UsbCommand c = {CMD_MIFARE_READBL, {i*4+j, 0, 0}};
356 memcpy(c.d.asBytes, keyA[i], 6);
357 SendCommand(&c);
358 resp = WaitForResponseTimeout(CMD_ACK, 1500);
359 }
360 }
361
362 if (resp != NULL) {
363 uint8_t isOK = resp->arg[0] & 0xff;
364 uint8_t *data = resp->d.asBytes;
365 if (j == 3) {
366 data[0] = (keyA[i][0]);
367 data[1] = (keyA[i][1]);
368 data[2] = (keyA[i][2]);
369 data[3] = (keyA[i][3]);
370 data[4] = (keyA[i][4]);
371 data[5] = (keyA[i][5]);
372 data[10] = (keyB[i][0]);
373 data[11] = (keyB[i][1]);
374 data[12] = (keyB[i][2]);
375 data[13] = (keyB[i][3]);
376 data[14] = (keyB[i][4]);
377 data[15] = (keyB[i][5]);
378 }
379 if (isOK) {
380 fwrite ( data, 1, 16, fout );
381 }
382 else {
383 PrintAndLog("Could not get access rights for block %d", i);
384 }
385 }
386 else {
387 PrintAndLog("Command execute timeout");
388 }
389 }
390 }
391
392 fclose(fin);
393 fclose(fout);
394
395 return 0;
396 }
397
398 int CmdHF14AMfRestore(const char *Cmd)
399 {
400
401 int i,j;
402 uint8_t keyType = 0;
403 uint8_t key[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
404 uint8_t bldata[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
405 uint8_t keyA[16][6];
406 uint8_t keyB[16][6];
407
408 FILE *fdump;
409 FILE *fkeys;
410
411 if ((fdump = fopen("dumpdata.bin","rb")) == NULL) {
412 PrintAndLog("Could not find file dumpdata.bin");
413 return 1;
414 }
415 if ((fkeys = fopen("dumpkeys.bin","rb")) == NULL) {
416 PrintAndLog("Could not find file dumpkeys.bin");
417 return 1;
418 }
419
420 for (i=0 ; i<16 ; i++) {
421 fread(keyA[i], 1, 6, fkeys);
422 }
423 for (i=0 ; i<16 ; i++) {
424 fread(keyB[i], 1, 6, fkeys);
425 }
426
427 PrintAndLog("Restoring dumpdata.bin to card");
428
429 for (i=0 ; i<16 ; i++) {
430 for( j=0 ; j<4 ; j++) {
431 UsbCommand c = {CMD_MIFARE_WRITEBL, {i*4 + j, keyType, 0}};
432 memcpy(c.d.asBytes, key, 6);
433
434 fread(bldata, 1, 16, fdump);
435
436 if (j == 3) {
437 bldata[0] = (keyA[i][0]);
438 bldata[1] = (keyA[i][1]);
439 bldata[2] = (keyA[i][2]);
440 bldata[3] = (keyA[i][3]);
441 bldata[4] = (keyA[i][4]);
442 bldata[5] = (keyA[i][5]);
443 bldata[10] = (keyB[i][0]);
444 bldata[11] = (keyB[i][1]);
445 bldata[12] = (keyB[i][2]);
446 bldata[13] = (keyB[i][3]);
447 bldata[14] = (keyB[i][4]);
448 bldata[15] = (keyB[i][5]);
449 }
450
451 PrintAndLog("Writing to block %2d: %s", i*4+j, sprint_hex(bldata, 16));
452
453 /*
454 PrintAndLog("Writing to block %2d: %s Confirm? [Y,N]", i*4+j, sprint_hex(bldata, 16));
455
456 scanf("%c",&ch);
457 if ((ch != 'y') && (ch != 'Y')){
458 PrintAndLog("Aborting !");
459 return 1;
460 }
461 */
462
463 memcpy(c.d.asBytes + 10, bldata, 16);
464 SendCommand(&c);
465 UsbCommand *resp = WaitForResponseTimeout(CMD_ACK, 1500);
466
467 if (resp != NULL) {
468 uint8_t isOK = resp->arg[0] & 0xff;
469 PrintAndLog("isOk:%02x", isOK);
470 } else {
471 PrintAndLog("Command execute timeout");
472 }
473 }
474 }
475
476 fclose(fdump);
477 fclose(fkeys);
478 return 0;
479 }
480
481 int CmdHF14AMfNested(const char *Cmd)
482 {
483 int i, j, res, iterations;
484 sector * e_sector = NULL;
485 uint8_t blockNo = 0;
486 uint8_t keyType = 0;
487 uint8_t trgBlockNo = 0;
488 uint8_t trgKeyType = 0;
489 uint8_t blDiff = 0;
490 int SectorsCnt = 0;
491 uint8_t key[6] = {0, 0, 0, 0, 0, 0};
492 uint8_t keyBlock[16 * 6];
493 uint64_t key64 = 0;
494 int transferToEml = 0;
495
496 int createDumpFile = 0;
497 FILE *fkeys;
498 uint8_t standart[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
499 uint8_t tempkey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
500
501 char cmdp, ctmp;
502
503 if (strlen(Cmd)<3) {
504 PrintAndLog("Usage:");
505 PrintAndLog(" all sectors: hf mf nested <card memory> <block number> <key A/B> <key (12 hex symbols)> [t,d]");
506 PrintAndLog(" one sector: hf mf nested o <block number> <key A/B> <key (12 hex symbols)>");
507 PrintAndLog(" <target block number> <target key A/B> [t]");
508 PrintAndLog("card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, <other> - 1K");
509 PrintAndLog("t - transfer keys into emulator memory");
510 PrintAndLog("d - write keys to binary file");
511 PrintAndLog(" ");
512 PrintAndLog(" sample1: hf mf nested 1 0 A FFFFFFFFFFFF ");
513 PrintAndLog(" sample1: hf mf nested 1 0 A FFFFFFFFFFFF t ");
514 PrintAndLog(" sample1: hf mf nested 1 0 A FFFFFFFFFFFF d ");
515 PrintAndLog(" sample2: hf mf nested o 0 A FFFFFFFFFFFF 4 A");
516 return 0;
517 }
518
519 cmdp = param_getchar(Cmd, 0);
520 blockNo = param_get8(Cmd, 1);
521 ctmp = param_getchar(Cmd, 2);
522 if (ctmp == 0x00) {
523 PrintAndLog("Key type must be A or B");
524 return 1;
525 }
526 if (ctmp != 'A' && ctmp != 'a') keyType = 1;
527 if (param_gethex(Cmd, 3, key, 12)) {
528 PrintAndLog("Key must include 12 HEX symbols");
529 return 1;
530 }
531
532 if (cmdp == 'o' || cmdp == 'O') {
533 cmdp = 'o';
534 trgBlockNo = param_get8(Cmd, 4);
535 ctmp = param_getchar(Cmd, 5);
536 if (ctmp == 0x00) {
537 PrintAndLog("Target key type must be A or B");
538 return 1;
539 }
540 if (ctmp != 'A' && ctmp != 'a') trgKeyType = 1;
541 } else {
542 switch (cmdp) {
543 case '0': SectorsCnt = 05; break;
544 case '1': SectorsCnt = 16; break;
545 case '2': SectorsCnt = 32; break;
546 case '4': SectorsCnt = 64; break;
547 default: SectorsCnt = 16;
548 }
549 }
550
551 ctmp = param_getchar(Cmd, 4);
552 if (ctmp == 't' || ctmp == 'T') transferToEml = 1;
553 else if (ctmp == 'd' || ctmp == 'D') createDumpFile = 1;
554
555 ctmp = param_getchar(Cmd, 6);
556 transferToEml |= (ctmp == 't' || ctmp == 'T');
557 transferToEml |= (ctmp == 'd' || ctmp == 'D');
558
559 PrintAndLog("--block no:%02x key type:%02x key:%s etrans:%d", blockNo, keyType, sprint_hex(key, 6), transferToEml);
560 if (cmdp == 'o')
561 PrintAndLog("--target block no:%02x target key type:%02x ", trgBlockNo, trgKeyType);
562
563 if (cmdp == 'o') {
564 if (mfnested(blockNo, keyType, key, trgBlockNo, trgKeyType, keyBlock)) {
565 PrintAndLog("Nested error.");
566 return 2;
567 }
568
569 for (i = 0; i < 16; i++) {
570 PrintAndLog("count=%d key= %s", i, sprint_hex(keyBlock + i * 6, 6));
571 }
572
573 // test keys
574 res = mfCheckKeys(trgBlockNo, trgKeyType, 8, keyBlock, &key64);
575 if (res)
576 res = mfCheckKeys(trgBlockNo, trgKeyType, 8, &keyBlock[6 * 8], &key64);
577 if (!res) {
578 PrintAndLog("Found valid key:%012I64x", key64);
579
580 // transfer key to the emulator
581 if (transferToEml) {
582 mfEmlGetMem(keyBlock, (trgBlockNo / 4) * 4 + 3, 1);
583
584 if (!trgKeyType)
585 num_to_bytes(key64, 6, keyBlock);
586 else
587 num_to_bytes(key64, 6, &keyBlock[10]);
588 mfEmlSetMem(keyBlock, (trgBlockNo / 4) * 4 + 3, 1);
589 }
590 } else {
591 PrintAndLog("No valid key found");
592 }
593 }
594 else { // ------------------------------------ multiple sectors working
595 blDiff = blockNo % 4;
596 PrintAndLog("Block shift=%d", blDiff);
597 e_sector = calloc(SectorsCnt, sizeof(sector));
598 if (e_sector == NULL) return 1;
599
600 //test current key 4 sectors
601 memcpy(keyBlock, key, 6);
602 num_to_bytes(0xa0a1a2a3a4a5, 6, (uint8_t*)(keyBlock + 1 * 6));
603 num_to_bytes(0xb0b1b2b3b4b5, 6, (uint8_t*)(keyBlock + 2 * 6));
604 num_to_bytes(0xffffffffffff, 6, (uint8_t*)(keyBlock + 3 * 6));
605 num_to_bytes(0x000000000000, 6, (uint8_t*)(keyBlock + 4 * 6));
606 num_to_bytes(0xaabbccddeeff, 6, (uint8_t*)(keyBlock + 5 * 6));
607
608 PrintAndLog("Testing known keys. Sector count=%d", SectorsCnt);
609 for (i = 0; i < SectorsCnt; i++) {
610 for (j = 0; j < 2; j++) {
611 if (e_sector[i].foundKey[j]) continue;
612
613 res = mfCheckKeys(i * 4 + blDiff, j, 6, keyBlock, &key64);
614
615 if (!res) {
616 e_sector[i].Key[j] = key64;
617 e_sector[i].foundKey[j] = 1;
618 }
619 }
620 }
621
622 // nested sectors
623 iterations = 0;
624 PrintAndLog("nested...");
625 for (i = 0; i < NESTED_SECTOR_RETRY; i++) {
626 for (trgBlockNo = blDiff; trgBlockNo < SectorsCnt * 4; trgBlockNo = trgBlockNo + 4)
627 for (trgKeyType = 0; trgKeyType < 2; trgKeyType++) {
628 if (e_sector[trgBlockNo / 4].foundKey[trgKeyType]) continue;
629 if (mfnested(blockNo, keyType, key, trgBlockNo, trgKeyType, keyBlock)) continue;
630
631 iterations++;
632
633 //try keys from nested
634 res = mfCheckKeys(trgBlockNo, trgKeyType, 8, keyBlock, &key64);
635 if (res)
636 res = mfCheckKeys(trgBlockNo, trgKeyType, 8, &keyBlock[6 * 8], &key64);
637 if (!res) {
638 PrintAndLog("Found valid key:%012I64x", key64);
639 e_sector[trgBlockNo / 4].foundKey[trgKeyType] = 1;
640 e_sector[trgBlockNo / 4].Key[trgKeyType] = key64;
641 }
642 }
643 }
644
645 PrintAndLog("Iterations count: %d", iterations);
646 //print them
647 PrintAndLog("|---|----------------|---|----------------|---|");
648 PrintAndLog("|sec|key A |res|key B |res|");
649 PrintAndLog("|---|----------------|---|----------------|---|");
650 for (i = 0; i < SectorsCnt; i++) {
651 PrintAndLog("|%03d| %012I64x | %d | %012I64x | %d |", i,
652 e_sector[i].Key[0], e_sector[i].foundKey[0], e_sector[i].Key[1], e_sector[i].foundKey[1]);
653 }
654 PrintAndLog("|---|----------------|---|----------------|---|");
655
656 // transfer them to the emulator
657 if (transferToEml) {
658 for (i = 0; i < SectorsCnt; i++) {
659 mfEmlGetMem(keyBlock, i * 4 + 3, 1);
660 if (e_sector[i].foundKey[0])
661 num_to_bytes(e_sector[i].Key[0], 6, keyBlock);
662 if (e_sector[i].foundKey[1])
663 num_to_bytes(e_sector[i].Key[1], 6, &keyBlock[10]);
664 mfEmlSetMem(keyBlock, i * 4 + 3, 1);
665 }
666 }
667
668 // Create dump file
669 if (createDumpFile) {
670 if ((fkeys = fopen("dumpkeys.bin","wb")) == NULL) {
671 PrintAndLog("Could not create file dumpkeys.bin");
672 free(e_sector);
673 return 1;
674 }
675 PrintAndLog("Printing keys to bynary file dumpkeys.bin...");
676 for(i=0; i<16; i++) {
677 if (e_sector[i].foundKey[0]){
678 num_to_bytes(e_sector[i].Key[0], 6, tempkey);
679 fwrite ( tempkey, 1, 6, fkeys );
680 }
681 else{
682 fwrite ( &standart, 1, 6, fkeys );
683 }
684 }
685 for(i=0; i<16; i++) {
686 if (e_sector[i].foundKey[1]){
687 num_to_bytes(e_sector[i].Key[1], 6, tempkey);
688 fwrite ( tempkey, 1, 6, fkeys );
689 }
690 else{
691 fwrite ( &standart, 1, 6, fkeys );
692 }
693 }
694 fclose(fkeys);
695 }
696
697 free(e_sector);
698 }
699
700 return 0;
701 }
702
703 static uint32_t
704 get_trailer_block (uint32_t uiBlock)
705 {
706 // Test if we are in the small or big sectors
707 uint32_t trailer_block = 0;
708 if (uiBlock < 128) {
709 trailer_block = uiBlock + (3 - (uiBlock % 4));
710 } else {
711 trailer_block = uiBlock + (15 - (uiBlock % 16));
712 }
713 return trailer_block;
714 }
715 int CmdHF14AMfChk(const char *Cmd)
716 {
717 FILE * f;
718 char filename[256]={0};
719 char buf[13];
720 uint8_t *keyBlock = NULL, *p;
721 uint8_t stKeyBlock = 20;
722
723 int i, res;
724 int keycnt = 0;
725 char ctmp = 0x00;
726 uint8_t blockNo = 0;
727 uint8_t SectorsCnt = 1;
728 uint8_t keyType = 0;
729 uint64_t key64 = 0;
730
731 int transferToEml = 0;
732 int createDumpFile = 0;
733
734 keyBlock = calloc(stKeyBlock, 6);
735 if (keyBlock == NULL) return 1;
736
737 num_to_bytes(0xffffffffffff, 6, (uint8_t*)(keyBlock + 0 * 6)); // Default key (first key used by program if no user defined key)
738 num_to_bytes(0x000000000000, 6, (uint8_t*)(keyBlock + 1 * 6)); // Blank key
739 num_to_bytes(0xa0a1a2a3a4a5, 6, (uint8_t*)(keyBlock + 2 * 6)); // NFCForum MAD key
740 num_to_bytes(0xb0b1b2b3b4b5, 6, (uint8_t*)(keyBlock + 3 * 6));
741 num_to_bytes(0xaabbccddeeff, 6, (uint8_t*)(keyBlock + 4 * 6));
742 num_to_bytes(0x4d3a99c351dd, 6, (uint8_t*)(keyBlock + 5 * 6));
743 num_to_bytes(0x1a982c7e459a, 6, (uint8_t*)(keyBlock + 6 * 6));
744 num_to_bytes(0xd3f7d3f7d3f7, 6, (uint8_t*)(keyBlock + 7 * 6));
745 num_to_bytes(0x714c5c886e97, 6, (uint8_t*)(keyBlock + 8 * 6));
746 num_to_bytes(0x587ee5f9350f, 6, (uint8_t*)(keyBlock + 9 * 6));
747 num_to_bytes(0xa0478cc39091, 6, (uint8_t*)(keyBlock + 10 * 6));
748 num_to_bytes(0x533cb6c723f6, 6, (uint8_t*)(keyBlock + 11 * 6));
749 num_to_bytes(0x8fd0a4f256e9, 6, (uint8_t*)(keyBlock + 12 * 6));
750
751 if (strlen(Cmd)<3) {
752 PrintAndLog("Usage: hf mf chk <block number>/<*card memory> <key type (A/B/?)> [t] [<key (12 hex symbols)>] [<dic (*.dic)>]");
753 PrintAndLog(" * - all sectors");
754 PrintAndLog("card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, <other> - 1K");
755 // PrintAndLog("d - write keys to binary file\n");
756
757 PrintAndLog(" sample: hf mf chk 0 A 1234567890ab keys.dic");
758 PrintAndLog(" hf mf chk *1 ? t");
759 return 0;
760 }
761
762 if (param_getchar(Cmd, 0)=='*') {
763 blockNo = 3;
764 switch(param_getchar(Cmd+1, 0)) {
765 case '0': SectorsCnt = 5; break;
766 case '1': SectorsCnt = 16; break;
767 case '2': SectorsCnt = 32; break;
768 case '4': SectorsCnt = 40; break;
769 default: SectorsCnt = 16;
770 }
771 }
772 else
773 blockNo = param_get8(Cmd, 0);
774
775 ctmp = param_getchar(Cmd, 1);
776 switch (ctmp) {
777 case 'a': case 'A':
778 keyType = !0;
779 break;
780 case 'b': case 'B':
781 keyType = !1;
782 break;
783 case '?':
784 keyType = 2;
785 break;
786 default:
787 PrintAndLog("Key type must be A , B or ?");
788 return 1;
789 };
790
791 ctmp = param_getchar(Cmd, 2);
792 if (ctmp == 't' || ctmp == 'T') transferToEml = 1;
793 else if (ctmp == 'd' || ctmp == 'D') createDumpFile = 1;
794
795 for (i = transferToEml || createDumpFile; param_getchar(Cmd, 2 + i); i++) {
796 if (!param_gethex(Cmd, 2 + i, keyBlock + 6 * keycnt, 12)) {
797 if ( stKeyBlock - keycnt < 2) {
798 p = realloc(keyBlock, 6*(stKeyBlock+=10));
799 if (!p) {
800 PrintAndLog("Cannot allocate memory for Keys");
801 free(keyBlock);
802 return 2;
803 }
804 keyBlock = p;
805 }
806 PrintAndLog("chk key[%d] %02x%02x%02x%02x%02x%02x", keycnt,
807 (keyBlock + 6*keycnt)[0],(keyBlock + 6*keycnt)[1], (keyBlock + 6*keycnt)[2],
808 (keyBlock + 6*keycnt)[3], (keyBlock + 6*keycnt)[4], (keyBlock + 6*keycnt)[5], 6);
809 keycnt++;
810 } else {
811 // May be a dic file
812 if ( param_getstr(Cmd, 2 + i,filename) > 255 ) {
813 PrintAndLog("File name too long");
814 free(keyBlock);
815 return 2;
816 }
817
818 if ( (f = fopen( filename , "r")) ) {
819 while( !feof(f) ){
820 memset(buf, 0, sizeof(buf));
821 fgets(buf, sizeof(buf), f);
822
823 if (strlen(buf) < 12 || buf[11] == '\n')
824 continue;
825
826 while (fgetc(f) != '\n' && !feof(f)) ; //goto next line
827
828 if( buf[0]=='#' ) continue; //The line start with # is remcommnet,skip
829
830 if (!isxdigit(buf[0])){
831 PrintAndLog("File content error. '%s' must include 12 HEX symbols",buf);
832 continue;
833 }
834
835 buf[12] = 0;
836
837 if ( stKeyBlock - keycnt < 2) {
838 p = realloc(keyBlock, 6*(stKeyBlock+=10));
839 if (!p) {
840 PrintAndLog("Cannot allocate memory for defKeys");
841 free(keyBlock);
842 return 2;
843 }
844 keyBlock = p;
845 }
846 memset(keyBlock + 6 * keycnt, 0, 6);
847 num_to_bytes(strtoll(buf, NULL, 16), 6, keyBlock + 6*keycnt);
848 PrintAndLog("chk custom key[%d] %012I64x", keycnt, bytes_to_num(keyBlock + 6*keycnt, 6));
849 keycnt++;
850 }
851 } else {
852 PrintAndLog("File: %s: not found or locked.", filename);
853 free(keyBlock);
854 return 1;
855 fclose(f);
856 }
857 }
858 }
859
860 if (keycnt == 0) {
861 PrintAndLog("No key specified,try default keys");
862 for (;keycnt <=12; keycnt++)
863 PrintAndLog("chk default key[%d] %02x%02x%02x%02x%02x%02x", keycnt,
864 (keyBlock + 6*keycnt)[0],(keyBlock + 6*keycnt)[1], (keyBlock + 6*keycnt)[2],
865 (keyBlock + 6*keycnt)[3], (keyBlock + 6*keycnt)[4], (keyBlock + 6*keycnt)[5], 6);
866 }
867
868 for ( int t = !keyType ; t < 2 ; keyType==2?(t++):(t=2) ) {
869 int b=blockNo;
870 for (int i=0; i<SectorsCnt; ++i) {
871 PrintAndLog("--SectorsCnt:%d block no:0x%02x key type:%C key count:%d ", i, b, t?'B':'A', keycnt);
872 int size = keycnt>8?8:keycnt;
873 for (int c = 0; c < keycnt; c+=size) {
874 size=keycnt-c>8?8:keycnt-c;
875 res = mfCheckKeys(b, t, size, keyBlock +6*c, &key64);
876 if (res !=1) {
877 if (!res) {
878 PrintAndLog("Found valid key:[%012I64x]",key64);
879 if (transferToEml) {
880 uint8_t block[16];
881 mfEmlGetMem(block, get_trailer_block(b), 1);
882 num_to_bytes(key64, 6, block + t*10);
883 mfEmlSetMem(block, get_trailer_block(b), 1);
884 }
885 break;
886 }
887 else {
888 printf("Not found yet, keycnt:%d\r", c+size);
889 fflush(stdout);
890 }
891 } else {
892 PrintAndLog("Command execute timeout");
893 }
894 }
895 b<127?(b+=4):(b+=16);
896 }
897 }
898
899 free(keyBlock);
900
901 /*
902 // Create dump file
903 if (createDumpFile) {
904 if ((fkeys = fopen("dumpkeys.bin","wb")) == NULL) {
905 PrintAndLog("Could not create file dumpkeys.bin");
906 free(e_sector);
907 return 1;
908 }
909 PrintAndLog("Printing keys to bynary file dumpkeys.bin...");
910 for(i=0; i<16; i++) {
911 if (e_sector[i].foundKey[0]){
912 num_to_bytes(e_sector[i].Key[0], 6, tempkey);
913 fwrite ( tempkey, 1, 6, fkeys );
914 }
915 else{
916 fwrite ( &standart, 1, 6, fkeys );
917 }
918 }
919 for(i=0; i<16; i++) {
920 if (e_sector[i].foundKey[1]){
921 num_to_bytes(e_sector[i].Key[1], 6, tempkey);
922 fwrite ( tempkey, 1, 6, fkeys );
923 }
924 else{
925 fwrite ( &standart, 1, 6, fkeys );
926 }
927 }
928 fclose(fkeys);
929 }
930 */
931 return 0;
932 }
933
934 int CmdHF14AMf1kSim(const char *Cmd)
935 {
936 uint8_t uid[4] = {0, 0, 0, 0};
937
938 if (param_getchar(Cmd, 0) == 'h') {
939 PrintAndLog("Usage: hf mf sim <uid (8 hex symbols)>");
940 PrintAndLog(" sample: hf mf sim 0a0a0a0a ");
941 return 0;
942 }
943
944 if (param_getchar(Cmd, 0) && param_gethex(Cmd, 0, uid, 8)) {
945 PrintAndLog("UID must include 8 HEX symbols");
946 return 1;
947 }
948 PrintAndLog(" uid:%s ", sprint_hex(uid, 4));
949
950 UsbCommand c = {CMD_SIMULATE_MIFARE_CARD, {0, 0, 0}};
951 memcpy(c.d.asBytes, uid, 4);
952 SendCommand(&c);
953
954 return 0;
955 }
956
957 int CmdHF14AMfDbg(const char *Cmd)
958 {
959 int dbgMode = param_get32ex(Cmd, 0, 0, 10);
960 if (dbgMode > 4) {
961 PrintAndLog("Max debud mode parameter is 4 \n");
962 }
963
964 if (strlen(Cmd) < 1 || !param_getchar(Cmd, 0) || dbgMode > 4) {
965 PrintAndLog("Usage: hf mf dbg <debug level>");
966 PrintAndLog(" 0 - no debug messages");
967 PrintAndLog(" 1 - error messages");
968 PrintAndLog(" 2 - all messages");
969 PrintAndLog(" 4 - extended debug mode");
970 return 0;
971 }
972
973 UsbCommand c = {CMD_MIFARE_SET_DBGMODE, {dbgMode, 0, 0}};
974 SendCommand(&c);
975
976 return 0;
977 }
978
979 int CmdHF14AMfEGet(const char *Cmd)
980 {
981 uint8_t blockNo = 0;
982 uint8_t data[3 * 16];
983 int i;
984
985 if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
986 PrintAndLog("Usage: hf mf eget <block number>");
987 PrintAndLog(" sample: hf mf eget 0 ");
988 return 0;
989 }
990
991 blockNo = param_get8(Cmd, 0);
992
993 PrintAndLog(" ");
994 if (!mfEmlGetMem(data, blockNo, 3)) {
995 for (i = 0; i < 3; i++) {
996 PrintAndLog("data[%d]:%s", blockNo + i, sprint_hex(data + i * 16, 16));
997 }
998 } else {
999 PrintAndLog("Command execute timeout");
1000 }
1001
1002 return 0;
1003 }
1004
1005 int CmdHF14AMfEClear(const char *Cmd)
1006 {
1007 if (param_getchar(Cmd, 0) == 'h') {
1008 PrintAndLog("Usage: hf mf eclr");
1009 PrintAndLog("It set card emulator memory to empty data blocks and key A/B FFFFFFFFFFFF \n");
1010 return 0;
1011 }
1012
1013 UsbCommand c = {CMD_MIFARE_EML_MEMCLR, {0, 0, 0}};
1014 SendCommand(&c);
1015 return 0;
1016 }
1017
1018 int CmdHF14AMfESet(const char *Cmd)
1019 {
1020 uint8_t memBlock[16];
1021 uint8_t blockNo = 0;
1022
1023 memset(memBlock, 0x00, sizeof(memBlock));
1024
1025 if (strlen(Cmd) < 3 || param_getchar(Cmd, 0) == 'h') {
1026 PrintAndLog("Usage: hf mf eset <block number> <block data (32 hex symbols)>");
1027 PrintAndLog(" sample: hf mf eset 1 000102030405060708090a0b0c0d0e0f ");
1028 return 0;
1029 }
1030
1031 blockNo = param_get8(Cmd, 0);
1032
1033 if (param_gethex(Cmd, 1, memBlock, 32)) {
1034 PrintAndLog("block data must include 32 HEX symbols");
1035 return 1;
1036 }
1037
1038 // 1 - blocks count
1039 UsbCommand c = {CMD_MIFARE_EML_MEMSET, {blockNo, 1, 0}};
1040 memcpy(c.d.asBytes, memBlock, 16);
1041 SendCommand(&c);
1042 return 0;
1043 }
1044
1045 int CmdHF14AMfELoad(const char *Cmd)
1046 {
1047 FILE * f;
1048 char filename[20];
1049 char * fnameptr = filename;
1050 char buf[64];
1051 uint8_t buf8[64];
1052 int i, len, blockNum;
1053
1054 memset(filename, 0, sizeof(filename));
1055 memset(buf, 0, sizeof(buf));
1056
1057 if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) {
1058 PrintAndLog("It loads emul dump from the file `filename.eml`");
1059 PrintAndLog("Usage: hf mf eload <file name w/o `.eml`>");
1060 PrintAndLog(" sample: hf mf eload filename");
1061 return 0;
1062 }
1063
1064 len = strlen(Cmd);
1065 if (len > 14) len = 14;
1066
1067 memcpy(filename, Cmd, len);
1068 fnameptr += len;
1069
1070 sprintf(fnameptr, ".eml");
1071
1072 // open file
1073 f = fopen(filename, "r");
1074 if (f == NULL) {
1075 PrintAndLog("File not found or locked.");
1076 return 1;
1077 }
1078
1079 blockNum = 0;
1080 while(!feof(f)){
1081 memset(buf, 0, sizeof(buf));
1082 fgets(buf, sizeof(buf), f);
1083
1084 if (strlen(buf) < 32){
1085 if(strlen(buf) && feof(f))
1086 break;
1087 PrintAndLog("File content error. Block data must include 32 HEX symbols");
1088 return 2;
1089 }
1090 for (i = 0; i < 32; i += 2)
1091 sscanf(&buf[i], "%02x", (unsigned int *)&buf8[i / 2]);
1092 // PrintAndLog("data[%02d]:%s", blockNum, sprint_hex(buf8, 16));
1093
1094 if (mfEmlSetMem(buf8, blockNum, 1)) {
1095 PrintAndLog("Cant set emul block: %d", blockNum);
1096 return 3;
1097 }
1098 blockNum++;
1099
1100 if (blockNum >= 32 * 4 + 8 * 16) break;
1101 }
1102 fclose(f);
1103
1104 if (blockNum != 16 * 4 && blockNum != 32 * 4 + 8 * 16){
1105 PrintAndLog("File content error. There must be 64 blocks");
1106 return 4;
1107 }
1108 PrintAndLog("Loaded from file: %s", filename);
1109 return 0;
1110 }
1111
1112 int CmdHF14AMfESave(const char *Cmd)
1113 {
1114 FILE * f;
1115 char filename[20];
1116 char * fnameptr = filename;
1117 uint8_t buf[64];
1118 int i, j, len;
1119
1120 memset(filename, 0, sizeof(filename));
1121 memset(buf, 0, sizeof(buf));
1122
1123 if (param_getchar(Cmd, 0) == 'h') {
1124 PrintAndLog("It saves emul dump into the file `filename.eml` or `cardID.eml`");
1125 PrintAndLog("Usage: hf mf esave [file name w/o `.eml`]");
1126 PrintAndLog(" sample: hf mf esave ");
1127 PrintAndLog(" hf mf esave filename");
1128 return 0;
1129 }
1130
1131 len = strlen(Cmd);
1132 if (len > 14) len = 14;
1133
1134 if (len < 1) {
1135 // get filename
1136 if (mfEmlGetMem(buf, 0, 1)) {
1137 PrintAndLog("Cant get block: %d", 0);
1138 return 1;
1139 }
1140 for (j = 0; j < 7; j++, fnameptr += 2)
1141 sprintf(fnameptr, "%02x", buf[j]);
1142 } else {
1143 memcpy(filename, Cmd, len);
1144 fnameptr += len;
1145 }
1146
1147 sprintf(fnameptr, ".eml");
1148
1149 // open file
1150 f = fopen(filename, "w+");
1151
1152 // put hex
1153 for (i = 0; i < 32 * 4 + 8 * 16; i++) {
1154 if (mfEmlGetMem(buf, i, 1)) {
1155 PrintAndLog("Cant get block: %d", i);
1156 break;
1157 }
1158 for (j = 0; j < 16; j++)
1159 fprintf(f, "%02x", buf[j]);
1160 fprintf(f,"\n");
1161 }
1162 fclose(f);
1163
1164 PrintAndLog("Saved to file: %s", filename);
1165
1166 return 0;
1167 }
1168
1169 int CmdHF14AMfECFill(const char *Cmd)
1170 {
1171 uint8_t keyType = 0;
1172
1173 if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
1174 PrintAndLog("Usage: hf mf efill <key A/B>");
1175 PrintAndLog("sample: hf mf efill A");
1176 PrintAndLog("Card data blocks transfers to card emulator memory.");
1177 PrintAndLog("Keys must be laid in the simulator memory. \n");
1178 return 0;
1179 }
1180
1181 char ctmp = param_getchar(Cmd, 0);
1182 if (ctmp == 0x00) {
1183 PrintAndLog("Key type must be A or B");
1184 return 1;
1185 }
1186 if (ctmp != 'A' && ctmp != 'a') keyType = 1;
1187
1188 UsbCommand c = {CMD_MIFARE_EML_CARDLOAD, {0, keyType, 0}};
1189 SendCommand(&c);
1190 return 0;
1191 }
1192
1193 int CmdHF14AMfEKeyPrn(const char *Cmd)
1194 {
1195 int i,b=-1;
1196 uint8_t data[16];
1197 uint64_t keyA, keyB;
1198
1199 PrintAndLog("|---|----------------|----------------|");
1200 PrintAndLog("|sec|key A |key B |");
1201 PrintAndLog("|---|----------------|----------------|");
1202 for (i = 0; i < 40; i++) {
1203 b<127?(b+=4):(b+=16);
1204 if (mfEmlGetMem(data, b, 1)) {
1205 PrintAndLog("error get block %d", b);
1206 break;
1207 }
1208 keyA = bytes_to_num(data, 6);
1209 keyB = bytes_to_num(data + 10, 6);
1210 PrintAndLog("|%03d| %012I64x | %012I64x |", i, keyA, keyB);
1211 }
1212 PrintAndLog("|---|----------------|----------------|");
1213
1214 return 0;
1215 }
1216
1217 int CmdHF14AMfCSetUID(const char *Cmd)
1218 {
1219 uint8_t wipeCard = 0;
1220 uint8_t uid[8];
1221 uint8_t oldUid[8];
1222 int res;
1223
1224 if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
1225 PrintAndLog("Usage: hf mf csetuid <UID 8 hex symbols> <w>");
1226 PrintAndLog("sample: hf mf csetuid 01020304 w");
1227 PrintAndLog("Set UID for magic Chinese card (only works with!!!)");
1228 PrintAndLog("If you want wipe card then add 'w' into command line. \n");
1229 return 0;
1230 }
1231
1232 if (param_getchar(Cmd, 0) && param_gethex(Cmd, 0, uid, 8)) {
1233 PrintAndLog("UID must include 8 HEX symbols");
1234 return 1;
1235 }
1236
1237 char ctmp = param_getchar(Cmd, 1);
1238 if (ctmp == 'w' || ctmp == 'W') wipeCard = 1;
1239
1240 PrintAndLog("--wipe card:%02x uid:%s", wipeCard, sprint_hex(uid, 4));
1241
1242 res = mfCSetUID(uid, oldUid, wipeCard);
1243 if (res) {
1244 PrintAndLog("Can't set UID. error=%d", res);
1245 return 1;
1246 }
1247
1248 PrintAndLog("old UID:%s", sprint_hex(oldUid, 4));
1249 return 0;
1250 }
1251
1252 int CmdHF14AMfCSetBlk(const char *Cmd)
1253 {
1254 uint8_t uid[8];
1255 uint8_t memBlock[16];
1256 uint8_t blockNo = 0;
1257 int res;
1258 memset(memBlock, 0x00, sizeof(memBlock));
1259
1260 if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
1261 PrintAndLog("Usage: hf mf csetblk <block number> <block data (32 hex symbols)>");
1262 PrintAndLog("sample: hf mf csetblk 1 01020304050607080910111213141516");
1263 PrintAndLog("Set block data for magic Chinese card (only works with!!!)");
1264 PrintAndLog("If you want wipe card then add 'w' into command line. \n");
1265 return 0;
1266 }
1267
1268 blockNo = param_get8(Cmd, 0);
1269
1270 if (param_gethex(Cmd, 1, memBlock, 32)) {
1271 PrintAndLog("block data must include 32 HEX symbols");
1272 return 1;
1273 }
1274
1275 PrintAndLog("--block number:%02x data:%s", blockNo, sprint_hex(memBlock, 16));
1276
1277 res = mfCSetBlock(blockNo, memBlock, uid, 0, CSETBLOCK_SINGLE_OPER);
1278 if (res) {
1279 PrintAndLog("Can't write block. error=%d", res);
1280 return 1;
1281 }
1282
1283 PrintAndLog("UID:%s", sprint_hex(uid, 4));
1284 return 0;
1285 }
1286
1287 int CmdHF14AMfCLoad(const char *Cmd)
1288 {
1289 FILE * f;
1290 char filename[20];
1291 char * fnameptr = filename;
1292 char buf[64];
1293 uint8_t buf8[64];
1294 uint8_t fillFromEmulator = 0;
1295 int i, len, blockNum, flags;
1296
1297 memset(filename, 0, sizeof(filename));
1298 memset(buf, 0, sizeof(buf));
1299
1300 if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) {
1301 PrintAndLog("It loads magic Chinese card (only works with!!!) from the file `filename.eml`");
1302 PrintAndLog("or from emulator memory (option `e`)");
1303 PrintAndLog("Usage: hf mf cload <file name w/o `.eml`>");
1304 PrintAndLog(" or: hf mf cload e ");
1305 PrintAndLog(" sample: hf mf cload filename");
1306 return 0;
1307 }
1308
1309 char ctmp = param_getchar(Cmd, 0);
1310 if (ctmp == 'e' || ctmp == 'E') fillFromEmulator = 1;
1311
1312 if (fillFromEmulator) {
1313 flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;
1314 for (blockNum = 0; blockNum < 16 * 4; blockNum += 1) {
1315 if (mfEmlGetMem(buf8, blockNum, 1)) {
1316 PrintAndLog("Cant get block: %d", blockNum);
1317 return 2;
1318 }
1319
1320 if (blockNum == 2) flags = 0;
1321 if (blockNum == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;
1322
1323 if (mfCSetBlock(blockNum, buf8, NULL, 0, flags)) {
1324 PrintAndLog("Cant set magic card block: %d", blockNum);
1325 return 3;
1326 }
1327 }
1328 return 0;
1329 } else {
1330 len = strlen(Cmd);
1331 if (len > 14) len = 14;
1332
1333 memcpy(filename, Cmd, len);
1334 fnameptr += len;
1335
1336 sprintf(fnameptr, ".eml");
1337
1338 // open file
1339 f = fopen(filename, "r");
1340 if (f == NULL) {
1341 PrintAndLog("File not found or locked.");
1342 return 1;
1343 }
1344
1345 blockNum = 0;
1346 flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;
1347 while(!feof(f)){
1348 memset(buf, 0, sizeof(buf));
1349 fgets(buf, sizeof(buf), f);
1350
1351 if (strlen(buf) < 32){
1352 if(strlen(buf) && feof(f))
1353 break;
1354 PrintAndLog("File content error. Block data must include 32 HEX symbols");
1355 return 2;
1356 }
1357 for (i = 0; i < 32; i += 2)
1358 sscanf(&buf[i], "%02x", (unsigned int *)&buf8[i / 2]);
1359
1360 if (blockNum == 2) flags = 0;
1361 if (blockNum == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;
1362
1363 if (mfCSetBlock(blockNum, buf8, NULL, 0, flags)) {
1364 PrintAndLog("Cant set magic card block: %d", blockNum);
1365 return 3;
1366 }
1367 blockNum++;
1368
1369 if (blockNum >= 16 * 4) break; // magic card type - mifare 1K
1370 }
1371 fclose(f);
1372
1373 if (blockNum != 16 * 4 && blockNum != 32 * 4 + 8 * 16){
1374 PrintAndLog("File content error. There must be 64 blocks");
1375 return 4;
1376 }
1377 PrintAndLog("Loaded from file: %s", filename);
1378 return 0;
1379 }
1380 }
1381
1382 int CmdHF14AMfCGetBlk(const char *Cmd) {
1383 uint8_t memBlock[16];
1384 uint8_t blockNo = 0;
1385 int res;
1386 memset(memBlock, 0x00, sizeof(memBlock));
1387
1388 if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
1389 PrintAndLog("Usage: hf mf cgetblk <block number>");
1390 PrintAndLog("sample: hf mf cgetblk 1");
1391 PrintAndLog("Get block data from magic Chinese card (only works with!!!)\n");
1392 return 0;
1393 }
1394
1395 blockNo = param_get8(Cmd, 0);
1396
1397 PrintAndLog("--block number:%02x ", blockNo);
1398
1399 res = mfCGetBlock(blockNo, memBlock, CSETBLOCK_SINGLE_OPER);
1400 if (res) {
1401 PrintAndLog("Can't read block. error=%d", res);
1402 return 1;
1403 }
1404
1405 PrintAndLog("block data:%s", sprint_hex(memBlock, 16));
1406 return 0;
1407 }
1408
1409 int CmdHF14AMfCGetSc(const char *Cmd) {
1410 uint8_t memBlock[16];
1411 uint8_t sectorNo = 0;
1412 int i, res, flags;
1413 memset(memBlock, 0x00, sizeof(memBlock));
1414
1415 if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
1416 PrintAndLog("Usage: hf mf cgetsc <sector number>");
1417 PrintAndLog("sample: hf mf cgetsc 0");
1418 PrintAndLog("Get sector data from magic Chinese card (only works with!!!)\n");
1419 return 0;
1420 }
1421
1422 sectorNo = param_get8(Cmd, 0);
1423 if (sectorNo > 15) {
1424 PrintAndLog("Sector number must be in [0..15] as in MIFARE classic.");
1425 return 1;
1426 }
1427
1428 PrintAndLog("--sector number:%02x ", sectorNo);
1429
1430 flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;
1431 for (i = 0; i < 4; i++) {
1432 if (i == 1) flags = 0;
1433 if (i == 3) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;
1434
1435 res = mfCGetBlock(sectorNo * 4 + i, memBlock, flags);
1436 if (res) {
1437 PrintAndLog("Can't read block. %02x error=%d", sectorNo * 4 + i, res);
1438 return 1;
1439 }
1440
1441 PrintAndLog("block %02x data:%s", sectorNo * 4 + i, sprint_hex(memBlock, 16));
1442 }
1443 return 0;
1444 }
1445
1446 int CmdHF14AMfCSave(const char *Cmd) {
1447
1448 FILE * f;
1449 char filename[20];
1450 char * fnameptr = filename;
1451 uint8_t fillFromEmulator = 0;
1452 uint8_t buf[64];
1453 int i, j, len, flags;
1454
1455 memset(filename, 0, sizeof(filename));
1456 memset(buf, 0, sizeof(buf));
1457
1458 if (param_getchar(Cmd, 0) == 'h') {
1459 PrintAndLog("It saves `magic Chinese` card dump into the file `filename.eml` or `cardID.eml`");
1460 PrintAndLog("or into emulator memory (option `e`)");
1461 PrintAndLog("Usage: hf mf esave [file name w/o `.eml`][e]");
1462 PrintAndLog(" sample: hf mf esave ");
1463 PrintAndLog(" hf mf esave filename");
1464 PrintAndLog(" hf mf esave e \n");
1465 return 0;
1466 }
1467
1468 char ctmp = param_getchar(Cmd, 0);
1469 if (ctmp == 'e' || ctmp == 'E') fillFromEmulator = 1;
1470
1471 if (fillFromEmulator) {
1472 // put into emulator
1473 flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;
1474 for (i = 0; i < 16 * 4; i++) {
1475 if (i == 1) flags = 0;
1476 if (i == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;
1477
1478 if (mfCGetBlock(i, buf, flags)) {
1479 PrintAndLog("Cant get block: %d", i);
1480 break;
1481 }
1482
1483 if (mfEmlSetMem(buf, i, 1)) {
1484 PrintAndLog("Cant set emul block: %d", i);
1485 return 3;
1486 }
1487 }
1488 return 0;
1489 } else {
1490 len = strlen(Cmd);
1491 if (len > 14) len = 14;
1492
1493 if (len < 1) {
1494 // get filename
1495 if (mfCGetBlock(0, buf, CSETBLOCK_SINGLE_OPER)) {
1496 PrintAndLog("Cant get block: %d", 0);
1497 return 1;
1498 }
1499 for (j = 0; j < 7; j++, fnameptr += 2)
1500 sprintf(fnameptr, "%02x", buf[j]);
1501 } else {
1502 memcpy(filename, Cmd, len);
1503 fnameptr += len;
1504 }
1505
1506 sprintf(fnameptr, ".eml");
1507
1508 // open file
1509 f = fopen(filename, "w+");
1510
1511 // put hex
1512 flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;
1513 for (i = 0; i < 16 * 4; i++) {
1514 if (i == 1) flags = 0;
1515 if (i == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;
1516
1517 if (mfCGetBlock(i, buf, flags)) {
1518 PrintAndLog("Cant get block: %d", i);
1519 break;
1520 }
1521 for (j = 0; j < 16; j++)
1522 fprintf(f, "%02x", buf[j]);
1523 fprintf(f,"\n");
1524 }
1525 fclose(f);
1526
1527 PrintAndLog("Saved to file: %s", filename);
1528
1529 return 0;
1530 }
1531 }
1532
1533 int CmdHF14AMfSniff(const char *Cmd){
1534 // params
1535 bool wantLogToFile = 0;
1536 bool wantDecrypt = 0;
1537 //bool wantSaveToEml = 0; TODO
1538 bool wantSaveToEmlFile = 0;
1539
1540 //var
1541 int res = 0;
1542 int len = 0;
1543 int blockLen = 0;
1544 int num = 0;
1545 int pckNum = 0;
1546 uint8_t uid[8];
1547 uint8_t atqa[2];
1548 uint8_t sak;
1549 bool isTag;
1550 uint32_t parity;
1551 uint8_t buf[3000];
1552 uint8_t * bufPtr = buf;
1553 memset(buf, 0x00, 3000);
1554
1555 if (param_getchar(Cmd, 0) == 'h') {
1556 PrintAndLog("It continuously get data from the field and saves it to: log, emulator, emulator file.");
1557 PrintAndLog("You can specify:");
1558 PrintAndLog(" l - save encrypted sequence to logfile `uid.log`");
1559 PrintAndLog(" d - decrypt sequence and put it to log file `uid.log`");
1560 PrintAndLog(" n/a e - decrypt sequence, collect read and write commands and save the result of the sequence to emulator memory");
1561 PrintAndLog(" r - decrypt sequence, collect read and write commands and save the result of the sequence to emulator dump file `uid.eml`");
1562 PrintAndLog("Usage: hf mf sniff [l][d][e][r]");
1563 PrintAndLog(" sample: hf mf sniff l d e");
1564 return 0;
1565 }
1566
1567 for (int i = 0; i < 4; i++) {
1568 char ctmp = param_getchar(Cmd, i);
1569 if (ctmp == 'l' || ctmp == 'L') wantLogToFile = true;
1570 if (ctmp == 'd' || ctmp == 'D') wantDecrypt = true;
1571 //if (ctmp == 'e' || ctmp == 'E') wantSaveToEml = true; TODO
1572 if (ctmp == 'f' || ctmp == 'F') wantSaveToEmlFile = true;
1573 }
1574
1575 printf("-------------------------------------------------------------------------\n");
1576 printf("Executing command. \n");
1577 printf("Press the key on the proxmark3 device to abort both proxmark3 and client.\n");
1578 printf("Press the key on pc keyboard to abort the client.\n");
1579 printf("-------------------------------------------------------------------------\n");
1580
1581 UsbCommand c = {CMD_MIFARE_SNIFFER, {0, 0, 0}};
1582 SendCommand(&c);
1583
1584 // wait cycle
1585 while (true) {
1586 printf(".");
1587 fflush(stdout);
1588 if (ukbhit()) {
1589 getchar();
1590 printf("\naborted via keyboard!\n");
1591 break;
1592 }
1593
1594 UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 2000);
1595 if (resp != NULL) {
1596 res = resp->arg[0] & 0xff;
1597 len = resp->arg[1];
1598 num = resp->arg[2];
1599
1600 if (res == 0) return 0;
1601 if (res == 1) {
1602 if (num ==0) {
1603 bufPtr = buf;
1604 memset(buf, 0x00, 3000);
1605 }
1606 memcpy(bufPtr, resp->d.asBytes, len);
1607 bufPtr += len;
1608 pckNum++;
1609 }
1610 if (res == 2) {
1611 blockLen = bufPtr - buf;
1612 bufPtr = buf;
1613 printf(">\n");
1614 PrintAndLog("received trace len: %d packages: %d", blockLen, pckNum);
1615 num = 0;
1616 while (bufPtr - buf + 9 < blockLen) {
1617 isTag = bufPtr[3] & 0x80 ? true:false;
1618 bufPtr += 4;
1619 parity = *((uint32_t *)(bufPtr));
1620 bufPtr += 4;
1621 len = bufPtr[0];
1622 bufPtr++;
1623 if ((len == 14) && (bufPtr[0] = 0xff) && (bufPtr[1] = 0xff)) {
1624 memcpy(uid, bufPtr + 2, 7);
1625 memcpy(atqa, bufPtr + 2 + 7, 2);
1626 sak = bufPtr[11];
1627
1628 PrintAndLog("tag select uid:%s atqa:%02x %02x sak:0x%02x", sprint_hex(uid, 7), atqa[0], atqa[1], sak);
1629 if (wantLogToFile) {
1630 FillFileNameByUID(logHexFileName, uid, ".log", 7);
1631 AddLogCurrentDT(logHexFileName);
1632 }
1633 if (wantDecrypt) mfTraceInit(uid, atqa, sak, wantSaveToEmlFile);
1634 } else {
1635 PrintAndLog("%s(%d):%s", isTag ? "TAG":"RDR", num, sprint_hex(bufPtr, len));
1636 if (wantLogToFile) AddLogHex(logHexFileName, isTag ? "TAG: ":"RDR: ", bufPtr, len);
1637 if (wantDecrypt) mfTraceDecode(bufPtr, len, parity, wantSaveToEmlFile);
1638 }
1639 bufPtr += len;
1640 num++;
1641 }
1642 }
1643 } // resp not NILL
1644 } // while (true)
1645 return 0;
1646 }
1647
1648 static command_t CommandTable[] =
1649 {
1650 {"help", CmdHelp, 1, "This help"},
1651 {"dbg", CmdHF14AMfDbg, 0, "Set default debug mode"},
1652 {"rdbl", CmdHF14AMfRdBl, 0, "Read MIFARE classic block"},
1653 {"rdsc", CmdHF14AMfRdSc, 0, "Read MIFARE classic sector"},
1654 {"dump", CmdHF14AMfDump, 0, "Dump MIFARE classic tag to binary file"},
1655 {"restore", CmdHF14AMfRestore, 0, "Restore MIFARE classic binary file to BLANK tag"},
1656 {"wrbl", CmdHF14AMfWrBl, 0, "Write MIFARE classic block"},
1657 {"chk", CmdHF14AMfChk, 0, "Test block keys"},
1658 {"mifare", CmdHF14AMifare, 0, "Read parity error messages. param - <used card nonce>"},
1659 {"nested", CmdHF14AMfNested, 0, "Test nested authentication"},
1660 {"sniff", CmdHF14AMfSniff, 0, "Sniff card-reader communication"},
1661 {"sim", CmdHF14AMf1kSim, 0, "Simulate MIFARE card"},
1662 {"eclr", CmdHF14AMfEClear, 0, "Clear simulator memory block"},
1663 {"eget", CmdHF14AMfEGet, 0, "Get simulator memory block"},
1664 {"eset", CmdHF14AMfESet, 0, "Set simulator memory block"},
1665 {"eload", CmdHF14AMfELoad, 0, "Load from file emul dump"},
1666 {"esave", CmdHF14AMfESave, 0, "Save to file emul dump"},
1667 {"ecfill", CmdHF14AMfECFill, 0, "Fill simulator memory with help of keys from simulator"},
1668 {"ekeyprn", CmdHF14AMfEKeyPrn, 0, "Print keys from simulator memory"},
1669 {"csetuid", CmdHF14AMfCSetUID, 0, "Set UID for magic Chinese card"},
1670 {"csetblk", CmdHF14AMfCSetBlk, 0, "Write block into magic Chinese card"},
1671 {"cgetblk", CmdHF14AMfCGetBlk, 0, "Read block from magic Chinese card"},
1672 {"cgetsc", CmdHF14AMfCGetSc, 0, "Read sector from magic Chinese card"},
1673 {"cload", CmdHF14AMfCLoad, 0, "Load dump into magic Chinese card"},
1674 {"csave", CmdHF14AMfCSave, 0, "Save dump from magic Chinese card into file or emulator"},
1675 {NULL, NULL, 0, NULL}
1676 };
1677
1678 int CmdHFMF(const char *Cmd)
1679 {
1680 // flush
1681 while (WaitForResponseTimeout(CMD_ACK, 500) != NULL) ;
1682
1683 CmdsParse(CommandTable, Cmd);
1684 return 0;
1685 }
1686
1687 int CmdHelp(const char *Cmd)
1688 {
1689 CmdsHelp(CommandTable);
1690 return 0;
1691 }
Impressum, Datenschutz