mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 13:23:51 -07:00
hf mf csetuid - now supports cliparser. Also experimental 7byte support. Not seen one in the wild. untested
This commit is contained in:
parent
3c2b04aa56
commit
e448d58291
5 changed files with 138 additions and 105 deletions
|
@ -188,21 +188,6 @@ static int usage_hf14_decryptbytes(void) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int usage_hf14_csetuid(void) {
|
|
||||||
PrintAndLogEx(NORMAL, "Set UID, ATQA, and SAK for magic Chinese card. Only works with magic cards");
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
|
||||||
PrintAndLogEx(NORMAL, "Usage: hf mf csetuid [h] <UID 8 hex symbols> [ATQA 4 hex symbols] [SAK 2 hex symbols] [w]");
|
|
||||||
PrintAndLogEx(NORMAL, "Options:");
|
|
||||||
PrintAndLogEx(NORMAL, " h this help");
|
|
||||||
PrintAndLogEx(NORMAL, " w wipe card before writing");
|
|
||||||
PrintAndLogEx(NORMAL, " <uid> UID 8 hex symbols");
|
|
||||||
PrintAndLogEx(NORMAL, " <atqa> ATQA 4 hex symbols");
|
|
||||||
PrintAndLogEx(NORMAL, " <sak> SAK 2 hex symbols");
|
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
|
||||||
PrintAndLogEx(NORMAL, _YELLOW_(" hf mf csetuid 01020304"));
|
|
||||||
PrintAndLogEx(NORMAL, _YELLOW_(" hf mf csetuid 01020304 0004 08 w"));
|
|
||||||
return PM3_SUCCESS;
|
|
||||||
}
|
|
||||||
static int usage_hf14_csetblk(void) {
|
static int usage_hf14_csetblk(void) {
|
||||||
PrintAndLogEx(NORMAL, "Set block data for magic Chinese card. Only works with magic cards");
|
PrintAndLogEx(NORMAL, "Set block data for magic Chinese card. Only works with magic cards");
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
@ -4313,109 +4298,126 @@ static int CmdHF14AMfEKeyPrn(const char *Cmd) {
|
||||||
|
|
||||||
// CHINESE MAGIC COMMANDS
|
// CHINESE MAGIC COMMANDS
|
||||||
static int CmdHF14AMfCSetUID(const char *Cmd) {
|
static int CmdHF14AMfCSetUID(const char *Cmd) {
|
||||||
uint8_t wipeCard = 0;
|
|
||||||
uint8_t uid[8] = {0x00};
|
CLIParserContext *ctx;
|
||||||
uint8_t oldUid[8] = {0x00};
|
CLIParserInit(&ctx, "hf mf csetuid",
|
||||||
|
"Set UID, ATQA, and SAK for magic gen1a card",
|
||||||
|
"hf mf csetuid -u 01020304\n"
|
||||||
|
"hf mf csetuid -w -u 01020304 --atqa 0004 --sak 08"
|
||||||
|
);
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_lit0("w", "wipe", "wipes card with backdoor cmd`"),
|
||||||
|
arg_str0("u", "uid", "<hex>", "UID, 4/7 hex bytes"),
|
||||||
|
arg_str0("a", "atqa", "<hex>", "ATQA, 2 hex bytes"),
|
||||||
|
arg_str0("s", "sak", "<hex>", "SAK, 1 hex byte"),
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
|
||||||
|
uint8_t wipe_card = arg_get_lit(ctx, 1);
|
||||||
|
|
||||||
|
int uidlen = 0;
|
||||||
|
uint8_t uid[7] = {0x00};
|
||||||
|
CLIGetHexWithReturn(ctx, 2, uid, &uidlen);
|
||||||
|
|
||||||
|
int alen = 0;
|
||||||
uint8_t atqa[2] = {0x00};
|
uint8_t atqa[2] = {0x00};
|
||||||
|
CLIGetHexWithReturn(ctx, 3, atqa, &alen);
|
||||||
|
|
||||||
|
int slen = 0;
|
||||||
uint8_t sak[1] = {0x00};
|
uint8_t sak[1] = {0x00};
|
||||||
uint8_t atqaPresent = 1;
|
CLIGetHexWithReturn(ctx, 4, sak, &slen);
|
||||||
int res, argi = 0;
|
CLIParserFree(ctx);
|
||||||
char ctmp;
|
|
||||||
|
|
||||||
if (strlen(Cmd) < 1 || param_getchar(Cmd, argi) == 'h')
|
// sanity checks
|
||||||
return usage_hf14_csetuid();
|
if (uidlen != 4 && uidlen != 7) {
|
||||||
|
PrintAndLogEx(FAILED, "UID must be 4 or 7 hex bytes. Got %d", uidlen);
|
||||||
if (param_getchar(Cmd, argi) && param_gethex(Cmd, argi, uid, 8))
|
return PM3_EINVARG;
|
||||||
return usage_hf14_csetuid();
|
}
|
||||||
|
if (alen && alen != 2) {
|
||||||
argi++;
|
PrintAndLogEx(FAILED, "ATQA must be 2 hex bytes. Got %d", alen);
|
||||||
|
return PM3_EINVARG;
|
||||||
ctmp = tolower(param_getchar(Cmd, argi));
|
}
|
||||||
if (ctmp == 'w') {
|
if (slen && slen != 1) {
|
||||||
wipeCard = 1;
|
PrintAndLogEx(FAILED, "SAK must be 1 hex byte. Got %d", slen);
|
||||||
atqaPresent = 0;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (atqaPresent) {
|
uint8_t old_uid[7] = {0};
|
||||||
if (param_getchar(Cmd, argi)) {
|
uint8_t verify_uid[7] = {0};
|
||||||
if (param_gethex(Cmd, argi, atqa, 4)) {
|
|
||||||
PrintAndLogEx(WARNING, "ATQA must include 4 HEX symbols");
|
|
||||||
return PM3_ESOFT;
|
|
||||||
}
|
|
||||||
argi++;
|
|
||||||
if (!param_getchar(Cmd, argi) || param_gethex(Cmd, argi, sak, 2)) {
|
|
||||||
PrintAndLogEx(WARNING, "SAK must include 2 HEX symbols");
|
|
||||||
return PM3_ESOFT;
|
|
||||||
}
|
|
||||||
argi++;
|
|
||||||
} else
|
|
||||||
atqaPresent = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!wipeCard) {
|
int res = mfCSetUID(
|
||||||
ctmp = tolower(param_getchar(Cmd, argi));
|
uid,
|
||||||
if (ctmp == 'w') {
|
uidlen,
|
||||||
wipeCard = 1;
|
(alen) ? atqa : NULL,
|
||||||
}
|
(slen) ? sak : NULL,
|
||||||
}
|
old_uid,
|
||||||
|
verify_uid,
|
||||||
|
wipe_card
|
||||||
|
);
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "--wipe card:%s uid:%s", (wipeCard) ? "YES" : "NO", sprint_hex(uid, 4));
|
|
||||||
|
|
||||||
res = mfCSetUID(uid, (atqaPresent) ? atqa : NULL, (atqaPresent) ? sak : NULL, oldUid, wipeCard);
|
|
||||||
if (res) {
|
if (res) {
|
||||||
PrintAndLogEx(ERR, "Can't set UID. error=%d", res);
|
PrintAndLogEx(ERR, "Can't set UID. error %d", res);
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "Old UID : %s", sprint_hex(oldUid, 4));
|
res = memcmp(uid, verify_uid, uidlen);
|
||||||
PrintAndLogEx(SUCCESS, "New UID : %s", sprint_hex(uid, 4));
|
|
||||||
|
PrintAndLogEx(SUCCESS, "Old UID... %s", sprint_hex(old_uid, uidlen));
|
||||||
|
PrintAndLogEx(SUCCESS, "New UID... %s ( %s )",
|
||||||
|
sprint_hex(verify_uid, uidlen),
|
||||||
|
(res == 0) ? _GREEN_("verified") : _RED_("fail")
|
||||||
|
);
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CmdHF14AMfCWipe(const char *cmd) {
|
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;
|
|
||||||
|
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "hf mf cwipe",
|
CLIParserInit(&ctx, "hf mf cwipe",
|
||||||
"Wipe gen1 magic chinese card. Set UID/ATQA/SAK/Data/Keys/Access to default values.",
|
"Wipe gen1 magic chinese card.\n"
|
||||||
"hf mf cwipe --> wipe card\n"
|
"Set UID / ATQA / SAK / Data / Keys / Access to default values",
|
||||||
|
"hf mf cwipe\n"
|
||||||
"hf mf cwipe -u 09080706 -a 0004 -s 18 --> set UID, ATQA and SAK and wipe card");
|
"hf mf cwipe -u 09080706 -a 0004 -s 18 --> set UID, ATQA and SAK and wipe card");
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_str0("u", "uid", "<UID (hex 4b)>", "UID for card"),
|
arg_str0("u", "uid", "<hex>", "UID, 4 hex bytes"),
|
||||||
arg_str0("a", "atqa", "<ATQA (hex 2b)>", "ATQA for card"),
|
arg_str0("a", "atqa", "<hex>", "ATQA, 2 hex bytes"),
|
||||||
arg_str0("s", "sak", "<SAK (hex 1b)>", "SAK for card"),
|
arg_str0("s", "sak", "<hex>", "SAK, 1 hex byte"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, cmd, argtable, true);
|
CLIExecWithReturn(ctx, cmd, argtable, true);
|
||||||
|
|
||||||
CLIGetHexWithReturn(ctx, 1, uid, &uidLen);
|
int uidlen = 0;
|
||||||
CLIGetHexWithReturn(ctx, 2, atqa, &atqaLen);
|
uint8_t uid[8] = {0x00};
|
||||||
CLIGetHexWithReturn(ctx, 3, sak, &sakLen);
|
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
||||||
|
|
||||||
|
int alen = 0;
|
||||||
|
uint8_t atqa[2] = {0x00};
|
||||||
|
CLIGetHexWithReturn(ctx, 2, atqa, &alen);
|
||||||
|
|
||||||
|
int slen = 0;
|
||||||
|
uint8_t sak[1] = {0x00};
|
||||||
|
CLIGetHexWithReturn(ctx, 3, sak, &slen);
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
if (uidLen && uidLen != 4) {
|
if (uidlen && uidlen != 4) {
|
||||||
PrintAndLogEx(ERR, "UID length must be 4 bytes instead of: %d", uidLen);
|
PrintAndLogEx(ERR, "UID length must be 4 bytes, got %d", uidlen);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
if (atqaLen && atqaLen != 2) {
|
if (alen && alen != 2) {
|
||||||
PrintAndLogEx(ERR, "ATQA length must be 2 bytes instead of: %d", atqaLen);
|
PrintAndLogEx(ERR, "ATQA length must be 2 bytes, got %d", alen);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
if (sakLen && sakLen != 1) {
|
if (slen && slen != 1) {
|
||||||
PrintAndLogEx(ERR, "SAK length must be 1 byte instead of: %d", sakLen);
|
PrintAndLogEx(ERR, "SAK length must be 1 byte, got %d", slen);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
int res = mfCWipe((uidLen) ? uid : NULL, (atqaLen) ? atqa : NULL, (sakLen) ? sak : NULL);
|
int res = mfCWipe((uidlen) ? uid : NULL, (alen) ? atqa : NULL, (slen) ? sak : NULL);
|
||||||
if (res) {
|
if (res) {
|
||||||
PrintAndLogEx(ERR, "Can't wipe card. error=%d", res);
|
PrintAndLogEx(ERR, "Can't wipe card. error %d", res);
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -853,37 +853,69 @@ int mfEmlSetMem_xt(uint8_t *data, int blockNum, int blocksCount, int blockBtWidt
|
||||||
}
|
}
|
||||||
|
|
||||||
// "MAGIC" CARD
|
// "MAGIC" CARD
|
||||||
int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, uint8_t wipecard) {
|
int mfCSetUID(uint8_t *uid, uint8_t uidlen, uint8_t *atqa, uint8_t *sak, uint8_t *old_uid, uint8_t *verifed_uid, uint8_t wipecard) {
|
||||||
|
|
||||||
uint8_t params = MAGIC_SINGLE;
|
uint8_t params = MAGIC_SINGLE;
|
||||||
uint8_t block0[16];
|
uint8_t block0[16];
|
||||||
memset(block0, 0x00, sizeof(block0));
|
memset(block0, 0x00, sizeof(block0));
|
||||||
|
|
||||||
int old = mfCGetBlock(0, block0, params);
|
int res = mfCGetBlock(0, block0, params);
|
||||||
if (old == 0)
|
if (res == 0) {
|
||||||
PrintAndLogEx(SUCCESS, "old block 0: %s", sprint_hex(block0, sizeof(block0)));
|
PrintAndLogEx(SUCCESS, "old block 0... %s", sprint_hex_inrow(block0, sizeof(block0)));
|
||||||
else
|
if (old_uid) {
|
||||||
PrintAndLogEx(FAILED, "couldn't get old data. Will write over the last bytes of Block 0.");
|
memcpy(old_uid, block0, uidlen);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(INFO, "couldn't get old data. Will write over the last bytes of block 0");
|
||||||
|
}
|
||||||
|
|
||||||
// fill in the new values
|
// fill in the new values
|
||||||
// UID
|
// UID
|
||||||
memcpy(block0, uid, 4);
|
memcpy(block0, uid, uidlen);
|
||||||
// Mifare UID BCC
|
// Mifare UID BCC
|
||||||
block0[4] = block0[0] ^ block0[1] ^ block0[2] ^ block0[3];
|
if (uidlen == 4) {
|
||||||
// mifare classic SAK(byte 5) and ATQA(byte 6 and 7, reversed)
|
block0[4] = block0[0] ^ block0[1] ^ block0[2] ^ block0[3];
|
||||||
if (sak != NULL)
|
|
||||||
block0[5] = sak[0];
|
|
||||||
|
|
||||||
if (atqa != NULL) {
|
// mifare classic SAK(byte 5) and ATQA(byte 6 and 7, reversed)
|
||||||
block0[6] = atqa[1];
|
if (sak)
|
||||||
block0[7] = atqa[0];
|
block0[5] = sak[0];
|
||||||
|
|
||||||
|
if (atqa) {
|
||||||
|
block0[6] = atqa[1];
|
||||||
|
block0[7] = atqa[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (uidlen == 7) {
|
||||||
|
block0[7] = block0[0] ^ block0[1] ^ block0[2] ^ block0[3] ^ block0[4] ^ block0[5] ^ block0[6];
|
||||||
|
|
||||||
|
// mifare classic SAK(byte 8) and ATQA(byte 9 and 10, reversed)
|
||||||
|
if (sak)
|
||||||
|
block0[8] = sak[0];
|
||||||
|
|
||||||
|
if (atqa) {
|
||||||
|
block0[9] = atqa[1];
|
||||||
|
block0[10] = atqa[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
PrintAndLogEx(SUCCESS, "new block 0: %s", sprint_hex(block0, 16));
|
|
||||||
|
|
||||||
if (wipecard) params |= MAGIC_WIPE;
|
PrintAndLogEx(SUCCESS, "new block 0... %s", sprint_hex_inrow(block0, 16));
|
||||||
if (oldUID != NULL) params |= MAGIC_UID;
|
|
||||||
|
|
||||||
return mfCSetBlock(0, block0, oldUID, params);
|
if (wipecard) {
|
||||||
|
params |= MAGIC_WIPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = mfCSetBlock(0, block0, NULL, params);
|
||||||
|
if (res == PM3_SUCCESS) {
|
||||||
|
params = MAGIC_SINGLE;
|
||||||
|
memset(block0, 0, sizeof(block0));
|
||||||
|
res = mfCGetBlock(0, block0, params);
|
||||||
|
if (res == 0) {
|
||||||
|
if (verifed_uid) {
|
||||||
|
memcpy(verifed_uid, block0, uidlen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mfCWipe(uint8_t *uid, uint8_t *atqa, uint8_t *sak) {
|
int mfCWipe(uint8_t *uid, uint8_t *atqa, uint8_t *sak) {
|
||||||
|
|
|
@ -76,7 +76,7 @@ int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount);
|
||||||
int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount);
|
int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount);
|
||||||
int mfEmlSetMem_xt(uint8_t *data, int blockNum, int blocksCount, int blockBtWidth);
|
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 mfCSetUID(uint8_t *uid, uint8_t uidlen, uint8_t *atqa, uint8_t *sak, uint8_t *old_uid, uint8_t *verifed_uid, uint8_t wipecard);
|
||||||
int mfCWipe(uint8_t *uid, uint8_t *atqa, uint8_t *sak);
|
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 mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, uint8_t params);
|
||||||
int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params);
|
int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params);
|
||||||
|
|
|
@ -24,7 +24,6 @@ hf mf restore
|
||||||
hf mf setmod
|
hf mf setmod
|
||||||
hf mf wrbl
|
hf mf wrbl
|
||||||
hf mf csetblk
|
hf mf csetblk
|
||||||
hf mf csetuid
|
|
||||||
hf mf gen3uid
|
hf mf gen3uid
|
||||||
hf mf gen3blk
|
hf mf gen3blk
|
||||||
hf mf gen3freeze
|
hf mf gen3freeze
|
||||||
|
|
|
@ -189,9 +189,9 @@ hf mf cwipe -u 11223344 -a 0044 -s 18
|
||||||
or just fixing block0:
|
or just fixing block0:
|
||||||
```
|
```
|
||||||
# MFC Gen1A 1k:
|
# MFC Gen1A 1k:
|
||||||
hf mf csetuid 11223344 0004 08
|
hf mf csetuid -u 11223344 -a 0004 -s 08
|
||||||
# MFC Gen1A 4k:
|
# MFC Gen1A 4k:
|
||||||
hf mf csetuid 11223344 0044 18
|
hf mf csetuid -u 11223344 -a 0044 -s 18
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue