### Changed
- Improved backdoor detection missbehaving magic s50/1k tag (Fl0-0)
+- Deleted wipe functionality from `hf mf csetuid` (Merlok)
### Fixed
- Added backdoor detection for gen1b magic s70/4k tag (Fl0-0)
- Added data fsktonrz, a fsk cleaning/demodulating routine for weak fsk signal. Note: follow this up with a `data rawdemod nr` to finish demoding your signal. (marshmellow)
- Added lf em 410xbrute, LF EM410x reader bruteforce attack by simulating UIDs from a file (Fl0-0)
+- Added `hf mf cwipe` command. It wipes "magic Chinese" card. For 1a generation it uses card's "wipe" command. For gen1a and gen1b it uses a write command. (Merlok)
## [3.0.1][2017-06-08]
break;
// Work with "magic Chinese" card
+ case CMD_MIFARE_CWIPE:
+ MifareCWipe(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
+ break;
case CMD_MIFARE_CSETBLOCK:
MifareCSetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
break;
void MifareEMemSet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
void MifareEMemGet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
-void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain); // Work with "magic Chinese" card
+void MifareCWipe(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain); // Work with "magic Chinese" card
+void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
void MifareCIdent(); // is "magic chinese" card?
void MifareUSetPwd(uint8_t arg0, uint8_t *datain);
// Work with "magic Chinese" card (email him: ouyangweidaxian@live.cn)\r
//\r
//-----------------------------------------------------------------------------\r
+\r
+static bool isBlockTrailer(int blockN) {\r
+ if (blockN >= 0 && blockN < 128) {\r
+ return ((blockN & 0x03) == 0x03);\r
+ }\r
+ if (blockN >= 128 && blockN <= 256) {\r
+ return ((blockN & 0x0F) == 0x0F);\r
+ }\r
+ return FALSE;\r
+}\r
+\r
+void MifareCWipe(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
+ // var\r
+ byte_t isOK = 0;\r
+ uint32_t numBlocks = arg0;\r
+ // cmdParams:\r
+ // bit 0 - wipe gen1a\r
+ // bit 1 - fill card with default data\r
+ // bit 2 - gen1a = 0, gen1b = 1\r
+ uint8_t cmdParams = arg1;\r
+ bool needWipe = cmdParams & 0x01;\r
+ bool needFill = cmdParams & 0x02;\r
+ bool gen1b = cmdParams & 0x04;\r
+ \r
+ uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
+ uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
+ \r
+ uint8_t block0[16] = {0x01, 0x02, 0x03, 0x04, 0x04, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xAF};\r
+ uint8_t block1[16] = {0x00};\r
+ uint8_t blockK[16] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x08, 0x77, 0x8F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};\r
+ uint8_t d_block[18] = {0x00};\r
+ \r
+ // card commands\r
+ uint8_t wupC1[] = { 0x40 };\r
+ uint8_t wupC2[] = { 0x43 };\r
+ uint8_t wipeC[] = { 0x41 };\r
+ \r
+ // iso14443 setup\r
+ LED_A_ON();\r
+ LED_B_OFF();\r
+ LED_C_OFF();\r
+ iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
+\r
+ // tracing\r
+ clear_trace();\r
+ set_tracing(true);\r
+ \r
+ while (true){\r
+ // wipe\r
+ if (needWipe){\r
+ ReaderTransmitBitsPar(wupC1,7,0, NULL);\r
+ if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");\r
+ break;\r
+ };\r
+\r
+ ReaderTransmit(wipeC, sizeof(wipeC), NULL);\r
+ if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("wipeC error");\r
+ break;\r
+ };\r
+\r
+ if(mifare_classic_halt(NULL, 0)) {\r
+ if (MF_DBGLEVEL > 2) Dbprintf("Halt error");\r
+ };\r
+ };\r
+ \r
+ // put default data\r
+ if (needFill){\r
+ // select commands\r
+ ReaderTransmitBitsPar(wupC1, 7, 0, NULL);\r
+\r
+ // gen1b magic tag : do no issue wupC2 and don't expect 0x0a response after SELECT_UID (after getting UID from chip in 'hf mf csetuid' command)\r
+ if (!gen1b) { \r
+\r
+ if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");\r
+ break;\r
+ };\r
+\r
+ ReaderTransmit(wupC2, sizeof(wupC2), NULL);\r
+ if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("wupC2 error");\r
+ break;\r
+ };\r
+ }\r
+\r
+ // send blocks command\r
+ for (int blockNo = 0; blockNo < numBlocks; blockNo++) {\r
+ if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("write block send command error");\r
+ break;\r
+ };\r
+ \r
+ // check type of block and add crc\r
+ if (!isBlockTrailer(blockNo)){\r
+ memcpy(d_block, block1, 16);\r
+ } else {\r
+ memcpy(d_block, blockK, 16);\r
+ }\r
+ if (blockNo == 0) {\r
+ memcpy(d_block, block0, 16);\r
+ }\r
+ AppendCrc14443a(d_block, 16);\r
+\r
+ // send write command\r
+ ReaderTransmit(d_block, sizeof(d_block), NULL);\r
+ if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("write block send data error");\r
+ break;\r
+ };\r
+ }\r
+ \r
+ // halt\r
+ // do no issue halt command for gen1b \r
+ if (!gen1b) {\r
+ if (mifare_classic_halt(NULL, 0)) {\r
+ if (MF_DBGLEVEL > 2) Dbprintf("Halt error");\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ break;\r
+ } \r
+\r
+ // send USB response\r
+ LED_B_ON();\r
+ cmd_send(CMD_ACK,isOK,0,0,NULL,0);\r
+ LED_B_OFF();\r
+ \r
+ // reset fpga\r
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+ LEDsoff();\r
+ \r
+ return;\r
+}\r
+\r
void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
\r
// params\r
if (workFlags & 0x01) {\r
if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
- break;\r
+ // Continue, if we set wrong UID or wrong UID checksum or some ATQA or SAK we will can't select card. But we need to write block 0 to make card work.\r
+ //break;\r
};\r
\r
if(mifare_classic_halt(NULL, cuid)) {\r
if (MF_DBGLEVEL > 2) Dbprintf("Halt error");\r
// Continue, some magic tags misbehavies and send an answer to it.\r
- // break;\r
+ // break;\r
};\r
};\r
\r
break;\r
};\r
\r
- if(mifare_classic_halt(NULL, cuid)) {\r
+ if(mifare_classic_halt(NULL, 0)) {\r
if (MF_DBGLEVEL > 2) Dbprintf("Halt error");\r
// Continue, some magic tags misbehavies and send an answer to it.\r
// break;\r
if (workFlags & 0x04) {\r
// do no issue halt command for gen1b magic tag (#db# halt error. response len: 1)\r
if (!(workFlags & 0x40)) {\r
- if (mifare_classic_halt(NULL, cuid)) {\r
+ if (mifare_classic_halt(NULL, 0)) {\r
if (MF_DBGLEVEL > 2) Dbprintf("Halt error");\r
// Continue, some magic tags misbehavies and send an answer to it.\r
// break;\r
\r
int CmdHF14AMfCSetUID(const char *Cmd)\r
{\r
- uint8_t wipeCard = 0;\r
uint8_t uid[8] = {0x00};\r
uint8_t oldUid[8] = {0x00};\r
uint8_t atqa[2] = {0x00};\r
uint8_t sak[1] = {0x00};\r
- uint8_t atqaPresent = 1;\r
+ uint8_t atqaPresent = 0;\r
int res;\r
- char ctmp;\r
- int argi=0;\r
\r
- if (strlen(Cmd) < 1 || param_getchar(Cmd, argi) == 'h') {\r
- PrintAndLog("Usage: hf mf csetuid <UID 8 hex symbols> [ATQA 4 hex symbols SAK 2 hex symbols] [w]");\r
+ uint8_t needHelp = 0;\r
+ char cmdp = 1;\r
+ \r
+ if (param_getchar(Cmd, 0) && param_gethex(Cmd, 0, uid, 8)) {\r
+ PrintAndLog("UID must include 8 HEX symbols");\r
+ return 1;\r
+ }\r
+\r
+ if (param_getlength(Cmd, 1) > 1 && param_getlength(Cmd, 2) > 1) {\r
+ atqaPresent = 1;\r
+ cmdp = 3;\r
+ \r
+ if (param_gethex(Cmd, 1, atqa, 4)) {\r
+ PrintAndLog("ATQA must include 4 HEX symbols");\r
+ return 1;\r
+ }\r
+ \r
+ if (param_gethex(Cmd, 2, sak, 2)) {\r
+ PrintAndLog("SAK must include 2 HEX symbols");\r
+ return 1;\r
+ }\r
+ }\r
+\r
+ while(param_getchar(Cmd, cmdp) != 0x00)\r
+ {\r
+ switch(param_getchar(Cmd, cmdp))\r
+ {\r
+ case 'h':\r
+ case 'H':\r
+ needHelp = 1;\r
+ break;\r
+ default:\r
+ PrintAndLog("ERROR: Unknown parameter '%c'", param_getchar(Cmd, cmdp));\r
+ needHelp = 1;\r
+ break;\r
+ }\r
+ cmdp++;\r
+ }\r
+\r
+ if (strlen(Cmd) < 1 || needHelp) {\r
+ PrintAndLog("");\r
+ PrintAndLog("Usage: hf mf csetuid <UID 8 hex symbols> [ATQA 4 hex symbols SAK 2 hex symbols]");\r
PrintAndLog("sample: hf mf csetuid 01020304");\r
- PrintAndLog("sample: hf mf csetuid 01020304 0004 08 w");\r
+ PrintAndLog("sample: hf mf csetuid 01020304 0004 08");\r
PrintAndLog("Set UID, ATQA, and SAK for magic Chinese card (only works with such cards)");\r
- PrintAndLog("If you also want to wipe the card then add 'w' at the end of the command line.");\r
return 0;\r
}\r
\r
- if (param_getchar(Cmd, argi) && param_gethex(Cmd, argi, uid, 8)) {\r
- PrintAndLog("UID must include 8 HEX symbols");\r
- return 1;\r
+ PrintAndLog("uid:%s", sprint_hex(uid, 4));\r
+ if (atqaPresent) {\r
+ PrintAndLog("--atqa:%s sak:%02x", sprint_hex(atqa, 2), sak[0]);\r
}\r
- argi++;\r
\r
- ctmp = param_getchar(Cmd, argi);\r
- if (ctmp == 'w' || ctmp == 'W') {\r
- wipeCard = 1;\r
- atqaPresent = 0;\r
+ res = mfCSetUID(uid, (atqaPresent)?atqa:NULL, (atqaPresent)?sak:NULL, oldUid);\r
+ if (res) {\r
+ PrintAndLog("Can't set UID. Error=%d", res);\r
+ return 1;\r
+ }\r
+\r
+ PrintAndLog("old UID:%s", sprint_hex(oldUid, 4));\r
+ PrintAndLog("new UID:%s", sprint_hex(uid, 4));\r
+ return 0;\r
+}\r
+\r
+static int ParamGetCardSize(const char c) {\r
+ int numBlocks = 16 * 4;\r
+ switch (c) {\r
+ case '0' : numBlocks = 5 * 4; break;\r
+ case '2' : numBlocks = 32 * 4; break;\r
+ case '4' : numBlocks = 32 * 4 + 8 * 16; break;\r
+ default: numBlocks = 16 * 4;\r
}\r
+ return numBlocks;\r
+}\r
\r
- if (atqaPresent) {\r
- if (param_getchar(Cmd, argi)) {\r
- if (param_gethex(Cmd, argi, atqa, 4)) {\r
- PrintAndLog("ATQA must include 4 HEX symbols");\r
- return 1;\r
- }\r
- argi++;\r
- if (!param_getchar(Cmd, argi) || param_gethex(Cmd, argi, sak, 2)) {\r
- PrintAndLog("SAK must include 2 HEX symbols");\r
- return 1;\r
- }\r
- argi++;\r
- } else\r
- atqaPresent = 0;\r
+int CmdHF14AMfCWipe(const char *Cmd)\r
+{\r
+ int res, gen = 0;\r
+ int numBlocks = 16 * 4;\r
+ bool wipeCard = false;\r
+ bool fillCard = false;\r
+ \r
+ if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {\r
+ PrintAndLog("Usage: hf mf cwipe [card size] [w] [p]");\r
+ PrintAndLog("sample: hf mf cwipe 1 w s");\r
+ PrintAndLog("[card size]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K");\r
+ PrintAndLog("w - Wipe magic Chinese card (only works with gen:1a cards)");\r
+ PrintAndLog("f - Fill the card with default data and keys (works with gen:1a and gen:1b cards only)");\r
+ return 0;\r
}\r
\r
- if(!wipeCard) {\r
- ctmp = param_getchar(Cmd, argi);\r
- if (ctmp == 'w' || ctmp == 'W') {\r
+ gen = mfCIdentify();\r
+ if ((gen != 1) && (gen != 2)) \r
+ return 1;\r
+ \r
+ numBlocks = ParamGetCardSize(param_getchar(Cmd, 0));\r
+\r
+ char cmdp = 0;\r
+ while(param_getchar(Cmd, cmdp) != 0x00){\r
+ switch(param_getchar(Cmd, cmdp)) {\r
+ case 'w':\r
+ case 'W':\r
wipeCard = 1;\r
+ break;\r
+ case 'f':\r
+ case 'F':\r
+ fillCard = 1;\r
+ break;\r
+ default:\r
+ break;\r
}\r
+ cmdp++;\r
}\r
\r
- PrintAndLog("--wipe card:%s uid:%s", (wipeCard)?"YES":"NO", sprint_hex(uid, 4));\r
+ if (!wipeCard && !fillCard) \r
+ wipeCard = true;\r
\r
- res = mfCSetUID(uid, (atqaPresent)?atqa:NULL, (atqaPresent)?sak:NULL, oldUid, wipeCard);\r
- if (res) {\r
- PrintAndLog("Can't set UID. error=%d", res);\r
- return 1;\r
+ PrintAndLog("--blocks count:%2d wipe:%c fill:%c", numBlocks, (wipeCard)?'y':'n', (fillCard)?'y':'n');\r
+\r
+ if (gen == 2) {\r
+ /* generation 1b magic card */\r
+ if (wipeCard) {\r
+ PrintAndLog("WARNING: can't wipe magic card 1b generation");\r
}\r
+ res = mfCWipe(numBlocks, true, false, fillCard); \r
+ } else {\r
+ /* generation 1a magic card by default */\r
+ res = mfCWipe(numBlocks, false, wipeCard, fillCard); \r
+ }\r
\r
- PrintAndLog("old UID:%s", sprint_hex(oldUid, 4));\r
- PrintAndLog("new UID:%s", sprint_hex(uid, 4));\r
+ if (res) {\r
+ PrintAndLog("Can't wipe. error=%d", res);\r
+ return 1;\r
+ }\r
+ PrintAndLog("OK");\r
return 0;\r
}\r
\r
}\r
\r
gen = mfCIdentify();\r
+ if ((gen != 1) && (gen != 2)) \r
+ return 1;\r
\r
blockNo = param_get8(Cmd, 0);\r
\r
if (param_getchar(Cmd, 0) == 'h') {\r
PrintAndLog("It saves `magic Chinese` card dump into the file `filename.eml` or `cardID.eml`");\r
PrintAndLog("or into emulator memory (option `e`). 4K card: (option `4`)");\r
- PrintAndLog("Usage: hf mf esave [file name w/o `.eml`][e][4]");\r
- PrintAndLog("Sample: hf mf esave ");\r
- PrintAndLog(" hf mf esave filename");\r
- PrintAndLog(" hf mf esave e");\r
- PrintAndLog(" hf mf esave 4");\r
- PrintAndLog(" hf mf esave filename 4");\r
- PrintAndLog(" hf mf esave e 4");\r
+ PrintAndLog("Usage: hf mf csave [file name w/o `.eml`][e][4]");\r
+ PrintAndLog("Sample: hf mf csave ");\r
+ PrintAndLog(" hf mf csave filename");\r
+ PrintAndLog(" hf mf csave e");\r
+ PrintAndLog(" hf mf csave 4");\r
+ PrintAndLog(" hf mf csave filename 4");\r
+ PrintAndLog(" hf mf csave e 4");\r
return 0;\r
}\r
\r
{"esave", CmdHF14AMfESave, 0, "Save to file emul dump"},\r
{"ecfill", CmdHF14AMfECFill, 0, "Fill simulator memory with help of keys from simulator"},\r
{"ekeyprn", CmdHF14AMfEKeyPrn, 0, "Print keys from simulator memory"},\r
+ {"cwipe", CmdHF14AMfCWipe, 0, "Wipe magic Chinese card"},\r
{"csetuid", CmdHF14AMfCSetUID, 0, "Set UID for magic Chinese card"},\r
{"csetblk", CmdHF14AMfCSetBlk, 0, "Write block - Magic Chinese card"},\r
{"cgetblk", CmdHF14AMfCGetBlk, 0, "Read block - Magic Chinese card"},\r
extern int CmdHF14AMfESave(const char* cmd);\r
extern int CmdHF14AMfECFill(const char* cmd);\r
extern int CmdHF14AMfEKeyPrn(const char* cmd);\r
+extern int CmdHF14AMfCWipe(const char* cmd);\r
extern int CmdHF14AMfCSetUID(const char* cmd);\r
extern int CmdHF14AMfCSetBlk(const char* cmd);\r
extern int CmdHF14AMfCGetBlk(const char* cmd);\r
char tmp2[20];
int phaseoff;
high = low = 0;
- memset(tmpbuff, 0, MAX_GRAPH_TRACE_LEN / 64);
+ memset(tmpbuff, 0, sizeof(tmpbuff));
// get user entry if any
sscanf(Cmd, "%i %i", &clk, &invert);
// }
#endif
// add the even state bits
- const bitslice_t const *restrict bitsliced_even_state = bitsliced_even_states[block_idx];
+ const bitslice_t *restrict bitsliced_even_state = bitsliced_even_states[block_idx];
for(uint32_t state_idx = 1; state_idx < STATE_SIZE; state_idx += 2) {
state_p[state_idx] = bitsliced_even_state[state_idx/2];
}
bool r6 = r >> 1 & 0x1;
bool r7 = r & 0x1;
- bool z0 = (r0 & r2) ^ (r1 & ~r3) ^ (r2 | r4);
+ bool z0 = (r0 & r2) ^ (r1 & !r3) ^ (r2 | r4);
bool z1 = (r0 | r2) ^ ( r5 | r7) ^ r1 ^ r6 ^ x ^ y;
- bool z2 = (r3 & ~r5) ^ (r4 & r6 ) ^ r7 ^ x;
+ bool z2 = (r3 & !r5) ^ (r4 & r6 ) ^ r7 ^ x;
// The three bitz z0.. z1 are packed into a uint8_t:
// 00000ZZZ
int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount) {\r
UsbCommand c = {CMD_MIFARE_EML_MEMGET, {blockNum, blocksCount, 0}};\r
SendCommand(&c);\r
- UsbCommand resp;\r
+\r
+ UsbCommand resp;\r
if (!WaitForResponseTimeout(CMD_ACK,&resp,1500)) return 1;\r
memcpy(data, resp.d.asBytes, blocksCount * 16);\r
return 0;\r
\r
UsbCommand c = {CMD_MIFARE_CGETBLOCK, {params, 0, blockNo}};\r
SendCommand(&c);\r
+\r
UsbCommand resp;\r
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {\r
isOK = resp.arg[0] & 0xff;\r
UsbCommand c = {CMD_MIFARE_CSETBLOCK, {wantWipe, params & (0xFE | (uid == NULL ? 0:1)), blockNo}};\r
memcpy(c.d.asBytes, data, 16);\r
SendCommand(&c);\r
+\r
UsbCommand resp;\r
- if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {\r
+ if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {\r
isOK = resp.arg[0] & 0xff;\r
if (uid != NULL)\r
memcpy(uid, resp.d.asBytes, 4);\r
PrintAndLog("Command execute timeout");\r
return 1;\r
}\r
+\r
return 0;\r
}\r
\r
-int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, bool wantWipe) {\r
+int mfCWipe(uint32_t numSectors, bool gen1b, bool wantWipe, bool wantFill) {\r
+ uint8_t isOK = 0;\r
+ uint8_t cmdParams = wantWipe + wantFill * 0x02 + gen1b * 0x04;\r
+ UsbCommand c = {CMD_MIFARE_CWIPE, {numSectors, cmdParams, 0}};\r
+ SendCommand(&c);\r
+\r
+ UsbCommand resp;\r
+ WaitForResponse(CMD_ACK,&resp);\r
+ isOK = resp.arg[0] & 0xff;\r
+ \r
+ return isOK;\r
+}\r
+\r
+int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID) {\r
uint8_t oldblock0[16] = {0x00};\r
uint8_t block0[16] = {0x00};\r
- int old, gen = 0;\r
+ int gen = 0, res;\r
\r
gen = mfCIdentify();\r
\r
+ /* generation 1a magic card by default */\r
+ uint8_t cmdParams = CSETBLOCK_SINGLE_OPER;\r
if (gen == 2) {\r
/* generation 1b magic card */\r
- old = mfCGetBlock(0, oldblock0, CSETBLOCK_SINGLE_OPER | CSETBLOCK_MAGIC_1B);\r
- } else {\r
- /* generation 1a magic card by default */\r
- old = mfCGetBlock(0, oldblock0, CSETBLOCK_SINGLE_OPER);\r
+ cmdParams = CSETBLOCK_SINGLE_OPER | CSETBLOCK_MAGIC_1B;\r
}\r
+ \r
+ res = mfCGetBlock(0, oldblock0, cmdParams);\r
\r
- if (old == 0) {\r
+ if (res == 0) {\r
memcpy(block0, oldblock0, 16);\r
PrintAndLog("old block 0: %s", sprint_hex(block0,16));\r
} else {\r
// UID\r
memcpy(block0, uid, 4);\r
// Mifare UID BCC\r
- block0[4] = block0[0]^block0[1]^block0[2]^block0[3];\r
+ block0[4] = block0[0] ^ block0[1] ^ block0[2] ^ block0[3];\r
// mifare classic SAK(byte 5) and ATQA(byte 6 and 7, reversed)\r
- if (sak!=NULL)\r
- block0[5]=sak[0];\r
- if (atqa!=NULL) {\r
- block0[6]=atqa[1];\r
- block0[7]=atqa[0];\r
+ if (sak != NULL)\r
+ block0[5] = sak[0];\r
+ if (atqa != NULL) {\r
+ block0[6] = atqa[1];\r
+ block0[7] = atqa[0];\r
}\r
- PrintAndLog("new block 0: %s", sprint_hex(block0,16));\r
+ PrintAndLog("new block 0: %s", sprint_hex(block0, 16));\r
\r
- if (gen == 2) {\r
- /* generation 1b magic card */\r
- return mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER | CSETBLOCK_MAGIC_1B);\r
- } else {\r
- /* generation 1a magic card by default */\r
- return mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER);\r
+ res = mfCSetBlock(0, block0, oldUID, false, cmdParams);\r
+ if (res) {\r
+ PrintAndLog("Can't set block 0. Error: %d", res);\r
+ return res;\r
}\r
+ \r
+ return 0;\r
+}\r
+\r
+int mfCIdentify()\r
+{\r
+ UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}};\r
+ SendCommand(&c);\r
+\r
+ UsbCommand resp;\r
+ WaitForResponse(CMD_ACK,&resp);\r
+\r
+ iso14a_card_select_t card;\r
+ memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t));\r
+\r
+ uint64_t select_status = resp.arg[0]; // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision\r
+\r
+ if(select_status != 0) {\r
+ uint8_t rats[] = { 0xE0, 0x80 }; // FSDI=8 (FSD=256), CID=0\r
+ c.arg[0] = ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT;\r
+ c.arg[1] = 2;\r
+ c.arg[2] = 0;\r
+ memcpy(c.d.asBytes, rats, 2);\r
+ SendCommand(&c);\r
+ WaitForResponse(CMD_ACK,&resp);\r
+ }\r
+\r
+ c.cmd = CMD_MIFARE_CIDENT;\r
+ c.arg[0] = 0;\r
+ c.arg[1] = 0;\r
+ c.arg[2] = 0;\r
+ SendCommand(&c);\r
+ WaitForResponse(CMD_ACK,&resp);\r
+\r
+ uint8_t isGeneration = resp.arg[0] & 0xff;\r
+ switch( isGeneration ){\r
+ case 1: PrintAndLog("Chinese magic backdoor commands (GEN 1a) detected"); break;\r
+ case 2: PrintAndLog("Chinese magic backdoor command (GEN 1b) detected"); break;\r
+ default: PrintAndLog("No chinese magic backdoor command detected"); break;\r
+ }\r
+\r
+ // disconnect\r
+ c.cmd = CMD_READER_ISO_14443a;\r
+ c.arg[0] = 0;\r
+ c.arg[1] = 0;\r
+ c.arg[2] = 0;\r
+ SendCommand(&c);\r
+\r
+ return (int) isGeneration;\r
}\r
\r
+\r
// SNIFFER\r
\r
// constants\r
}\r
\r
int isBlockTrailer(int blockN) {\r
- return ((blockN & 0x03) == 0x03);\r
+ return ((blockN & 0x03) == 0x03);\r
}\r
\r
int saveTraceCard(void) {\r
blockNum++;\r
}\r
fclose(f);\r
+\r
return 0;\r
}\r
\r
uid = bytes_to_num(tuid + 3, 4);\r
\r
traceState = TRACE_IDLE;\r
+\r
return 0;\r
}\r
\r
return 0;\r
}\r
\r
+// DECODING\r
+\r
int tryDecryptWord(uint32_t nt, uint32_t ar_enc, uint32_t at_enc, uint8_t *data, int len){\r
/*\r
uint32_t nt; // tag challenge\r
return 0;\r
}\r
\r
-int mfCIdentify()\r
-{\r
- UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}};\r
- SendCommand(&c);\r
- UsbCommand resp;\r
- WaitForResponse(CMD_ACK,&resp);\r
-\r
- iso14a_card_select_t card;\r
- memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t));\r
-\r
- uint64_t select_status = resp.arg[0]; // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision\r
-\r
- if(select_status != 0) {\r
- uint8_t rats[] = { 0xE0, 0x80 }; // FSDI=8 (FSD=256), CID=0\r
- c.arg[0] = ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT;\r
- c.arg[1] = 2;\r
- c.arg[2] = 0;\r
- memcpy(c.d.asBytes, rats, 2);\r
- SendCommand(&c);\r
- WaitForResponse(CMD_ACK,&resp);\r
- }\r
-\r
- c.cmd = CMD_MIFARE_CIDENT;\r
- c.arg[0] = 0;\r
- c.arg[1] = 0;\r
- c.arg[2] = 0;\r
- SendCommand(&c);\r
- WaitForResponse(CMD_ACK,&resp);\r
-\r
- uint8_t isGeneration = resp.arg[0] & 0xff;\r
- switch( isGeneration ){\r
- case 1: PrintAndLog("Chinese magic backdoor commands (GEN 1a) detected"); break;\r
- case 2: PrintAndLog("Chinese magic backdoor command (GEN 1b) detected"); break;\r
- default: PrintAndLog("No chinese magic backdoor command detected"); break;\r
- }\r
-\r
- // disconnect\r
- c.cmd = CMD_READER_ISO_14443a;\r
- c.arg[0] = 0;\r
- c.arg[1] = 0;\r
- c.arg[2] = 0;\r
- SendCommand(&c);\r
-\r
- return (int) isGeneration;\r
-}\r
extern int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount);\r
extern int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount);\r
\r
-extern int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, bool wantWipe);\r
+extern int mfCWipe(uint32_t numSectors, bool gen1b, bool wantWipe, bool wantFill);\r
+extern int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID);\r
extern int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, bool wantWipe, uint8_t params);\r
extern int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params);\r
\r
// -------------------------------------------------------------------------
// line - param line
-// bg, en - symbol numbers in param line of beginning an ending parameter
+// bg, en - symbol numbers in param line of beginning and ending parameter
// paramnum - param number (from 0)
// -------------------------------------------------------------------------
int param_getptr(const char *line, int *bg, int *en, int paramnum)
}
+int param_getlength(const char *line, int paramnum)
+{
+ int bg, en;
+
+ if (param_getptr(line, &bg, &en, paramnum)) return 0;
+
+ return en - bg + 1;
+}
+
char param_getchar(const char *line, int paramnum)
{
int bg, en;
extern uint8_t *SwapEndian64(const uint8_t *src, const size_t len, const uint8_t blockSize);
extern void SwapEndian64ex(const uint8_t *src, const size_t len, const uint8_t blockSize, uint8_t *dest);
+extern int param_getlength(const char *line, int paramnum);
extern char param_getchar(const char *line, int paramnum);
extern int param_getptr(const char *line, int *bg, int *en, int paramnum);
extern uint8_t param_get8(const char *line, int paramnum);
#define CMD_MIFARE_CSETBLOCK 0x0605
#define CMD_MIFARE_CGETBLOCK 0x0606
#define CMD_MIFARE_CIDENT 0x0607
+#define CMD_MIFARE_CWIPE 0x0608
#define CMD_SIMULATE_MIFARE_CARD 0x0610