mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 21:33:47 -07:00
Rewrote completely cmds & options lf hitag read/dump/wrbl/ta
for more coherence with other pm3 cmds. Still there remain strange things but it should be a step in the right direction...
This commit is contained in:
parent
216ad5740b
commit
173379b999
2 changed files with 387 additions and 174 deletions
|
@ -281,7 +281,7 @@ static void hitag2_handle_reader_command(uint8_t *rx, const size_t rxlen, uint8_
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Received RWD authentication challenge and respnse
|
// Received RWD authentication challenge and response
|
||||||
case 64: {
|
case 64: {
|
||||||
// Store the authentication attempt
|
// Store the authentication attempt
|
||||||
if (auth_table_len < (AUTH_TABLE_LENGTH - 8)) {
|
if (auth_table_len < (AUTH_TABLE_LENGTH - 8)) {
|
||||||
|
@ -891,7 +891,7 @@ static bool hitag2_test_auth_attempts(uint8_t *rx, const size_t rxlen, uint8_t *
|
||||||
if (bCrypto) {
|
if (bCrypto) {
|
||||||
Dbprintf("auth: %02x%02x%02x%02x%02x%02x%02x%02x Failed, removed entry!", NrAr[0], NrAr[1], NrAr[2], NrAr[3], NrAr[4], NrAr[5], NrAr[6], NrAr[7]);
|
Dbprintf("auth: %02x%02x%02x%02x%02x%02x%02x%02x Failed, removed entry!", NrAr[0], NrAr[1], NrAr[2], NrAr[3], NrAr[4], NrAr[5], NrAr[6], NrAr[7]);
|
||||||
|
|
||||||
// Removing failed entry from authentiations table
|
// Removing failed entry from authentications table
|
||||||
memcpy(auth_table + auth_table_pos, auth_table + auth_table_pos + 8, 8);
|
memcpy(auth_table + auth_table_pos, auth_table + auth_table_pos + 8, 8);
|
||||||
auth_table_len -= 8;
|
auth_table_len -= 8;
|
||||||
|
|
||||||
|
|
|
@ -224,7 +224,7 @@ static int CmdLFHitagEload(const char *Cmd) {
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_str1("f", "file", "<fn>", "Specfiy dump filename"),
|
arg_str1("f", "file", "<fn>", "Specify dump filename"),
|
||||||
arg_lit0("1", NULL, "Card type Hitag 1"),
|
arg_lit0("1", NULL, "Card type Hitag 1"),
|
||||||
arg_lit0("2", NULL, "Card type Hitag 2"),
|
arg_lit0("2", NULL, "Card type Hitag 2"),
|
||||||
arg_lit0("s", NULL, "Card type Hitag S"),
|
arg_lit0("s", NULL, "Card type Hitag S"),
|
||||||
|
@ -243,9 +243,12 @@ static int CmdLFHitagEload(const char *Cmd) {
|
||||||
bool use_htm = arg_get_lit(ctx, 5);
|
bool use_htm = arg_get_lit(ctx, 5);
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
uint8_t n = (use_ht1 + use_ht2 + use_hts + use_htm);
|
if ((use_ht1 + use_ht2 + use_hts + use_htm) > 1) {
|
||||||
if (n != 1) {
|
PrintAndLogEx(ERR, "error, specify only one Hitag type");
|
||||||
PrintAndLogEx(ERR, "error, only specify one Hitag type");
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
if ((use_ht1 + use_ht2 + use_hts + use_htm) == 0) {
|
||||||
|
PrintAndLogEx(ERR, "error, specify one Hitag type");
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,16 +291,16 @@ static int CmdLFHitagEload(const char *Cmd) {
|
||||||
static int CmdLFHitagSim(const char *Cmd) {
|
static int CmdLFHitagSim(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "lf hitag sim",
|
CLIParserInit(&ctx, "lf hitag sim",
|
||||||
"Simulate Hitag2 / HitagS transponder\n"
|
"Simulate Hitag transponder\n"
|
||||||
"You need to `lf hitag eload` first",
|
"You need to `lf hitag eload` first",
|
||||||
"lf hitag sim -2"
|
"lf hitag sim -2"
|
||||||
);
|
);
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_lit0("1", NULL, "simulate Hitag1"),
|
arg_lit0("1", "ht1", "simulate Hitag 1"),
|
||||||
arg_lit0("2", NULL, "simulate Hitag2"),
|
arg_lit0("2", "ht2", "simulate Hitag 2"),
|
||||||
arg_lit0("s", NULL, "simulate HitagS"),
|
arg_lit0("s", "hts", "simulate Hitag S"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
@ -305,10 +308,15 @@ static int CmdLFHitagSim(const char *Cmd) {
|
||||||
bool use_ht1 = arg_get_lit(ctx, 1);
|
bool use_ht1 = arg_get_lit(ctx, 1);
|
||||||
bool use_ht2 = arg_get_lit(ctx, 2);
|
bool use_ht2 = arg_get_lit(ctx, 2);
|
||||||
bool use_hts = arg_get_lit(ctx, 3);
|
bool use_hts = arg_get_lit(ctx, 3);
|
||||||
|
bool use_htm = false; // not implemented yet
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
if ((use_ht1 + use_ht2 + use_hts) > 1) {
|
if ((use_ht1 + use_ht2 + use_hts + use_htm) > 1) {
|
||||||
PrintAndLogEx(ERR, "error, Only specify one Hitag type");
|
PrintAndLogEx(ERR, "error, specify only one Hitag type");
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
if ((use_ht1 + use_ht2 + use_hts + use_htm) == 0) {
|
||||||
|
PrintAndLogEx(ERR, "error, specify one Hitag type");
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -523,67 +531,85 @@ static int CmdLFHitagInfo(const char *Cmd) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: iceman
|
|
||||||
// Hitag2 reader, problem is that this command mixes up stuff. So 26 give uid. 21 etc will also give you a memory dump !?
|
|
||||||
//
|
|
||||||
static int CmdLFHitagReader(const char *Cmd) {
|
static int CmdLFHitagReader(const char *Cmd) {
|
||||||
|
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "lf hitag reader",
|
CLIParserInit(&ctx, "lf hitag read",
|
||||||
"Act like a Hitag Reader",
|
"Read Hitag memory\n"
|
||||||
"Hitag S\n"
|
"Crypto mode key format: ISK high + ISK low",
|
||||||
" lf hitag reader --01 --nrar 0102030411223344\n"
|
"Hitag S, plain mode\n"
|
||||||
" lf hitag reader --02 -k 4F4E4D494B52\n"
|
" lf hitag read --hts\n"
|
||||||
"Hitag 2\n"
|
"Hitag S, challenge mode\n"
|
||||||
" lf hitag reader --21 -k 4D494B52\n"
|
" lf hitag read --hts --nrar 0102030411223344\n"
|
||||||
" lf hitag reader --22 --nrar 0102030411223344\n"
|
"Hitag S, crypto mode => use default key 4F4E4D494B52 (ONMIKR)\n"
|
||||||
" lf hitag reader --23 -k 4F4E4D494B52\n"
|
" lf hitag read --hts --crypto\n"
|
||||||
" lf hitag reader --26\n"
|
"Hitag S, long key = crypto mode\n"
|
||||||
|
" lf hitag read --hts -k 4F4E4D494B52\n\n"
|
||||||
|
|
||||||
|
"Hitag 2, password mode => use default key 4D494B52 (MIKR)\n"
|
||||||
|
" lf hitag read --ht2 --pwd\n"
|
||||||
|
"Hitag 2, providing a short key = password mode\n"
|
||||||
|
" lf hitag read --ht2 -k 4D494B52\n"
|
||||||
|
"Hitag 2, challenge mode\n"
|
||||||
|
" lf hitag read --ht2 --nrar 0102030411223344\n"
|
||||||
|
"Hitag 2, crypto mode => use default key 4F4E4D494B52 (ONMIKR)\n"
|
||||||
|
" lf hitag read --ht2 --crypto\n"
|
||||||
|
"Hitag 2, providing a long key = crypto mode\n"
|
||||||
|
" lf hitag read --ht2 -k 4F4E4D494B52\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_lit0(NULL, "01", "HitagS, read all pages, challenge mode"),
|
arg_lit0(NULL, "hts", "Hitag S"),
|
||||||
arg_lit0(NULL, "02", "HitagS, read all pages, crypto mode. Set key=0 for no auth"),
|
arg_lit0(NULL, "ht2", "Hitag 2"),
|
||||||
arg_lit0(NULL, "21", "Hitag2, read all pages, password mode. def 4D494B52 (MIKR)"),
|
arg_lit0(NULL, "pwd", "password mode"),
|
||||||
arg_lit0(NULL, "22", "Hitag2, read all pages, challenge mode"),
|
arg_str0(NULL, "nrar", "<hex>", "nonce / answer writer, 8 hex bytes"),
|
||||||
arg_lit0(NULL, "23", "Hitag2, read all pages, crypto mode. Key ISK high + ISK low. def 4F4E4D494B52 (ONMIKR)"),
|
arg_lit0(NULL, "crypto", "crypto mode"),
|
||||||
arg_lit0(NULL, "25", "Hitag2, test recorded authentications (replay?)"),
|
|
||||||
arg_lit0(NULL, "26", "Hitag2, read UID"),
|
|
||||||
arg_str0("k", "key", "<hex>", "key, 4 or 6 hex bytes"),
|
arg_str0("k", "key", "<hex>", "key, 4 or 6 hex bytes"),
|
||||||
arg_str0(NULL, "nrar", "<hex>", "nonce / answer reader, 8 hex bytes"),
|
// currently pm3 fw reads all the memory anyway
|
||||||
|
// arg_int1("p", "page", "<dec>", "page address to write to"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
|
||||||
// Hitag S
|
bool use_ht1 = false; // not yet implemented
|
||||||
bool s01 = arg_get_lit(ctx, 1);
|
bool use_hts = arg_get_lit(ctx, 1);
|
||||||
bool s02 = arg_get_lit(ctx, 2);
|
bool use_ht2 = arg_get_lit(ctx, 2);
|
||||||
|
bool use_htm = false; // not yet implemented
|
||||||
|
|
||||||
// Hitag 2
|
bool use_plain = false;
|
||||||
bool h21 = arg_get_lit(ctx, 3);
|
bool use_pwd = arg_get_lit(ctx, 3);
|
||||||
bool h22 = arg_get_lit(ctx, 4);
|
uint8_t nrar[8];
|
||||||
bool h23 = arg_get_lit(ctx, 5);
|
int nalen = 0;
|
||||||
bool h25 = arg_get_lit(ctx, 6);
|
int res = CLIParamHexToBuf(arg_get_str(ctx, 4), nrar, sizeof(nrar), &nalen);
|
||||||
bool h26 = arg_get_lit(ctx, 7);
|
if (res != 0) {
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
bool use_nrar = nalen > 0;
|
||||||
|
bool use_crypto = arg_get_lit(ctx, 5);
|
||||||
|
|
||||||
uint8_t key[6];
|
uint8_t key[6];
|
||||||
int keylen = 0;
|
int keylen = 0;
|
||||||
int res = CLIParamHexToBuf(arg_get_str(ctx, 8), key, sizeof(key), &keylen);
|
res = CLIParamHexToBuf(arg_get_str(ctx, 6), key, sizeof(key), &keylen);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
// uint32_t page = arg_get_u32_def(ctx, 6, 0);
|
||||||
|
|
||||||
uint8_t nrar[8];
|
|
||||||
int nalen = 0;
|
|
||||||
res = CLIParamHexToBuf(arg_get_str(ctx, 9), nrar, sizeof(nrar), &nalen);
|
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
if (res != 0) {
|
|
||||||
return PM3_EINVARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
// sanity checks
|
// sanity checks
|
||||||
|
if ((use_ht1 + use_ht2 + use_hts + use_htm) > 1) {
|
||||||
|
PrintAndLogEx(ERR, "error, specify only one Hitag type");
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
if ((use_ht1 + use_ht2 + use_hts + use_htm) == 0) {
|
||||||
|
PrintAndLogEx(ERR, "error, specify one Hitag type");
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
|
||||||
if (keylen != 0 && keylen != 4 && keylen != 6) {
|
if (keylen != 0 && keylen != 4 && keylen != 6) {
|
||||||
PrintAndLogEx(WARNING, "Wrong KEY len expected 0, 4 or 6, got %d", keylen);
|
PrintAndLogEx(WARNING, "Wrong KEY len expected 0, 4 or 6, got %d", keylen);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
|
@ -594,48 +620,73 @@ static int CmdLFHitagReader(const char *Cmd) {
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t foo = (s01 + s02 + h21 + h22 + h23 + h25 + h26);
|
// complete options
|
||||||
|
if (keylen == 4) {
|
||||||
|
use_pwd = true;
|
||||||
|
}
|
||||||
|
if (keylen == 6) {
|
||||||
|
use_crypto = true;
|
||||||
|
}
|
||||||
|
if ((keylen == 0) && use_pwd) {
|
||||||
|
memcpy(key, "MIKR", 4);
|
||||||
|
keylen = 4;
|
||||||
|
}
|
||||||
|
if ((keylen == 0) && use_crypto) {
|
||||||
|
memcpy(key, "ONMIKR", 6);
|
||||||
|
keylen = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check coherence
|
||||||
|
uint8_t foo = (use_plain + use_pwd + use_nrar + use_crypto);
|
||||||
if (foo > 1) {
|
if (foo > 1) {
|
||||||
PrintAndLogEx(WARNING, "Only specify one HITAG reader cmd");
|
PrintAndLogEx(WARNING, "Specify only one authentication mode");
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
} else if (foo == 0) {
|
} else if (foo == 0) {
|
||||||
PrintAndLogEx(WARNING, "Specify one HITAG reader cms");
|
if (use_hts) {
|
||||||
|
use_plain = true;
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(WARNING, "Specify one authentication mode");
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_hts && use_pwd) { // not sure for the other types...
|
||||||
|
PrintAndLogEx(WARNING, "Chosen Hitag type does not have Password mode");
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_ht2 && use_plain) { // not sure for the other types...
|
||||||
|
PrintAndLogEx(WARNING, "Chosen Hitag type does not have Plain mode");
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
hitag_function htf;
|
hitag_function htf;
|
||||||
hitag_data htd;
|
hitag_data htd;
|
||||||
memset(&htd, 0, sizeof(htd));
|
memset(&htd, 0, sizeof(htd));
|
||||||
|
uint16_t cmd;
|
||||||
|
if (use_hts && use_nrar) {
|
||||||
uint16_t cmd = CMD_LF_HITAG_READER;
|
|
||||||
if (s01) {
|
|
||||||
cmd = CMD_LF_HITAGS_READ;
|
cmd = CMD_LF_HITAGS_READ;
|
||||||
htf = RHTSF_CHALLENGE;
|
htf = RHTSF_CHALLENGE;
|
||||||
memcpy(htd.auth.NrAr, nrar, sizeof(htd.auth.NrAr));
|
memcpy(htd.auth.NrAr, nrar, sizeof(htd.auth.NrAr));
|
||||||
}
|
} else if (use_hts && use_crypto) {
|
||||||
if (s02) {
|
|
||||||
cmd = CMD_LF_HITAGS_READ;
|
cmd = CMD_LF_HITAGS_READ;
|
||||||
htf = RHTSF_KEY;
|
htf = RHTSF_KEY;
|
||||||
memcpy(htd.crypto.key, key, sizeof(htd.crypto.key));
|
memcpy(htd.crypto.key, key, sizeof(htd.crypto.key));
|
||||||
}
|
} else if (use_ht2 && use_pwd) {
|
||||||
if (h21) {
|
cmd = CMD_LF_HITAG_READER;
|
||||||
htf = RHT2F_PASSWORD;
|
htf = RHT2F_PASSWORD;
|
||||||
memcpy(htd.pwd.password, key, sizeof(htd.pwd.password));
|
memcpy(htd.pwd.password, key, sizeof(htd.pwd.password));
|
||||||
}
|
} else if (use_ht2 && use_nrar) {
|
||||||
if (h22) {
|
cmd = CMD_LF_HITAG_READER;
|
||||||
htf = RHT2F_AUTHENTICATE;
|
htf = RHT2F_AUTHENTICATE;
|
||||||
memcpy(htd.auth.NrAr, nrar, sizeof(htd.auth.NrAr));
|
memcpy(htd.auth.NrAr, nrar, sizeof(htd.auth.NrAr));
|
||||||
}
|
} else if (use_ht2 && use_crypto) {
|
||||||
if (h23) {
|
|
||||||
htf = RHT2F_CRYPTO;
|
htf = RHT2F_CRYPTO;
|
||||||
|
cmd = CMD_LF_HITAG_READER;
|
||||||
memcpy(htd.crypto.key, key, sizeof(htd.crypto.key));
|
memcpy(htd.crypto.key, key, sizeof(htd.crypto.key));
|
||||||
}
|
} else {
|
||||||
if (h25) {
|
PrintAndLogEx(WARNING, "Sorry, not yet implemented");
|
||||||
htf = RHT2F_TEST_AUTH_ATTEMPTS;
|
return PM3_ENOTIMPL;
|
||||||
}
|
|
||||||
if (h26) {
|
|
||||||
htf = RHT2F_UID_ONLY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
|
@ -653,21 +704,13 @@ static int CmdLFHitagReader(const char *Cmd) {
|
||||||
uint32_t id = bytes_to_num(resp.data.asBytes, 4);
|
uint32_t id = bytes_to_num(resp.data.asBytes, 4);
|
||||||
uint8_t *data = resp.data.asBytes;
|
uint8_t *data = resp.data.asBytes;
|
||||||
PrintAndLogEx(SUCCESS, " UID: " _YELLOW_("%08x"), id);
|
PrintAndLogEx(SUCCESS, " UID: " _YELLOW_("%08x"), id);
|
||||||
|
|
||||||
if (htf != RHT2F_UID_ONLY) {
|
|
||||||
|
|
||||||
// block3, 1 byte
|
|
||||||
printHitag2Configuration(data[4 * 3]);
|
printHitag2Configuration(data[4 * 3]);
|
||||||
|
|
||||||
// print data
|
|
||||||
print_hex_break(data, 48, 4);
|
print_hex_break(data, 48, 4);
|
||||||
|
|
||||||
printHitag2PaxtonDowngrade(data);
|
printHitag2PaxtonDowngrade(data);
|
||||||
}
|
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CmdLFHitagCheckChallenges(const char *Cmd) {
|
static int CmdLFHitagSCheckChallenges(const char *Cmd) {
|
||||||
|
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "lf hitag cc",
|
CLIParserInit(&ctx, "lf hitag cc",
|
||||||
|
@ -708,92 +751,169 @@ static int CmdLFHitagCheckChallenges(const char *Cmd) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int CmdLFHitag2CheckChallenges(const char *Cmd) {
|
||||||
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "lf hitag ta",
|
||||||
|
"Test recorded authentications (replay?)",
|
||||||
|
"lf hitag ta"
|
||||||
|
);
|
||||||
|
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommandMIX(CMD_LF_HITAG_READER, RHT2F_TEST_AUTH_ATTEMPTS, 0, 0, NULL, 0);
|
||||||
|
PacketResponseNG resp;
|
||||||
|
if (WaitForResponseTimeout(CMD_ACK, &resp, 2000) == false) {
|
||||||
|
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
if (resp.oldarg[0] == false) {
|
||||||
|
PrintAndLogEx(DEBUG, "DEBUG: Error - hitag failed");
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: doegox: not sure what this fct does and what it returns...
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int CmdLFHitagWriter(const char *Cmd) {
|
static int CmdLFHitagWriter(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "lf hitag writer",
|
CLIParserInit(&ctx, "lf hitag wrbl",
|
||||||
"Act like a Hitag writer"
|
"Write a page in Hitag memory\n"
|
||||||
"In password mode the default key is 4D494B52 (MIKR)\n"
|
"Crypto mode key format: ISK high + ISK low",
|
||||||
"In crypto mode the default key is 4F4E4D494B52 (ONMIKR) format: ISK high + ISK low.",
|
"Hitag S, plain mode\n"
|
||||||
"Hitag S\n"
|
" lf hitag wrbl --hts -p 6 -d 01020304\n"
|
||||||
" lf hitag writer --03 --nrar 0102030411223344 -p 3 -d 01020304\n"
|
"Hitag S, challenge mode\n"
|
||||||
" lf hitag writer --04 -k 4F4E4D494B52 -p 3 -d 01020304\n"
|
" lf hitag wrbl --hts --nrar 0102030411223344 -p 6 -d 01020304\n"
|
||||||
"Hitag 2\n"
|
"Hitag S, crypto mode => use default key 4F4E4D494B52 (ONMIKR)\n"
|
||||||
" lf hitag writer --24 -k 4F4E4D494B52 -p 3 -d 01020304\n"
|
" lf hitag wrbl --hts --crypto -p 6 -d 01020304\n"
|
||||||
" lf hitag writer --27 -k 4D494B52 -p 3 -d 01020304\n"
|
"Hitag S, long key = crypto mode\n"
|
||||||
|
" lf hitag wrbl --hts -k 4F4E4D494B52 -p 6 -d 01020304\n\n"
|
||||||
|
|
||||||
|
"Hitag 2, password mode => use default key 4D494B52 (MIKR)\n"
|
||||||
|
" lf hitag wrbl --ht2 --pwd -p 6 -d 01020304\n"
|
||||||
|
"Hitag 2, providing a short key = password mode\n"
|
||||||
|
" lf hitag wrbl --ht2 -k 4D494B52 -p 6 -d 01020304\n"
|
||||||
|
"Hitag 2, challenge mode\n"
|
||||||
|
" lf hitag wrbl --ht2 --nrar 0102030411223344 -p 6 -d 01020304\n"
|
||||||
|
"Hitag 2, crypto mode => use default key 4F4E4D494B52 (ONMIKR)\n"
|
||||||
|
" lf hitag wrbl --ht2 --crypto -p 6 -d 01020304\n"
|
||||||
|
"Hitag 2, providing a long key = crypto mode\n"
|
||||||
|
" lf hitag wrbl --ht2 -k 4F4E4D494B52 -p 6 -d 01020304\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_lit0(NULL, "03", "HitagS, write page, challenge mode"),
|
arg_lit0(NULL, "hts", "Hitag S"),
|
||||||
arg_lit0(NULL, "04", "HitagS, write page, crypto mode. Set key=0 for no auth"),
|
arg_lit0(NULL, "ht2", "Hitag 2"),
|
||||||
arg_lit0(NULL, "24", "Hitag2, write page, crypto mode."),
|
arg_lit0(NULL, "pwd", "password mode"),
|
||||||
arg_lit0(NULL, "27", "Hitag2, write page, password mode"),
|
|
||||||
arg_int1("p", "page", "<dec>", "page address to write to"),
|
|
||||||
arg_str0("d", "data", "<hex>", "data, 4 hex bytes"),
|
|
||||||
arg_str0("k", "key", "<hex>", "key, 4 or 6 hex bytes"),
|
|
||||||
arg_str0(NULL, "nrar", "<hex>", "nonce / answer writer, 8 hex bytes"),
|
arg_str0(NULL, "nrar", "<hex>", "nonce / answer writer, 8 hex bytes"),
|
||||||
|
arg_lit0(NULL, "crypto", "crypto mode"),
|
||||||
|
arg_str0("k", "key", "<hex>", "key, 4 or 6 hex bytes"),
|
||||||
|
arg_int1("p", "page", "<dec>", "page address to write to"),
|
||||||
|
arg_str1("d", "data", "<hex>", "data, 4 hex bytes"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
|
||||||
// Hitag S
|
bool use_ht1 = false; // not yet implemented
|
||||||
bool s03 = arg_get_lit(ctx, 1);
|
bool use_hts = arg_get_lit(ctx, 1);
|
||||||
bool s04 = arg_get_lit(ctx, 2);
|
bool use_ht2 = arg_get_lit(ctx, 2);
|
||||||
|
bool use_htm = false; // not yet implemented
|
||||||
|
|
||||||
// Hitag 2
|
bool use_plain = false;
|
||||||
bool h24 = arg_get_lit(ctx, 3);
|
bool use_pwd = arg_get_lit(ctx, 3);
|
||||||
bool h27 = arg_get_lit(ctx, 4);
|
uint8_t nrar[8];
|
||||||
|
int nalen = 0;
|
||||||
uint32_t page = arg_get_u32_def(ctx, 5, 0);
|
int res = CLIParamHexToBuf(arg_get_str(ctx, 4), nrar, sizeof(nrar), &nalen);
|
||||||
|
|
||||||
uint8_t data[4];
|
|
||||||
int dlen = 0;
|
|
||||||
int res = CLIParamHexToBuf(arg_get_str(ctx, 6), data, sizeof(data), &dlen);
|
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
bool use_nrar = nalen > 0;
|
||||||
|
bool use_crypto = arg_get_lit(ctx, 5);
|
||||||
|
|
||||||
uint8_t key[6];
|
uint8_t key[6];
|
||||||
int keylen = 0;
|
int keylen = 0;
|
||||||
res = CLIParamHexToBuf(arg_get_str(ctx, 7), key, sizeof(key), &keylen);
|
res = CLIParamHexToBuf(arg_get_str(ctx, 6), key, sizeof(key), &keylen);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t nrar[8];
|
uint32_t page = arg_get_u32_def(ctx, 7, 0);
|
||||||
int nalen = 0;
|
|
||||||
res = CLIParamHexToBuf(arg_get_str(ctx, 8), nrar, sizeof(nrar), &nalen);
|
|
||||||
|
|
||||||
CLIParserFree(ctx);
|
|
||||||
|
|
||||||
|
uint8_t data[4];
|
||||||
|
int dlen = 0;
|
||||||
|
res = CLIParamHexToBuf(arg_get_str(ctx, 8), data, sizeof(data), &dlen);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
|
CLIParserFree(ctx);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
// sanity checks
|
// sanity checks
|
||||||
if (dlen != sizeof(data)) {
|
if ((use_ht1 + use_ht2 + use_hts + use_htm) > 1) {
|
||||||
PrintAndLogEx(WARNING, "Wrong DATA len expected 4, got %d", dlen);
|
PrintAndLogEx(ERR, "error, specify only one Hitag type");
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
if ((use_ht1 + use_ht2 + use_hts + use_htm) == 0) {
|
||||||
|
PrintAndLogEx(ERR, "error, specify one Hitag type");
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keylen != 0 && keylen != 6 && keylen != 4) {
|
if (keylen != 0 && keylen != 4 && keylen != 6) {
|
||||||
PrintAndLogEx(WARNING, "Wrong KEY len expected 0, 4 or 6, got %d", keylen);
|
PrintAndLogEx(WARNING, "Wrong KEY len expected 0, 4 or 6, got %d", keylen);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dlen != sizeof(data)) {
|
||||||
|
PrintAndLogEx(WARNING, "Wrong DATA len expected 4, got %d", dlen);
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
|
||||||
if (nalen != 0 && nalen != 8) {
|
if (nalen != 0 && nalen != 8) {
|
||||||
PrintAndLogEx(WARNING, "Wrong NR/AR len expected 0 or 8, got %d", nalen);
|
PrintAndLogEx(WARNING, "Wrong NR/AR len expected 0 or 8, got %d", nalen);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t foo = (s03 + s04 + h24 + h27);
|
// complete options
|
||||||
|
if (keylen == 4) {
|
||||||
|
use_pwd = true;
|
||||||
|
}
|
||||||
|
if (keylen == 6) {
|
||||||
|
use_crypto = true;
|
||||||
|
}
|
||||||
|
if ((keylen == 0) && use_pwd) {
|
||||||
|
memcpy(key, "MIKR", 4);
|
||||||
|
keylen = 4;
|
||||||
|
}
|
||||||
|
if ((keylen == 0) && use_crypto) {
|
||||||
|
memcpy(key, "ONMIKR", 6);
|
||||||
|
keylen = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check coherence
|
||||||
|
uint8_t foo = (use_plain + use_pwd + use_nrar + use_crypto);
|
||||||
if (foo > 1) {
|
if (foo > 1) {
|
||||||
PrintAndLogEx(WARNING, "Only specify one HITAG write cmd");
|
PrintAndLogEx(WARNING, "Specify only one authentication mode");
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
} else if (foo == 0) {
|
} else if (foo == 0) {
|
||||||
PrintAndLogEx(WARNING, "Specify one HITAG write cmd");
|
if (use_hts) {
|
||||||
|
use_plain = true;
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(WARNING, "Specify one authentication mode");
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_hts && use_pwd) { // not sure for the other types...
|
||||||
|
PrintAndLogEx(WARNING, "Chosen Hitag type does not have Password mode");
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_ht2 && use_plain) { // not sure for the other types...
|
||||||
|
PrintAndLogEx(WARNING, "Chosen Hitag type does not have Plain mode");
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -801,29 +921,33 @@ static int CmdLFHitagWriter(const char *Cmd) {
|
||||||
hitag_data htd;
|
hitag_data htd;
|
||||||
memset(&htd, 0, sizeof(htd));
|
memset(&htd, 0, sizeof(htd));
|
||||||
|
|
||||||
if (s03) {
|
if (use_hts && use_nrar) {
|
||||||
htf = WHTSF_CHALLENGE;
|
htf = WHTSF_CHALLENGE;
|
||||||
memcpy(htd.auth.NrAr, nrar, sizeof(htd.auth.NrAr));
|
memcpy(htd.auth.NrAr, nrar, sizeof(htd.auth.NrAr));
|
||||||
memcpy(htd.auth.data, data, sizeof(data));
|
memcpy(htd.auth.data, data, sizeof(data));
|
||||||
}
|
PrintAndLogEx(INFO, "Authenticating to Hitag S in Challenge mode");
|
||||||
if (s04) {
|
} else if (use_hts && use_crypto) {
|
||||||
htf = WHTSF_KEY;
|
htf = WHTSF_KEY;
|
||||||
memcpy(htd.crypto.key, key, sizeof(htd.crypto.key));
|
memcpy(htd.crypto.key, key, sizeof(htd.crypto.key));
|
||||||
memcpy(htd.crypto.data, data, sizeof(data));
|
memcpy(htd.crypto.data, data, sizeof(data));
|
||||||
}
|
PrintAndLogEx(INFO, "Authenticating to Hitag S in Crypto mode");
|
||||||
if (h24) {
|
} else if (use_ht2 && use_pwd) {
|
||||||
htf = WHT2F_CRYPTO;
|
|
||||||
memcpy(htd.crypto.key, key, sizeof(htd.crypto.key));
|
|
||||||
memcpy(htd.crypto.data, data, sizeof(data));
|
|
||||||
}
|
|
||||||
if (h27) {
|
|
||||||
htf = WHT2F_PASSWORD;
|
htf = WHT2F_PASSWORD;
|
||||||
memcpy(htd.pwd.password, key, sizeof(htd.pwd.password));
|
memcpy(htd.pwd.password, key, sizeof(htd.pwd.password));
|
||||||
memcpy(htd.crypto.data, data, sizeof(data));
|
memcpy(htd.crypto.data, data, sizeof(data));
|
||||||
|
PrintAndLogEx(INFO, "Authenticating to Hitag 2 in Password mode");
|
||||||
|
} else if (use_ht2 && use_crypto) {
|
||||||
|
htf = WHT2F_CRYPTO;
|
||||||
|
memcpy(htd.crypto.key, key, sizeof(htd.crypto.key));
|
||||||
|
memcpy(htd.crypto.data, data, sizeof(data));
|
||||||
|
PrintAndLogEx(INFO, "Authenticating to Hitag 2 in Crypto mode");
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(WARNING, "Sorry, not yet implemented");
|
||||||
|
return PM3_ENOTIMPL;
|
||||||
}
|
}
|
||||||
|
uint16_t cmd = CMD_LF_HITAGS_WRITE;
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandMIX(CMD_LF_HITAGS_WRITE, htf, 0, page, &htd, sizeof(htd));
|
SendCommandMIX(cmd, htf, 0, page, &htd, sizeof(htd));
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 4000) == false) {
|
if (WaitForResponseTimeout(CMD_ACK, &resp, 4000) == false) {
|
||||||
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
||||||
|
@ -841,56 +965,132 @@ static int CmdLFHitag2Dump(const char *Cmd) {
|
||||||
|
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "lf hitag dump",
|
CLIParserInit(&ctx, "lf hitag dump",
|
||||||
"Read all card memory and save to file"
|
"Read all Hitag 2 card memory and save to file\n"
|
||||||
"In password mode the default key is 4D494B52 (MIKR)\n"
|
"Crypto mode key format: ISK high + ISK low",
|
||||||
"In crypto mode the default key is 4F4E4D494B52 (ONMIKR) format: ISK high + ISK low.",
|
"Password mode => use default key 4D494B52 (MIKR)\n"
|
||||||
"lf hitag dump -k 4F4E4D494B52\n"
|
" lf hitag dump --pwd\n"
|
||||||
|
"Short key = password mode\n"
|
||||||
" lf hitag dump -k 4D494B52\n"
|
" lf hitag dump -k 4D494B52\n"
|
||||||
|
"Challenge mode\n"
|
||||||
|
" lf hitag dump --nrar 0102030411223344\n"
|
||||||
|
"Crypto mode => use default key 4F4E4D494B52 (ONMIKR)\n"
|
||||||
|
" lf hitag dump --crypto\n"
|
||||||
|
"Long key = crypto mode\n"
|
||||||
|
" lf hitag dump -k 4F4E4D494B52\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_str0("f", "file", "<fn>", "specify file name"),
|
arg_lit0(NULL, "pwd", "password mode"),
|
||||||
arg_str0("k", "key", "<hex>", "key, 4 or 6 hex bytes"),
|
|
||||||
arg_str0(NULL, "nrar", "<hex>", "nonce / answer reader, 8 hex bytes"),
|
arg_str0(NULL, "nrar", "<hex>", "nonce / answer reader, 8 hex bytes"),
|
||||||
|
arg_lit0(NULL, "crypto", "crypto mode"),
|
||||||
|
arg_str0("k", "key", "<hex>", "key, 4 or 6 hex bytes"),
|
||||||
|
arg_str0("f", "file", "<fn>", "specify file name"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
|
||||||
int fnlen = 0;
|
bool use_ht1 = false; // not yet implemented
|
||||||
char filename[FILE_PATH_SIZE] = {0};
|
bool use_hts = false; // not yet implemented
|
||||||
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
|
bool use_ht2 = true;
|
||||||
|
bool use_htm = false; // not yet implemented
|
||||||
|
|
||||||
|
bool use_plain = false;
|
||||||
|
bool use_pwd = arg_get_lit(ctx, 1);
|
||||||
|
uint8_t nrar[8];
|
||||||
|
int nalen = 0;
|
||||||
|
int res = CLIParamHexToBuf(arg_get_str(ctx, 2), nrar, sizeof(nrar), &nalen);
|
||||||
|
if (res != 0) {
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
bool use_nrar = nalen > 0;
|
||||||
|
bool use_crypto = arg_get_lit(ctx, 3);
|
||||||
|
|
||||||
uint8_t key[6];
|
uint8_t key[6];
|
||||||
int keylen = 0;
|
int keylen = 0;
|
||||||
int res = CLIParamHexToBuf(arg_get_str(ctx, 2), key, sizeof(key), &keylen);
|
res = CLIParamHexToBuf(arg_get_str(ctx, 4), key, sizeof(key), &keylen);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t nrar[8];
|
int fnlen = 0;
|
||||||
int nalen = 0;
|
char filename[FILE_PATH_SIZE] = {0};
|
||||||
res = CLIParamHexToBuf(arg_get_str(ctx, 3), nrar, sizeof(nrar), &nalen);
|
CLIParamStrToBuf(arg_get_str(ctx, 5), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
|
||||||
|
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
if (res != 0) {
|
|
||||||
|
// sanity checks
|
||||||
|
if ((use_ht1 + use_ht2 + use_hts + use_htm) > 1) {
|
||||||
|
PrintAndLogEx(ERR, "error, specify only one Hitag type");
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
if ((use_ht1 + use_ht2 + use_hts + use_htm) == 0) {
|
||||||
|
PrintAndLogEx(ERR, "error, specify one Hitag type");
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keylen != 0 && keylen != 4 && keylen != 6) {
|
||||||
|
PrintAndLogEx(WARNING, "Wrong KEY len expected 0, 4 or 6, got %d", keylen);
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
// complete options
|
||||||
|
if (keylen == 4) {
|
||||||
|
use_pwd = true;
|
||||||
|
}
|
||||||
|
if (keylen == 6) {
|
||||||
|
use_crypto = true;
|
||||||
|
}
|
||||||
|
if ((keylen == 0) && use_pwd) {
|
||||||
|
memcpy(key, "MIKR", 4);
|
||||||
|
keylen = 4;
|
||||||
|
}
|
||||||
|
if ((keylen == 0) && use_crypto) {
|
||||||
|
memcpy(key, "ONMIKR", 6);
|
||||||
|
keylen = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check coherence
|
||||||
|
uint8_t foo = (use_plain + use_pwd + use_nrar + use_crypto);
|
||||||
|
if (foo > 1) {
|
||||||
|
PrintAndLogEx(WARNING, "Specify only one authentication mode");
|
||||||
|
return PM3_EINVARG;
|
||||||
|
} else if (foo == 0) {
|
||||||
|
if (use_hts) {
|
||||||
|
use_plain = true;
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(WARNING, "Specify one authentication mode");
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_hts && use_pwd) { // not sure for the other types...
|
||||||
|
PrintAndLogEx(WARNING, "Chosen Hitag type does not have Password mode");
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_ht2 && use_plain) { // not sure for the other types...
|
||||||
|
PrintAndLogEx(WARNING, "Chosen Hitag type does not have Plain mode");
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
hitag_function htf;
|
hitag_function htf;
|
||||||
hitag_data htd;
|
hitag_data htd;
|
||||||
memset(&htd, 0, sizeof(htd));
|
memset(&htd, 0, sizeof(htd));
|
||||||
|
if (use_ht2 && use_pwd) {
|
||||||
if (keylen == 6) {
|
|
||||||
htf = RHT2F_CRYPTO;
|
|
||||||
memcpy(htd.crypto.key, key, sizeof(htd.crypto.key));
|
|
||||||
PrintAndLogEx(INFO, "Authenticating in crypto mode");
|
|
||||||
} else {
|
|
||||||
htf = RHT2F_PASSWORD;
|
htf = RHT2F_PASSWORD;
|
||||||
memcpy(htd.pwd.password, key, sizeof(htd.pwd.password));
|
memcpy(htd.pwd.password, key, sizeof(htd.pwd.password));
|
||||||
PrintAndLogEx(INFO, "Authenticating in password mode");
|
PrintAndLogEx(INFO, "Authenticating to Hitag 2 in Password mode");
|
||||||
|
} else if (use_ht2 && use_crypto) {
|
||||||
|
htf = RHT2F_CRYPTO;
|
||||||
|
memcpy(htd.crypto.key, key, sizeof(htd.crypto.key));
|
||||||
|
PrintAndLogEx(INFO, "Authenticating to Hitag 2 in Crypto mode");
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(WARNING, "Sorry, not yet implemented");
|
||||||
|
return PM3_ENOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t cmd = CMD_LF_HITAG_READER;
|
uint16_t cmd = CMD_LF_HITAG_READER;
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandMIX(cmd, htf, 0, 0, &htd, sizeof(htd));
|
SendCommandMIX(cmd, htf, 0, 0, &htd, sizeof(htd));
|
||||||
|
@ -909,7 +1109,8 @@ static int CmdLFHitag2Dump(const char *Cmd) {
|
||||||
if (data == NULL)
|
if (data == NULL)
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "Dumping tag memory...");
|
uint32_t id = bytes_to_num(resp.data.asBytes, 4);
|
||||||
|
PrintAndLogEx(SUCCESS, " UID: " _YELLOW_("%08x"), id);
|
||||||
|
|
||||||
if (fnlen < 1) {
|
if (fnlen < 1) {
|
||||||
char *fptr = filename;
|
char *fptr = filename;
|
||||||
|
@ -917,8 +1118,16 @@ static int CmdLFHitag2Dump(const char *Cmd) {
|
||||||
FillFileNameByUID(fptr, data, "-dump", 4);
|
FillFileNameByUID(fptr, data, "-dump", 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// block3, 1 byte
|
||||||
|
printHitag2Configuration(data[4 * 3]);
|
||||||
|
|
||||||
|
// print data
|
||||||
print_hex_break(data, 48, 4);
|
print_hex_break(data, 48, 4);
|
||||||
|
|
||||||
|
printHitag2PaxtonDowngrade(data);
|
||||||
|
|
||||||
|
PrintAndLogEx(SUCCESS, "Dumping tag memory...");
|
||||||
|
|
||||||
pm3_save_dump(filename, data, 48, jsfHitag, 4);
|
pm3_save_dump(filename, data, 48, jsfHitag, 4);
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -982,16 +1191,20 @@ void annotateHitagS(char *exp, size_t size, const uint8_t *cmd, uint8_t cmdsize,
|
||||||
}
|
}
|
||||||
|
|
||||||
static command_t CommandTable[] = {
|
static command_t CommandTable[] = {
|
||||||
|
{"-----------", CmdHelp, IfPm3Hitag, "------------------------ " _CYAN_("General") " ------------------------"},
|
||||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||||
{"eload", CmdLFHitagEload, IfPm3Hitag, "Load Hitag dump file into emulator memory"},
|
|
||||||
{"list", CmdLFHitagList, AlwaysAvailable, "List Hitag trace history"},
|
{"list", CmdLFHitagList, AlwaysAvailable, "List Hitag trace history"},
|
||||||
|
{"-----------", CmdHelp, IfPm3Hitag, "----------------------- " _CYAN_("operations") " -----------------------"},
|
||||||
{"info", CmdLFHitagInfo, IfPm3Hitag, "Hitag 2 tag information"},
|
{"info", CmdLFHitagInfo, IfPm3Hitag, "Hitag 2 tag information"},
|
||||||
{"reader", CmdLFHitagReader, IfPm3Hitag, "Act like a Hitag reader"},
|
|
||||||
{"sim", CmdLFHitagSim, IfPm3Hitag, "Simulate Hitag transponder"},
|
|
||||||
{"sniff", CmdLFHitagSniff, IfPm3Hitag, "Eavesdrop Hitag communication"},
|
|
||||||
{"writer", CmdLFHitagWriter, IfPm3Hitag, "Act like a Hitag writer"},
|
|
||||||
{"dump", CmdLFHitag2Dump, IfPm3Hitag, "Dump Hitag 2 tag"},
|
{"dump", CmdLFHitag2Dump, IfPm3Hitag, "Dump Hitag 2 tag"},
|
||||||
{"cc", CmdLFHitagCheckChallenges, IfPm3Hitag, "Test all challenges"},
|
{"read", CmdLFHitagReader, IfPm3Hitag, "Read Hitag memory"},
|
||||||
|
{"wrbl", CmdLFHitagWriter, IfPm3Hitag, "Write a block (page) in Hitag memory"},
|
||||||
|
{"sniff", CmdLFHitagSniff, IfPm3Hitag, "Eavesdrop Hitag communication"},
|
||||||
|
{"cc", CmdLFHitagSCheckChallenges, IfPm3Hitag, "Hitag S: test all provided challenges"},
|
||||||
|
{"ta", CmdLFHitag2CheckChallenges, IfPm3Hitag, "Hitag 2: test all recorded authentications"},
|
||||||
|
{"-----------", CmdHelp, IfPm3Hitag, "----------------------- " _CYAN_("simulation") " -----------------------"},
|
||||||
|
{"eload", CmdLFHitagEload, IfPm3Hitag, "Load Hitag dump file into emulator memory"},
|
||||||
|
{"sim", CmdLFHitagSim, IfPm3Hitag, "Simulate Hitag transponder"},
|
||||||
{ NULL, NULL, 0, NULL }
|
{ NULL, NULL, 0, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue