diff --git a/CHANGELOG.md b/CHANGELOG.md index 296c892dc..e1f3cf2c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Added `hf mf cwipe` magic chinese card (gen1a) wipe to default state (@merlokk) - Added 'pm3_mf7b_wipe.py' python script. Wipes magic S70 7B Gen2 card. (@vulnersCom) - Added `hf mfp chk` Mifare plus command for check keys from public keys list, from dictionary or 1 and 2-byte bruteforce (@merlokk) - Change `hf 15` - some refactoring (@grspy) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index ad6fe31b2..2ace2d214 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..e9baa7ee7 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); diff --git a/tools/pm3_mf7b_wipe.py b/tools/pm3_mf7b_wipe.py index f4c58ce01..9f7b29c6b 100644 --- a/tools/pm3_mf7b_wipe.py +++ b/tools/pm3_mf7b_wipe.py @@ -71,7 +71,7 @@ # # Thats it! Your S50 7byte UID card is wiped back. Now you can return back to Step 1 of this manual. # -# +#