From 326e6aa9f2b38bd818f39c2bc45be9443393f60f Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 6 Dec 2019 17:04:22 +0200 Subject: [PATCH] added hf mf cwipe --- client/cmdhfmf.c | 51 ++++++++++++++++++++++++++++++++++++++ client/mifare/mifarehost.c | 44 ++++++++++++++++++++++++++++++++ client/mifare/mifarehost.h | 1 + 3 files changed, 96 insertions(+) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index ad6fe31b2..680b9da19 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -3665,6 +3665,56 @@ static int CmdHF14AMfCSetUID(const char *Cmd) { return PM3_SUCCESS; } +static int CmdHF14AMfCWipe(const char *cmd) { + uint8_t uid[8] = {0x00}; + int uidLen = 0; + uint8_t atqa[2] = {0x00}; + int atqaLen = 0; + uint8_t sak[1] = {0x00}; + int sakLen = 0; + + CLIParserInit("hf mf cwipe", + "Wipe Gen1 magic cheneese card. Set UID/ATQA/SAK/Data/Keys/Access to default values.", + "Usage:\n\thf mf cwipe -> wipe card.\n" + "\thf mfp mf cwipe -u 09080706 -a 0004 -s 18 -> set UID, ATQA and SAK and wipe card."); + + void *argtable[] = { + arg_param_begin, + arg_str0("uU", "uid", "", "UID for card"), + arg_str0("aA", "atqa", "", "ATQA for card"), + arg_str0("sS", "sak", "", "SAK for card"), + arg_param_end + }; + CLIExecWithReturn(cmd, argtable, true); + + CLIGetHexWithReturn(1, uid, &uidLen); + CLIGetHexWithReturn(2, atqa, &atqaLen); + CLIGetHexWithReturn(3, sak, &sakLen); + CLIParserFree(); + + if (uidLen && uidLen != 4) { + PrintAndLogEx(ERR, "UID length must be 4 bytes instead of: %d", uidLen); + return PM3_EINVARG; + } + if (atqaLen && atqaLen != 2) { + PrintAndLogEx(ERR, "UID length must be 2 bytes instead of: %d", atqaLen); + return PM3_EINVARG; + } + if (sakLen && sakLen != 1) { + PrintAndLogEx(ERR, "UID length must be 1 byte instead of: %d", sakLen); + return PM3_EINVARG; + } + + int res = mfCWipe((uidLen)? uid : NULL, (atqaLen) ? atqa : NULL, (sakLen) ? sak : NULL); + if (res) { + PrintAndLogEx(ERR, "Can't wipe card. error=%d", res); + return PM3_ESOFT; + } + + PrintAndLogEx(SUCCESS, "Card wiped successfully"); + return PM3_SUCCESS; +} + static int CmdHF14AMfCSetBlk(const char *Cmd) { uint8_t block[16] = {0x00}; uint8_t blockNo = 0; @@ -4446,6 +4496,7 @@ static command_t CommandTable[] = { {"ekeyprn", CmdHF14AMfEKeyPrn, IfPm3Iso14443a, "Print keys from simulator memory"}, {"-----------", CmdHelp, IfPm3Iso14443a, ""}, {"csetuid", CmdHF14AMfCSetUID, IfPm3Iso14443a, "Set UID (magic chinese card)"}, + {"cwipe", CmdHF14AMfCWipe, IfPm3Iso14443a, "Wipe card to default UID/Sectors/Keys"}, {"csetblk", CmdHF14AMfCSetBlk, IfPm3Iso14443a, "Write block (magic chinese card)"}, {"cgetblk", CmdHF14AMfCGetBlk, IfPm3Iso14443a, "Read block (magic chinese card)"}, {"cgetsc", CmdHF14AMfCGetSc, IfPm3Iso14443a, "Read sector (magic chinese card)"}, diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index 39d2d6001..151ac72cf 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -615,6 +615,50 @@ int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, uint8_ return mfCSetBlock(0, block0, oldUID, params); } +int mfCWipe(uint8_t *uid, uint8_t *atqa, uint8_t *sak) { + uint8_t block0[16] = {0x01, 0x02, 0x03, 0x04, 0x04, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xAF}; + uint8_t blockD[16] = {0x00}; + uint8_t blockK[16] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x08, 0x77, 0x8F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + uint8_t params = MAGIC_SINGLE; + + if (uid != NULL) { + memcpy(block0, uid, 4); + block0[4] = block0[0] ^ block0[1] ^ block0[2] ^ block0[3]; + } + if (sak != NULL) + block0[5] = sak[0]; + + if (atqa != NULL) { + block0[6] = atqa[1]; + block0[7] = atqa[0]; + } + int res; + for (int blockNo = 0; blockNo < 4 * 16; blockNo++) { + for (int retry = 0; retry < 3; retry++) { + if (blockNo == 0) { + res = mfCSetBlock(blockNo, block0, NULL, params); + } else { + if (mfIsSectorTrailer(blockNo)) + res = mfCSetBlock(blockNo, blockK, NULL, params); + else + res = mfCSetBlock(blockNo, blockD, NULL, params); + } + + if (res == PM3_SUCCESS) + break; + PrintAndLogEx(WARNING, "Retry block[%d]...", blockNo); + } + + if (res) { + PrintAndLogEx(ERR, "Error setting block[%d]: %d", blockNo, res); + return res; + } + } + DropField(); + + return PM3_SUCCESS; +} + int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, uint8_t params) { clearCommandBuffer(); diff --git a/client/mifare/mifarehost.h b/client/mifare/mifarehost.h index 11bd3f29c..50ed9d8e2 100644 --- a/client/mifare/mifarehost.h +++ b/client/mifare/mifarehost.h @@ -73,6 +73,7 @@ int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount); int mfEmlSetMem_xt(uint8_t *data, int blockNum, int blocksCount, int blockBtWidth); int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, uint8_t wipecard); +int mfCWipe(uint8_t *uid, uint8_t *atqa, uint8_t *sak); int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, uint8_t params); int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params);