]>
cvs.zerfleddert.de Git - proxmark3-svn/blob - client/cmdhfmf.c
ee72dad5855d07314575809d917b86bfb9b1a808
   1 //----------------------------------------------------------------------------- 
   2 // Copyright (C) 2011 Merlok 
   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 
   7 //----------------------------------------------------------------------------- 
   8 // High frequency MIFARE commands 
   9 //----------------------------------------------------------------------------- 
  13 static int CmdHelp(const char *Cmd
); 
  16 int CmdHF14AMifare(const char *Cmd
) 
  20         uint64_t par_list 
= 0, ks_list 
= 0, r_key 
= 0; 
  22         uint8_t keyBlock
[6] = {0,0,0,0,0,0}; 
  24         if (param_getchar(Cmd
, 0) && param_gethex(Cmd
, 0, keyBlock
, 8)) { 
  25                 PrintAndLog("Nt must include 8 HEX symbols"); 
  29         UsbCommand c 
= {CMD_READER_MIFARE
, {(uint32_t)bytes_to_num(keyBlock
, 4), 0, 0}}; 
  33         while (ukbhit())        getchar(); 
  36         printf("-------------------------------------------------------------------------\n"); 
  37         printf("Executing command. It may take up to 30 min.\n"); 
  38         printf("Press the key on proxmark3 device to abort proxmark3.\n"); 
  39         printf("Press the key on the proxmark3 device to abort both proxmark3 and client.\n"); 
  40         printf("-------------------------------------------------------------------------\n"); 
  47                         printf("\naborted via keyboard!\n"); 
  51                 UsbCommand 
* resp 
= WaitForResponseTimeout(CMD_ACK
, 2000); 
  53                         isOK  
= resp
->arg
[0] & 0xff; 
  55                         uid 
= (uint32_t)bytes_to_num(resp
->d
.asBytes 
+  0, 4); 
  56                         nt 
=  (uint32_t)bytes_to_num(resp
->d
.asBytes 
+  4, 4); 
  57                         par_list 
= bytes_to_num(resp
->d
.asBytes 
+  8, 8); 
  58                         ks_list 
= bytes_to_num(resp
->d
.asBytes 
+  16, 8); 
  61                         PrintAndLog("isOk:%02x", isOK
); 
  62                         if (!isOK
) PrintAndLog("Proxmark can't get statistic info. Execution aborted.\n"); 
  69         if (isOK 
!= 1) return 1; 
  71         // execute original function from util nonce2key 
  72         if (nonce2key(uid
, nt
, par_list
, ks_list
, &r_key
)) return 2; 
  73         printf("------------------------------------------------------------------\n"); 
  74         PrintAndLog("Key found:%012llx \n", r_key
); 
  76         num_to_bytes(r_key
, 6, keyBlock
); 
  77         isOK 
= mfCheckKeys(0, 0, 1, keyBlock
, &r_key
); 
  79                 PrintAndLog("Found valid key:%012llx", r_key
); 
  81                 PrintAndLog("Found invalid key. ( Nt=%08x", nt
);         
  87 int CmdHF14AMfWrBl(const char *Cmd
) 
  91         uint8_t key
[6] = {0, 0, 0, 0, 0, 0}; 
  92         uint8_t bldata
[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 
  97                 PrintAndLog("Usage:  hf mf wrbl    <block number> <key A/B> <key (12 hex symbols)> <block data (32 hex symbols)>"); 
  98                 PrintAndLog("        sample: hf mf wrbl 0 A FFFFFFFFFFFF 000102030405060708090A0B0C0D0E0F"); 
 102         blockNo 
= param_get8(Cmd
, 0); 
 103         cmdp 
= param_getchar(Cmd
, 1); 
 105                 PrintAndLog("Key type must be A or B"); 
 108         if (cmdp 
!= 'A' && cmdp 
!= 'a') keyType 
= 1; 
 109         if (param_gethex(Cmd
, 2, key
, 12)) { 
 110                 PrintAndLog("Key must include 12 HEX symbols"); 
 113         if (param_gethex(Cmd
, 3, bldata
, 32)) { 
 114                 PrintAndLog("Block data must include 32 HEX symbols"); 
 117         PrintAndLog("--block no:%02x key type:%02x key:%s", blockNo
, keyType
, sprint_hex(key
, 6)); 
 118         PrintAndLog("--data: %s", sprint_hex(bldata
, 16)); 
 120   UsbCommand c 
= {CMD_MIFARE_WRITEBL
, {blockNo
, keyType
, 0}}; 
 121         memcpy(c
.d
.asBytes
, key
, 6); 
 122         memcpy(c
.d
.asBytes 
+ 10, bldata
, 16); 
 124         UsbCommand 
* resp 
= WaitForResponseTimeout(CMD_ACK
, 1500); 
 127                 uint8_t                isOK  
= resp
->arg
[0] & 0xff; 
 129                 PrintAndLog("isOk:%02x", isOK
); 
 131                 PrintAndLog("Command execute timeout"); 
 137 int CmdHF14AMfRdBl(const char *Cmd
) 
 141         uint8_t key
[6] = {0, 0, 0, 0, 0, 0}; 
 147                 PrintAndLog("Usage:  hf mf rdbl    <block number> <key A/B> <key (12 hex symbols)>"); 
 148                 PrintAndLog("        sample: hf mf rdbl 0 A FFFFFFFFFFFF "); 
 152         blockNo 
= param_get8(Cmd
, 0); 
 153         cmdp 
= param_getchar(Cmd
, 1); 
 155                 PrintAndLog("Key type must be A or B"); 
 158         if (cmdp 
!= 'A' && cmdp 
!= 'a') keyType 
= 1; 
 159         if (param_gethex(Cmd
, 2, key
, 12)) { 
 160                 PrintAndLog("Key must include 12 HEX symbols"); 
 163         PrintAndLog("--block no:%02x key type:%02x key:%s ", blockNo
, keyType
, sprint_hex(key
, 6)); 
 165   UsbCommand c 
= {CMD_MIFARE_READBL
, {blockNo
, keyType
, 0}}; 
 166         memcpy(c
.d
.asBytes
, key
, 6); 
 168         UsbCommand 
* resp 
= WaitForResponseTimeout(CMD_ACK
, 1500); 
 171                 uint8_t                isOK  
= resp
->arg
[0] & 0xff; 
 172                 uint8_t              * data  
= resp
->d
.asBytes
; 
 175                         PrintAndLog("isOk:%02x data:%s", isOK
, sprint_hex(data
, 16)); 
 177                         PrintAndLog("isOk:%02x", isOK
); 
 179                 PrintAndLog("Command execute timeout"); 
 185 int CmdHF14AMfRdSc(const char *Cmd
) 
 188         uint8_t sectorNo 
= 0; 
 190         uint8_t key
[6] = {0, 0, 0, 0, 0, 0}; 
 193         uint8_t * data  
= NULL
; 
 198                 PrintAndLog("Usage:  hf mf rdsc    <sector number> <key A/B> <key (12 hex symbols)>"); 
 199                 PrintAndLog("        sample: hf mf rdsc 0 A FFFFFFFFFFFF "); 
 203         sectorNo 
= param_get8(Cmd
, 0); 
 205                 PrintAndLog("Sector number must be less than 64"); 
 208         cmdp 
= param_getchar(Cmd
, 1); 
 210                 PrintAndLog("Key type must be A or B"); 
 213         if (cmdp 
!= 'A' && cmdp 
!= 'a') keyType 
= 1; 
 214         if (param_gethex(Cmd
, 2, key
, 12)) { 
 215                 PrintAndLog("Key must include 12 HEX symbols"); 
 218         PrintAndLog("--sector no:%02x key type:%02x key:%s ", sectorNo
, keyType
, sprint_hex(key
, 6)); 
 220   UsbCommand c 
= {CMD_MIFARE_READSC
, {sectorNo
, keyType
, 0}}; 
 221         memcpy(c
.d
.asBytes
, key
, 6); 
 223         UsbCommand 
* resp 
= WaitForResponseTimeout(CMD_ACK
, 1500); 
 227                 isOK  
= resp
->arg
[0] & 0xff; 
 228                 data  
= resp
->d
.asBytes
; 
 230                 PrintAndLog("isOk:%02x", isOK
); 
 232                         for (i 
= 0; i 
< 2; i
++) { 
 233                                 PrintAndLog("data:%s", sprint_hex(data 
+ i 
* 16, 16)); 
 236                 PrintAndLog("Command1 execute timeout"); 
 240         resp 
= WaitForResponseTimeout(CMD_ACK
, 500); 
 244                 isOK  
= resp
->arg
[0] & 0xff; 
 245                 data  
= resp
->d
.asBytes
; 
 248                         for (i 
= 0; i 
< 2; i
++) { 
 249                                 PrintAndLog("data:%s", sprint_hex(data 
+ i 
* 16, 16)); 
 252                 PrintAndLog("Command2 execute timeout"); 
 258 int CmdHF14AMfNested(const char *Cmd
) 
 260         int i
, j
, res
, iterations
; 
 261         sector  
*       e_sector 
= NULL
; 
 264         uint8_t trgBlockNo 
= 0; 
 265         uint8_t trgKeyType 
= 0; 
 268         uint8_t key
[6] = {0, 0, 0, 0, 0, 0}; 
 269         uint8_t keyBlock
[16 * 6]; 
 275                 PrintAndLog("Usage:"); 
 276                 PrintAndLog(" all sectors:  hf mf nested  <card memory> <block number> <key A/B> <key (12 hex symbols)>"); 
 277                 PrintAndLog(" one sector:   hf mf nested  o <block number> <key A/B> <key (12 hex symbols)>"); 
 278                 PrintAndLog("               <target block number> <target key A/B>"); 
 279                 PrintAndLog("card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, <other> - 1K"); 
 281                 PrintAndLog("      sample1: hf mf nested 1 0 A FFFFFFFFFFFF "); 
 282                 PrintAndLog("      sample2: hf mf nested o 0 A FFFFFFFFFFFF 4 A"); 
 286         cmdp 
= param_getchar(Cmd
, 0); 
 287         blockNo 
= param_get8(Cmd
, 1); 
 288         ctmp 
= param_getchar(Cmd
, 2); 
 290                 PrintAndLog("Key type must be A or B"); 
 293         if (ctmp 
!= 'A' && ctmp 
!= 'a') keyType 
= 1; 
 294         if (param_gethex(Cmd
, 3, key
, 12)) { 
 295                 PrintAndLog("Key must include 12 HEX symbols"); 
 299         if (cmdp 
=='o' || cmdp 
== 'O') { 
 301                 trgBlockNo 
= param_get8(Cmd
, 4); 
 302                 ctmp 
= param_getchar(Cmd
, 5); 
 304                         PrintAndLog("Target key type must be A or B"); 
 307                 if (ctmp 
!= 'A' && ctmp 
!= 'a') trgKeyType 
= 1; 
 310                         case '0': SectorsCnt 
= 05; break; 
 311                         case '1': SectorsCnt 
= 16; break; 
 312                         case '2': SectorsCnt 
= 32; break; 
 313                         case '4': SectorsCnt 
= 64; break; 
 314                         default:  SectorsCnt 
= 16; 
 318         PrintAndLog("--block no:%02x key type:%02x key:%s ", blockNo
, keyType
, sprint_hex(key
, 6)); 
 320                 PrintAndLog("--target block no:%02x target key type:%02x ", trgBlockNo
, trgKeyType
); 
 323                 if (mfnested(blockNo
, keyType
, key
, trgBlockNo
, trgKeyType
, keyBlock
)) { 
 324                         PrintAndLog("Nested error."); 
 328                 for (i 
= 0; i 
< 16; i
++) { 
 329                         PrintAndLog("cnt=%d key= %s", i
, sprint_hex(keyBlock 
+ i 
* 6, 6)); 
 333                 res 
= mfCheckKeys(trgBlockNo
, trgKeyType
, 8, keyBlock
, &key64
); 
 335                         res 
= mfCheckKeys(trgBlockNo
, trgKeyType
, 8, &keyBlock
[6 * 8], &key64
); 
 337                         PrintAndLog("Found valid key:%012llx", key64
); 
 339                         PrintAndLog("No valid key found"); 
 340         } else  // ------------------------------------  multiple sectors working 
 342                 blDiff 
= blockNo 
% 4; 
 343                 PrintAndLog("Block shift=%d", blDiff
); 
 344                 e_sector 
= calloc(SectorsCnt
, sizeof(sector
)); 
 345                 if (e_sector 
== NULL
) return 1; 
 347                 //test current key 4 sectors 
 348                 memcpy(keyBlock
, key
, 6); 
 349                 num_to_bytes(0xa0a1a2a3a4a5, 6, (uint8_t*)(keyBlock 
+ 1 * 6)); 
 350                 num_to_bytes(0xb0b1b2b3b4b5, 6, (uint8_t*)(keyBlock 
+ 2 * 6)); 
 351                 num_to_bytes(0xffffffffffff, 6, (uint8_t*)(keyBlock 
+ 3 * 6)); 
 352                 num_to_bytes(0x000000000000, 6, (uint8_t*)(keyBlock 
+ 4 * 6)); 
 353                 num_to_bytes(0xaabbccddeeff, 6, (uint8_t*)(keyBlock 
+ 5 * 6)); 
 355                 PrintAndLog("Testing known keys. Sector count=%d", SectorsCnt
); 
 356                 for (i 
= 0; i 
< SectorsCnt
; i
++) { 
 357                         for (j 
= 0; j 
< 2; j
++) { 
 358                                 if (e_sector
[i
].foundKey
[j
]) continue; 
 360                                 res 
= mfCheckKeys(i 
* 4 + blDiff
, j
, 6, keyBlock
, &key64
); 
 363                                         e_sector
[i
].Key
[j
] = key64
; 
 364                                         e_sector
[i
].foundKey
[j
] = 1; 
 372                 PrintAndLog("nested..."); 
 373                 for (i 
= 0; i 
< NESTED_SECTOR_RETRY
; i
++) { 
 374                         for (trgBlockNo 
= blDiff
; trgBlockNo 
< SectorsCnt 
* 4; trgBlockNo 
= trgBlockNo 
+ 4)  
 375                                 for (trgKeyType 
= 0; trgKeyType 
< 2; trgKeyType
++) {  
 376                                         if (e_sector
[trgBlockNo 
/ 4].foundKey
[trgKeyType
]) continue; 
 377                                         if (mfnested(blockNo
, keyType
, key
, trgBlockNo
, trgKeyType
, keyBlock
)) continue; 
 381                                         //try keys from nested 
 382                                         res 
= mfCheckKeys(trgBlockNo
, trgKeyType
, 8, keyBlock
, &key64
); 
 384                                                 res 
= mfCheckKeys(trgBlockNo
, trgKeyType
, 8, &keyBlock
[6 * 8], &key64
); 
 386                                                 PrintAndLog("Found valid key:%012llx", key64
);   
 387                                                 e_sector
[trgBlockNo 
/ 4].foundKey
[trgKeyType
] = 1; 
 388                                                 e_sector
[trgBlockNo 
/ 4].Key
[trgKeyType
] = key64
; 
 393                 PrintAndLog("Iterations count: %d", iterations
); 
 395                 PrintAndLog("|---|----------------|---|----------------|---|"); 
 396                 PrintAndLog("|sec|key A           |res|key B           |res|"); 
 397                 PrintAndLog("|---|----------------|---|----------------|---|"); 
 398                 for (i 
= 0; i 
< SectorsCnt
; i
++) { 
 399                         PrintAndLog("|%03d|  %012llx  | %d |  %012llx  | %d |", i
,  
 400                                 e_sector
[i
].Key
[0], e_sector
[i
].foundKey
[0], e_sector
[i
].Key
[1], e_sector
[i
].foundKey
[1]); 
 402                 PrintAndLog("|---|----------------|---|----------------|---|"); 
 410 int CmdHF14AMfChk(const char *Cmd
) 
 417         uint8_t keyBlock
[8 * 6]; 
 420         memset(keyBlock
, 0x00, sizeof(keyBlock
)); 
 423                 PrintAndLog("Usage:  hf mf chk <block number> <key A/B> [<key (12 hex symbols)>]"); 
 424                 PrintAndLog("      sample: hf mf chk 0 A FFFFFFFFFFFF a0a1a2a3a4a5 b01b2b3b4b5 "); 
 428         blockNo 
= param_get8(Cmd
, 0); 
 429         ctmp 
= param_getchar(Cmd
, 1); 
 431                 PrintAndLog("Key type must be A or B"); 
 434         if (ctmp 
!= 'A' && ctmp 
!= 'a') keyType 
= 1; 
 436         for (i 
= 0; i 
< 6; i
++) { 
 437                 if (!isxdigit(param_getchar(Cmd
, 2 + i
))) break; 
 439                 if (param_gethex(Cmd
, 2 + i
, keyBlock 
+ 6 * i
, 12)) { 
 440                         PrintAndLog("Key[%d] must include 12 HEX symbols", i
); 
 447                 PrintAndLog("There is must be at least one key"); 
 451         PrintAndLog("--block no:%02x key type:%02x key count:%d ", blockNo
, keyType
, keycnt
); 
 453         res 
= mfCheckKeys(blockNo
, keyType
, keycnt
, keyBlock
, &key64
); 
 456                         PrintAndLog("isOk:%02x valid key:%012llx", 1, key64
); 
 458                         PrintAndLog("isOk:%02x", 0); 
 460                 PrintAndLog("Command execute timeout"); 
 466 int CmdHF14AMf1kSim(const char *Cmd
) 
 468         uint8_t uid
[4] = {0, 0, 0, 0}; 
 470         if (param_getchar(Cmd
, 0) == 'h') { 
 471                 PrintAndLog("Usage:  hf mf sim  <uid (8 hex symbols)>"); 
 472                 PrintAndLog("           sample: hf mf sim 0a0a0a0a "); 
 476         if (param_getchar(Cmd
, 0) && param_gethex(Cmd
, 0, uid
, 8)) { 
 477                 PrintAndLog("UID must include 8 HEX symbols"); 
 480         PrintAndLog(" uid:%s ", sprint_hex(uid
, 4)); 
 482   UsbCommand c 
= {CMD_SIMULATE_MIFARE_CARD
, {0, 0, 0}}; 
 483         memcpy(c
.d
.asBytes
, uid
, 4); 
 489 int CmdHF14AMfDbg(const char *Cmd
) 
 491         if (strlen(Cmd
) < 1) { 
 492                 PrintAndLog("Usage:  hf mf dbg  <debug level>"); 
 493                 PrintAndLog(" 0 - no debug messages"); 
 494                 PrintAndLog(" 1 - error messages"); 
 495                 PrintAndLog(" 2 - all messages"); 
 496                 PrintAndLog(" 4 - extended debug mode"); 
 500         PrintAndLog("No code here ("); 
 504 int CmdHF14AMfEGet(const char *Cmd
) 
 506         PrintAndLog("No code here ("); 
 510 int CmdHF14AMfESet(const char *Cmd
) 
 512         PrintAndLog("No code here ("); 
 516 int CmdHF14AMfELoad(const char *Cmd
) 
 518         PrintAndLog("No code here ("); 
 522 int CmdHF14AMfESave(const char *Cmd
) 
 524         PrintAndLog("No code here ("); 
 528 static command_t CommandTable
[] =  
 530   {"help",              CmdHelp
,                                                1, "This help"}, 
 531   {"dbg",                       CmdHF14AMfDbg
,                  0, "Set default debug mode"}, 
 532   {"rdbl",              CmdHF14AMfRdBl
,                 0, "Read MIFARE classic block"}, 
 533   {"rdsc",              CmdHF14AMfRdSc
,                 0, "Read MIFARE classic sector"}, 
 534   {"wrbl",              CmdHF14AMfWrBl
,                 0, "Write MIFARE classic block"}, 
 535   {"chk",                       CmdHF14AMfChk
,                  0, "Test block up to 8 keys"}, 
 536   {"mifare",    CmdHF14AMifare
,                 0, "Read parity error messages. param - <used card nonce>"}, 
 537   {"nested",    CmdHF14AMfNested
,               0, "Test nested authentication"}, 
 538   {"sim",                       CmdHF14AMf1kSim
,                0, "Simulate MIFARE 1k card"}, 
 539   {"eget",              CmdHF14AMfEGet
,                 0, "Set simulator memory block"}, 
 540   {"eset",              CmdHF14AMfESet
,                 0, "Get simulator memory block"}, 
 541   {"eload",             CmdHF14AMfELoad
,                0, "Load from file emul dump"}, 
 542   {"esave",             CmdHF14AMfESave
,                0, "Save to file emul dump"}, 
 543   {NULL
, NULL
, 0, NULL
} 
 546 int CmdHFMF(const char *Cmd
) 
 549         while (WaitForResponseTimeout(CMD_ACK
, 500) != NULL
) ; 
 551   CmdsParse(CommandTable
, Cmd
); 
 555 int CmdHelp(const char *Cmd
) 
 557   CmdsHelp(CommandTable
);