]> git.zerfleddert.de Git - proxmark3-svn/blob - client/cmdhfmf.c
CHG: @Marshmellow42 's fixes. ref: https://github.com/marshmellow42/proxmark3/commi...
[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
13 static int CmdHelp(const char *Cmd);
14 int usage_hf14_mifare(void){
15 PrintAndLog("Usage: hf mf mifare [h] <block number> <A|B>");
16 PrintAndLog("options:");
17 PrintAndLog(" h this help");
18 PrintAndLog(" <block number> (Optional) target other block");
19 PrintAndLog(" <A|B> (optional) target key type");
20 PrintAndLog("samples:");
21 PrintAndLog(" hf mf mifare");
22 PrintAndLog(" hf mf mifare 16");
23 PrintAndLog(" hf mf mifare 16 B");
24 return 0;
25 }
26 int usage_hf14_mf1ksim(void){
27 PrintAndLog("Usage: hf mf sim [h] u <uid> n <numreads> [i] [x] [e] [v]");
28 PrintAndLog("options:");
29 PrintAndLog(" h this help");
30 PrintAndLog(" u (Optional) UID 4,7 or 10bytes. If not specified, the UID 4b from emulator memory will be used");
31 PrintAndLog(" n (Optional) Automatically exit simulation after <numreads> blocks have been read by reader. 0 = infinite");
32 PrintAndLog(" i (Optional) Interactive, means that console will not be returned until simulation finishes or is aborted");
33 PrintAndLog(" x (Optional) Crack, performs the 'reader attack', nr/ar attack against a reader");
34 PrintAndLog(" e (Optional) Fill simulator keys from found keys");
35 PrintAndLog(" v (Optional) Verbose");
36 PrintAndLog("samples:");
37 PrintAndLog(" hf mf sim u 0a0a0a0a");
38 PrintAndLog(" hf mf sim u 11223344556677");
39 PrintAndLog(" hf mf sim u 112233445566778899AA");
40 PrintAndLog(" hf mf sim u 11223344 i x");
41 return 0;
42 }
43 int usage_hf14_dbg(void){
44 PrintAndLog("Usage: hf mf dbg [h] <debug level>");
45 PrintAndLog("options:");
46 PrintAndLog(" h this help");
47 PrintAndLog(" <debug level> (Optional) see list for valid levels");
48 PrintAndLog(" 0 - no debug messages");
49 PrintAndLog(" 1 - error messages");
50 PrintAndLog(" 2 - plus information messages");
51 PrintAndLog(" 3 - plus debug messages");
52 PrintAndLog(" 4 - print even debug messages in timing critical functions");
53 PrintAndLog(" Note: this option therefore may cause malfunction itself");
54 PrintAndLog("samples:");
55 PrintAndLog(" hf mf dbg 3");
56 return 0;
57 }
58 int usage_hf14_sniff(void){
59 PrintAndLog("It continuously gets data from the field and saves it to: log, emulator, emulator file.");
60 PrintAndLog("Usage: hf mf sniff [h] [l] [d] [f]");
61 PrintAndLog("options:");
62 PrintAndLog(" h this help");
63 PrintAndLog(" l save encrypted sequence to logfile `uid.log`");
64 PrintAndLog(" d decrypt sequence and put it to log file `uid.log`");
65 // PrintAndLog(" n/a e decrypt sequence, collect read and write commands and save the result of the sequence to emulator memory");
66 PrintAndLog(" f decrypt sequence, collect read and write commands and save the result of the sequence to emulator dump file `uid.eml`");
67 PrintAndLog("sample:");
68 PrintAndLog(" hf mf sniff l d f");
69 return 0;
70 }
71 int usage_hf14_nested(void){
72 PrintAndLog("Usage:");
73 PrintAndLog(" all sectors: hf mf nested <card memory> <block number> <key A/B> <key (12 hex symbols)> [t,d]");
74 PrintAndLog(" one sector: hf mf nested o <block number> <key A/B> <key (12 hex symbols)>");
75 PrintAndLog(" <target block number> <target key A/B> [t]");
76 PrintAndLog("options:");
77 PrintAndLog(" h this help");
78 PrintAndLog(" card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, <other> - 1K");
79 PrintAndLog(" t transfer keys into emulator memory");
80 PrintAndLog(" d write keys to binary file");
81 PrintAndLog(" ");
82 PrintAndLog("samples:");
83 PrintAndLog(" hf mf nested 1 0 A FFFFFFFFFFFF ");
84 PrintAndLog(" hf mf nested 1 0 A FFFFFFFFFFFF t ");
85 PrintAndLog(" hf mf nested 1 0 A FFFFFFFFFFFF d ");
86 PrintAndLog(" hf mf nested o 0 A FFFFFFFFFFFF 4 A");
87 return 0;
88 }
89 int usage_hf14_hardnested(void){
90 PrintAndLog("Usage:");
91 PrintAndLog(" hf mf hardnested <block number> <key A|B> <key (12 hex symbols)>");
92 PrintAndLog(" <target block number> <target key A|B> [known target key (12 hex symbols)] [w] [s]");
93 PrintAndLog(" or hf mf hardnested r [known target key]");
94 PrintAndLog(" ");
95 PrintAndLog("options:");
96 PrintAndLog(" h this help");
97 PrintAndLog(" w acquire nonces and write them to binary file nonces.bin");
98 PrintAndLog(" s slower acquisition (required by some non standard cards)");
99 PrintAndLog(" r read nonces.bin and start attack");
100 PrintAndLog(" t tests?");
101 PrintAndLog(" ");
102 PrintAndLog("samples:");
103 PrintAndLog(" hf mf hardnested 0 A FFFFFFFFFFFF 4 A");
104 PrintAndLog(" hf mf hardnested 0 A FFFFFFFFFFFF 4 A w");
105 PrintAndLog(" hf mf hardnested 0 A FFFFFFFFFFFF 4 A w s");
106 PrintAndLog(" hf mf hardnested r");
107 PrintAndLog(" hf mf hardnested r a0a1a2a3a4a5");
108 PrintAndLog(" ");
109 PrintAndLog("Add the known target key to check if it is present in the remaining key space:");
110 PrintAndLog(" sample5: hf mf hardnested 0 A A0A1A2A3A4A5 4 A FFFFFFFFFFFF");
111 return 0;
112 }
113 int usage_hf14_chk(void){
114 PrintAndLog("Usage: hf mf chk <block number>|<*card memory> <key type (A/B/?)> [t|d] [<key (12 hex symbols)>] [<dic (*.dic)>]");
115 PrintAndLog("options:");
116 PrintAndLog(" h this help");
117 PrintAndLog(" * all sectors based on card memory, other values then below defaults to 1k");
118 PrintAndLog(" 0 - MINI(320 bytes)");
119 PrintAndLog(" 1 - 1K");
120 PrintAndLog(" 2 - 2K");
121 PrintAndLog(" 4 - 4K");
122 PrintAndLog(" d write keys to binary file");
123 PrintAndLog(" t write keys to emulator memory\n");
124 PrintAndLog(" ");
125 PrintAndLog("samples:");
126 PrintAndLog(" hf mf chk 0 A 1234567890ab keys.dic -- target block 0, Key A");
127 PrintAndLog(" hf mf chk *1 ? t -- target all blocks, all keys, 1K, write to emul");
128 PrintAndLog(" hf mf chk *1 ? d -- target all blocks, all keys, 1K, write to file");
129 return 0;
130 }
131 int usage_hf14_keybrute(void){
132 PrintAndLog("J_Run's 2nd phase of multiple sector nested authentication key recovery");
133 PrintAndLog("You have a known 4 last bytes of a key recovered with mf_nonce_brute tool.");
134 PrintAndLog("First 2 bytes of key will be bruteforced");
135 PrintAndLog("");
136 PrintAndLog("Usage: hf mf keybrute [h] <block number> <A|B> <key>");
137 PrintAndLog("options:");
138 PrintAndLog(" h this help");
139 PrintAndLog(" <block number> target block number");
140 PrintAndLog(" <A|B> target key type");
141 PrintAndLog(" <key> candidate key from mf_nonce_brute tool");
142 PrintAndLog("samples:");
143 PrintAndLog(" hf mf keybrute 1 A 000011223344");
144 return 0;
145 }
146
147 int CmdHF14AMifare(const char *Cmd) {
148 uint32_t uid = 0;
149 uint32_t nt = 0, nr = 0;
150 uint64_t par_list = 0, ks_list = 0, r_key = 0;
151 int16_t isOK = 0;
152 int tmpchar;
153 uint8_t blockNo = 0, keytype = MIFARE_AUTH_KEYA;
154
155 char cmdp = param_getchar(Cmd, 0);
156 if ( cmdp == 'H' || cmdp == 'h') return usage_hf14_mifare();
157
158 blockNo = param_get8(Cmd, 0);
159
160 cmdp = param_getchar(Cmd, 1);
161 if (cmdp == 'B' || cmdp == 'b')
162 keytype = MIFARE_AUTH_KEYB;
163
164 UsbCommand c = {CMD_READER_MIFARE, {true, blockNo, keytype}};
165
166 // message
167 printf("-------------------------------------------------------------------------\n");
168 printf("Executing darkside attack. Expected execution time: 25sec on average :-)\n");
169 printf("Press button on the proxmark3 device to abort both proxmark3 and client.\n");
170 printf("-------------------------------------------------------------------------\n");
171 clock_t t1 = clock();
172 time_t start, end;
173 time(&start);
174
175 start:
176 clearCommandBuffer();
177 SendCommand(&c);
178
179 //flush queue
180 while (ukbhit()) {
181 tmpchar = getchar();
182 (void)tmpchar;
183 }
184
185 // wait cycle
186 while (true) {
187 printf(".");
188 fflush(stdout);
189 if (ukbhit()) {
190 tmpchar = getchar();
191 (void)tmpchar;
192 printf("\naborted via keyboard!\n");
193 break;
194 }
195
196 UsbCommand resp;
197 if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
198 isOK = resp.arg[0];
199 printf("\n");
200 uid = (uint32_t)bytes_to_num(resp.d.asBytes + 0, 4);
201 nt = (uint32_t)bytes_to_num(resp.d.asBytes + 4, 4);
202 par_list = bytes_to_num(resp.d.asBytes + 8, 8);
203 ks_list = bytes_to_num(resp.d.asBytes + 16, 8);
204 nr = bytes_to_num(resp.d.asBytes + 24, 4);
205
206 switch (isOK) {
207 case -1 : PrintAndLog("Button pressed. Aborted.\n"); break;
208 case -2 : PrintAndLog("Card isn't vulnerable to Darkside attack (doesn't send NACK on authentication requests).\n"); break;
209 case -3 : PrintAndLog("Card isn't vulnerable to Darkside attack (its random number generator is not predictable).\n"); break;
210 case -4 : PrintAndLog("Card isn't vulnerable to Darkside attack (its random number generator seems to be based on the wellknown");
211 PrintAndLog("generating polynomial with 16 effective bits only, but shows unexpected behaviour.\n"); break;
212 default: ;
213 }
214 break;
215 }
216 }
217 printf("\n");
218 // error
219 if (isOK != 1) return 1;
220
221 if (par_list == 0 && ks_list != 0) {
222 // this special attack when parities is zero, uses checkkeys. Which now with block/keytype option also needs.
223 // but it uses 0|1 instead of 0x60|0x61...
224 if (nonce2key_ex(blockNo, keytype - 0x60 , uid, nt, nr, ks_list, &r_key) ){
225 PrintAndLog("Trying again with a different reader nonce...");
226 c.arg[0] = false;
227 goto start;
228 } else {
229 PrintAndLog("Found valid key: %012" PRIx64 " \n", r_key);
230 goto END;
231 }
232 }
233
234 // execute original function from util nonce2key
235 if (nonce2key(uid, nt, nr, par_list, ks_list, &r_key)) {
236 isOK = 2;
237 PrintAndLog("Key not found (lfsr_common_prefix list is null). Nt=%08x", nt);
238 PrintAndLog("Failing is expected to happen in 25%% of all cases. Trying again with a different reader nonce...");
239 c.arg[0] = false;
240 goto start;
241 } else {
242
243 // nonce2key found a candidate key. Lets verify it.
244 uint8_t keyblock[] = {0,0,0,0,0,0};
245 num_to_bytes(r_key, 6, keyblock);
246 uint64_t key64 = 0;
247 int res = mfCheckKeys(blockNo, keytype - 0x60 , false, 1, keyblock, &key64);
248 if ( res > 0 ) {
249 PrintAndLog("Candidate Key found (%012" PRIx64 ") - Test authentication failed. [%d] Restarting darkside attack", r_key, res);
250 goto start;
251 }
252 PrintAndLog("Found valid key: %012" PRIx64 " \n", r_key);
253 }
254 END:
255 t1 = clock() - t1;
256 time(&end);
257 unsigned long elapsed_time = difftime(end, start);
258 if ( t1 > 0 )
259 PrintAndLog("Time in darkside: %.0f ticks %u seconds\n", (float)t1, elapsed_time);
260 return 0;
261 }
262
263 int CmdHF14AMfWrBl(const char *Cmd) {
264 uint8_t blockNo = 0;
265 uint8_t keyType = 0;
266 uint8_t key[6] = {0, 0, 0, 0, 0, 0};
267 uint8_t bldata[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
268
269 char cmdp = 0x00;
270
271 if (strlen(Cmd)<3) {
272 PrintAndLog("Usage: hf mf wrbl <block number> <key A/B> <key (12 hex symbols)> <block data (32 hex symbols)>");
273 PrintAndLog(" sample: hf mf wrbl 0 A FFFFFFFFFFFF 000102030405060708090A0B0C0D0E0F");
274 return 0;
275 }
276
277 blockNo = param_get8(Cmd, 0);
278 cmdp = param_getchar(Cmd, 1);
279 if (cmdp == 0x00) {
280 PrintAndLog("Key type must be A or B");
281 return 1;
282 }
283 if (cmdp != 'A' && cmdp != 'a') keyType = 1;
284 if (param_gethex(Cmd, 2, key, 12)) {
285 PrintAndLog("Key must include 12 HEX symbols");
286 return 1;
287 }
288 if (param_gethex(Cmd, 3, bldata, 32)) {
289 PrintAndLog("Block data must include 32 HEX symbols");
290 return 1;
291 }
292 PrintAndLog("--block no:%d, key type:%c, key:%s", blockNo, keyType?'B':'A', sprint_hex(key, 6));
293 PrintAndLog("--data: %s", sprint_hex(bldata, 16));
294
295 UsbCommand c = {CMD_MIFARE_WRITEBL, {blockNo, keyType, 0}};
296 memcpy(c.d.asBytes, key, 6);
297 memcpy(c.d.asBytes + 10, bldata, 16);
298 clearCommandBuffer();
299 SendCommand(&c);
300
301 UsbCommand resp;
302 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
303 uint8_t isOK = resp.arg[0] & 0xff;
304 PrintAndLog("isOk:%02x", isOK);
305 } else {
306 PrintAndLog("Command execute timeout");
307 }
308
309 return 0;
310 }
311
312 int CmdHF14AMfRdBl(const char *Cmd) {
313 uint8_t blockNo = 0;
314 uint8_t keyType = 0;
315 uint8_t key[6] = {0, 0, 0, 0, 0, 0};
316 char cmdp = 0x00;
317
318 if (strlen(Cmd)<3) {
319 PrintAndLog("Usage: hf mf rdbl <block number> <key A/B> <key (12 hex symbols)>");
320 PrintAndLog(" sample: hf mf rdbl 0 A FFFFFFFFFFFF ");
321 return 0;
322 }
323
324 blockNo = param_get8(Cmd, 0);
325 cmdp = param_getchar(Cmd, 1);
326 if (cmdp == 0x00) {
327 PrintAndLog("Key type must be A or B");
328 return 1;
329 }
330 if (cmdp != 'A' && cmdp != 'a') keyType = 1;
331 if (param_gethex(Cmd, 2, key, 12)) {
332 PrintAndLog("Key must include 12 HEX symbols");
333 return 1;
334 }
335 PrintAndLog("--block no:%d, key type:%c, key:%s ", blockNo, keyType?'B':'A', sprint_hex(key, 6));
336
337 UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}};
338 memcpy(c.d.asBytes, key, 6);
339 clearCommandBuffer();
340 SendCommand(&c);
341
342 UsbCommand resp;
343 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
344 uint8_t isOK = resp.arg[0] & 0xff;
345 uint8_t *data = resp.d.asBytes;
346
347 if (isOK)
348 PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 16));
349 else
350 PrintAndLog("isOk:%02x", isOK);
351 } else {
352 PrintAndLog("Command execute timeout");
353 }
354
355 return 0;
356 }
357
358 int CmdHF14AMfRdSc(const char *Cmd) {
359 int i;
360 uint8_t sectorNo = 0;
361 uint8_t keyType = 0;
362 uint8_t key[6] = {0, 0, 0, 0, 0, 0};
363 uint8_t isOK = 0;
364 uint8_t *data = NULL;
365 char cmdp = 0x00;
366
367 if (strlen(Cmd)<3) {
368 PrintAndLog("Usage: hf mf rdsc <sector number> <key A/B> <key (12 hex symbols)>");
369 PrintAndLog(" sample: hf mf rdsc 0 A FFFFFFFFFFFF ");
370 return 0;
371 }
372
373 sectorNo = param_get8(Cmd, 0);
374 if (sectorNo > 39) {
375 PrintAndLog("Sector number must be less than 40");
376 return 1;
377 }
378 cmdp = param_getchar(Cmd, 1);
379 if (cmdp != 'a' && cmdp != 'A' && cmdp != 'b' && cmdp != 'B') {
380 PrintAndLog("Key type must be A or B");
381 return 1;
382 }
383 if (cmdp != 'A' && cmdp != 'a') keyType = 1;
384 if (param_gethex(Cmd, 2, key, 12)) {
385 PrintAndLog("Key must include 12 HEX symbols");
386 return 1;
387 }
388 PrintAndLog("--sector no:%d key type:%c key:%s ", sectorNo, keyType?'B':'A', sprint_hex(key, 6));
389
390 UsbCommand c = {CMD_MIFARE_READSC, {sectorNo, keyType, 0}};
391 memcpy(c.d.asBytes, key, 6);
392 clearCommandBuffer();
393 SendCommand(&c);
394 PrintAndLog(" ");
395
396 UsbCommand resp;
397 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
398 isOK = resp.arg[0] & 0xff;
399 data = resp.d.asBytes;
400
401 PrintAndLog("isOk:%02x", isOK);
402 if (isOK) {
403 for (i = 0; i < (sectorNo<32?3:15); i++) {
404 PrintAndLog("data : %s", sprint_hex(data + i * 16, 16));
405 }
406 PrintAndLog("trailer: %s", sprint_hex(data + (sectorNo<32?3:15) * 16, 16));
407 }
408 } else {
409 PrintAndLog("Command execute timeout");
410 }
411
412 return 0;
413 }
414
415 uint8_t FirstBlockOfSector(uint8_t sectorNo) {
416 if (sectorNo < 32) {
417 return sectorNo * 4;
418 } else {
419 return 32 * 4 + (sectorNo - 32) * 16;
420 }
421 }
422
423 uint8_t NumBlocksPerSector(uint8_t sectorNo) {
424 if (sectorNo < 32) {
425 return 4;
426 } else {
427 return 16;
428 }
429 }
430
431 int CmdHF14AMfDump(const char *Cmd) {
432 uint8_t sectorNo, blockNo;
433
434 uint8_t keyA[40][6];
435 uint8_t keyB[40][6];
436 uint8_t rights[40][4];
437 uint8_t carddata[256][16];
438 uint8_t numSectors = 16;
439
440 FILE *fin;
441 FILE *fout;
442
443 UsbCommand resp;
444
445 char cmdp = param_getchar(Cmd, 0);
446 switch (cmdp) {
447 case '0' : numSectors = 5; break;
448 case '1' :
449 case '\0': numSectors = 16; break;
450 case '2' : numSectors = 32; break;
451 case '4' : numSectors = 40; break;
452 default: numSectors = 16;
453 }
454
455 if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') {
456 PrintAndLog("Usage: hf mf dump [card memory]");
457 PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K");
458 PrintAndLog("");
459 PrintAndLog("Samples: hf mf dump");
460 PrintAndLog(" hf mf dump 4");
461 return 0;
462 }
463
464 if ((fin = fopen("dumpkeys.bin","rb")) == NULL) {
465 PrintAndLog("Could not find file dumpkeys.bin");
466 return 1;
467 }
468
469 // Read keys A from file
470 size_t bytes_read;
471 for (sectorNo=0; sectorNo<numSectors; sectorNo++) {
472 bytes_read = fread( keyA[sectorNo], 1, 6, fin );
473 if ( bytes_read != 6) {
474 PrintAndLog("File reading error.");
475 fclose(fin);
476 return 2;
477 }
478 }
479
480 // Read keys B from file
481 for (sectorNo=0; sectorNo<numSectors; sectorNo++) {
482 bytes_read = fread( keyB[sectorNo], 1, 6, fin );
483 if ( bytes_read != 6) {
484 PrintAndLog("File reading error.");
485 fclose(fin);
486 return 2;
487 }
488 }
489
490 fclose(fin);
491
492 PrintAndLog("|-----------------------------------------|");
493 PrintAndLog("|------ Reading sector access bits...-----|");
494 PrintAndLog("|-----------------------------------------|");
495
496 for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {
497 UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 0, 0}};
498 memcpy(c.d.asBytes, keyA[sectorNo], 6);
499 clearCommandBuffer();
500 SendCommand(&c);
501
502 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
503 uint8_t isOK = resp.arg[0] & 0xff;
504 uint8_t *data = resp.d.asBytes;
505 if (isOK){
506 rights[sectorNo][0] = ((data[7] & 0x10)>>2) | ((data[8] & 0x1)<<1) | ((data[8] & 0x10)>>4); // C1C2C3 for data area 0
507 rights[sectorNo][1] = ((data[7] & 0x20)>>3) | ((data[8] & 0x2)<<0) | ((data[8] & 0x20)>>5); // C1C2C3 for data area 1
508 rights[sectorNo][2] = ((data[7] & 0x40)>>4) | ((data[8] & 0x4)>>1) | ((data[8] & 0x40)>>6); // C1C2C3 for data area 2
509 rights[sectorNo][3] = ((data[7] & 0x80)>>5) | ((data[8] & 0x8)>>2) | ((data[8] & 0x80)>>7); // C1C2C3 for sector trailer
510 } else {
511 PrintAndLog("Could not get access rights for sector %2d. Trying with defaults...", sectorNo);
512 rights[sectorNo][0] = rights[sectorNo][1] = rights[sectorNo][2] = 0x00;
513 rights[sectorNo][3] = 0x01;
514 }
515 } else {
516 PrintAndLog("Command execute timeout when trying to read access rights for sector %2d. Trying with defaults...", sectorNo);
517 rights[sectorNo][0] = rights[sectorNo][1] = rights[sectorNo][2] = 0x00;
518 rights[sectorNo][3] = 0x01;
519 }
520 }
521
522 PrintAndLog("|-----------------------------------------|");
523 PrintAndLog("|----- Dumping all blocks to file... -----|");
524 PrintAndLog("|-----------------------------------------|");
525
526 bool isOK = true;
527 for (sectorNo = 0; isOK && sectorNo < numSectors; sectorNo++) {
528 for (blockNo = 0; isOK && blockNo < NumBlocksPerSector(sectorNo); blockNo++) {
529 bool received = false;
530
531 if (blockNo == NumBlocksPerSector(sectorNo) - 1) { // sector trailer. At least the Access Conditions can always be read with key A.
532 UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + blockNo, 0, 0}};
533 memcpy(c.d.asBytes, keyA[sectorNo], 6);
534 clearCommandBuffer();
535 SendCommand(&c);
536 received = WaitForResponseTimeout(CMD_ACK,&resp,1500);
537 } else { // data block. Check if it can be read with key A or key B
538 uint8_t data_area = sectorNo<32?blockNo:blockNo/5;
539 if ((rights[sectorNo][data_area] == 0x03) || (rights[sectorNo][data_area] == 0x05)) { // only key B would work
540 UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + blockNo, 1, 0}};
541 memcpy(c.d.asBytes, keyB[sectorNo], 6);
542 SendCommand(&c);
543 received = WaitForResponseTimeout(CMD_ACK,&resp,1500);
544 } else if (rights[sectorNo][data_area] == 0x07) { // no key would work
545 isOK = false;
546 PrintAndLog("Access rights do not allow reading of sector %2d block %3d", sectorNo, blockNo);
547 } else { // key A would work
548 UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + blockNo, 0, 0}};
549 memcpy(c.d.asBytes, keyA[sectorNo], 6);
550 clearCommandBuffer();
551 SendCommand(&c);
552 received = WaitForResponseTimeout(CMD_ACK,&resp,1500);
553 }
554 }
555
556 if (received) {
557 isOK = resp.arg[0] & 0xff;
558 uint8_t *data = resp.d.asBytes;
559 if (blockNo == NumBlocksPerSector(sectorNo) - 1) { // sector trailer. Fill in the keys.
560 data[0] = (keyA[sectorNo][0]);
561 data[1] = (keyA[sectorNo][1]);
562 data[2] = (keyA[sectorNo][2]);
563 data[3] = (keyA[sectorNo][3]);
564 data[4] = (keyA[sectorNo][4]);
565 data[5] = (keyA[sectorNo][5]);
566 data[10] = (keyB[sectorNo][0]);
567 data[11] = (keyB[sectorNo][1]);
568 data[12] = (keyB[sectorNo][2]);
569 data[13] = (keyB[sectorNo][3]);
570 data[14] = (keyB[sectorNo][4]);
571 data[15] = (keyB[sectorNo][5]);
572 }
573 if (isOK) {
574 memcpy(carddata[FirstBlockOfSector(sectorNo) + blockNo], data, 16);
575 PrintAndLog("Successfully read block %2d of sector %2d.", blockNo, sectorNo);
576 } else {
577 PrintAndLog("Could not read block %2d of sector %2d", blockNo, sectorNo);
578 break;
579 }
580 }
581 else {
582 isOK = false;
583 PrintAndLog("Command execute timeout when trying to read block %2d of sector %2d.", blockNo, sectorNo);
584 break;
585 }
586 }
587 }
588
589 if (isOK) {
590 if ((fout = fopen("dumpdata.bin","wb")) == NULL) {
591 PrintAndLog("Could not create file name dumpdata.bin");
592 return 1;
593 }
594 uint16_t numblocks = FirstBlockOfSector(numSectors - 1) + NumBlocksPerSector(numSectors - 1);
595 fwrite(carddata, 1, 16*numblocks, fout);
596 fclose(fout);
597 fout = NULL;
598 PrintAndLog("Dumped %d blocks (%d bytes) to file dumpdata.bin", numblocks, 16*numblocks);
599 }
600
601 return 0;
602 }
603
604 int CmdHF14AMfRestore(const char *Cmd) {
605 uint8_t sectorNo,blockNo;
606 uint8_t keyType = 0;
607 uint8_t key[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
608 uint8_t bldata[16] = {0x00};
609 uint8_t keyA[40][6];
610 uint8_t keyB[40][6];
611 uint8_t numSectors;
612
613 FILE *fdump;
614 FILE *fkeys;
615
616 char cmdp = param_getchar(Cmd, 0);
617 switch (cmdp) {
618 case '0' : numSectors = 5; break;
619 case '1' :
620 case '\0': numSectors = 16; break;
621 case '2' : numSectors = 32; break;
622 case '4' : numSectors = 40; break;
623 default: numSectors = 16;
624 }
625
626 if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') {
627 PrintAndLog("Usage: hf mf restore [card memory]");
628 PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K");
629 PrintAndLog("");
630 PrintAndLog("Samples: hf mf restore");
631 PrintAndLog(" hf mf restore 4");
632 return 0;
633 }
634
635 if ((fkeys = fopen("dumpkeys.bin","rb")) == NULL) {
636 PrintAndLog("Could not find file dumpkeys.bin");
637 return 1;
638 }
639
640 size_t bytes_read;
641 for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {
642 bytes_read = fread( keyA[sectorNo], 1, 6, fkeys );
643 if ( bytes_read != 6) {
644 PrintAndLog("File reading error (dumpkeys.bin).");
645 fclose(fkeys);
646 return 2;
647 }
648 }
649
650 for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {
651 bytes_read = fread( keyB[sectorNo], 1, 6, fkeys );
652 if ( bytes_read != 6) {
653 PrintAndLog("File reading error (dumpkeys.bin).");
654 fclose(fkeys);
655 return 2;
656 }
657 }
658
659 fclose(fkeys);
660
661 if ((fdump = fopen("dumpdata.bin","rb")) == NULL) {
662 PrintAndLog("Could not find file dumpdata.bin");
663 return 1;
664 }
665 PrintAndLog("Restoring dumpdata.bin to card");
666
667 for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {
668 for(blockNo = 0; blockNo < NumBlocksPerSector(sectorNo); blockNo++) {
669 UsbCommand c = {CMD_MIFARE_WRITEBL, {FirstBlockOfSector(sectorNo) + blockNo, keyType, 0}};
670 memcpy(c.d.asBytes, key, 6);
671 bytes_read = fread(bldata, 1, 16, fdump);
672 if ( bytes_read != 16) {
673 PrintAndLog("File reading error (dumpdata.bin).");
674 fclose(fdump);
675 fdump = NULL;
676 return 2;
677 }
678
679 if (blockNo == NumBlocksPerSector(sectorNo) - 1) { // sector trailer
680 bldata[0] = (keyA[sectorNo][0]);
681 bldata[1] = (keyA[sectorNo][1]);
682 bldata[2] = (keyA[sectorNo][2]);
683 bldata[3] = (keyA[sectorNo][3]);
684 bldata[4] = (keyA[sectorNo][4]);
685 bldata[5] = (keyA[sectorNo][5]);
686 bldata[10] = (keyB[sectorNo][0]);
687 bldata[11] = (keyB[sectorNo][1]);
688 bldata[12] = (keyB[sectorNo][2]);
689 bldata[13] = (keyB[sectorNo][3]);
690 bldata[14] = (keyB[sectorNo][4]);
691 bldata[15] = (keyB[sectorNo][5]);
692 }
693
694 PrintAndLog("Writing to block %3d: %s", FirstBlockOfSector(sectorNo) + blockNo, sprint_hex(bldata, 16));
695
696 memcpy(c.d.asBytes + 10, bldata, 16);
697 clearCommandBuffer();
698 SendCommand(&c);
699
700 UsbCommand resp;
701 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
702 uint8_t isOK = resp.arg[0] & 0xff;
703 PrintAndLog("isOk:%02x", isOK);
704 } else {
705 PrintAndLog("Command execute timeout");
706 }
707 }
708 }
709
710 fclose(fdump);
711 return 0;
712 }
713
714 int CmdHF14AMfNested(const char *Cmd) {
715 int i, j, res, iterations;
716 sector *e_sector = NULL;
717 uint8_t blockNo = 0;
718 uint8_t keyType = 0;
719 uint8_t trgBlockNo = 0;
720 uint8_t trgKeyType = 0;
721 uint8_t SectorsCnt = 0;
722 uint8_t key[6] = {0, 0, 0, 0, 0, 0};
723 uint8_t keyBlock[6*6];
724 uint64_t key64 = 0;
725 bool transferToEml = false;
726
727 bool createDumpFile = false;
728 FILE *fkeys;
729 uint8_t standart[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
730 uint8_t tempkey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
731
732 if (strlen(Cmd)<3) return usage_hf14_nested();
733
734 char cmdp, ctmp;
735 cmdp = param_getchar(Cmd, 0);
736 blockNo = param_get8(Cmd, 1);
737 ctmp = param_getchar(Cmd, 2);
738
739 if (ctmp != 'a' && ctmp != 'A' && ctmp != 'b' && ctmp != 'B') {
740 PrintAndLog("Key type must be A or B");
741 return 1;
742 }
743
744 if (ctmp != 'A' && ctmp != 'a')
745 keyType = 1;
746
747 if (param_gethex(Cmd, 3, key, 12)) {
748 PrintAndLog("Key must include 12 HEX symbols");
749 return 1;
750 }
751
752 if (cmdp == 'o' || cmdp == 'O') {
753 cmdp = 'o';
754 trgBlockNo = param_get8(Cmd, 4);
755 ctmp = param_getchar(Cmd, 5);
756 if (ctmp != 'a' && ctmp != 'A' && ctmp != 'b' && ctmp != 'B') {
757 PrintAndLog("Target key type must be A or B");
758 return 1;
759 }
760 if (ctmp != 'A' && ctmp != 'a')
761 trgKeyType = 1;
762 } else {
763
764 switch (cmdp) {
765 case '0': SectorsCnt = 05; 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
773 ctmp = param_getchar(Cmd, 4);
774 if (ctmp == 't' || ctmp == 'T') transferToEml = true;
775 else if (ctmp == 'd' || ctmp == 'D') createDumpFile = true;
776
777 ctmp = param_getchar(Cmd, 6);
778 transferToEml |= (ctmp == 't' || ctmp == 'T');
779 transferToEml |= (ctmp == 'd' || ctmp == 'D');
780
781 if (cmdp == 'o') {
782 int16_t isOK = mfnested(blockNo, keyType, key, trgBlockNo, trgKeyType, keyBlock, true);
783 switch (isOK) {
784 case -1 : PrintAndLog("Error: No response from Proxmark.\n"); break;
785 case -2 : PrintAndLog("Button pressed. Aborted.\n"); break;
786 case -3 : PrintAndLog("Tag isn't vulnerable to Nested Attack (random number generator is not predictable).\n"); break;
787 case -4 : PrintAndLog("No valid key found"); break;
788 case -5 :
789 key64 = bytes_to_num(keyBlock, 6);
790
791 // transfer key to the emulator
792 if (transferToEml) {
793 uint8_t sectortrailer;
794 if (trgBlockNo < 32*4) { // 4 block sector
795 sectortrailer = (trgBlockNo & 0x03) + 3;
796 } else { // 16 block sector
797 sectortrailer = (trgBlockNo & 0x0f) + 15;
798 }
799 mfEmlGetMem(keyBlock, sectortrailer, 1);
800
801 if (!trgKeyType)
802 num_to_bytes(key64, 6, keyBlock);
803 else
804 num_to_bytes(key64, 6, &keyBlock[10]);
805 mfEmlSetMem(keyBlock, sectortrailer, 1);
806 }
807 return 0;
808 default : PrintAndLog("Unknown Error.\n");
809 }
810 return 2;
811 }
812 else { // ------------------------------------ multiple sectors working
813 clock_t t1 = clock();
814 unsigned long elapsed_time;
815 time_t start, end;
816 time(&start);
817
818 e_sector = calloc(SectorsCnt, sizeof(sector));
819 if (e_sector == NULL) return 1;
820
821 //test current key and additional standard keys first
822 memcpy(keyBlock, key, 6);
823 num_to_bytes(0xffffffffffff, 6, (uint8_t*)(keyBlock + 1 * 6));
824 num_to_bytes(0x000000000000, 6, (uint8_t*)(keyBlock + 2 * 6));
825 num_to_bytes(0xa0a1a2a3a4a5, 6, (uint8_t*)(keyBlock + 3 * 6));
826 num_to_bytes(0xb0b1b2b3b4b5, 6, (uint8_t*)(keyBlock + 4 * 6));
827 num_to_bytes(0xaabbccddeeff, 6, (uint8_t*)(keyBlock + 5 * 6));
828
829 PrintAndLog("Testing known keys. Sector count=%d", SectorsCnt);
830 for (i = 0; i < SectorsCnt; i++) {
831 for (j = 0; j < 2; j++) {
832 if (e_sector[i].foundKey[j]) continue;
833
834 res = mfCheckKeys(FirstBlockOfSector(i), j, true, 6, keyBlock, &key64);
835
836 if (!res) {
837 e_sector[i].Key[j] = key64;
838 e_sector[i].foundKey[j] = TRUE;
839 }
840 }
841 }
842 clock_t t2 = clock() - t1;
843 time(&end);
844 elapsed_time = difftime(end, start);
845 if ( t2 > 0 )
846 PrintAndLog("Time to check 6 known keys: %.0f ticks %u seconds\n", (float)t2 , elapsed_time);
847
848 PrintAndLog("enter nested...");
849
850 // nested sectors
851 iterations = 0;
852 bool calibrate = true;
853
854 for (i = 0; i < NESTED_SECTOR_RETRY; i++) {
855 for (uint8_t sectorNo = 0; sectorNo < SectorsCnt; ++sectorNo) {
856 for (trgKeyType = 0; trgKeyType < 2; ++trgKeyType) {
857
858 if (e_sector[sectorNo].foundKey[trgKeyType]) continue;
859
860 int16_t isOK = mfnested(blockNo, keyType, key, FirstBlockOfSector(sectorNo), trgKeyType, keyBlock, calibrate);
861 switch (isOK) {
862 case -1 : PrintAndLog("Error: No response from Proxmark.\n"); break;
863 case -2 : PrintAndLog("Button pressed. Aborted.\n"); break;
864 case -3 : PrintAndLog("Tag isn't vulnerable to Nested Attack (its random number generator is not predictable).\n"); break;
865 case -4 : //key not found
866 calibrate = false;
867 iterations++;
868 continue;
869 case -5 :
870 calibrate = false;
871 iterations++;
872 e_sector[sectorNo].foundKey[trgKeyType] = 1;
873 e_sector[sectorNo].Key[trgKeyType] = bytes_to_num(keyBlock, 6);
874 continue;
875
876 default : PrintAndLog("Unknown Error.\n");
877 }
878 free(e_sector);
879 return 2;
880 }
881 }
882 }
883
884 t1 = clock() - t1;
885 time(&end);
886 elapsed_time = difftime(end, start);
887 if ( t1 > 0 )
888 PrintAndLog("Time in nested: %.0f ticks %u seconds\n", (float)t1, elapsed_time);
889
890
891 // 20160116 If Sector A is found, but not Sector B, try just reading it of the tag?
892 PrintAndLog("trying to read key B...");
893 for (i = 0; i < SectorsCnt; i++) {
894 // KEY A but not KEY B
895 if ( e_sector[i].foundKey[0] && !e_sector[i].foundKey[1] ) {
896
897 uint8_t sectrail = (FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1);
898
899 PrintAndLog("Reading block %d", sectrail);
900
901 UsbCommand c = {CMD_MIFARE_READBL, {sectrail, 0, 0}};
902 num_to_bytes(e_sector[i].Key[0], 6, c.d.asBytes); // KEY A
903 clearCommandBuffer();
904 SendCommand(&c);
905
906 UsbCommand resp;
907 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500)) continue;
908
909 uint8_t isOK = resp.arg[0] & 0xff;
910 if (!isOK) continue;
911
912 uint8_t *data = resp.d.asBytes;
913 key64 = bytes_to_num(data+10, 6);
914 if (key64) {
915 PrintAndLog("Data:%s", sprint_hex(data+10, 6));
916 e_sector[i].foundKey[1] = TRUE;
917 e_sector[i].Key[1] = key64;
918 }
919 }
920 }
921
922
923 //print them
924 printKeyTable( SectorsCnt, e_sector );
925
926 // transfer them to the emulator
927 if (transferToEml) {
928 for (i = 0; i < SectorsCnt; i++) {
929 mfEmlGetMem(keyBlock, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1);
930 if (e_sector[i].foundKey[0])
931 num_to_bytes(e_sector[i].Key[0], 6, keyBlock);
932 if (e_sector[i].foundKey[1])
933 num_to_bytes(e_sector[i].Key[1], 6, &keyBlock[10]);
934 mfEmlSetMem(keyBlock, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1);
935 }
936 }
937
938 // Create dump file
939 if (createDumpFile) {
940 if ((fkeys = fopen("dumpkeys.bin","wb")) == NULL) {
941 PrintAndLog("Could not create file dumpkeys.bin");
942 free(e_sector);
943 return 1;
944 }
945 PrintAndLog("Printing keys to binary file dumpkeys.bin...");
946 for(i=0; i<SectorsCnt; i++) {
947 if (e_sector[i].foundKey[0]){
948 num_to_bytes(e_sector[i].Key[0], 6, tempkey);
949 fwrite ( tempkey, 1, 6, fkeys );
950 }
951 else{
952 fwrite ( &standart, 1, 6, fkeys );
953 }
954 }
955 for(i=0; i<SectorsCnt; i++) {
956 if (e_sector[i].foundKey[1]){
957 num_to_bytes(e_sector[i].Key[1], 6, tempkey);
958 fwrite ( tempkey, 1, 6, fkeys );
959 }
960 else{
961 fwrite ( &standart, 1, 6, fkeys );
962 }
963 }
964 fclose(fkeys);
965 }
966
967 free(e_sector);
968 }
969 return 0;
970 }
971
972 int CmdHF14AMfNestedHard(const char *Cmd) {
973 uint8_t blockNo = 0;
974 uint8_t keyType = 0;
975 uint8_t trgBlockNo = 0;
976 uint8_t trgKeyType = 0;
977 uint8_t key[6] = {0, 0, 0, 0, 0, 0};
978 uint8_t trgkey[6] = {0, 0, 0, 0, 0, 0};
979
980 char ctmp;
981 ctmp = param_getchar(Cmd, 0);
982 if (ctmp == 'H' || ctmp == 'h' ) return usage_hf14_hardnested();
983 if (ctmp != 'R' && ctmp != 'r' && ctmp != 'T' && ctmp != 't' && strlen(Cmd) < 20) return usage_hf14_hardnested();
984
985 bool know_target_key = false;
986 bool nonce_file_read = false;
987 bool nonce_file_write = false;
988 bool slow = false;
989 int tests = 0;
990
991 if (ctmp == 'R' || ctmp == 'r') {
992 nonce_file_read = true;
993 if (!param_gethex(Cmd, 1, trgkey, 12)) {
994 know_target_key = true;
995 }
996 } else if (ctmp == 'T' || ctmp == 't') {
997 tests = param_get32ex(Cmd, 1, 100, 10);
998 } else {
999 blockNo = param_get8(Cmd, 0);
1000 ctmp = param_getchar(Cmd, 1);
1001 if (ctmp != 'a' && ctmp != 'A' && ctmp != 'b' && ctmp != 'B') {
1002 PrintAndLog("Key type must be A or B");
1003 return 1;
1004 }
1005 if (ctmp != 'A' && ctmp != 'a') {
1006 keyType = 1;
1007 }
1008
1009 if (param_gethex(Cmd, 2, key, 12)) {
1010 PrintAndLog("Key must include 12 HEX symbols");
1011 return 1;
1012 }
1013
1014 trgBlockNo = param_get8(Cmd, 3);
1015 ctmp = param_getchar(Cmd, 4);
1016 if (ctmp != 'a' && ctmp != 'A' && ctmp != 'b' && ctmp != 'B') {
1017 PrintAndLog("Target key type must be A or B");
1018 return 1;
1019 }
1020 if (ctmp != 'A' && ctmp != 'a') {
1021 trgKeyType = 1;
1022 }
1023
1024 uint16_t i = 5;
1025
1026 if (!param_gethex(Cmd, 5, trgkey, 12)) {
1027 know_target_key = true;
1028 i++;
1029 }
1030
1031 while ((ctmp = param_getchar(Cmd, i))) {
1032 if (ctmp == 's' || ctmp == 'S') {
1033 slow = true;
1034 } else if (ctmp == 'w' || ctmp == 'W') {
1035 nonce_file_write = true;
1036 } else {
1037 PrintAndLog("Possible options are w and/or s");
1038 return 1;
1039 }
1040 i++;
1041 }
1042 }
1043
1044 PrintAndLog("--target block no:%3d, target key type:%c, known target key: 0x%02x%02x%02x%02x%02x%02x%s, file action: %s, Slow: %s, Tests: %d ",
1045 trgBlockNo,
1046 trgKeyType?'B':'A',
1047 trgkey[0], trgkey[1], trgkey[2], trgkey[3], trgkey[4], trgkey[5],
1048 know_target_key ? "" : " (not set)",
1049 nonce_file_write ? "write": nonce_file_read ? "read" : "none",
1050 slow ? "Yes" : "No",
1051 tests);
1052
1053 uint64_t foundkey = 0;
1054 int16_t isOK = mfnestedhard(blockNo, keyType, key, trgBlockNo, trgKeyType, know_target_key ? trgkey : NULL, nonce_file_read, nonce_file_write, slow, tests, &foundkey);
1055
1056 if (isOK) {
1057 switch (isOK) {
1058 case 1 : PrintAndLog("Error: No response from Proxmark.\n"); break;
1059 case 2 : PrintAndLog("Button pressed. Aborted.\n"); break;
1060 default : break;
1061 }
1062 return 2;
1063 }
1064
1065 return 0;
1066 }
1067
1068 int CmdHF14AMfChk(const char *Cmd) {
1069
1070 if (strlen(Cmd)<3) return usage_hf14_chk();
1071
1072 FILE * f;
1073 char filename[FILE_PATH_SIZE]={0};
1074 char buf[13];
1075 uint8_t *keyBlock = NULL, *p;
1076 uint8_t stKeyBlock = 20;
1077
1078 sector *e_sector = NULL;
1079
1080 int i, res;
1081 int keycnt = 0;
1082 char ctmp = 0x00;
1083 uint8_t blockNo = 0;
1084 uint8_t SectorsCnt = 1;
1085 uint8_t keyType = 0;
1086 uint64_t key64 = 0;
1087
1088 uint8_t tempkey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
1089
1090 int transferToEml = 0;
1091 int createDumpFile = 0;
1092
1093 keyBlock = calloc(stKeyBlock, 6);
1094 if (keyBlock == NULL) return 1;
1095
1096 uint64_t defaultKeys[] = {
1097 0xffffffffffff, // Default key (first key used by program if no user defined key)
1098 0x000000000000, // Blank key
1099 0xa0a1a2a3a4a5, // NFCForum MAD key
1100 0xb0b1b2b3b4b5,
1101 0xaabbccddeeff,
1102 0x4d3a99c351dd,
1103 0x1a982c7e459a,
1104 0xd3f7d3f7d3f7,
1105 0x714c5c886e97,
1106 0x587ee5f9350f,
1107 0xa0478cc39091,
1108 0x533cb6c723f6,
1109 0x8fd0a4f256e9
1110 };
1111 int defaultKeysSize = sizeof(defaultKeys) / sizeof(uint64_t);
1112
1113 for (int defaultKeyCounter = 0; defaultKeyCounter < defaultKeysSize; defaultKeyCounter++)
1114 num_to_bytes(defaultKeys[defaultKeyCounter], 6, (uint8_t*)(keyBlock + defaultKeyCounter * 6));
1115
1116
1117 if (param_getchar(Cmd, 0)=='*') {
1118 blockNo = 3;
1119 switch(param_getchar(Cmd+1, 0)) {
1120 case '0': SectorsCnt = 5; break;
1121 case '1': SectorsCnt = 16; break;
1122 case '2': SectorsCnt = 32; break;
1123 case '4': SectorsCnt = 40; break;
1124 default: SectorsCnt = 16;
1125 }
1126 } else {
1127 blockNo = param_get8(Cmd, 0);
1128 }
1129
1130 ctmp = param_getchar(Cmd, 1);
1131 switch (ctmp) {
1132 case 'a': case 'A':
1133 keyType = !0;
1134 break;
1135 case 'b': case 'B':
1136 keyType = !1;
1137 break;
1138 case '?':
1139 keyType = 2;
1140 break;
1141 default:
1142 PrintAndLog("Key type must be A , B or ?");
1143 free(keyBlock);
1144 return 1;
1145 };
1146
1147 ctmp = param_getchar(Cmd, 2);
1148 if (ctmp == 't' || ctmp == 'T') transferToEml = 1;
1149 else if (ctmp == 'd' || ctmp == 'D') createDumpFile = 1;
1150
1151 for (i = transferToEml || createDumpFile; param_getchar(Cmd, 2 + i); i++) {
1152 if (!param_gethex(Cmd, 2 + i, keyBlock + 6 * keycnt, 12)) {
1153 if ( stKeyBlock - keycnt < 2) {
1154 p = realloc(keyBlock, 6*(stKeyBlock+=10));
1155 if (!p) {
1156 PrintAndLog("Cannot allocate memory for Keys");
1157 free(keyBlock);
1158 return 2;
1159 }
1160 keyBlock = p;
1161 }
1162 PrintAndLog("key[%2d] %02x%02x%02x%02x%02x%02x", keycnt,
1163 (keyBlock + 6*keycnt)[0],(keyBlock + 6*keycnt)[1], (keyBlock + 6*keycnt)[2],
1164 (keyBlock + 6*keycnt)[3], (keyBlock + 6*keycnt)[4], (keyBlock + 6*keycnt)[5], 6);
1165 keycnt++;
1166 } else {
1167 // May be a dic file
1168 if ( param_getstr(Cmd, 2 + i,filename) >= FILE_PATH_SIZE ) {
1169 PrintAndLog("File name too long");
1170 free(keyBlock);
1171 return 2;
1172 }
1173
1174 if ( (f = fopen( filename , "r")) ) {
1175 while( fgets(buf, sizeof(buf), f) ){
1176 if (strlen(buf) < 12 || buf[11] == '\n')
1177 continue;
1178
1179 while (fgetc(f) != '\n' && !feof(f)) ; //goto next line
1180
1181 if( buf[0]=='#' ) continue; //The line start with # is comment, skip
1182
1183 if (!isxdigit(buf[0])){
1184 PrintAndLog("File content error. '%s' must include 12 HEX symbols",buf);
1185 continue;
1186 }
1187
1188 buf[12] = 0;
1189
1190 if ( stKeyBlock - keycnt < 2) {
1191 p = realloc(keyBlock, 6*(stKeyBlock+=10));
1192 if (!p) {
1193 PrintAndLog("Cannot allocate memory for defKeys");
1194 free(keyBlock);
1195 fclose(f);
1196 return 2;
1197 }
1198 keyBlock = p;
1199 }
1200 memset(keyBlock + 6 * keycnt, 0, 6);
1201 num_to_bytes(strtoll(buf, NULL, 16), 6, keyBlock + 6*keycnt);
1202 PrintAndLog("check key[%2d] %012" PRIx64, keycnt, bytes_to_num(keyBlock + 6*keycnt, 6));
1203 keycnt++;
1204 memset(buf, 0, sizeof(buf));
1205 }
1206 fclose(f);
1207 } else {
1208 PrintAndLog("File: %s: not found or locked.", filename);
1209 free(keyBlock);
1210 return 1;
1211
1212 }
1213 }
1214 }
1215
1216 if (keycnt == 0) {
1217 PrintAndLog("No key specified, trying default keys");
1218 for (;keycnt < defaultKeysSize; keycnt++)
1219 PrintAndLog("key[%2d] %02x%02x%02x%02x%02x%02x", keycnt,
1220 (keyBlock + 6*keycnt)[0],(keyBlock + 6*keycnt)[1], (keyBlock + 6*keycnt)[2],
1221 (keyBlock + 6*keycnt)[3], (keyBlock + 6*keycnt)[4], (keyBlock + 6*keycnt)[5], 6);
1222 }
1223
1224 // initialize storage for found keys
1225 e_sector = calloc(SectorsCnt, sizeof(sector));
1226 if (e_sector == NULL) {
1227 free(keyBlock);
1228 return 1;
1229 }
1230
1231 // empty e_sector
1232 for(int i = 0; i < SectorsCnt; ++i){
1233 e_sector[i].Key[0] = 0xffffffffffff;
1234 e_sector[i].Key[1] = 0xffffffffffff;
1235 e_sector[i].foundKey[0] = FALSE;
1236 e_sector[i].foundKey[1] = FALSE;
1237 }
1238
1239
1240 uint8_t trgKeyType = 0;
1241 uint32_t max_keys = keycnt > (USB_CMD_DATA_SIZE/6) ? (USB_CMD_DATA_SIZE/6) : keycnt;
1242
1243 // time
1244 clock_t t1 = clock();
1245 time_t start, end;
1246 time(&start);
1247
1248 // check keys.
1249 for (trgKeyType = !keyType; trgKeyType < 2; (keyType==2) ? (++trgKeyType) : (trgKeyType=2) ) {
1250
1251 int b = blockNo;
1252 for (int i = 0; i < SectorsCnt; ++i) {
1253
1254 // skip already found keys.
1255 if (e_sector[i].foundKey[trgKeyType]) continue;
1256
1257 for (uint32_t c = 0; c < keycnt; c += max_keys) {
1258 printf(".");
1259 fflush(stdout);
1260 uint32_t size = keycnt-c > max_keys ? max_keys : keycnt-c;
1261
1262 res = mfCheckKeys(b, trgKeyType, true, size, &keyBlock[6*c], &key64);
1263 if (!res) {
1264 e_sector[i].Key[trgKeyType] = key64;
1265 e_sector[i].foundKey[trgKeyType] = TRUE;
1266 break;
1267 }
1268 }
1269 b < 127 ? ( b +=4 ) : ( b += 16 );
1270 }
1271 }
1272 t1 = clock() - t1;
1273 time(&end);
1274 unsigned long elapsed_time = difftime(end, start);
1275 if ( t1 > 0 )
1276 PrintAndLog("\nTime in checkkeys: %.0f ticks %u seconds\n", (float)t1, elapsed_time);
1277
1278
1279 // 20160116 If Sector A is found, but not Sector B, try just reading it of the tag?
1280 if ( keyType != 1 ) {
1281 PrintAndLog("testing to read key B...");
1282 for (i = 0; i < SectorsCnt; i++) {
1283 // KEY A but not KEY B
1284 if ( e_sector[i].foundKey[0] && !e_sector[i].foundKey[1] ) {
1285
1286 uint8_t sectrail = (FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1);
1287
1288 PrintAndLog("Reading block %d", sectrail);
1289
1290 UsbCommand c = {CMD_MIFARE_READBL, {sectrail, 0, 0}};
1291 num_to_bytes(e_sector[i].Key[0], 6, c.d.asBytes); // KEY A
1292 clearCommandBuffer();
1293 SendCommand(&c);
1294
1295 UsbCommand resp;
1296 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500)) continue;
1297
1298 uint8_t isOK = resp.arg[0] & 0xff;
1299 if (!isOK) continue;
1300
1301 uint8_t *data = resp.d.asBytes;
1302 key64 = bytes_to_num(data+10, 6);
1303 if (key64) {
1304 PrintAndLog("Data:%s", sprint_hex(data+10, 6));
1305 e_sector[i].foundKey[1] = 1;
1306 e_sector[i].Key[1] = key64;
1307 }
1308 }
1309 }
1310 }
1311
1312
1313 //print them
1314 printKeyTable( SectorsCnt, e_sector );
1315
1316 if (transferToEml) {
1317 uint8_t block[16] = {0x00};
1318 for (uint8_t i = 0; i < SectorsCnt; ++i ) {
1319 mfEmlGetMem(block, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1);
1320 if (e_sector[i].foundKey[0])
1321 num_to_bytes(e_sector[i].Key[0], 6, block);
1322 if (e_sector[i].foundKey[1])
1323 num_to_bytes(e_sector[i].Key[1], 6, block+10);
1324 mfEmlSetMem(block, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1);
1325 }
1326 PrintAndLog("Found keys have been transferred to the emulator memory");
1327 }
1328
1329 if (createDumpFile) {
1330 FILE *fkeys = fopen("dumpkeys.bin","wb");
1331 if (fkeys == NULL) {
1332 PrintAndLog("Could not create file dumpkeys.bin");
1333 free(keyBlock);
1334 free(e_sector);
1335 return 1;
1336 }
1337 PrintAndLog("Printing keys to binary file dumpkeys.bin...");
1338
1339 for( i=0; i<SectorsCnt; i++) {
1340 num_to_bytes(e_sector[i].Key[0], 6, tempkey);
1341 fwrite ( tempkey, 1, 6, fkeys );
1342 }
1343 for(i=0; i<SectorsCnt; i++) {
1344 num_to_bytes(e_sector[i].Key[1], 6, tempkey);
1345 fwrite ( tempkey, 1, 6, fkeys );
1346 }
1347 fclose(fkeys);
1348 PrintAndLog("Found keys have been dumped to file dumpkeys.bin. 0xffffffffffff has been inserted for unknown keys.");
1349 }
1350
1351 free(keyBlock);
1352 free(e_sector);
1353 PrintAndLog("");
1354 return 0;
1355 }
1356
1357 sector *k_sector = NULL;
1358 uint8_t k_sectorsCount = 16;
1359 static void emptySectorTable(){
1360
1361 // initialize storage for found keys
1362 if (k_sector == NULL)
1363 k_sector = calloc(k_sectorsCount, sizeof(sector));
1364 if (k_sector == NULL)
1365 return;
1366
1367 // empty e_sector
1368 for(int i = 0; i < k_sectorsCount; ++i){
1369 k_sector[i].Key[0] = 0xffffffffffff;
1370 k_sector[i].Key[1] = 0xffffffffffff;
1371 k_sector[i].foundKey[0] = FALSE;
1372 k_sector[i].foundKey[1] = FALSE;
1373 }
1374 }
1375 void showSectorTable(){
1376 if (k_sector != NULL) {
1377 printKeyTable(k_sectorsCount, k_sector);
1378 free(k_sector);
1379 k_sector = NULL;
1380 }
1381 }
1382 void readerAttack(nonces_t data, bool setEmulatorMem, bool verbose) {
1383
1384 uint64_t key = 0;
1385 bool success = FALSE;
1386
1387 if (k_sector == NULL)
1388 emptySectorTable();
1389
1390 success = tryMfk32_moebius(data, &key, verbose);
1391 if (success) {
1392 uint8_t sector = data.sector;
1393 uint8_t keytype = data.keytype;
1394
1395 PrintAndLog("Reader is trying authenticate with: Key %s, sector %02d: [%012" PRIx64 "]"
1396 , keytype ? "B" : "A"
1397 , sector
1398 , key
1399 );
1400
1401 k_sector[sector].Key[keytype] = key;
1402 k_sector[sector].foundKey[keytype] = TRUE;
1403
1404 //set emulator memory for keys
1405 if (setEmulatorMem) {
1406 uint8_t memBlock[16] = {0,0,0,0,0,0, 0xff, 0x0F, 0x80, 0x69, 0,0,0,0,0,0};
1407 num_to_bytes( k_sector[sector].Key[0], 6, memBlock);
1408 num_to_bytes( k_sector[sector].Key[1], 6, memBlock+10);
1409 //iceman, guessing this will not work so well for 4K tags.
1410 PrintAndLog("Setting Emulator Memory Block %02d: [%s]"
1411 , (sector*4) + 3
1412 , sprint_hex( memBlock, sizeof(memBlock))
1413 );
1414 mfEmlSetMem( memBlock, (sector*4) + 3, 1);
1415 }
1416 }
1417 }
1418
1419 int CmdHF14AMf1kSim(const char *Cmd) {
1420
1421 uint8_t uid[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1422 uint8_t exitAfterNReads = 0;
1423 uint8_t flags = (FLAG_UID_IN_EMUL | FLAG_4B_UID_IN_DATA);
1424 int uidlen = 0;
1425 uint8_t cmdp = 0;
1426 bool errors = FALSE;
1427 bool verbose = FALSE;
1428 bool setEmulatorMem = FALSE;
1429 nonces_t data[1];
1430
1431 while(param_getchar(Cmd, cmdp) != 0x00) {
1432 switch(param_getchar(Cmd, cmdp)) {
1433 case 'e':
1434 case 'E':
1435 setEmulatorMem = TRUE;
1436 cmdp++;
1437 break;
1438 case 'h':
1439 case 'H':
1440 return usage_hf14_mf1ksim();
1441 case 'i':
1442 case 'I':
1443 flags |= FLAG_INTERACTIVE;
1444 cmdp++;
1445 break;
1446 case 'n':
1447 case 'N':
1448 exitAfterNReads = param_get8(Cmd, cmdp+1);
1449 cmdp += 2;
1450 break;
1451 case 'u':
1452 case 'U':
1453 param_gethex_ex(Cmd, cmdp+1, uid, &uidlen);
1454 switch(uidlen) {
1455 case 20: flags = FLAG_10B_UID_IN_DATA; break;
1456 case 14: flags = FLAG_7B_UID_IN_DATA; break;
1457 case 8: flags = FLAG_4B_UID_IN_DATA; break;
1458 default: return usage_hf14_mf1ksim();
1459 }
1460 cmdp += 2;
1461 break;
1462 case 'v':
1463 case 'V':
1464 verbose = TRUE;
1465 cmdp++;
1466 break;
1467 case 'x':
1468 case 'X':
1469 flags |= FLAG_NR_AR_ATTACK;
1470 cmdp++;
1471 break;
1472 default:
1473 PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
1474 errors = TRUE;
1475 break;
1476 }
1477 if(errors) break;
1478 }
1479 //Validations
1480 if(errors) return usage_hf14_mf1ksim();
1481
1482 PrintAndLog(" uid:%s, numreads:%d, flags:%d (0x%02x) "
1483 , (uidlen == 0 ) ? "N/A" : sprint_hex(uid, uidlen>>1)
1484 , exitAfterNReads
1485 , flags
1486 , flags);
1487
1488 UsbCommand c = {CMD_SIMULATE_MIFARE_CARD, {flags, exitAfterNReads, 0}};
1489 memcpy(c.d.asBytes, uid, sizeof(uid));
1490 clearCommandBuffer();
1491 SendCommand(&c);
1492 UsbCommand resp;
1493
1494 if(flags & FLAG_INTERACTIVE) {
1495 PrintAndLog("Press pm3-button or send another cmd to abort simulation");
1496
1497 while( !ukbhit() ){
1498 if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500) ) continue;
1499 if ( !(flags & FLAG_NR_AR_ATTACK) ) break;
1500 if ( (resp.arg[0] & 0xffff) != CMD_SIMULATE_MIFARE_CARD ) break;
1501
1502 memcpy(data, resp.d.asBytes, sizeof(data));
1503 readerAttack(data[0], setEmulatorMem, verbose);
1504 }
1505 showSectorTable();
1506 }
1507 return 0;
1508 }
1509
1510 int CmdHF14AMfSniff(const char *Cmd){
1511 bool wantLogToFile = FALSE;
1512 bool wantDecrypt = FALSE;
1513 //bool wantSaveToEml = FALSE; TODO
1514 bool wantSaveToEmlFile = FALSE;
1515
1516 //var
1517 int tmpchar;
1518 int res = 0;
1519 int len = 0;
1520 int blockLen = 0;
1521 int pckNum = 0;
1522 int num = 0;
1523 uint8_t uid[10];
1524 uint8_t uid_len = 0;
1525 uint8_t atqa[2] = {0x00, 0x00};
1526 uint8_t sak = 0;
1527 bool isTag = FALSE;
1528 uint8_t *buf = NULL;
1529 uint16_t bufsize = 0;
1530 uint8_t *bufPtr = NULL;
1531 uint16_t traceLen = 0;
1532
1533 memset(uid, 0x00, sizeof(uid));
1534
1535 char ctmp = param_getchar(Cmd, 0);
1536 if ( ctmp == 'h' || ctmp == 'H' ) return usage_hf14_sniff();
1537
1538 for (int i = 0; i < 4; i++) {
1539 ctmp = param_getchar(Cmd, i);
1540 if (ctmp == 'l' || ctmp == 'L') wantLogToFile = true;
1541 if (ctmp == 'd' || ctmp == 'D') wantDecrypt = true;
1542 //if (ctmp == 'e' || ctmp == 'E') wantSaveToEml = true; TODO
1543 if (ctmp == 'f' || ctmp == 'F') wantSaveToEmlFile = true;
1544 }
1545
1546 printf("-------------------------------------------------------------------------\n");
1547 printf("Executing mifare sniffing command. \n");
1548 printf("Press the key on the proxmark3 device to abort both proxmark3 and client.\n");
1549 printf("Press the key on pc keyboard to abort the client.\n");
1550 printf("-------------------------------------------------------------------------\n");
1551
1552 UsbCommand c = {CMD_MIFARE_SNIFFER, {0, 0, 0}};
1553 clearCommandBuffer();
1554 SendCommand(&c);
1555
1556 // wait cycle
1557 while (true) {
1558 printf(".");
1559 fflush(stdout);
1560 if (ukbhit()) {
1561 tmpchar = getchar();
1562 (void)tmpchar;
1563 printf("\naborted via keyboard!\n");
1564 break;
1565 }
1566
1567 UsbCommand resp;
1568 if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
1569 res = resp.arg[0] & 0xff;
1570 traceLen = resp.arg[1];
1571 len = resp.arg[2];
1572
1573 // we are done?
1574 if (res == 0) {
1575 free(buf);
1576 return 0;
1577 }
1578
1579 if (res == 1) { // there is (more) data to be transferred
1580 if (pckNum == 0) { // first packet, (re)allocate necessary buffer
1581 if (traceLen > bufsize || buf == NULL) {
1582 uint8_t *p;
1583 if (buf == NULL) // not yet allocated
1584 p = malloc(traceLen);
1585 else // need more memory
1586 p = realloc(buf, traceLen);
1587
1588 if (p == NULL) {
1589 PrintAndLog("Cannot allocate memory for trace");
1590 free(buf);
1591 return 2;
1592 }
1593 buf = p;
1594 }
1595 bufPtr = buf;
1596 bufsize = traceLen;
1597 memset(buf, 0x00, traceLen);
1598 }
1599 if (bufPtr == NULL) {
1600 PrintAndLog("Cannot allocate memory for trace");
1601 free(buf);
1602 return 2;
1603 }
1604 // what happens if LEN is bigger then TRACELEN --iceman
1605 memcpy(bufPtr, resp.d.asBytes, len);
1606 bufPtr += len;
1607 pckNum++;
1608 }
1609
1610 if (res == 2) { // received all data, start displaying
1611 blockLen = bufPtr - buf;
1612 bufPtr = buf;
1613 printf(">\n");
1614 PrintAndLog("received trace len: %d packages: %d", blockLen, pckNum);
1615 while (bufPtr - buf < blockLen) {
1616 bufPtr += 6; // skip (void) timing information
1617 len = *((uint16_t *)bufPtr);
1618 if(len & 0x8000) {
1619 isTag = true;
1620 len &= 0x7fff;
1621 } else {
1622 isTag = false;
1623 }
1624 bufPtr += 2;
1625 if ((len == 17) && (bufPtr[0] == 0xff) && (bufPtr[1] == 0xff) && (bufPtr[15] == 0xff) && (bufPtr[16] == 0xff)) {
1626 memcpy(uid, bufPtr + 2, 10);
1627 memcpy(atqa, bufPtr + 2 + 10, 2);
1628 switch (atqa[0] & 0xC0) {
1629 case 0x80: uid_len = 10; break;
1630 case 0x40: uid_len = 7; break;
1631 default: uid_len = 4; break;
1632 }
1633 sak = bufPtr[14];
1634 PrintAndLog("tag select uid| %s atqa:0x%02x%02x sak:0x%02x",
1635 sprint_hex(uid, uid_len),
1636 atqa[1],
1637 atqa[0],
1638 sak);
1639 if (wantLogToFile || wantDecrypt) {
1640 FillFileNameByUID(logHexFileName, uid, ".log", uid_len);
1641 AddLogCurrentDT(logHexFileName);
1642 }
1643 if (wantDecrypt)
1644 mfTraceInit(uid, uid_len, atqa, sak, wantSaveToEmlFile);
1645 } else {
1646 PrintAndLog("%03d| %s |%s", num, isTag ? "TAG" : "RDR", sprint_hex(bufPtr, len));
1647 if (wantLogToFile)
1648 AddLogHex(logHexFileName, isTag ? "TAG| ":"RDR| ", bufPtr, len);
1649 if (wantDecrypt)
1650 mfTraceDecode(bufPtr, len, wantSaveToEmlFile);
1651 num++;
1652 }
1653 bufPtr += len;
1654 bufPtr += ((len-1)/8+1); // ignore parity
1655 }
1656 pckNum = 0;
1657 }
1658 } // resp not NULL
1659 } // while (true)
1660
1661 free(buf);
1662 return 0;
1663 }
1664
1665 int CmdHF14AMfDbg(const char *Cmd) {
1666
1667 char ctmp = param_getchar(Cmd, 0);
1668 if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_hf14_dbg();
1669
1670 uint8_t dbgMode = param_get8ex(Cmd, 0, 0, 10);
1671 if (dbgMode > 4) return usage_hf14_dbg();
1672
1673 UsbCommand c = {CMD_MIFARE_SET_DBGMODE, {dbgMode, 0, 0}};
1674 SendCommand(&c);
1675 return 0;
1676 }
1677
1678 int CmdHF14AMfKeyBrute(const char *Cmd) {
1679
1680 uint8_t blockNo = 0, keytype = 0;
1681 uint8_t key[6] = {0, 0, 0, 0, 0, 0};
1682 uint64_t foundkey = 0;
1683
1684 char cmdp = param_getchar(Cmd, 0);
1685 if ( cmdp == 'H' || cmdp == 'h') return usage_hf14_keybrute();
1686
1687 // block number
1688 blockNo = param_get8(Cmd, 0);
1689
1690 // keytype
1691 cmdp = param_getchar(Cmd, 1);
1692 if (cmdp == 'B' || cmdp == 'b') keytype = 1;
1693
1694 // key
1695 if (param_gethex(Cmd, 2, key, 12)) return usage_hf14_keybrute();
1696
1697 clock_t t1 = clock();
1698 time_t start, end;
1699 time(&start);
1700
1701 if (mfKeyBrute( blockNo, keytype, key, &foundkey))
1702 PrintAndLog("Found valid key: %012" PRIx64 " \n", foundkey);
1703 else
1704 PrintAndLog("Key not found");
1705
1706 t1 = clock() - t1;
1707 time(&end);
1708 unsigned long elapsed_time = difftime(end, start);
1709 if ( t1 > 0 )
1710 PrintAndLog("\nTime in keybrute: %.0f ticks %u seconds\n", (float)t1, elapsed_time);
1711
1712 return 0;
1713 }
1714
1715 void printKeyTable( uint8_t sectorscnt, sector *e_sector ){
1716 PrintAndLog("|---|----------------|---|----------------|---|");
1717 PrintAndLog("|sec|key A |res|key B |res|");
1718 PrintAndLog("|---|----------------|---|----------------|---|");
1719 for (uint8_t i = 0; i < sectorscnt; ++i) {
1720 PrintAndLog("|%03d| %012" PRIx64 " | %d | %012" PRIx64 " | %d |", i,
1721 e_sector[i].Key[0], e_sector[i].foundKey[0],
1722 e_sector[i].Key[1], e_sector[i].foundKey[1]
1723 );
1724 }
1725 PrintAndLog("|---|----------------|---|----------------|---|");
1726 }
1727
1728 // EMULATOR COMMANDS
1729 int CmdHF14AMfEGet(const char *Cmd)
1730 {
1731 uint8_t blockNo = 0;
1732 uint8_t data[16] = {0x00};
1733
1734 if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
1735 PrintAndLog("Usage: hf mf eget <block number>");
1736 PrintAndLog(" sample: hf mf eget 0 ");
1737 return 0;
1738 }
1739
1740 blockNo = param_get8(Cmd, 0);
1741
1742 PrintAndLog("");
1743 if (!mfEmlGetMem(data, blockNo, 1)) {
1744 PrintAndLog("data[%3d]:%s", blockNo, sprint_hex(data, 16));
1745 } else {
1746 PrintAndLog("Command execute timeout");
1747 }
1748
1749 return 0;
1750 }
1751
1752 int CmdHF14AMfEClear(const char *Cmd)
1753 {
1754 if (param_getchar(Cmd, 0) == 'h') {
1755 PrintAndLog("Usage: hf mf eclr");
1756 PrintAndLog("It set card emulator memory to empty data blocks and key A/B FFFFFFFFFFFF \n");
1757 return 0;
1758 }
1759
1760 UsbCommand c = {CMD_MIFARE_EML_MEMCLR, {0, 0, 0}};
1761 SendCommand(&c);
1762 return 0;
1763 }
1764
1765 int CmdHF14AMfESet(const char *Cmd)
1766 {
1767 uint8_t memBlock[16];
1768 uint8_t blockNo = 0;
1769 memset(memBlock, 0x00, sizeof(memBlock));
1770
1771 if (strlen(Cmd) < 3 || param_getchar(Cmd, 0) == 'h') {
1772 PrintAndLog("Usage: hf mf eset <block number> <block data (32 hex symbols)>");
1773 PrintAndLog(" sample: hf mf eset 1 000102030405060708090a0b0c0d0e0f ");
1774 return 0;
1775 }
1776
1777 blockNo = param_get8(Cmd, 0);
1778
1779 if (param_gethex(Cmd, 1, memBlock, 32)) {
1780 PrintAndLog("block data must include 32 HEX symbols");
1781 return 1;
1782 }
1783
1784 // 1 - blocks count
1785 UsbCommand c = {CMD_MIFARE_EML_MEMSET, {blockNo, 1, 0}};
1786 memcpy(c.d.asBytes, memBlock, 16);
1787 SendCommand(&c);
1788 return 0;
1789 }
1790
1791 int CmdHF14AMfELoad(const char *Cmd)
1792 {
1793 FILE * f;
1794 char filename[FILE_PATH_SIZE];
1795 char *fnameptr = filename;
1796 char buf[64] = {0x00};
1797 uint8_t buf8[64] = {0x00};
1798 int i, len, blockNum, numBlocks;
1799 int nameParamNo = 1;
1800 uint8_t blockWidth = 32;
1801 char ctmp = param_getchar(Cmd, 0);
1802
1803 if ( ctmp == 'h' || ctmp == 'H' || ctmp == 0x00) {
1804 PrintAndLog("It loads emul dump from the file `filename.eml`");
1805 PrintAndLog("Usage: hf mf eload [card memory] <file name w/o `.eml`> [numblocks]");
1806 PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K, u = UL");
1807 PrintAndLog("");
1808 PrintAndLog(" sample: hf mf eload filename");
1809 PrintAndLog(" hf mf eload 4 filename");
1810 return 0;
1811 }
1812
1813 switch (ctmp) {
1814 case '0' : numBlocks = 5*4; break;
1815 case '1' :
1816 case '\0': numBlocks = 16*4; break;
1817 case '2' : numBlocks = 32*4; break;
1818 case '4' : numBlocks = 256; break;
1819 case 'U' : // fall through
1820 case 'u' : numBlocks = 255; blockWidth = 8; break;
1821 default: {
1822 numBlocks = 16*4;
1823 nameParamNo = 0;
1824 }
1825 }
1826 uint32_t numblk2 = param_get32ex(Cmd,2,0,10);
1827 if (numblk2 > 0) numBlocks = numblk2;
1828
1829 len = param_getstr(Cmd,nameParamNo,filename);
1830
1831 if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5;
1832
1833 fnameptr += len;
1834
1835 sprintf(fnameptr, ".eml");
1836
1837 // open file
1838 f = fopen(filename, "r");
1839 if (f == NULL) {
1840 PrintAndLog("File %s not found or locked", filename);
1841 return 1;
1842 }
1843
1844 blockNum = 0;
1845 while(!feof(f)){
1846 memset(buf, 0, sizeof(buf));
1847
1848 if (fgets(buf, sizeof(buf), f) == NULL) {
1849
1850 if (blockNum >= numBlocks) break;
1851
1852 PrintAndLog("File reading error.");
1853 fclose(f);
1854 return 2;
1855 }
1856
1857 if (strlen(buf) < blockWidth){
1858 if(strlen(buf) && feof(f))
1859 break;
1860 PrintAndLog("File content error. Block data must include %d HEX symbols", blockWidth);
1861 fclose(f);
1862 return 2;
1863 }
1864
1865 for (i = 0; i < blockWidth; i += 2) {
1866 sscanf(&buf[i], "%02x", (unsigned int *)&buf8[i / 2]);
1867 }
1868 if (mfEmlSetMem_xt(buf8, blockNum, 1, blockWidth/2)) {
1869 PrintAndLog("Cant set emul block: %3d", blockNum);
1870 fclose(f);
1871 return 3;
1872 }
1873 printf(".");
1874 blockNum++;
1875
1876 if (blockNum >= numBlocks) break;
1877 }
1878 fclose(f);
1879 printf("\n");
1880
1881 if ((blockNum != numBlocks)) {
1882 PrintAndLog("File content error. Got %d must be %d blocks.",blockNum, numBlocks);
1883 return 4;
1884 }
1885 PrintAndLog("Loaded %d blocks from file: %s", blockNum, filename);
1886 return 0;
1887 }
1888
1889 int CmdHF14AMfESave(const char *Cmd)
1890 {
1891 FILE * f;
1892 char filename[FILE_PATH_SIZE];
1893 char * fnameptr = filename;
1894 uint8_t buf[64];
1895 int i, j, len, numBlocks;
1896 int nameParamNo = 1;
1897
1898 memset(filename, 0, sizeof(filename));
1899 memset(buf, 0, sizeof(buf));
1900
1901 char ctmp = param_getchar(Cmd, 0);
1902
1903 if ( ctmp == 'h' || ctmp == 'H') {
1904 PrintAndLog("It saves emul dump into the file `filename.eml` or `cardID.eml`");
1905 PrintAndLog(" Usage: hf mf esave [card memory] [file name w/o `.eml`]");
1906 PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K");
1907 PrintAndLog("");
1908 PrintAndLog(" sample: hf mf esave ");
1909 PrintAndLog(" hf mf esave 4");
1910 PrintAndLog(" hf mf esave 4 filename");
1911 return 0;
1912 }
1913
1914 switch (ctmp) {
1915 case '0' : numBlocks = 5*4; break;
1916 case '1' :
1917 case '\0': numBlocks = 16*4; break;
1918 case '2' : numBlocks = 32*4; break;
1919 case '4' : numBlocks = 256; break;
1920 default: {
1921 numBlocks = 16*4;
1922 nameParamNo = 0;
1923 }
1924 }
1925
1926 len = param_getstr(Cmd,nameParamNo,filename);
1927
1928 if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5;
1929
1930 // user supplied filename?
1931 if (len < 1) {
1932 // get filename (UID from memory)
1933 if (mfEmlGetMem(buf, 0, 1)) {
1934 PrintAndLog("Can\'t get UID from block: %d", 0);
1935 len = sprintf(fnameptr, "dump");
1936 fnameptr += len;
1937 }
1938 else {
1939 for (j = 0; j < 7; j++, fnameptr += 2)
1940 sprintf(fnameptr, "%02X", buf[j]);
1941 }
1942 } else {
1943 fnameptr += len;
1944 }
1945
1946 // add file extension
1947 sprintf(fnameptr, ".eml");
1948
1949 // open file
1950 f = fopen(filename, "w+");
1951
1952 if ( !f ) {
1953 PrintAndLog("Can't open file %s ", filename);
1954 return 1;
1955 }
1956
1957 // put hex
1958 for (i = 0; i < numBlocks; i++) {
1959 if (mfEmlGetMem(buf, i, 1)) {
1960 PrintAndLog("Cant get block: %d", i);
1961 break;
1962 }
1963 for (j = 0; j < 16; j++)
1964 fprintf(f, "%02X", buf[j]);
1965 fprintf(f,"\n");
1966 }
1967 fclose(f);
1968
1969 PrintAndLog("Saved %d blocks to file: %s", numBlocks, filename);
1970
1971 return 0;
1972 }
1973
1974 int CmdHF14AMfECFill(const char *Cmd)
1975 {
1976 uint8_t keyType = 0;
1977 uint8_t numSectors = 16;
1978
1979 if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
1980 PrintAndLog("Usage: hf mf ecfill <key A/B> [card memory]");
1981 PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K");
1982 PrintAndLog("");
1983 PrintAndLog("samples: hf mf ecfill A");
1984 PrintAndLog(" hf mf ecfill A 4");
1985 PrintAndLog("Read card and transfer its data to emulator memory.");
1986 PrintAndLog("Keys must be laid in the emulator memory. \n");
1987 return 0;
1988 }
1989
1990 char ctmp = param_getchar(Cmd, 0);
1991 if (ctmp != 'a' && ctmp != 'A' && ctmp != 'b' && ctmp != 'B') {
1992 PrintAndLog("Key type must be A or B");
1993 return 1;
1994 }
1995 if (ctmp != 'A' && ctmp != 'a') keyType = 1;
1996
1997 ctmp = param_getchar(Cmd, 1);
1998 switch (ctmp) {
1999 case '0' : numSectors = 5; break;
2000 case '1' :
2001 case '\0': numSectors = 16; break;
2002 case '2' : numSectors = 32; break;
2003 case '4' : numSectors = 40; break;
2004 default: numSectors = 16;
2005 }
2006
2007 printf("--params: numSectors: %d, keyType:%d", numSectors, keyType);
2008 UsbCommand c = {CMD_MIFARE_EML_CARDLOAD, {numSectors, keyType, 0}};
2009 SendCommand(&c);
2010 return 0;
2011 }
2012
2013 int CmdHF14AMfEKeyPrn(const char *Cmd)
2014 {
2015 int i;
2016 uint8_t numSectors;
2017 uint8_t data[16];
2018 uint64_t keyA, keyB;
2019
2020 char cmdp = param_getchar(Cmd, 0);
2021
2022 if ( cmdp == 'h' || cmdp == 'H' ) {
2023 PrintAndLog("It prints the keys loaded in the emulator memory");
2024 PrintAndLog("Usage: hf mf ekeyprn [card memory]");
2025 PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K");
2026 PrintAndLog("");
2027 PrintAndLog(" sample: hf mf ekeyprn 1");
2028 return 0;
2029 }
2030
2031 switch (cmdp) {
2032 case '0' : numSectors = 5; break;
2033 case '1' :
2034 case '\0': numSectors = 16; break;
2035 case '2' : numSectors = 32; break;
2036 case '4' : numSectors = 40; break;
2037 default: numSectors = 16;
2038 }
2039
2040 PrintAndLog("|---|----------------|----------------|");
2041 PrintAndLog("|sec|key A |key B |");
2042 PrintAndLog("|---|----------------|----------------|");
2043 for (i = 0; i < numSectors; i++) {
2044 if (mfEmlGetMem(data, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1)) {
2045 PrintAndLog("error get block %d", FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1);
2046 break;
2047 }
2048 keyA = bytes_to_num(data, 6);
2049 keyB = bytes_to_num(data + 10, 6);
2050 PrintAndLog("|%03d| %012" PRIx64 " | %012" PRIx64 " |", i, keyA, keyB);
2051 }
2052 PrintAndLog("|---|----------------|----------------|");
2053
2054 return 0;
2055 }
2056
2057 // CHINESE MAGIC COMMANDS
2058
2059 int CmdHF14AMfCSetUID(const char *Cmd) {
2060 uint8_t wipeCard = 0;
2061 uint8_t uid[8] = {0x00};
2062 uint8_t oldUid[8] = {0x00};
2063 uint8_t atqa[2] = {0x00};
2064 uint8_t sak[1] = {0x00};
2065 uint8_t atqaPresent = 1;
2066 int res;
2067 char ctmp;
2068 int argi=0;
2069
2070 if (strlen(Cmd) < 1 || param_getchar(Cmd, argi) == 'h') {
2071 PrintAndLog("Set UID, ATQA, and SAK for magic Chinese card (only works with such cards)");
2072 PrintAndLog("If you also want to wipe the card then add 'w' at the end of the command line.");
2073 PrintAndLog("");
2074 PrintAndLog("Usage: hf mf csetuid <UID 8 hex symbols> [ATQA 4 hex symbols SAK 2 hex symbols] [w]");
2075 PrintAndLog("");
2076 PrintAndLog("sample: hf mf csetuid 01020304");
2077 PrintAndLog(" hf mf csetuid 01020304 0004 08 w");
2078 return 0;
2079 }
2080
2081 if (param_getchar(Cmd, argi) && param_gethex(Cmd, argi, uid, 8)) {
2082 PrintAndLog("UID must include 8 HEX symbols");
2083 return 1;
2084 }
2085 argi++;
2086
2087 ctmp = param_getchar(Cmd, argi);
2088 if (ctmp == 'w' || ctmp == 'W') {
2089 wipeCard = 1;
2090 atqaPresent = 0;
2091 }
2092
2093 if (atqaPresent) {
2094 if (param_getchar(Cmd, argi)) {
2095 if (param_gethex(Cmd, argi, atqa, 4)) {
2096 PrintAndLog("ATQA must include 4 HEX symbols");
2097 return 1;
2098 }
2099 argi++;
2100 if (!param_getchar(Cmd, argi) || param_gethex(Cmd, argi, sak, 2)) {
2101 PrintAndLog("SAK must include 2 HEX symbols");
2102 return 1;
2103 }
2104 argi++;
2105 } else
2106 atqaPresent = 0;
2107 }
2108
2109 if(!wipeCard) {
2110 ctmp = param_getchar(Cmd, argi);
2111 if (ctmp == 'w' || ctmp == 'W') {
2112 wipeCard = 1;
2113 }
2114 }
2115
2116 PrintAndLog("--wipe card:%s uid:%s", (wipeCard)?"YES":"NO", sprint_hex(uid, 4));
2117
2118 res = mfCSetUID(uid, (atqaPresent) ? atqa : NULL, (atqaPresent) ? sak : NULL, oldUid, wipeCard);
2119 if (res) {
2120 PrintAndLog("Can't set UID. error=%d", res);
2121 return 1;
2122 }
2123
2124 PrintAndLog("old UID:%s", sprint_hex(oldUid, 4));
2125 PrintAndLog("new UID:%s", sprint_hex(uid, 4));
2126 return 0;
2127 }
2128
2129 int CmdHF14AMfCSetBlk(const char *Cmd) {
2130 uint8_t block[16] = {0x00};
2131 uint8_t blockNo = 0;
2132 uint8_t params = MAGIC_SINGLE;
2133 int res;
2134
2135 if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
2136 PrintAndLog("Usage: hf mf csetblk <block number> <block data (32 hex symbols)> [w]");
2137 PrintAndLog("sample: hf mf csetblk 1 01020304050607080910111213141516");
2138 PrintAndLog("Set block data for magic Chinese card (only works with such cards)");
2139 PrintAndLog("If you also want wipe the card then add 'w' at the end of the command line");
2140 return 0;
2141 }
2142
2143 blockNo = param_get8(Cmd, 0);
2144
2145 if (param_gethex(Cmd, 1, block, 32)) {
2146 PrintAndLog("block data must include 32 HEX symbols");
2147 return 1;
2148 }
2149
2150 char ctmp = param_getchar(Cmd, 2);
2151 if (ctmp == 'w' || ctmp == 'W')
2152 params |= MAGIC_WIPE;
2153
2154 PrintAndLog("--block number:%2d data:%s", blockNo, sprint_hex(block, 16));
2155
2156 res = mfCSetBlock(blockNo, block, NULL, params);
2157 if (res) {
2158 PrintAndLog("Can't write block. error=%d", res);
2159 return 1;
2160 }
2161 return 0;
2162 }
2163
2164 int CmdHF14AMfCLoad(const char *Cmd) {
2165 FILE * f;
2166 char filename[FILE_PATH_SIZE];
2167 char * fnameptr = filename;
2168 char buf[64] = {0x00};
2169 uint8_t buf8[64] = {0x00};
2170 uint8_t fillFromEmulator = 0;
2171 int i, len, blockNum, flags=0;
2172
2173 memset(filename, 0, sizeof(filename));
2174
2175 char ctmp = param_getchar(Cmd, 0);
2176
2177 if (ctmp == 'h' || ctmp == 'H' || ctmp == 0x00) {
2178 PrintAndLog("It loads magic Chinese card from the file `filename.eml`");
2179 PrintAndLog("or from emulator memory (option `e`)");
2180 PrintAndLog("Usage: hf mf cload <file name w/o `.eml`>");
2181 PrintAndLog(" or: hf mf cload e ");
2182 PrintAndLog(" sample: hf mf cload filename");
2183 return 0;
2184 }
2185
2186 if (ctmp == 'e' || ctmp == 'E') fillFromEmulator = 1;
2187
2188 if (fillFromEmulator) {
2189 for (blockNum = 0; blockNum < 16 * 4; blockNum += 1) {
2190 if (mfEmlGetMem(buf8, blockNum, 1)) {
2191 PrintAndLog("Cant get block: %d", blockNum);
2192 return 2;
2193 }
2194 if (blockNum == 0) flags = MAGIC_INIT + MAGIC_WUPC; // switch on field and send magic sequence
2195 if (blockNum == 1) flags = 0; // just write
2196 if (blockNum == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF; // Done. Magic Halt and switch off field.
2197
2198 if (mfCSetBlock(blockNum, buf8, NULL, flags)) {
2199 PrintAndLog("Cant set magic card block: %d", blockNum);
2200 return 3;
2201 }
2202 }
2203 return 0;
2204 } else {
2205 len = strlen(Cmd);
2206 if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5;
2207
2208 memcpy(filename, Cmd, len);
2209 fnameptr += len;
2210
2211 sprintf(fnameptr, ".eml");
2212
2213 // open file
2214 f = fopen(filename, "r");
2215 if (f == NULL) {
2216 PrintAndLog("File not found or locked.");
2217 return 1;
2218 }
2219
2220 blockNum = 0;
2221 while(!feof(f)){
2222
2223 memset(buf, 0, sizeof(buf));
2224
2225 if (fgets(buf, sizeof(buf), f) == NULL) {
2226 fclose(f);
2227 PrintAndLog("File reading error.");
2228 return 2;
2229 }
2230
2231 if (strlen(buf) < 32) {
2232 if(strlen(buf) && feof(f))
2233 break;
2234 PrintAndLog("File content error. Block data must include 32 HEX symbols");
2235 fclose(f);
2236 return 2;
2237 }
2238 for (i = 0; i < 32; i += 2)
2239 sscanf(&buf[i], "%02x", (unsigned int *)&buf8[i / 2]);
2240
2241 if (blockNum == 0) flags = MAGIC_INIT + MAGIC_WUPC; // switch on field and send magic sequence
2242 if (blockNum == 1) flags = 0; // just write
2243 if (blockNum == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF; // Done. Switch off field.
2244
2245 if (mfCSetBlock(blockNum, buf8, NULL, flags)) {
2246 PrintAndLog("Can't set magic card block: %d", blockNum);
2247 fclose(f);
2248 return 3;
2249 }
2250 blockNum++;
2251
2252 if (blockNum >= 16 * 4) break; // magic card type - mifare 1K
2253 }
2254 fclose(f);
2255
2256 // 64 or 256blocks.
2257 if (blockNum != 16 * 4 && blockNum != 32 * 4 + 8 * 16){
2258 PrintAndLog("File content error. There must be 64 blocks");
2259 return 4;
2260 }
2261 PrintAndLog("Loaded from file: %s", filename);
2262 return 0;
2263 }
2264 return 0;
2265 }
2266
2267 int CmdHF14AMfCGetBlk(const char *Cmd) {
2268 uint8_t data[16];
2269 uint8_t blockNo = 0;
2270 int res;
2271 memset(data, 0x00, sizeof(data));
2272 char ctmp = param_getchar(Cmd, 0);
2273
2274 if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') {
2275 PrintAndLog("Usage: hf mf cgetblk <block number>");
2276 PrintAndLog("sample: hf mf cgetblk 1");
2277 PrintAndLog("Get block data from magic Chinese card (only works with such cards)\n");
2278 return 0;
2279 }
2280
2281 blockNo = param_get8(Cmd, 0);
2282
2283 PrintAndLog("--block number:%2d ", blockNo);
2284
2285 res = mfCGetBlock(blockNo, data, MAGIC_SINGLE);
2286 if (res) {
2287 PrintAndLog("Can't read block. error=%d", res);
2288 return 1;
2289 }
2290
2291 PrintAndLog("data: %s", sprint_hex(data, sizeof(data)));
2292 return 0;
2293 }
2294
2295 int CmdHF14AMfCGetSc(const char *Cmd) {
2296 uint8_t data[16];
2297 uint8_t sectorNo = 0;
2298 int i, res, flags;
2299 memset(data, 0x00, sizeof(data));
2300 char ctmp = param_getchar(Cmd, 0);
2301
2302 if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') {
2303 PrintAndLog("Usage: hf mf cgetsc <sector number>");
2304 PrintAndLog("sample: hf mf cgetsc 0");
2305 PrintAndLog("Get sector data from magic Chinese card (only works with such cards)\n");
2306 return 0;
2307 }
2308
2309 sectorNo = param_get8(Cmd, 0);
2310 if (sectorNo > 15) {
2311 PrintAndLog("Sector number must be in [0..15] as in MIFARE classic.");
2312 return 1;
2313 }
2314
2315 PrintAndLog("--sector number:%d ", sectorNo);
2316 PrintAndLog("block | data");
2317
2318 flags = MAGIC_INIT + MAGIC_WUPC;
2319 for (i = 0; i < 4; i++) {
2320 if (i == 1) flags = 0;
2321 if (i == 3) flags = MAGIC_HALT + MAGIC_OFF;
2322
2323 res = mfCGetBlock(sectorNo * 4 + i, data, flags);
2324 if (res) {
2325 PrintAndLog("Can't read block. %d error=%d", sectorNo * 4 + i, res);
2326 return 1;
2327 }
2328 PrintAndLog(" %3d | %s", sectorNo * 4 + i, sprint_hex(data, sizeof(data)));
2329 }
2330 return 0;
2331 }
2332
2333 int CmdHF14AMfCSave(const char *Cmd) {
2334
2335 FILE * f;
2336 char filename[FILE_PATH_SIZE];
2337 char * fnameptr = filename;
2338 uint8_t fillFromEmulator = 0;
2339 uint8_t buf[64];
2340 int i, j, len, flags;
2341
2342 memset(filename, 0, sizeof(filename));
2343 memset(buf, 0, sizeof(buf));
2344 char ctmp = param_getchar(Cmd, 0);
2345
2346 if ( ctmp == 'h' || ctmp == 'H' ) {
2347 PrintAndLog("It saves `magic Chinese` card dump into the file `filename.eml` or `cardID.eml`");
2348 PrintAndLog("or into emulator memory (option `e`)");
2349 PrintAndLog("Usage: hf mf esave [file name w/o `.eml`][e]");
2350 PrintAndLog(" sample: hf mf esave ");
2351 PrintAndLog(" hf mf esave filename");
2352 PrintAndLog(" hf mf esave e \n");
2353 return 0;
2354 }
2355 if (ctmp == 'e' || ctmp == 'E') fillFromEmulator = 1;
2356
2357 if (fillFromEmulator) {
2358 // put into emulator
2359 flags = MAGIC_INIT + MAGIC_WUPC;
2360 for (i = 0; i < 16 * 4; i++) {
2361 if (i == 1) flags = 0;
2362 if (i == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF;
2363
2364 if (mfCGetBlock(i, buf, flags)) {
2365 PrintAndLog("Cant get block: %d", i);
2366 break;
2367 }
2368
2369 if (mfEmlSetMem(buf, i, 1)) {
2370 PrintAndLog("Cant set emul block: %d", i);
2371 return 3;
2372 }
2373 }
2374 return 0;
2375 } else {
2376 len = strlen(Cmd);
2377 if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5;
2378
2379 // get filename based on UID
2380 if (len < 1) {
2381
2382 if (mfCGetBlock(0, buf, MAGIC_SINGLE)) {
2383 PrintAndLog("Cant get block: %d", 0);
2384 len = sprintf(fnameptr, "dump");
2385 fnameptr += len;
2386 } else {
2387 for (j = 0; j < 7; j++, fnameptr += 2)
2388 sprintf(fnameptr, "%02x", buf[j]);
2389 }
2390 } else {
2391 memcpy(filename, Cmd, len);
2392 fnameptr += len;
2393 }
2394
2395 // add .eml extension
2396 sprintf(fnameptr, ".eml");
2397
2398 // open file
2399 f = fopen(filename, "w+");
2400
2401 if (f == NULL) {
2402 PrintAndLog("File not found or locked.");
2403 return 1;
2404 }
2405
2406 // put hex
2407 flags = MAGIC_INIT + MAGIC_WUPC;
2408 for (i = 0; i < 16 * 4; i++) {
2409 if (i == 1) flags = 0;
2410 if (i == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF;
2411
2412 if (mfCGetBlock(i, buf, flags)) {
2413 PrintAndLog("Cant get block: %d", i);
2414 break;
2415 }
2416 for (j = 0; j < 16; j++)
2417 fprintf(f, "%02x", buf[j]);
2418 fprintf(f,"\n");
2419 }
2420 fflush(f);
2421 fclose(f);
2422 PrintAndLog("Saved to file: %s", filename);
2423 return 0;
2424 }
2425 }
2426
2427 //needs nt, ar, at, Data to decrypt
2428 int CmdHf14MfDecryptBytes(const char *Cmd){
2429 uint8_t data[50];
2430 uint32_t nt = param_get32ex(Cmd,0,0,16);
2431 uint32_t ar_enc = param_get32ex(Cmd,1,0,16);
2432 uint32_t at_enc = param_get32ex(Cmd,2,0,16);
2433
2434 int len = 0;
2435 param_gethex_ex(Cmd, 3, data, &len);
2436
2437 len /= 2;
2438 int limit = sizeof(data) / 2;
2439
2440 if ( len >= limit )
2441 len = limit;
2442
2443 return tryDecryptWord( nt, ar_enc, at_enc, data, len);
2444 }
2445
2446 static command_t CommandTable[] = {
2447 {"help", CmdHelp, 1, "This help"},
2448 {"dbg", CmdHF14AMfDbg, 0, "Set default debug mode"},
2449 {"rdbl", CmdHF14AMfRdBl, 0, "Read MIFARE classic block"},
2450 {"rdsc", CmdHF14AMfRdSc, 0, "Read MIFARE classic sector"},
2451 {"dump", CmdHF14AMfDump, 0, "Dump MIFARE classic tag to binary file"},
2452 {"restore", CmdHF14AMfRestore, 0, "Restore MIFARE classic binary file to BLANK tag"},
2453 {"wrbl", CmdHF14AMfWrBl, 0, "Write MIFARE classic block"},
2454 {"chk", CmdHF14AMfChk, 0, "Check keys"},
2455 {"mifare", CmdHF14AMifare, 0, "Darkside attack. read parity error messages."},
2456 {"nested", CmdHF14AMfNested, 0, "Nested attack. Test nested authentication"},
2457 {"hardnested", CmdHF14AMfNestedHard, 0, "Nested attack for hardened Mifare cards"},
2458 {"keybrute", CmdHF14AMfKeyBrute, 0, "J_Run's 2nd phase of multiple sector nested authentication key recovery"},
2459 {"sniff", CmdHF14AMfSniff, 0, "Sniff card-reader communication"},
2460 {"sim", CmdHF14AMf1kSim, 0, "Simulate MIFARE card"},
2461 {"eclr", CmdHF14AMfEClear, 0, "Clear simulator memory block"},
2462 {"eget", CmdHF14AMfEGet, 0, "Get simulator memory block"},
2463 {"eset", CmdHF14AMfESet, 0, "Set simulator memory block"},
2464 {"eload", CmdHF14AMfELoad, 0, "Load from file emul dump"},
2465 {"esave", CmdHF14AMfESave, 0, "Save to file emul dump"},
2466 {"ecfill", CmdHF14AMfECFill, 0, "Fill simulator memory with help of keys from simulator"},
2467 {"ekeyprn", CmdHF14AMfEKeyPrn, 0, "Print keys from simulator memory"},
2468 {"csetuid", CmdHF14AMfCSetUID, 0, "Set UID for magic Chinese card"},
2469 {"csetblk", CmdHF14AMfCSetBlk, 0, "Write block - Magic Chinese card"},
2470 {"cgetblk", CmdHF14AMfCGetBlk, 0, "Read block - Magic Chinese card"},
2471 {"cgetsc", CmdHF14AMfCGetSc, 0, "Read sector - Magic Chinese card"},
2472 {"cload", CmdHF14AMfCLoad, 0, "Load dump into magic Chinese card"},
2473 {"csave", CmdHF14AMfCSave, 0, "Save dump from magic Chinese card into file or emulator"},
2474 {"decrypt", CmdHf14MfDecryptBytes, 1, "[nt] [ar_enc] [at_enc] [data] - to decrypt snoop or trace"},
2475 {NULL, NULL, 0, NULL}
2476 };
2477
2478 int CmdHFMF(const char *Cmd) {
2479 clearCommandBuffer();
2480 CmdsParse(CommandTable, Cmd);
2481 return 0;
2482 }
2483
2484 int CmdHelp(const char *Cmd) {
2485 CmdsHelp(CommandTable);
2486 return 0;
2487 }
Impressum, Datenschutz