X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/c626c56ef51a4bc1a16c3f59e569ca8efbfb23dc..a0bf7ba787ea7b309d034e1d5412a7d63b1c2fa3:/client/cmdhfmf.c diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index b66aa3a6..10c56cdc 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -7,7 +7,7 @@ //----------------------------------------------------------------------------- // High frequency MIFARE commands //----------------------------------------------------------------------------- - +#include "../include/mifare.h" #include "cmdhfmf.h" static int CmdHelp(const char *Cmd); @@ -36,7 +36,6 @@ start: //flush queue while (ukbhit()) getchar(); - // wait cycle while (true) { printf("."); @@ -140,6 +139,7 @@ int CmdHF14AMfWrBl(const char *Cmd) return 0; } +/* dublett finns i CMDHFMFU.C int CmdHF14AMfUWrBl(const char *Cmd) { uint8_t blockNo = 0; @@ -249,8 +249,7 @@ int CmdHF14AMfUWrBl(const char *Cmd) } return 0; } - - +*/ int CmdHF14AMfRdBl(const char *Cmd) { uint8_t blockNo = 0; @@ -299,6 +298,7 @@ int CmdHF14AMfRdBl(const char *Cmd) return 0; } +/* dublett finns i CMDHFMFU.C int CmdHF14AMfURdBl(const char *Cmd) { uint8_t blockNo = 0; @@ -330,8 +330,9 @@ int CmdHF14AMfURdBl(const char *Cmd) return 0; } +*/ - +/* dublett finns i CMDHFMFU.C int CmdHF14AMfURdCard(const char *Cmd) { int i; @@ -422,7 +423,7 @@ int CmdHF14AMfURdCard(const char *Cmd) } return 0; } - +*/ int CmdHF14AMfRdSc(const char *Cmd) { @@ -517,7 +518,14 @@ int CmdHF14AMfDump(const char *Cmd) UsbCommand resp; + int size = GetCardSize(); char cmdp = param_getchar(Cmd, 0); + + if ( size > -1) + cmdp = (char)(48+size); + + PrintAndLog("Got %d",cmdp); + switch (cmdp) { case '0' : numSectors = 5; break; case '1' : @@ -537,28 +545,30 @@ int CmdHF14AMfDump(const char *Cmd) } if ((fin = fopen("dumpkeys.bin","rb")) == NULL) { - PrintAndLog("Could not find file dumpkeys.bin"); + PrintAndLog("Could not find file dumpkeys.bin"); return 1; } - // Read key file - + // Read keys A from file for (sectorNo=0; sectorNo|<*card memory> [t|d] [] []"); + PrintAndLog(" * - all sectors"); + PrintAndLog("card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, - 1K"); + PrintAndLog("d - write keys to binary file\n"); + PrintAndLog("t - write keys to emulator memory"); + PrintAndLog(" sample: hf mf chk 0 A 1234567890ab keys.dic"); + PrintAndLog(" hf mf chk *1 ? t"); + PrintAndLog(" hf mf chk *1 ? d"); + return 0; + } + FILE * f; char filename[256]={0}; char buf[13]; @@ -1047,16 +1085,6 @@ int CmdHF14AMfChk(const char *Cmd) num_to_bytes(defaultKeys[defaultKeyCounter], 6, (uint8_t*)(keyBlock + defaultKeyCounter * 6)); } - if (strlen(Cmd)<3) { - PrintAndLog("Usage: hf mf chk |<*card memory> [t] [] []"); - PrintAndLog(" * - all sectors"); - PrintAndLog("card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, - 1K"); - PrintAndLog("d - write keys to binary file\n"); - PrintAndLog(" sample: hf mf chk 0 A 1234567890ab keys.dic"); - PrintAndLog(" hf mf chk *1 ? t"); - return 0; - } - if (param_getchar(Cmd, 0)=='*') { blockNo = 3; switch(param_getchar(Cmd+1, 0)) { @@ -1144,11 +1172,12 @@ int CmdHF14AMfChk(const char *Cmd) keycnt++; memset(buf, 0, sizeof(buf)); } + fclose(f); } else { PrintAndLog("File: %s: not found or locked.", filename); free(keyBlock); return 1; - fclose(f); + } } } @@ -1157,8 +1186,8 @@ int CmdHF14AMfChk(const char *Cmd) PrintAndLog("No key specified, trying default keys"); for (;keycnt < defaultKeysSize; keycnt++) PrintAndLog("chk default key[%2d] %02x%02x%02x%02x%02x%02x", keycnt, - (keyBlock + 6*keycnt)[0],(keyBlock + 6*keycnt)[1], (keyBlock + 6*keycnt)[2], - (keyBlock + 6*keycnt)[3], (keyBlock + 6*keycnt)[4], (keyBlock + 6*keycnt)[5], 6); + (keyBlock + 6*keycnt)[0],(keyBlock + 6*keycnt)[1], (keyBlock + 6*keycnt)[2], + (keyBlock + 6*keycnt)[3], (keyBlock + 6*keycnt)[4], (keyBlock + 6*keycnt)[5], 6); } // initialize storage for found keys @@ -1203,13 +1232,13 @@ int CmdHF14AMfChk(const char *Cmd) for (uint16_t t = 0; t < 2; t++) { if (validKey[t][sectorNo]) { memcpy(block + t*10, foundKey[t][sectorNo], 6); - } - } + } + } mfEmlSetMem(block, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1); } } PrintAndLog("Found keys have been transferred to the emulator memory"); - } + } if (createDumpFile) { FILE *fkeys = fopen("dumpkeys.bin","wb"); @@ -1217,7 +1246,7 @@ int CmdHF14AMfChk(const char *Cmd) PrintAndLog("Could not create file dumpkeys.bin"); free(keyBlock); return 1; - } + } for (uint16_t t = 0; t < 2; t++) { fwrite(foundKey[t], 1, 6*SectorsCnt, fkeys); } @@ -1227,7 +1256,7 @@ int CmdHF14AMfChk(const char *Cmd) free(keyBlock); - return 0; + return 0; } @@ -1321,7 +1350,6 @@ int CmdHF14AMfDbg(const char *Cmd) return 0; } - int CmdHF14AMfEGet(const char *Cmd) { uint8_t blockNo = 0; @@ -1391,7 +1419,7 @@ int CmdHF14AMfESet(const char *Cmd) int CmdHF14AMfELoad(const char *Cmd) { FILE * f; - char filename[20]; + char filename[255]; char *fnameptr = filename; char buf[64]; uint8_t buf8[64]; @@ -1408,7 +1436,7 @@ int CmdHF14AMfELoad(const char *Cmd) } len = strlen(Cmd); - if (len > 14) len = 14; + if (len > 250) len = 250; memcpy(filename, Cmd, len); fnameptr += len; @@ -1430,6 +1458,7 @@ int CmdHF14AMfELoad(const char *Cmd) break; } PrintAndLog("File reading error."); + fclose(f); return 2; } if (strlen(buf) < 32){ @@ -1454,6 +1483,7 @@ int CmdHF14AMfELoad(const char *Cmd) if ((blockNum != 16*4) && (blockNum != 32*4 + 8*16)) { PrintAndLog("File content error. There must be 64 or 256 blocks."); + fclose(f); return 4; } PrintAndLog("Loaded %d blocks from file: %s", blockNum, filename); @@ -1464,7 +1494,7 @@ int CmdHF14AMfELoad(const char *Cmd) int CmdHF14AMfESave(const char *Cmd) { FILE * f; - char filename[20]; + char filename[255]; char * fnameptr = filename; uint8_t buf[64]; int i, j, len; @@ -1481,7 +1511,7 @@ int CmdHF14AMfESave(const char *Cmd) } len = strlen(Cmd); - if (len > 14) len = 14; + if (len > 250) len = 250; if (len < 1) { // get filename @@ -1562,13 +1592,32 @@ int CmdHF14AMfECFill(const char *Cmd) int CmdHF14AMfEKeyPrn(const char *Cmd) { int i; + uint8_t numSectors; uint8_t data[16]; uint64_t keyA, keyB; + if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) { + PrintAndLog("It prints the keys loaded in the emulator memory"); + PrintAndLog("Usage: hf mf ekeyprn [card memory]"); + PrintAndLog(" [card memory]: 1 = 1K (default), 4 = 4K"); + PrintAndLog(""); + PrintAndLog(" sample: hf mf ekeyprn 1"); + return 0; + } + + char cmdp = param_getchar(Cmd, 0); + + switch (cmdp) { + case '1' : + case '\0': numSectors = 16; break; + case '4' : numSectors = 40; break; + default: numSectors = 16; + } + PrintAndLog("|---|----------------|----------------|"); PrintAndLog("|sec|key A |key B |"); PrintAndLog("|---|----------------|----------------|"); - for (i = 0; i < 40; i++) { + for (i = 0; i < numSectors; i++) { if (mfEmlGetMem(data, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1)) { PrintAndLog("error get block %d", FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1); break; @@ -1586,8 +1635,8 @@ int CmdHF14AMfEKeyPrn(const char *Cmd) int CmdHF14AMfCSetUID(const char *Cmd) { uint8_t wipeCard = 0; - uint8_t uid[8]; - uint8_t oldUid[8]; + uint8_t uid[8] = {0x00}; + uint8_t oldUid[8] = {0x00}; int res; if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') { @@ -1618,7 +1667,6 @@ int CmdHF14AMfCSetUID(const char *Cmd) return 0; } - int CmdHF14AMfCSetBlk(const char *Cmd) { uint8_t uid[8]; @@ -1658,7 +1706,7 @@ int CmdHF14AMfCSetBlk(const char *Cmd) int CmdHF14AMfCLoad(const char *Cmd) { FILE * f; - char filename[20]; + char filename[255]; char * fnameptr = filename; char buf[64]; uint8_t buf8[64]; @@ -1699,7 +1747,7 @@ int CmdHF14AMfCLoad(const char *Cmd) return 0; } else { len = strlen(Cmd); - if (len > 14) len = 14; + if (len > 250) len = 250; memcpy(filename, Cmd, len); fnameptr += len; @@ -1744,7 +1792,7 @@ int CmdHF14AMfCLoad(const char *Cmd) } fclose(f); - if (blockNum != 16 * 4){ + if (blockNum != 16 * 4 && blockNum != 32 * 4 + 8 * 16){ PrintAndLog("File content error. There must be 64 blocks"); return 4; } @@ -1753,7 +1801,6 @@ int CmdHF14AMfCLoad(const char *Cmd) } } - int CmdHF14AMfCGetBlk(const char *Cmd) { uint8_t memBlock[16]; uint8_t blockNo = 0; @@ -1823,7 +1870,7 @@ int CmdHF14AMfCGetSc(const char *Cmd) { int CmdHF14AMfCSave(const char *Cmd) { FILE * f; - char filename[20]; + char filename[255]; char * fnameptr = filename; uint8_t fillFromEmulator = 0; uint8_t buf[64]; @@ -1865,7 +1912,7 @@ int CmdHF14AMfCSave(const char *Cmd) { return 0; } else { len = strlen(Cmd); - if (len > 14) len = 14; + if (len > 250) len = 250; if (len < 1) { // get filename @@ -2015,30 +2062,128 @@ int CmdHF14AMfSniff(const char *Cmd){ FillFileNameByUID(logHexFileName, uid + (7 - uid_len), ".log", uid_len); AddLogCurrentDT(logHexFileName); } - if (wantDecrypt) mfTraceInit(uid, atqa, sak, wantSaveToEmlFile); + if (wantDecrypt) + mfTraceInit(uid, atqa, sak, wantSaveToEmlFile); } else { PrintAndLog("%s(%d):%s", isTag ? "TAG":"RDR", num, sprint_hex(bufPtr, len)); - if (wantLogToFile) AddLogHex(logHexFileName, isTag ? "TAG: ":"RDR: ", bufPtr, len); - if (wantDecrypt) mfTraceDecode(bufPtr, len, parity, wantSaveToEmlFile); + if (wantLogToFile) + AddLogHex(logHexFileName, isTag ? "TAG: ":"RDR: ", bufPtr, len); + if (wantDecrypt) + mfTraceDecode(bufPtr, len, parity, wantSaveToEmlFile); } bufPtr += len; num++; } } - } // resp not NILL + } // resp not NULL } // while (true) return 0; } +// Tries to identify cardsize. +// Returns where num is: +// -1 unidentified +// 0 - MINI (320bytes) +// 1 - 1K +// 2 - 2K +// 4 - 4K +int GetCardSize() +{ + UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT, 0, 0}}; + SendCommand(&c); + + UsbCommand resp; + WaitForResponse(CMD_ACK,&resp); + + if(resp.arg[0] == 0) { + PrintAndLog("iso14443a card select failed"); + return -1; + } + + iso14a_card_select_t *card = (iso14a_card_select_t *)resp.d.asBytes; + + PrintAndLog("Trying to detect card size."); + + uint16_t atqa = 0; + uint8_t sak = 0; + atqa = (card->atqa[1] & 0xff) << 8; + atqa += card->atqa[0] & 0xff; + sak = card->sak; + + // https://code.google.com/p/libnfc/source/browse/libnfc/target-subr.c + + PrintAndLog("found ATAQ: %04X SAK: %02X", atqa, sak); + + + // NXP MIFARE Mini 0.3k + if ( ( (atqa & 0xff0f) == 0x0004) && (sak == 0x09) ) return 0; + + // MIFARE Classic 1K + if ( ((atqa & 0xff0f) == 0x0004) && (sak == 0x08) ) return 1; + + // MIFARE Classik 4K + if ( ((atqa & 0xff0f) == 0x0002) && (sak == 0x18) ) return 4; + + // SmartMX with MIFARE 1K emulation + if ( ((atqa & 0xf0ff) == 0x0004) ) return 1; + + // SmartMX with MIFARE 4K emulation + if ( ((atqa & 0xf0ff) == 0x0002) ) return 4; + + // Infineon MIFARE CLASSIC 1K + if ( ((atqa & 0xffff) == 0x0004) && (sak == 0x88) ) return 1; + + // MFC 4K emulated by Nokia 6212 Classic + if ( ((atqa & 0xffff) == 0x0002) && (sak == 0x38) ) return 4; + + // MFC 4K emulated by Nokia 6131 NFC + if ( ((atqa & 0xffff) == 0x0008) && (sak == 0x38) ) return 4; + + + PrintAndLog("BEFOOO 1K %02X", (atqa & 0xff0f)); + + // MIFARE Plus (4 Byte UID or 4 Byte RID) + // MIFARE Plus (7 Byte UID) + if ( + ((atqa & 0xffff) == 0x0002) | + ((atqa & 0xffff) == 0x0004) | + ((atqa & 0xffff) == 0x0042) | + ((atqa & 0xffff) == 0x0044) + ) + { + switch(sak){ + case 0x08: + case 0x10: { + //case 0x20: + PrintAndLog("2"); + return 2; + break; + } + case 0x11: + case 0x18:{ + //case 0x20: + PrintAndLog("4"); + return 4; + break; + } + } + } + + return -1; +} + + + + static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, {"dbg", CmdHF14AMfDbg, 0, "Set default debug mode"}, {"rdbl", CmdHF14AMfRdBl, 0, "Read MIFARE classic block"}, - {"urdbl", CmdHF14AMfURdBl, 0, "Read MIFARE Ultralight block"}, - {"urdcard", CmdHF14AMfURdCard, 0,"Read MIFARE Ultralight Card"}, - {"uwrbl", CmdHF14AMfUWrBl, 0,"Write MIFARE Ultralight block"}, + //{"urdbl", CmdHF14AMfURdBl, 0, "Read MIFARE Ultralight block"}, + //{"urdcard", CmdHF14AMfURdCard, 0,"Read MIFARE Ultralight Card"}, + //{"uwrbl", CmdHF14AMfUWrBl, 0,"Write MIFARE Ultralight block"}, {"rdsc", CmdHF14AMfRdSc, 0, "Read MIFARE classic sector"}, {"dump", CmdHF14AMfDump, 0, "Dump MIFARE classic tag to binary file"}, {"restore", CmdHF14AMfRestore, 0, "Restore MIFARE classic binary file to BLANK tag"},