feat: Added support for 8268/8310

This commit is contained in:
douniwan5788 2024-09-13 16:54:07 +08:00
commit 3860942e55
4 changed files with 122 additions and 36 deletions

View file

@ -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... 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] ## [unreleased][unreleased]
- Added support for 8268/8310 (@douniwan5788)
- Changed scripting string params to accept 1024 chars, Thanks @evildaemond! (@iceman1001) - Changed scripting string params to accept 1024 chars, Thanks @evildaemond! (@iceman1001)
- Added detection for FM11NT021 (@iceman1001) - Added detection for FM11NT021 (@iceman1001)
- Added detection of a magic NTAG 215 (@iceman1001) - Added detection of a magic NTAG 215 (@iceman1001)

View file

@ -37,7 +37,19 @@
#define CRC_PRESET 0xFF #define CRC_PRESET 0xFF
#define CRC_POLYNOM 0x1D #define CRC_POLYNOM 0x1D
static struct hitagS_tag tag; static struct hitagS_tag tag = {
.pages =
{
// Plain mode: | Authentication mode:
[0] = {0x88, 0xcd, 0x6d, 0xf3}, // UID | UID
[1] = {0xca, 0x24, 0x00, 0x00}, // CON0 CON1 CON2 Reserved | CON0 CON1 CON2 PWDH0
[2] = {0xaa, 0xaa, 0xaa, 0xaa}, // Data | PWDL0 PWDL1 KEYH0 KEYH1
[3] = {0x55, 0x55, 0x55, 0x55}, // Data | KEYL0 KEYL1 KEYL2 KEYL3
[4] = {0xff, 0x80, 0x00, 0x00}, // Data
[5] = {0x00, 0x00, 0x00, 0x00}, // Data
// up to index 63 for HITAG S2048 public data
},
};
static uint8_t page_to_be_written = 0; static uint8_t page_to_be_written = 0;
static int block_data_left = 0; static int block_data_left = 0;
@ -1360,6 +1372,40 @@ static int selectHitagS(const lf_hitag_data_t *packet, uint8_t *tx, size_t sizeo
tx[i] = ((NrAr >> (56 - (i * 8))) & 0xFF); tx[i] = ((NrAr >> (56 - (i * 8))) & 0xFF);
} }
} else if (packet->cmd == RHTSF_82xx || packet->cmd == WHTSF_82xx) {
// 8268/8310 Authentication by writing password to block 64
//send write page request
txlen = 0;
cmd = HITAGS_WRITE_PAGE;
txlen = concatbits(tx, txlen, &cmd, 0, 4);
uint8_t addr = 64;
txlen = concatbits(tx, txlen, &addr, 0, 8);
crc = CRC8Hitag1Bits(tx, txlen);
txlen = concatbits(tx, txlen, &crc, 0, 8);
sendReceiveHitagS(tx, txlen, rx, sizeofrx, &rxlen, HITAG_T_WAIT_SC, ledcontrol, false);
if ((rxlen != 2) || (rx[0] >> (8 - 2) != 0x01)) {
Dbprintf("no write access on page " _YELLOW_("64") ". not 82xx?");
return -1;
}
txlen = 0;
txlen = concatbits(tx, txlen, packet->pwd, 0, 32);
crc = CRC8Hitag1Bits(tx, txlen);
txlen = concatbits(tx, txlen, &crc, 0, 8);
sendReceiveHitagS(tx, txlen, rx, sizeofrx, &rxlen, HITAG_T_WAIT_SC, ledcontrol, false);
if ((rxlen != 2) || (rx[0] >> (8 - 2) != 0x01)) {
Dbprintf("write to page " _YELLOW_("64") " failed! wrong password?");
return -1;
}
return 0;
} else if (packet->cmd == RHTSF_PLAIN || packet->cmd == WHTSF_PLAIN) { } else if (packet->cmd == RHTSF_PLAIN || packet->cmd == WHTSF_PLAIN) {
Dbprintf("Error, " _YELLOW_("AUT=1") " This tag is configured in Authentication Mode"); Dbprintf("Error, " _YELLOW_("AUT=1") " This tag is configured in Authentication Mode");
return -1; return -1;
@ -1413,19 +1459,15 @@ static int selectHitagS(const lf_hitag_data_t *packet, uint8_t *tx, size_t sizeo
* Reads every page of a hitag S transpoder. * Reads every page of a hitag S transpoder.
*/ */
void ReadHitagS(const lf_hitag_data_t *payload, bool ledcontrol) { void ReadHitagS(const lf_hitag_data_t *payload, bool ledcontrol) {
int status = PM3_SUCCESS;
uint8_t rx[HITAG_FRAME_LEN]; uint8_t rx[HITAG_FRAME_LEN];
size_t rxlen = 0; size_t rxlen = 0;
uint8_t tx[HITAG_FRAME_LEN]; uint8_t tx[HITAG_FRAME_LEN];
if (selectHitagS(payload, tx, ARRAYLEN(tx), rx, ARRAYLEN(rx), HITAG_T_WAIT_FIRST, ledcontrol) == -1) { if (selectHitagS(payload, tx, ARRAYLEN(tx), rx, ARRAYLEN(rx), HITAG_T_WAIT_FIRST, ledcontrol) == -1) {
status = PM3_ERFTRANS;
hitagS_stop_clock(); goto read_end;
set_tracing(false);
lf_finalize(ledcontrol);
reply_ng(CMD_LF_HITAGS_READ, PM3_ERFTRANS, NULL, 0);
return;
} }
int pageNum = 0; int pageNum = 0;
@ -1445,9 +1487,10 @@ void ReadHitagS(const lf_hitag_data_t *payload, bool ledcontrol) {
sendReceiveHitagS(tx, txlen, rx, ARRAYLEN(rx), &rxlen, HITAG_T_WAIT_SC, ledcontrol, false); sendReceiveHitagS(tx, txlen, rx, ARRAYLEN(rx), &rxlen, HITAG_T_WAIT_SC, ledcontrol, false);
if (rxlen == 0) { if (rxlen != 40) {
Dbprintf("Read page failed!"); Dbprintf("Read page failed!");
break; status = PM3_ERFTRANS;
goto read_end;
} }
//save received data - 40 bits //save received data - 40 bits
@ -1499,10 +1542,11 @@ void ReadHitagS(const lf_hitag_data_t *payload, bool ledcontrol) {
} }
} }
read_end:
hitagS_stop_clock(); hitagS_stop_clock();
set_tracing(false); set_tracing(false);
lf_finalize(ledcontrol); lf_finalize(ledcontrol);
reply_ng(CMD_LF_HITAGS_READ, PM3_SUCCESS, (uint8_t *)tag.pages, sizeof(tag.pages)); reply_ng(CMD_LF_HITAGS_READ, status, (uint8_t *)tag.pages, sizeof(tag.pages));
} }
/* /*

View file

@ -43,8 +43,11 @@ static int CmdLFHitagSRead(const char *Cmd) {
"Read Hitag S memory.\n\n" "Read Hitag S memory.\n\n"
" Crypto mode: \n" " Crypto mode: \n"
" - key format ISK high + ISK low\n" " - key format ISK high + ISK low\n"
" - default key 4F4E4D494B52 (ONMIKR)\n", " - default key 4F4E4D494B52 (ONMIKR)\n\n"
" lf hitag hts read -> Hitag S, plain mode\n" " 8268/8310 password mode: \n"
" - default password BBDD3399\n",
" lf hitag hts read -> Hitag S/8211, plain mode\n"
" lf hitag hts read --8 -k BBDD3399 -> 8268/8310, password mode\n"
" lf hitag hts read --nrar 0102030411223344 -> Hitag S, challenge mode\n" " lf hitag hts read --nrar 0102030411223344 -> Hitag S, challenge mode\n"
" lf hitag hts read --crypto -> Hitag S, crypto mode, def key\n" " lf hitag hts read --crypto -> Hitag S, crypto mode, def key\n"
" lf hitag hts read -k 4F4E4D494B52 -> Hitag S, crypto mode\n\n" " lf hitag hts read -k 4F4E4D494B52 -> Hitag S, crypto mode\n\n"
@ -53,8 +56,9 @@ static int CmdLFHitagSRead(const char *Cmd) {
void *argtable[] = { void *argtable[] = {
arg_param_begin, arg_param_begin,
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, "8", "8268/8310 mode"),
arg_lit0(NULL, "crypto", "crypto mode"), arg_lit0(NULL, "crypto", "crypto mode"),
arg_str0("k", "key", "<hex>", "key, 4 or 6 hex bytes"), arg_str0("k", "key", "<hex>", "pwd or key, 4 or 6 hex bytes"),
arg_param_end arg_param_end
}; };
CLIExecWithReturn(ctx, Cmd, argtable, true); CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -71,12 +75,13 @@ static int CmdLFHitagSRead(const char *Cmd) {
} }
bool use_nrar = nrar_len > 0; bool use_nrar = nrar_len > 0;
bool use_crypto = arg_get_lit(ctx, 2); bool use_82xx = arg_get_lit(ctx, 2);
bool use_crypto = arg_get_lit(ctx, 3);
uint8_t key[6]; uint8_t key[6];
int key_len = 0; int key_len = 0;
res = CLIParamHexToBuf(arg_get_str(ctx, 3), key, sizeof(key), &key_len); res = CLIParamHexToBuf(arg_get_str(ctx, 4), key, sizeof(key), &key_len);
if (res != 0) { if (res != 0) {
CLIParserFree(ctx); CLIParserFree(ctx);
return PM3_EINVARG; return PM3_EINVARG;
@ -84,8 +89,8 @@ static int CmdLFHitagSRead(const char *Cmd) {
CLIParserFree(ctx); CLIParserFree(ctx);
if (key_len && key_len != HITAGS_CRYPTOKEY_SIZE) { if (key_len != 0 && key_len != 4 && key_len != 6) {
PrintAndLogEx(WARNING, "Wrong KEY len expected %d, got %d", HITAGS_CRYPTOKEY_SIZE, key_len); PrintAndLogEx(WARNING, "Wrong KEY len expected 0, 4 or 6, got %d", key_len);
return PM3_EINVARG; return PM3_EINVARG;
} }
@ -94,13 +99,24 @@ static int CmdLFHitagSRead(const char *Cmd) {
return PM3_EINVARG; return PM3_EINVARG;
} }
if (!key_len && use_crypto) { // complete options
if (key_len == 4) {
use_82xx = true;
}
if (key_len == 6) {
use_crypto = true;
}
if ((key_len == 0) && use_82xx) {
memcpy(key, (uint8_t[]){0xBB, 0xDD, 0x33, 0x99}, 4);
key_len = 4;
}
if ((key_len == 0) && use_crypto) {
memcpy(key, "ONMIKR", 6); memcpy(key, "ONMIKR", 6);
key_len = 6; key_len = 6;
} }
// check coherence // check coherence
uint8_t auth_methods = (use_plain + use_nrar + use_crypto); uint8_t auth_methods = (use_plain + use_nrar + use_82xx + use_crypto);
if (auth_methods > 1) { if (auth_methods > 1) {
PrintAndLogEx(WARNING, "Specify only one authentication mode"); PrintAndLogEx(WARNING, "Specify only one authentication mode");
return PM3_EINVARG; return PM3_EINVARG;
@ -118,6 +134,11 @@ static int CmdLFHitagSRead(const char *Cmd) {
memcpy(packet.NrAr, nrar, sizeof(packet.NrAr)); memcpy(packet.NrAr, nrar, sizeof(packet.NrAr));
} }
if (use_82xx) {
packet.cmd = RHTSF_82xx;
memcpy(packet.pwd, key, sizeof(packet.pwd));
}
if (use_crypto) { if (use_crypto) {
packet.cmd = RHTSF_KEY; packet.cmd = RHTSF_KEY;
memcpy(packet.key, key, sizeof(packet.key)); memcpy(packet.key, key, sizeof(packet.key));
@ -168,8 +189,11 @@ static int CmdLFHitagSWrite(const char *Cmd) {
"Write a page in Hitag S memory.\n" "Write a page in Hitag S memory.\n"
" Crypto mode: \n" " Crypto mode: \n"
" - key format ISK high + ISK low\n" " - key format ISK high + ISK low\n"
" - default key 4F4E4D494B52 (ONMIKR)\n", " - default key 4F4E4D494B52 (ONMIKR)\n\n"
" lf hitag hts write -p 6 -d 01020304 -> Hitag S, plain mode\n" " 8268/8310 password mode: \n"
" - default password BBDD3399\n",
" lf hitag hts write -p 6 -d 01020304 -> Hitag S/8211, plain mode\n"
" lf hitag hts write -p 6 -d 01020304 --8 -k BBDD3399 -> 8268/8310, password mode\n"
" lf hitag hts write -p 6 -d 01020304 --nrar 0102030411223344 -> Hitag S, challenge mode\n" " lf hitag hts write -p 6 -d 01020304 --nrar 0102030411223344 -> Hitag S, challenge mode\n"
" lf hitag hts write -p 6 -d 01020304 --crypto -> Hitag S, crypto mode, default key\n" " lf hitag hts write -p 6 -d 01020304 --crypto -> Hitag S, crypto mode, default key\n"
" lf hitag hts write -p 6 -d 01020304 -k 4F4E4D494B52 -> Hitag S, crypto mode\n\n" " lf hitag hts write -p 6 -d 01020304 -k 4F4E4D494B52 -> Hitag S, crypto mode\n\n"
@ -178,8 +202,9 @@ static int CmdLFHitagSWrite(const char *Cmd) {
void *argtable[] = { void *argtable[] = {
arg_param_begin, arg_param_begin,
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, "8", "8268/8310 mode"),
arg_lit0(NULL, "crypto", "crypto mode"), arg_lit0(NULL, "crypto", "crypto mode"),
arg_str0("k", "key", "<hex>", "key, 6 hex bytes"), arg_str0("k", "key", "<hex>", "pwd or key, 4 or 6 hex bytes"),
arg_int1("p", "page", "<dec>", "page address to write to"), arg_int1("p", "page", "<dec>", "page address to write to"),
arg_str1("d", "data", "<hex>", "data, 4 hex bytes"), arg_str1("d", "data", "<hex>", "data, 4 hex bytes"),
arg_param_end arg_param_end
@ -198,23 +223,24 @@ static int CmdLFHitagSWrite(const char *Cmd) {
} }
bool use_nrar = nrar_len > 0; bool use_nrar = nrar_len > 0;
bool use_crypto = arg_get_lit(ctx, 2); bool use_82xx = arg_get_lit(ctx, 2);
bool use_crypto = arg_get_lit(ctx, 3);
uint8_t key[6]; uint8_t key[6];
int key_len = 0; int key_len = 0;
res = CLIParamHexToBuf(arg_get_str(ctx, 3), key, sizeof(key), &key_len); res = CLIParamHexToBuf(arg_get_str(ctx, 4), key, sizeof(key), &key_len);
if (res != 0) { if (res != 0) {
CLIParserFree(ctx); CLIParserFree(ctx);
return PM3_EINVARG; return PM3_EINVARG;
} }
int page = arg_get_int_def(ctx, 4, 0); int page = arg_get_int_def(ctx, 5, 0);
uint8_t data[4]; uint8_t data[4];
int data_len = 0; int data_len = 0;
res = CLIParamHexToBuf(arg_get_str(ctx, 5), data, sizeof(data), &data_len); res = CLIParamHexToBuf(arg_get_str(ctx, 6), data, sizeof(data), &data_len);
if (res != 0) { if (res != 0) {
CLIParserFree(ctx); CLIParserFree(ctx);
return PM3_EINVARG; return PM3_EINVARG;
@ -222,8 +248,8 @@ static int CmdLFHitagSWrite(const char *Cmd) {
CLIParserFree(ctx); CLIParserFree(ctx);
if (key_len && key_len != HITAGS_CRYPTOKEY_SIZE) { if (key_len != 0 && key_len != 4 && key_len != 6) {
PrintAndLogEx(WARNING, "Wrong KEY len expected %d, got %d", HITAGS_CRYPTOKEY_SIZE, key_len); PrintAndLogEx(WARNING, "Wrong KEY len expected 0, 4 or 6, got %d", key_len);
return PM3_EINVARG; return PM3_EINVARG;
} }
@ -232,13 +258,24 @@ static int CmdLFHitagSWrite(const char *Cmd) {
return PM3_EINVARG; return PM3_EINVARG;
} }
if (!key_len && use_crypto) { // complete options
if (key_len == 4) {
use_82xx = true;
}
if (key_len == 6) {
use_crypto = true;
}
if ((key_len == 0) && use_82xx) {
memcpy(key, (uint8_t[]){0xBB, 0xDD, 0x33, 0x99}, 4);
key_len = 4;
}
if ((key_len == 0) && use_crypto) {
memcpy(key, "ONMIKR", 6); memcpy(key, "ONMIKR", 6);
key_len = 6; key_len = 6;
} }
// check coherence // check coherence
uint8_t auth_methods = (use_plain + use_nrar + use_crypto); uint8_t auth_methods = (use_plain + use_nrar + use_82xx + use_crypto);
if (auth_methods > 1) { if (auth_methods > 1) {
PrintAndLogEx(WARNING, "Specify only one authentication mode"); PrintAndLogEx(WARNING, "Specify only one authentication mode");
return PM3_EINVARG; return PM3_EINVARG;
@ -257,6 +294,11 @@ static int CmdLFHitagSWrite(const char *Cmd) {
memcpy(packet.NrAr, nrar, sizeof(packet.NrAr)); memcpy(packet.NrAr, nrar, sizeof(packet.NrAr));
} }
if (use_82xx) {
packet.cmd = WHTSF_82xx;
memcpy(packet.pwd, key, sizeof(packet.pwd));
}
if (use_crypto) { if (use_crypto) {
packet.cmd = WHTSF_KEY; packet.cmd = WHTSF_KEY;
memcpy(packet.key, key, sizeof(packet.key)); memcpy(packet.key, key, sizeof(packet.key));
@ -292,10 +334,7 @@ static int CmdLFHitagSList(const char *Cmd) {
static command_t CommandTable[] = { static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"}, {"help", CmdHelp, AlwaysAvailable, "This help"},
{"list", CmdLFHitagSList, AlwaysAvailable, "List Hitag S trace history"}, {"list", CmdLFHitagSList, AlwaysAvailable, "List Hitag S trace history"},
{ {"-----------", CmdHelp, IfPm3Hitag, "----------------------- " _CYAN_("General") " ------------------------"},
"-----------", CmdHelp, IfPm3Hitag, "----------------------- " _CYAN_(
"General") " ------------------------"
},
{"read", CmdLFHitagSRead, IfPm3Hitag, "Read Hitag S memory"}, {"read", CmdLFHitagSRead, IfPm3Hitag, "Read Hitag S memory"},
{"write", CmdLFHitagSWrite, IfPm3Hitag, "Write Hitag S page"}, {"write", CmdLFHitagSWrite, IfPm3Hitag, "Write Hitag S page"},
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}

View file

@ -48,6 +48,8 @@
typedef enum { typedef enum {
RHTSF_PLAIN, RHTSF_PLAIN,
WHTSF_PLAIN, WHTSF_PLAIN,
RHTSF_82xx,
WHTSF_82xx,
RHTSF_CHALLENGE, RHTSF_CHALLENGE,
WHTSF_CHALLENGE, WHTSF_CHALLENGE,
RHTSF_KEY, RHTSF_KEY,