]> git.zerfleddert.de Git - proxmark3-svn/blob - client/cmdhf14a.c
improved version of "hf 14a mifare" command
[proxmark3-svn] / client / cmdhf14a.c
1 //-----------------------------------------------------------------------------
2 // 2011, Merlok
3 // Copyright (C) 2010 iZsh <izsh at fail0verflow.com>, Hagen Fritsch
4 //
5 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
6 // at your option, any later version. See the LICENSE.txt file for the text of
7 // the license.
8 //-----------------------------------------------------------------------------
9 // High frequency ISO14443A commands
10 //-----------------------------------------------------------------------------
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <conio.h>
16 #include "util.h"
17 #include "iso14443crc.h"
18 #include "data.h"
19 #include "proxusb.h"
20 #include "ui.h"
21 #include "cmdparser.h"
22 #include "cmdhf14a.h"
23 #include "common.h"
24 #include "cmdmain.h"
25 #include "nonce2key/nonce2key.h"
26 #include "nonce2key/crapto1.h"
27
28 static int CmdHelp(const char *Cmd);
29
30 int CmdHF14AList(const char *Cmd)
31 {
32 uint8_t got[1920];
33 GetFromBigBuf(got, sizeof(got));
34
35 PrintAndLog("recorded activity:");
36 PrintAndLog(" ETU :rssi: who bytes");
37 PrintAndLog("---------+----+----+-----------");
38
39 int i = 0;
40 int prev = -1;
41
42 for (;;) {
43 if(i >= 1900) {
44 break;
45 }
46
47 bool isResponse;
48 int timestamp = *((uint32_t *)(got+i));
49 if (timestamp & 0x80000000) {
50 timestamp &= 0x7fffffff;
51 isResponse = 1;
52 } else {
53 isResponse = 0;
54 }
55
56 int metric = 0;
57 int parityBits = *((uint32_t *)(got+i+4));
58 // 4 bytes of additional information...
59 // maximum of 32 additional parity bit information
60 //
61 // TODO:
62 // at each quarter bit period we can send power level (16 levels)
63 // or each half bit period in 256 levels.
64
65
66 int len = got[i+8];
67
68 if (len > 100) {
69 break;
70 }
71 if (i + len >= 1900) {
72 break;
73 }
74
75 uint8_t *frame = (got+i+9);
76
77 // Break and stick with current result if buffer was not completely full
78 if (frame[0] == 0x44 && frame[1] == 0x44 && frame[3] == 0x44) { break; }
79
80 char line[1000] = "";
81 int j;
82 for (j = 0; j < len; j++) {
83 int oddparity = 0x01;
84 int k;
85
86 for (k=0;k<8;k++) {
87 oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
88 }
89
90 //if((parityBits >> (len - j - 1)) & 0x01) {
91 if (isResponse && (oddparity != ((parityBits >> (len - j - 1)) & 0x01))) {
92 sprintf(line+(j*4), "%02x! ", frame[j]);
93 }
94 else {
95 sprintf(line+(j*4), "%02x ", frame[j]);
96 }
97 }
98
99 char *crc;
100 crc = "";
101 if (len > 2) {
102 uint8_t b1, b2;
103 for (j = 0; j < (len - 1); j++) {
104 // gives problems... search for the reason..
105 /*if(frame[j] == 0xAA) {
106 switch(frame[j+1]) {
107 case 0x01:
108 crc = "[1] Two drops close after each other";
109 break;
110 case 0x02:
111 crc = "[2] Potential SOC with a drop in second half of bitperiod";
112 break;
113 case 0x03:
114 crc = "[3] Segment Z after segment X is not possible";
115 break;
116 case 0x04:
117 crc = "[4] Parity bit of a fully received byte was wrong";
118 break;
119 default:
120 crc = "[?] Unknown error";
121 break;
122 }
123 break;
124 }*/
125 }
126
127 if (strlen(crc)==0) {
128 ComputeCrc14443(CRC_14443_A, frame, len-2, &b1, &b2);
129 if (b1 != frame[len-2] || b2 != frame[len-1]) {
130 crc = (isResponse & (len < 6)) ? "" : " !crc";
131 } else {
132 crc = "";
133 }
134 }
135 } else {
136 crc = ""; // SHORT
137 }
138
139 char metricString[100];
140 if (isResponse) {
141 sprintf(metricString, "%3d", metric);
142 } else {
143 strcpy(metricString, " ");
144 }
145
146 PrintAndLog(" +%7d: %s: %s %s %s",
147 (prev < 0 ? 0 : (timestamp - prev)),
148 metricString,
149 (isResponse ? "TAG" : " "), line, crc);
150
151 prev = timestamp;
152 i += (len + 9);
153 }
154 return 0;
155 }
156
157 void iso14a_set_timeout(uint32_t timeout) {
158 UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_SET_TIMEOUT, 0, timeout}};
159 SendCommand(&c);
160 }
161
162 int CmdHF14AMifare(const char *Cmd)
163 {
164 uint32_t uid = 0;
165 uint32_t nt = 0;
166 uint64_t par_list = 0, ks_list = 0, r_key = 0;
167 uint8_t isOK = 0;
168
169 UsbCommand c = {CMD_READER_MIFARE, {strtol(Cmd, NULL, 0), 0, 0}};
170 SendCommand(&c);
171
172 //flush queue
173 while (kbhit()) getchar();
174 while (WaitForResponseTimeout(CMD_ACK, 500) != NULL) ;
175
176 // message
177 printf("-------------------------------------------------------------------------\n");
178 printf("Executing command. It may take up to 30 min.\n");
179 printf("Press the key on proxmark3 device to abort proxmark3.\n");
180 printf("Press the key on the proxmark3 device to abort both proxmark3 and client.\n");
181 printf("-------------------------------------------------------------------------\n");
182
183 // wait cycle
184 while (true) {
185 printf(".");
186 if (kbhit()) {
187 getchar();
188 printf("\naborted via keyboard!\n");
189 break;
190 }
191
192 UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 2000);
193 if (resp != NULL) {
194 isOK = resp->arg[0] & 0xff;
195
196 uid = (uint32_t)bytes_to_num(resp->d.asBytes + 0, 4);
197 nt = (uint32_t)bytes_to_num(resp->d.asBytes + 4, 4);
198 par_list = bytes_to_num(resp->d.asBytes + 8, 8);
199 ks_list = bytes_to_num(resp->d.asBytes + 16, 8);
200
201 printf("\n\n");
202 PrintAndLog("isOk:%02x", isOK);
203 if (!isOK) PrintAndLog("Proxmark can't get statistic info. Execution aborted.\n");
204 break;
205 }
206 }
207 printf("\n");
208
209 // error
210 if (isOK != 1) return 1;
211
212 // execute original function from util nonce2key
213 if (nonce2key(uid, nt, par_list, ks_list, &r_key)) return 2;
214 printf("-------------------------------------------------------------------------\n");
215 PrintAndLog("Key found:%012llx \n", r_key);
216
217 return 0;
218 }
219
220 int CmdHF14AMfWrBl(const char *Cmd)
221 {
222 int i, temp;
223 uint8_t blockNo = 0;
224 uint8_t keyType = 0;
225 uint8_t key[6] = {0, 0, 0, 0, 0, 0};
226 uint8_t bldata[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
227
228 const char *cmdp = Cmd;
229 const char *cmdpe = Cmd;
230
231 if (strlen(Cmd)<3) {
232 PrintAndLog("Usage: hf 14 mfwrbl <block number> <key A/B> <key (12 hex symbols)> <block data (32 hex symbols)>");
233 PrintAndLog(" sample: hf 14a mfwrbl 0 A FFFFFFFFFFFF 000102030405060708090A0B0C0D0E0F");
234 return 0;
235 }
236 PrintAndLog("l: %s", Cmd);
237
238 // skip spaces
239 while (*cmdp==' ' || *cmdp=='\t') cmdp++;
240 blockNo = strtol(cmdp, NULL, 0) & 0xff;
241
242 // next value
243 while (*cmdp!=' ' && *cmdp!='\t') cmdp++;
244 while (*cmdp==' ' || *cmdp=='\t') cmdp++;
245 if (*cmdp != 'A' && *cmdp != 'a') {
246 keyType = 1;
247 }
248
249 // next value
250 while (*cmdp!=' ' && *cmdp!='\t') cmdp++;
251 while (*cmdp==' ' || *cmdp=='\t') cmdp++;
252
253 // next value here:cmdpe
254 cmdpe = cmdp;
255 while (*cmdpe!=' ' && *cmdpe!='\t') cmdpe++;
256 while (*cmdpe==' ' || *cmdpe=='\t') cmdpe++;
257
258 if ((int)cmdpe - (int)cmdp != 13) {
259 PrintAndLog("Length of key must be 12 hex symbols");
260 return 0;
261 }
262
263 for(i = 0; i < 6; i++) {
264 sscanf((char[]){cmdp[0],cmdp[1],0},"%X",&temp);
265 key[i] = temp & 0xff;
266 cmdp++;
267 cmdp++;
268 }
269
270 // next value
271 while (*cmdp!=' ' && *cmdp!='\t') cmdp++;
272 while (*cmdp==' ' || *cmdp=='\t') cmdp++;
273
274 if (strlen(cmdp) != 32) {
275 PrintAndLog("Length of block data must be 32 hex symbols");
276 return 0;
277 }
278
279 for(i = 0; i < 16; i++) {
280 sscanf((char[]){cmdp[0],cmdp[1],0},"%X",&temp);
281 bldata[i] = temp & 0xff;
282 cmdp++;
283 cmdp++;
284 }
285 PrintAndLog(" block no:%02x key type:%02x key:%s", blockNo, keyType, sprint_hex(key, 6));
286 PrintAndLog(" data: %s", sprint_hex(bldata, 16));
287
288 UsbCommand c = {CMD_MIFARE_WRITEBL, {blockNo, keyType, 0}};
289 memcpy(c.d.asBytes, key, 6);
290 memcpy(c.d.asBytes + 10, bldata, 16);
291 SendCommand(&c);
292 UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
293
294 if (resp != NULL) {
295 uint8_t isOK = resp->arg[0] & 0xff;
296
297 PrintAndLog("isOk:%02x", isOK);
298 } else {
299 PrintAndLog("Command execute timeout");
300 }
301
302 return 0;
303 }
304
305 int CmdHF14AMfRdBl(const char *Cmd)
306 {
307 int i, temp;
308 uint8_t blockNo = 0;
309 uint8_t keyType = 0;
310 uint8_t key[6] = {0, 0, 0, 0, 0, 0};
311
312 const char *cmdp = Cmd;
313
314
315 if (strlen(Cmd)<3) {
316 PrintAndLog("Usage: hf 14 mfrdbl <block number> <key A/B> <key (12 hex symbols)>");
317 PrintAndLog(" sample: hf 14a mfrdbl 0 A FFFFFFFFFFFF ");
318 return 0;
319 }
320
321 // skip spaces
322 while (*cmdp==' ' || *cmdp=='\t') cmdp++;
323 blockNo = strtol(cmdp, NULL, 0) & 0xff;
324
325 // next value
326 while (*cmdp!=' ' && *cmdp!='\t') cmdp++;
327 while (*cmdp==' ' || *cmdp=='\t') cmdp++;
328 if (*cmdp != 'A' && *cmdp != 'a') {
329 keyType = 1;
330 }
331
332 // next value
333 while (*cmdp!=' ' && *cmdp!='\t') cmdp++;
334 while (*cmdp==' ' || *cmdp=='\t') cmdp++;
335
336 if (strlen(cmdp) != 12) {
337 PrintAndLog("Length of key must be 12 hex symbols");
338 return 0;
339 }
340
341 for(i = 0; i < 6; i++) {
342 sscanf((char[]){cmdp[0],cmdp[1],0},"%X",&temp);
343 key[i] = temp & 0xff;
344 cmdp++;
345 cmdp++;
346 }
347 PrintAndLog(" block no:%02x key type:%02x key:%s ", blockNo, keyType, sprint_hex(key, 6));
348
349 UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}};
350 memcpy(c.d.asBytes, key, 6);
351 SendCommand(&c);
352 UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
353
354 if (resp != NULL) {
355 uint8_t isOK = resp->arg[0] & 0xff;
356 uint8_t * data = resp->d.asBytes;
357
358 PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 16));
359 } else {
360 PrintAndLog("Command execute timeout");
361 }
362
363 return 0;
364 }
365
366 int CmdHF14AMfRdSc(const char *Cmd)
367 {
368 int i, temp;
369 uint8_t sectorNo = 0;
370 uint8_t keyType = 0;
371 uint8_t key[6] = {0, 0, 0, 0, 0, 0};
372
373 const char *cmdp = Cmd;
374
375
376 if (strlen(Cmd)<3) {
377 PrintAndLog("Usage: hf 14 mfrdsc <sector number> <key A/B> <key (12 hex symbols)>");
378 PrintAndLog(" sample: hf 14a mfrdsc 0 A FFFFFFFFFFFF ");
379 return 0;
380 }
381
382 // skip spaces
383 while (*cmdp==' ' || *cmdp=='\t') cmdp++;
384 sectorNo = strtol(cmdp, NULL, 0) & 0xff;
385
386 // next value
387 while (*cmdp!=' ' && *cmdp!='\t') cmdp++;
388 while (*cmdp==' ' || *cmdp=='\t') cmdp++;
389 if (*cmdp != 'A' && *cmdp != 'a') {
390 keyType = 1;
391 }
392
393 // next value
394 while (*cmdp!=' ' && *cmdp!='\t') cmdp++;
395 while (*cmdp==' ' || *cmdp=='\t') cmdp++;
396
397 if (strlen(cmdp) != 12) {
398 PrintAndLog("Length of key must be 12 hex symbols");
399 return 0;
400 }
401
402 for(i = 0; i < 6; i++) {
403 sscanf((char[]){cmdp[0],cmdp[1],0},"%X",&temp);
404 key[i] = temp & 0xff;
405 cmdp++;
406 cmdp++;
407 }
408 PrintAndLog(" sector no:%02x key type:%02x key:%s ", sectorNo, keyType, sprint_hex(key, 6));
409
410 UsbCommand c = {CMD_MIFARE_READSC, {sectorNo, keyType, 0}};
411 memcpy(c.d.asBytes, key, 6);
412 SendCommand(&c);
413 UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
414 PrintAndLog(" ");
415
416 if (resp != NULL) {
417 uint8_t isOK = resp->arg[0] & 0xff;
418 uint8_t * data = resp->d.asBytes;
419
420 PrintAndLog("isOk:%02x", isOK);
421 for (i = 0; i < 2; i++) {
422 PrintAndLog("data:%s", sprint_hex(data + i * 16, 16));
423 }
424 } else {
425 PrintAndLog("Command1 execute timeout");
426 }
427
428 // response2
429 resp = WaitForResponseTimeout(CMD_ACK, 500);
430 PrintAndLog(" ");
431
432 if (resp != NULL) {
433 uint8_t * data = resp->d.asBytes;
434
435 for (i = 0; i < 2; i++) {
436 PrintAndLog("data:%s", sprint_hex(data + i * 16, 16));
437 }
438 } else {
439 PrintAndLog("Command2 execute timeout");
440 }
441
442 return 0;
443 }
444
445 int CmdHF14AMfNested(const char *Cmd)
446 {
447 int i, temp;
448 uint8_t sectorNo = 0;
449 uint8_t keyType = 0;
450 uint8_t key[6] = {0, 0, 0, 0, 0, 0};
451
452 const char *cmdp = Cmd;
453
454
455 if (strlen(Cmd)<3) {
456 PrintAndLog("Usage: hf 14a nested <sector number> <key A/B> <key (12 hex symbols)>");
457 PrintAndLog(" sample: hf 14a nested 0 A FFFFFFFFFFFF ");
458 return 0;
459 }
460
461 // skip spaces
462 while (*cmdp==' ' || *cmdp=='\t') cmdp++;
463 sectorNo = strtol(cmdp, NULL, 0) & 0xff;
464
465 // next value
466 while (*cmdp!=' ' && *cmdp!='\t') cmdp++;
467 while (*cmdp==' ' || *cmdp=='\t') cmdp++;
468 if (*cmdp != 'A' && *cmdp != 'a') {
469 keyType = 1;
470 }
471
472 // next value
473 while (*cmdp!=' ' && *cmdp!='\t') cmdp++;
474 while (*cmdp==' ' || *cmdp=='\t') cmdp++;
475
476 if (strlen(cmdp) != 12) {
477 PrintAndLog("Length of key must be 12 hex symbols");
478 return 0;
479 }
480
481 for(i = 0; i < 6; i++) {
482 sscanf((char[]){cmdp[0],cmdp[1],0},"%X",&temp);
483 key[i] = temp & 0xff;
484 cmdp++;
485 cmdp++;
486 }
487 PrintAndLog(" sector no:%02x key type:%02x key:%s ", sectorNo, keyType, sprint_hex(key, 6));
488
489 UsbCommand c = {CMD_MIFARE_NESTED, {sectorNo, keyType, 0}};
490 memcpy(c.d.asBytes, key, 6);
491 SendCommand(&c);
492 UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
493 PrintAndLog(" ");
494
495 if (resp != NULL) {
496 uint8_t isOK = resp->arg[0] & 0xff;
497 uint8_t * data = resp->d.asBytes;
498
499 PrintAndLog("isOk:%02x", isOK);
500 for (i = 0; i < 2; i++) {
501 PrintAndLog("data:%s", sprint_hex(data + i * 16, 16));
502 }
503 } else {
504 PrintAndLog("Command execute timeout");
505 }
506
507 return 0;
508 }
509
510 int CmdHF14AMf1kSim(const char *Cmd)
511 {
512 int i, temp;
513 uint8_t uid[4] = {0, 0, 0, 0};
514
515 const char *cmdp = Cmd;
516
517
518 if (strlen(Cmd)<3) {
519 PrintAndLog("Usage: hf 14a mfsim <uid (8 hex symbols)>");
520 PrintAndLog(" sample: hf 14a mfsim 0a0a0a0a ");
521 return 0;
522 }
523
524 // skip spaces
525 while (*cmdp==' ' || *cmdp=='\t') cmdp++;
526
527 if (strlen(cmdp) != 8) {
528 PrintAndLog("Length of UID must be 8 hex symbols");
529 return 0;
530 }
531
532 for(i = 0; i < 4; i++) {
533 sscanf((char[]){cmdp[0],cmdp[1],0},"%X",&temp);
534 uid[i] = temp & 0xff;
535 cmdp++;
536 cmdp++;
537 }
538 PrintAndLog(" uid:%s ", sprint_hex(uid, 4));
539
540 UsbCommand c = {CMD_SIMULATE_MIFARE_CARD, {0, 0, 0}};
541 memcpy(c.d.asBytes, uid, 6);
542 SendCommand(&c);
543
544 return 0;
545 }
546
547
548 int CmdHF14AReader(const char *Cmd)
549 {
550 UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT, 0, 0}};
551 SendCommand(&c);
552 UsbCommand * resp = WaitForResponse(CMD_ACK);
553 uint8_t * uid = resp->d.asBytes;
554 iso14a_card_select_t * card = uid + 12;
555
556 if(resp->arg[0] == 0) {
557 PrintAndLog("iso14443a card select failed");
558 return 0;
559 }
560
561 PrintAndLog("ATQA : %02x %02x", card->atqa[0], card->atqa[1]);
562 PrintAndLog(" UID : %s", sprint_hex(uid, 12));
563 PrintAndLog(" SAK : %02x [%d]", card->sak, resp->arg[0]);
564 if(resp->arg[0] == 1)
565 PrintAndLog(" ATS : %s", sprint_hex(card->ats, card->ats_len));
566 else
567 PrintAndLog("proprietary non-iso14443a card found, RATS not supported");
568
569 return resp->arg[0];
570 }
571
572 // ## simulate iso14443a tag
573 // ## greg - added ability to specify tag UID
574 int CmdHF14ASim(const char *Cmd)
575 {
576
577 unsigned int hi = 0, lo = 0;
578 int n = 0, i = 0;
579 while (sscanf(&Cmd[i++], "%1x", &n ) == 1) {
580 hi= (hi << 4) | (lo >> 28);
581 lo= (lo << 4) | (n & 0xf);
582 }
583
584 // c.arg should be set to *Cmd or convert *Cmd to the correct format for a uid
585 UsbCommand c = {CMD_SIMULATE_TAG_ISO_14443a, {hi, lo, 0}};
586 PrintAndLog("Emulating 14443A TAG with UID %x%16x", hi, lo);
587 SendCommand(&c);
588 return 0;
589 }
590
591 int CmdHF14ASnoop(const char *Cmd)
592 {
593 UsbCommand c = {CMD_SNOOP_ISO_14443a};
594 SendCommand(&c);
595 return 0;
596 }
597
598 static command_t CommandTable[] =
599 {
600 {"help", CmdHelp, 1, "This help"},
601 {"list", CmdHF14AList, 0, "List ISO 14443a history"},
602 {"mifare", CmdHF14AMifare, 0, "Read out sector 0 parity error messages. param - <used card nonce>"},
603 {"mfrdbl", CmdHF14AMfRdBl, 0, "Read MIFARE classic block"},
604 {"mfrdsc", CmdHF14AMfRdSc, 0, "Read MIFARE classic sector"},
605 {"mfwrbl", CmdHF14AMfWrBl, 0, "Write MIFARE classic block"},
606 {"nested", CmdHF14AMfNested, 0, "Test nested authentication"},
607 {"mfsim", CmdHF14AMf1kSim, 0, "Simulate MIFARE 1k card - NOT WORKING!!!"},
608 {"reader", CmdHF14AReader, 0, "Act like an ISO14443 Type A reader"},
609 {"sim", CmdHF14ASim, 0, "<UID> -- Fake ISO 14443a tag"},
610 {"snoop", CmdHF14ASnoop, 0, "Eavesdrop ISO 14443 Type A"},
611 {NULL, NULL, 0, NULL}
612 };
613
614 int CmdHF14A(const char *Cmd)
615 {
616 CmdsParse(CommandTable, Cmd);
617 return 0;
618 }
619
620 int CmdHelp(const char *Cmd)
621 {
622 CmdsHelp(CommandTable);
623 return 0;
624 }
Impressum, Datenschutz