This commit is contained in:
iceman1001 2025-08-29 14:01:34 +02:00
parent 2602661435
commit d6aeda7075
4 changed files with 316 additions and 175 deletions

View file

@ -91,25 +91,25 @@ static const uint8_t c_aEncode[256] = {
};
uint8_t magic_table[192] = {
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0xF0, 0x57, 0xB3, 0x9E, 0xE3, 0xD8,
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0x96, 0x9D, 0x95, 0x4A, 0xC1, 0x57,
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0x8F, 0x43, 0x58, 0x0D, 0x2C, 0x9D,
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0xFF, 0xCC, 0xE0, 0x05, 0x0C, 0x43,
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0x34, 0x1B, 0x15, 0xA6, 0x90, 0xCC,
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0x89, 0x58, 0x56, 0x12, 0xE7, 0x1B,
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0xBB, 0x74, 0xB0, 0x95, 0x36, 0x58,
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0xFB, 0x97, 0xF8, 0x4B, 0x5B, 0x74,
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0xC9, 0xD1, 0x88, 0x35, 0x9F, 0x92,
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0x8F, 0x92, 0xE9, 0x7F, 0x58, 0x97,
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0x16, 0x6C, 0xA2, 0xB0, 0x9F, 0xD1,
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0x27, 0xDD, 0x93, 0x10, 0x1C, 0x6C,
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0xDA, 0x3E, 0x3F, 0xD6, 0x49, 0xDD,
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0x58, 0xDD, 0xED, 0x07, 0x8E, 0x3E,
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0x5C, 0xD0, 0x05, 0xCF, 0xD9, 0x07,
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0x11, 0x8D, 0xD0, 0x01, 0x87, 0xD0
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0xF0, 0x57, 0xB3, 0x9E, 0xE3, 0xD8,
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0x96, 0x9D, 0x95, 0x4A, 0xC1, 0x57,
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0x8F, 0x43, 0x58, 0x0D, 0x2C, 0x9D,
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0xFF, 0xCC, 0xE0, 0x05, 0x0C, 0x43,
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0x34, 0x1B, 0x15, 0xA6, 0x90, 0xCC,
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0x89, 0x58, 0x56, 0x12, 0xE7, 0x1B,
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0xBB, 0x74, 0xB0, 0x95, 0x36, 0x58,
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0xFB, 0x97, 0xF8, 0x4B, 0x5B, 0x74,
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0xC9, 0xD1, 0x88, 0x35, 0x9F, 0x92,
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0x8F, 0x92, 0xE9, 0x7F, 0x58, 0x97,
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0x16, 0x6C, 0xA2, 0xB0, 0x9F, 0xD1,
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0x27, 0xDD, 0x93, 0x10, 0x1C, 0x6C,
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0xDA, 0x3E, 0x3F, 0xD6, 0x49, 0xDD,
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0x58, 0xDD, 0xED, 0x07, 0x8E, 0x3E,
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0x5C, 0xD0, 0x05, 0xCF, 0xD9, 0x07,
0x00, 0x00, 0xAA, 0x00, 0x00, 0x00, 0x11, 0x8D, 0xD0, 0x01, 0x87, 0xD0
};
static const char* level_names[] = {
static const char *level_names[] = {
"Guest Key", // Index 0
"Connectors", // Index 1
"Suite", // Index 2
@ -133,7 +133,7 @@ static int CmdHelp(const char *Cmd);
static void saflok_decrypt(uint8_t *strCard, int length, uint8_t *decryptedCard) {
for (int i = 0; i < length; i++) {
for (int i = 0; i < length; i++) {
int num = c_aDecode[strCard[i]] - (i + 1);
if (num < 0) {
num += 256;
@ -218,15 +218,15 @@ static void insert_bits(uint8_t *data, size_t start_bit, size_t num_bits, uint32
for (size_t i = 0; i < num_bits; i++) {
size_t current_bit = start_bit + i;
size_t byte_index = current_bit / 8;
size_t bit_index = 7 - (current_bit % 8);
size_t bit_index = 7 - (current_bit % 8);
uint32_t bit_value = (value >> (num_bits - 1 - i)) & 1U;
data[byte_index] = (data[byte_index] & ~(1 << bit_index)) | (bit_value << bit_index);
}
}
static char* bytes_to_hex(const uint8_t *data, size_t len) {
static char *bytes_to_hex(const uint8_t *data, size_t len) {
static char buf[256];
for (size_t i = 0; i < len; i++) {
sprintf(buf + (i * 2), "%02X", data[i]);
@ -236,37 +236,37 @@ static char* bytes_to_hex(const uint8_t *data, size_t len) {
}
static int pack_datetime_expr(char* exp_datetime, uint8_t* data) {
static int pack_datetime_expr(char *exp_datetime, uint8_t *data) {
int year, month, day, hour, minute;
if (sscanf(exp_datetime, "%4d-%2d-%2dT%2d:%2d",
if (sscanf(exp_datetime, "%4d-%2d-%2dT%2d:%2d",
&year, &month, &day, &hour, &minute) != 5) {
return -1;
}
data[8] = ((year & 0x0F) << 4) | (month & 0x0F);
data[9] = ((day & 0x1F) << 3) | ((hour & 0x1C) >> 2);
data[10] = ((hour & 0x03) << 6) | (minute & 0x3F);
return 0;
return 0;
}
static int pack_datetime(char* datetime_str, uint8_t* data) {
static int pack_datetime(char *datetime_str, uint8_t *data) {
int year, month, day, hour, minute;
if (sscanf(datetime_str, "%4d-%2d-%2dT%2d:%2d",
if (sscanf(datetime_str, "%4d-%2d-%2dT%2d:%2d",
&year, &month, &day, &hour, &minute) != 5) {
return -1;
return -1;
}
uint8_t year_offset = year - 1980;
data[11] = ((year_offset & 0x0F) << 4) | (month & 0x0F);
data[12] = ((day & 0x1F) << 3) | ((hour & 0x1C) >> 2);
data[13] = ((hour & 0x03) << 6) | (minute & 0x3F);
data[14] = (data[14] & 0x0F) | ((year_offset & 0x70) << 0);
return 0;
return 0;
}
@ -279,7 +279,7 @@ static uint8_t saflok_checksum(unsigned char *data, int length) {
return sum & 0xFF;
}
static void saflok_kdf(const uint8_t* uid, uint8_t* key_out) {
static void saflok_kdf(const uint8_t *uid, uint8_t *key_out) {
uint8_t magic_byte = (uid[3] >> 4) + (uid[2] >> 4) + (uid[0] & 0x0F);
uint8_t magickal_index = (magic_byte & 0x0F) * 12 + 11;
@ -321,7 +321,7 @@ static void saflok_decode(uint8_t *data) {
uint8_t creation_year_bits = (data[14] & 0xF0);
uint16_t creation_year =
(creation_year_bits | ((data[11] & 0xF0) >> 4)) + 1980;
(creation_year_bits | ((data[11] & 0xF0) >> 4)) + 1980;
uint8_t creation_month = data[11] & 0x0F;
uint8_t creation_day = (data[12] >> 3) & 0x1F;
uint8_t creation_hour = ((data[12] & 0x07) << 2) | (data[13] >> 6);
@ -334,26 +334,26 @@ static void saflok_decode(uint8_t *data) {
uint8_t expire_minute = interval_minute;
// Handle month rollover
while(expire_month > 12) {
while (expire_month > 12) {
expire_month -= 12;
expire_year++;
}
// Handle day rollover
static const uint8_t days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
while(true) {
while (true) {
uint8_t max_days = days_in_month[expire_month - 1];
// Adjust for leap years
if(expire_month == 2 &&
(expire_year % 4 == 0 && (expire_year % 100 != 0 || expire_year % 400 == 0))) {
if (expire_month == 2 &&
(expire_year % 4 == 0 && (expire_year % 100 != 0 || expire_year % 400 == 0))) {
max_days = 29;
}
if(expire_day <= max_days) {
if (expire_day <= max_days) {
break;
}
expire_day -= max_days;
expire_month++;
if(expire_month > 12) {
if (expire_month > 12) {
expire_month = 1;
expire_year++;
}
@ -369,19 +369,19 @@ static void saflok_decode(uint8_t *data) {
PrintAndLogEx(SUCCESS, "Deadbolt Override: " _GREEN_("%u"), deadbolt_override);
PrintAndLogEx(SUCCESS, "Restricted Days: " _GREEN_("%u"), restricted_days);
PrintAndLogEx(SUCCESS, "Card Creation Date: " _GREEN_("%u-%02d-%02d %02d:%02d"),
creation_year,
creation_month,
creation_day,
creation_hour,
creation_minute);
creation_year,
creation_month,
creation_day,
creation_hour,
creation_minute);
PrintAndLogEx(SUCCESS, "Expire Date: " _GREEN_("%u-%02d-%02d %02d:%02d"),
expire_year,
expire_month,
expire_day,
expire_hour,
expire_minute);
expire_year,
expire_month,
expire_day,
expire_hour,
expire_minute);
PrintAndLogEx(SUCCESS, "Property ID: " _GREEN_("%u"), property_id);
PrintAndLogEx(SUCCESS, "Checksum: " _GREEN_("0x%X") " (%s)", checksum,(checksum == saflok_checksum(data, 16)) ? _GREEN_("ok") : _RED_("bad"));
PrintAndLogEx(SUCCESS, "Checksum: " _GREEN_("0x%X") " (%s)", checksum, (checksum == saflok_checksum(data, 16)) ? _GREEN_("ok") : _RED_("bad"));
PrintAndLogEx(NORMAL, "");
}
@ -390,7 +390,7 @@ static void saflok_encode(uint8_t *data, uint32_t card_level, uint32_t card_type
uint32_t opening_key, uint32_t lock_id, uint32_t pass_number,
uint32_t sequence_and_combination, uint32_t deadbolt_override,
uint32_t restricted_days, uint32_t expire_date, uint32_t card_creation_date,
uint32_t property_id, char* dt_e, char* dt) {
uint32_t property_id, char *dt_e, char *dt) {
insert_bits(data, 0, 4, card_level);
insert_bits(data, 4, 4, card_type);
insert_bits(data, 8, 8, card_id);
@ -401,23 +401,23 @@ static void saflok_encode(uint8_t *data, uint32_t card_level, uint32_t card_type
insert_bits(data, 56, 1, deadbolt_override);
insert_bits(data, 57, 7, restricted_days);
insert_bits(data, 64, 24, expire_date);
insert_bits(data, 88, 28,card_creation_date);
insert_bits(data, 88, 28, card_creation_date);
insert_bits(data, 116, 12, property_id);
int year, month, day, hour, minute;
if (sscanf(dt, "%4d-%2d-%2dT%2d:%2d",
if (sscanf(dt, "%4d-%2d-%2dT%2d:%2d",
&year, &month, &day, &hour, &minute) == 5) {
pack_datetime(dt,data);
pack_datetime(dt, data);
}
//else{
//insert_bits(data, 88, 28,card_creation_date);
//PrintAndLogEx(SUCCESS, "DT BITS INSERTED");
//}
if (sscanf(dt_e, "%4d-%2d-%2dT%2d:%2d",
if (sscanf(dt_e, "%4d-%2d-%2dT%2d:%2d",
&year, &month, &day, &hour, &minute) == 5) {
pack_datetime_expr(dt_e,data);
pack_datetime_expr(dt_e, data);
}
//else{
//insert_bits(data, 64, 24, expire_date);
@ -514,8 +514,8 @@ static int CmdHFSaflokEncode(const char *Cmd) {
CLIExecWithReturn(ctx, Cmd, argtable, true);
uint8_t rsaflokdata[17]={0};
uint8_t esaflokdata[17]={0};
uint8_t rsaflokdata[17] = {0};
uint8_t esaflokdata[17] = {0};
int slen = 0;
char dt[100];
@ -525,23 +525,23 @@ static int CmdHFSaflokEncode(const char *Cmd) {
CLIParamStrToBuf(arg_get_str(ctx, 10), (uint8_t *)dt_e, 100, &slen);
saflok_encode(rsaflokdata,
arg_get_u32_def(ctx, 1, 0),
arg_get_u32_def(ctx, 2, 0),
arg_get_u32_def(ctx, 3, 0),
arg_get_u32_def(ctx, 4, 0),
arg_get_u32_def(ctx, 5, 0),
arg_get_u32_def(ctx, 6, 0),
arg_get_u32_def(ctx, 7, 0),
arg_get_u32_def(ctx, 8, 0),
arg_get_u32_def(ctx, 9, 0),
0,
0,
arg_get_u32_def(ctx, 12, 0),
dt_e,
dt);
saflok_encode(rsaflokdata,
arg_get_u32_def(ctx, 1, 0),
arg_get_u32_def(ctx, 2, 0),
arg_get_u32_def(ctx, 3, 0),
arg_get_u32_def(ctx, 4, 0),
arg_get_u32_def(ctx, 5, 0),
arg_get_u32_def(ctx, 6, 0),
arg_get_u32_def(ctx, 7, 0),
arg_get_u32_def(ctx, 8, 0),
arg_get_u32_def(ctx, 9, 0),
0,
0,
arg_get_u32_def(ctx, 12, 0),
dt_e,
dt);
saflok_encrypt(rsaflokdata,17,esaflokdata);
saflok_encrypt(rsaflokdata, 17, esaflokdata);
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "--- " _CYAN_("Encoded Card Data"));
@ -573,8 +573,8 @@ static int CmdHFSaflokDecode(const char *Cmd) {
if (dlen != 17) {
PrintAndLogEx(WARNING, "saflok data must include 17 HEX bytes. Got %i", dlen);
return PM3_EINVARG;
PrintAndLogEx(WARNING, "saflok data must include 17 HEX bytes. Got %i", dlen);
return PM3_EINVARG;
}
saflok_decrypt(saflokdata, 17, dsaflokdata);
@ -614,14 +614,14 @@ static int CmdHFSaflokModify(const char *Cmd) {
uint8_t user_saflokdata[17];
uint8_t rsaflokdata[17];
uint8_t esaflokdata[17]={0};
uint8_t esaflokdata[17] = {0};
int dlen;
CLIGetHexWithReturn(ctx, 13, user_saflokdata, &dlen);
if (dlen != 17) {
PrintAndLogEx(WARNING, "block data must include 17 HEX bytes. Got %i", dlen);
return PM3_EINVARG;
PrintAndLogEx(WARNING, "block data must include 17 HEX bytes. Got %i", dlen);
return PM3_EINVARG;
}
saflok_decrypt(user_saflokdata, 17, rsaflokdata);
@ -671,23 +671,23 @@ static int CmdHFSaflokModify(const char *Cmd) {
CLIParamStrToBuf(arg_get_str(ctx, 10), (uint8_t *)dt_e, 100, &slen2);
saflok_encode(rsaflokdata,
card_level,
card_type,
card_id,
opening_key,
lock_id,
pass_number,
sequence_and_combination,
deadbolt_override,
restricted_days,
expire_date,
card_creation_date,
property_id,
dt_e,
dt);
card_level,
card_type,
card_id,
opening_key,
lock_id,
pass_number,
sequence_and_combination,
deadbolt_override,
restricted_days,
expire_date,
card_creation_date,
property_id,
dt_e,
dt);
saflok_encrypt(rsaflokdata,17,esaflokdata);
saflok_encrypt(rsaflokdata, 17, esaflokdata);
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "--- " _CYAN_("Modified Card Data"));
@ -717,7 +717,7 @@ static int CmdHFSaflokEncrypt(const char *Cmd) {
int len;
CLIGetHexWithReturn(ctx, 1, raw, &len);
if(len != 17) {
if (len != 17) {
PrintAndLogEx(WARNING, "Expected 17 bytes. Got %d.", len);
CLIParserFree(ctx);
return PM3_EINVARG;
@ -748,7 +748,7 @@ static int CmdHFSaflokDecrypt(const char *Cmd) {
int len;
CLIGetHexWithReturn(ctx, 1, encrypted, &len);
if(len != 17) {
if (len != 17) {
PrintAndLogEx(WARNING, "Expected 17 bytes. Got %d.", len);
CLIParserFree(ctx);
return PM3_EINVARG;
@ -774,18 +774,18 @@ static int CmdHFSaflokChecksum(const char *Cmd) {
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
uint8_t data[17];
int len;
CLIGetHexWithReturn(ctx, 1, data, &len);
if(len != 16) {
if (len != 16) {
PrintAndLogEx(WARNING, "Expected 16 bytes. Got %d.", len);
CLIParserFree(ctx);
return PM3_EINVARG;
}
data[16] = saflok_checksum(data, 16);
data[16] = saflok_checksum(data, 16);
PrintAndLogEx(SUCCESS, "Block + checksum: " _GREEN_("%s"), bytes_to_hex(data, 17));
PrintAndLogEx(SUCCESS, "Checksum byte: " _GREEN_("0x%02X"), data[16]);
@ -794,13 +794,13 @@ static int CmdHFSaflokChecksum(const char *Cmd) {
return PM3_SUCCESS;
}
static int CmdHFSaflokProvision(const char* Cmd) {
CLIParserContext* ctx;
static int CmdHFSaflokProvision(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf saflok provision",
"Provision a Saflok card",
"hf saflok provision -d <17-byte encrypted hex block>");
"Provision a Saflok card",
"hf saflok provision -d <17-byte encrypted hex block>");
void* argtable[] = {
void *argtable[] = {
arg_param_begin,
arg_str1("d", NULL, "data", "17-byte block"),
arg_param_end,
@ -871,7 +871,7 @@ static int CmdHFSaflokProvision(const char* Cmd) {
set_keys = 1;
}
if(set_keys){
if (set_keys) {
uint8_t trailer7[16] = {
0x2A, 0x2C, 0x13, 0xCC, 0x24, 0x2A,
0xFF, 0x07, 0x80, 0x69,
@ -892,17 +892,17 @@ static int CmdHFSaflokProvision(const char* Cmd) {
return PM3_SUCCESS;
}
static int CmdHFSaflokInterrogate(const char* Cmd) {
CLIParserContext* ctx;
static int CmdHFSaflokInterrogate(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf saflok interrogate",
"Interrogate Saflok card",
"hf saflok interrogate");
void* argtable[] = {
void *argtable[] = {
arg_param_begin,
arg_param_end,
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
@ -927,7 +927,7 @@ static int CmdHFSaflokInterrogate(const char* Cmd) {
uint8_t control_byte = block2[5];
uint8_t subblock_stop = (control_byte >> 3);
if(subblock_stop == 0) {
if (subblock_stop == 0) {
CLIParserFree(ctx);
return PM3_EINVARG;
}
@ -937,7 +937,7 @@ static int CmdHFSaflokInterrogate(const char* Cmd) {
int total_bytes = 0;
while (1) {
int current_subblocks = (current_block-16) * 2;
int current_subblocks = (current_block - 16) * 2;
if (current_subblocks >= subblock_stop) break;
if (current_block % 4 == 3) {
@ -954,15 +954,14 @@ static int CmdHFSaflokInterrogate(const char* Cmd) {
current_block++;
}
if(subblock_stop % 2 != 0){
total_bytes-=8;
if (subblock_stop % 2 != 0) {
total_bytes -= 8;
}
if(total_bytes>0){
if (total_bytes > 0) {
PrintAndLogEx(SUCCESS, "Card has variable keys to the following locks:");
}
else{
} else {
PrintAndLogEx(SUCCESS, "Card has no variable keys");
}
int cursor = 0;
@ -988,13 +987,13 @@ static command_t CommandTable[] = {
{"modify", CmdHFSaflokModify, AlwaysAvailable, "Modify Saflok card data"},
{"encrypt", CmdHFSaflokEncrypt, AlwaysAvailable, "Encrypt 17-byte decrypted block"},
{"decrypt", CmdHFSaflokDecrypt, AlwaysAvailable, "Decrypt 17-byte encrypted block"},
{"interrogate", CmdHFSaflokInterrogate,IfPm3NfcBarcode, "Interrogate saflok card"},
{"interrogate", CmdHFSaflokInterrogate, IfPm3NfcBarcode, "Interrogate saflok card"},
{"cksum", CmdHFSaflokChecksum, IfPm3NfcBarcode, "Generate checksum for data block"},
{NULL, NULL, NULL, NULL}
};
static int CmdHelp(const char *Cmd) {
(void)Cmd;
(void)Cmd;
CmdsHelp(CommandTable);
return PM3_SUCCESS;
}

View file

@ -477,7 +477,6 @@ const static vocabulary_t vocabulary[] = {
{ 0, "hf mfdes getkeyversions" },
{ 0, "hf mfdes getfileids" },
{ 0, "hf mfdes getfileisoids" },
{ 0, "hf mfdes lsfile" },
{ 0, "hf mfdes lsfiles" },
{ 0, "hf mfdes dump" },
{ 0, "hf mfdes createfile" },
@ -501,6 +500,16 @@ const static vocabulary_t vocabulary[] = {
{ 0, "hf ntag424 getfs" },
{ 0, "hf ntag424 changefs" },
{ 0, "hf ntag424 changekey" },
{ 1, "hf saflok help" },
{ 0, "hf saflok read" },
{ 0, "hf saflok provision" },
{ 1, "hf saflok encode" },
{ 1, "hf saflok decode" },
{ 1, "hf saflok modify" },
{ 1, "hf saflok encrypt" },
{ 1, "hf saflok decrypt" },
{ 0, "hf saflok interrogate" },
{ 0, "hf saflok cksum" },
{ 1, "hf seos help" },
{ 1, "hf seos list" },
{ 0, "hf seos sam" },

View file

@ -3237,7 +3237,7 @@
},
"hf help": {
"command": "hf help",
"description": "-------- ----------------------- High Frequency ----------------------- 14a { ISO14443A RFIDs... } 14b { ISO14443B RFIDs... } 15 { ISO15693 RFIDs... } cipurse { Cipurse transport Cards... } epa { German Identification Card... } emrtd { Machine Readable Travel Document... } felica { ISO18092 / FeliCa RFIDs... } fido { FIDO and FIDO2 authenticators... } fudan { Fudan RFIDs... } gallagher { Gallagher DESFire RFIDs... } iclass { ICLASS RFIDs... } ict { ICT MFC/DESfire RFIDs... } jooki { Jooki RFIDs... } ksx6924 { KS X 6924 (T-Money, Snapper+) RFIDs } legic { LEGIC RFIDs... } lto { LTO Cartridge Memory RFIDs... } mf { MIFARE RFIDs... } mfp { MIFARE Plus RFIDs... } mfu { MIFARE Ultralight RFIDs... } mfdes { MIFARE Desfire RFIDs... } ntag424 { NXP NTAG 4242 DNA RFIDs... } seos { SEOS RFIDs... } st25ta { ST25TA RFIDs... } tesla { TESLA Cards... } texkom { Texkom RFIDs... } thinfilm { Thinfilm RFIDs... } topaz { TOPAZ (NFC Type 1) RFIDs... } vas { Apple Value Added Service... } waveshare { Waveshare NFC ePaper... } xerox { Fuji/Xerox cartridge RFIDs... } ----------- --------------------- General --------------------- help This help list List protocol data in trace buffer search Search for known HF tags --------------------------------------------------------------------------------------- hf list available offline: yes Alias of `trace list -t raw` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol",
"description": "-------- ----------------------- High Frequency ----------------------- 14a { ISO14443A RFIDs... } 14b { ISO14443B RFIDs... } 15 { ISO15693 RFIDs... } cipurse { Cipurse transport Cards... } epa { German Identification Card... } emrtd { Machine Readable Travel Document... } felica { ISO18092 / FeliCa RFIDs... } fido { FIDO and FIDO2 authenticators... } fudan { Fudan RFIDs... } gallagher { Gallagher DESFire RFIDs... } iclass { ICLASS RFIDs... } ict { ICT MFC/DESfire RFIDs... } jooki { Jooki RFIDs... } ksx6924 { KS X 6924 (T-Money, Snapper+) RFIDs } legic { LEGIC RFIDs... } lto { LTO Cartridge Memory RFIDs... } mf { MIFARE RFIDs... } mfp { MIFARE Plus RFIDs... } mfu { MIFARE Ultralight RFIDs... } mfdes { MIFARE Desfire RFIDs... } ntag424 { NXP NTAG 4242 DNA RFIDs... } saflok { Saflok MFC RFIDs... } seos { SEOS RFIDs... } st25ta { ST25TA RFIDs... } tesla { TESLA Cards... } texkom { Texkom RFIDs... } thinfilm { Thinfilm RFIDs... } topaz { TOPAZ (NFC Type 1) RFIDs... } vas { Apple Value Added Service... } waveshare { Waveshare NFC ePaper... } xerox { Fuji/Xerox cartridge RFIDs... } ----------- --------------------- General --------------------- help This help list List protocol data in trace buffer search Search for known HF tags --------------------------------------------------------------------------------------- hf list available offline: yes Alias of `trace list -t raw` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol",
"notes": [
"hf list --frame -> show frame delay times",
"hf list -1 -> use trace buffer"
@ -5344,8 +5344,8 @@
"notes": [
"hf mf ndefread -> shows NDEF parsed data",
"hf mf ndefread -vv -> shows NDEF parsed and raw data",
"hf mf ndefread --aid e103 -k ffffffffffff -b -> shows NDEF data with custom AID, key and with key B",
"hf mf ndefread -f myfilename -> save raw NDEF to file"
"hf mf ndefread -f myfilename -> save raw NDEF to file",
"hf mf ndefread --aid e103 -k ffffffffffff -b -> shows NDEF data with custom AID, key and with key B"
],
"offline": false,
"options": [
@ -5354,9 +5354,10 @@
"--aid <aid> replace default aid for NDEF",
"-k, --key <key> replace default key for NDEF",
"-b, --keyb use key B for access sectors (by default: key A)",
"-f, --file <fn> save raw NDEF to file"
"-f, --file <fn> save raw NDEF to file",
"--override override failed crc check"
],
"usage": "hf mf ndefread [-hvb] [--aid <aid>] [-k <key>] [-f <fn>]"
"usage": "hf mf ndefread [-hvb] [--aid <aid>] [-k <key>] [-f <fn>] [--override]"
},
"hf mf ndefwrite": {
"command": "hf mf ndefwrite",
@ -6552,34 +6553,6 @@
],
"usage": "hf mfdes lsapp [-hav] [-n <dec>] [-t <DES|2TDEA|3TDEA|AES>] [-k <hex>] [--kdf <none|AN10922|gallagher>] [-i <hex>] [-m <plain|mac|encrypt>] [-c <native|niso|iso>] [--schann <d40|ev1|ev2|lrp>] [--no-auth] [--no-deep] [--files] [--dfname <hex>]"
},
"hf mfdes lsfile": {
"command": "hf mfdes lsfile",
"description": "This commands List files inside application AID / ISOID. Master key needs to be provided or flag --no-auth set (depend on cards settings).",
"notes": [
"hf mfdes lsfiles --aid 123456 -> AID 123456, list files using `default` command creds",
"hf mfdes lsfiles --isoid df01 --no-auth -> list files for DESFire light",
"hf mfdes lsfiles --dfname D2760000850100 -> select DF by name and list files"
],
"offline": false,
"options": [
"-h, --help This help",
"-a, --apdu Show APDU requests and responses",
"-v, --verbose Verbose output",
"-n, --keyno <dec> Key number",
"-t, --algo <DES|2TDEA|3TDEA|AES> Crypt algo",
"-k, --key <hex> Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)",
"--kdf <none|AN10922|gallagher> Key Derivation Function (KDF)",
"-i, --kdfi <hex> KDF input (1-31 hex bytes)",
"-m, --cmode <plain|mac|encrypt> Communicaton mode",
"-c, --ccset <native|niso|iso> Communicaton command set",
"--schann <d40|ev1|ev2|lrp> Secure channel",
"--aid <hex> Application ID (3 hex bytes, big endian)",
"--isoid <hex> Application ISO ID (ISO DF ID) (2 hex bytes, big endian)",
"--dfname <hex> Application ISO DF Name (5-16 hex bytes, big endian)",
"--no-auth Execute without authentication"
],
"usage": "hf mfdes lsfiles [-hav] [-n <dec>] [-t <DES|2TDEA|3TDEA|AES>] [-k <hex>] [--kdf <none|AN10922|gallagher>] [-i <hex>] [-m <plain|mac|encrypt>] [-c <native|niso|iso>] [--schann <d40|ev1|ev2|lrp>] [--aid <hex>] [--isoid <hex>] [--dfname <hex>] [--no-auth]"
},
"hf mfdes lsfiles": {
"command": "hf mfdes lsfiles",
"description": "This commands List files inside application AID / ISOID. Master key needs to be provided or flag --no-auth set (depend on cards settings).",
@ -7029,9 +7002,10 @@
"-k, --key <hex> Key for printing sectors",
"-b, --keyb Use key B for access printing sectors (def: key A)",
"--be (optional: BigEndian)",
"--dch Decode Card Holder information"
"--dch Decode Card Holder information",
"--override override failed crc check"
],
"usage": "hf mfp mad [-hvb] [--aid <hex>] [-k <hex>] [--be] [--dch]"
"usage": "hf mfp mad [-hvb] [--aid <hex>] [-k <hex>] [--be] [--dch] [--override]"
},
"hf mfp ndefformat": {
"command": "hf mfp ndefformat",
@ -7053,8 +7027,8 @@
"notes": [
"hf mfp ndefread",
"hf mfp ndefread -vv -> shows NDEF parsed and raw data",
"hf mfp ndefread --aid e103 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7 -> shows NDEF data with custom AID and key",
"hf mfp ndefread -f myfilename -> save raw NDEF to file"
"hf mfp ndefread -f myfilename -> save raw NDEF to file",
"hf mfp ndefread --aid e103 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7 -> shows NDEF data with custom AID and key"
],
"offline": false,
"options": [
@ -7063,9 +7037,10 @@
"--aid <aid> replace default aid for NDEF",
"-k, --key <key> replace default key for NDEF",
"-b, --keyb use key B for access sectors (by default: key A)",
"-f, --file <fn> save raw NDEF to file"
"-f, --file <fn> save raw NDEF to file",
"--override override failed crc check"
],
"usage": "hf mfp ndefread [-hvb] [--aid <aid>] [-k <key>] [-f <fn>]"
"usage": "hf mfp ndefread [-hvb] [--aid <aid>] [-k <key>] [-f <fn>] [--override]"
},
"hf mfp ndefwrite": {
"command": "hf mfp ndefwrite",
@ -7724,6 +7699,144 @@
],
"usage": "hf plot [-h]"
},
"hf saflok cksum": {
"command": "hf saflok cksum",
"description": "Generate Saflok checksum and append to block",
"notes": [
"hf saflok cksum -d <16 byte hex>"
],
"offline": false,
"options": [
"-h, --help This help",
"-d data 16-byte decrypted Saflok block"
],
"usage": "hf saflok cksum [-h] -d data"
},
"hf saflok decode": {
"command": "hf saflok decode",
"description": "Decode saflok data",
"notes": [
"hf saflok decode"
],
"offline": true,
"options": [
"-h, --help This help",
"-d data Encrypted 17 byte card data"
],
"usage": "hf saflok decode [-h] -d data"
},
"hf saflok decrypt": {
"command": "hf saflok decrypt",
"description": "Decrypt a 17-byte Saflok block",
"notes": [
"hf saflok decrypt -d <17 byte hex>"
],
"offline": true,
"options": [
"-h, --help This help",
"-d data 17-byte encrypted hex block"
],
"usage": "hf saflok decrypt [-h] -d data"
},
"hf saflok encode": {
"command": "hf saflok encode",
"description": "Encode Saflok data",
"notes": [
"hf saflok encode"
],
"offline": true,
"options": [
"-h, --help This help",
"--level <decimal> Card Level",
"--type <decimal> Card Type",
"--id <decimal> Card ID",
"--open <decimal> Opening Bits",
"--lock_id <decimal> Lock ID",
"--pass_num <decimal> Pass Number",
"--seq_combo <decimal> Sequence and Combination",
"--deadbolt <decimal> Deadbolt Override",
"--days <decimal> Restricted Days",
"--expire <YYYY-MM-DDTHH:mm> Expire Date Offset",
"--created <YYYY-MM-DDTHH:mm> Card Creation Date",
"--prop_id <decimal> Property ID"
],
"usage": "hf saflok encode [-h] --level <decimal> --type <decimal> --id <decimal> --open <decimal> --lock_id <decimal> --pass_num <decimal> --seq_combo <decimal> --deadbolt <decimal> --days <decimal> --expire <YYYY-MM-DDTHH:mm> --created <YYYY-MM-DDTHH:mm> --prop_id <decimal>"
},
"hf saflok encrypt": {
"command": "hf saflok encrypt",
"description": "Encrypt a 17-byte Saflok block",
"notes": [
"hf saflok encrypt -d <17 byte hex>"
],
"offline": true,
"options": [
"-h, --help This help",
"-d data 17-byte unencrypted hex block"
],
"usage": "hf saflok encrypt [-h] -d data"
},
"hf saflok help": {
"command": "hf saflok help",
"description": "help This help encode Encode Saflok card data decode Decode Saflok card data modify Modify Saflok card data encrypt Encrypt 17-byte decrypted block decrypt Decrypt 17-byte encrypted block --------------------------------------------------------------------------------------- hf saflok read available offline: no Read Saflok card (MIFARE Classic only)",
"notes": [
"hf saflok read"
],
"offline": true,
"options": [
"-h, --help This help"
],
"usage": "hf saflok read [-h]"
},
"hf saflok interrogate": {
"command": "hf saflok interrogate",
"description": "Interrogate Saflok card",
"notes": [
"hf saflok interrogate"
],
"offline": false,
"options": [
"-h, --help This help"
],
"usage": "hf saflok interrogate [-h]"
},
"hf saflok modify": {
"command": "hf saflok modify",
"description": "Modify Saflok card data",
"notes": [
"hf saflok modify"
],
"offline": true,
"options": [
"-h, --help This help",
"--level <decimal> Card Level",
"--type <decimal> Card Type",
"--id <decimal> Card ID",
"--open <decimal> Opening Bits",
"--lock_id <decimal> Lock ID",
"--pass_num <decimal> Pass Number",
"--seq_combo <decimal> Sequence and Combination",
"--deadbolt <decimal> Deadbolt Override",
"--days <decimal> Restricted Days",
"--expire <YYYY-MM-DDTHH:mm> Expire Date Offset",
"--created <YYYY-MM-DDTHH:mm> Card Creation Date",
"--prop_id <decimal> Property ID",
"-d data Unencrypted 17 byte card data"
],
"usage": "hf saflok modify [-h] [--level <decimal>] [--type <decimal>] [--id <decimal>] [--open <decimal>] [--lock_id <decimal>] [--pass_num <decimal>] [--seq_combo <decimal>] [--deadbolt <decimal>] [--days <decimal>] [--expire <YYYY-MM-DDTHH:mm>] [--created <YYYY-MM-DDTHH:mm>] [--prop_id <decimal>] -d data"
},
"hf saflok provision": {
"command": "hf saflok provision",
"description": "Provision a Saflok card",
"notes": [
"hf saflok provision -d <17-byte encrypted hex block>"
],
"offline": false,
"options": [
"-h, --help This help",
"-d data 17-byte block"
],
"usage": "hf saflok provision [-h] -d data"
},
"hf search": {
"command": "hf search",
"description": "Will try to find a HF read out of the unknown tag. Continues to search for all different HF protocols.",
@ -12523,9 +12636,10 @@
"-h, --help This help",
"-d, --data <hex> NDEF data to decode",
"-f, --file <fn> file to load",
"--override override failed crc check",
"-v, --verbose verbose output"
],
"usage": "nfc decode [-hv] [-d <hex>] [-f <fn>]"
"usage": "nfc decode [-hv] [-d <hex>] [-f <fn>] [--override]"
},
"nfc mf cread": {
"command": "nfc mf cread",
@ -12533,8 +12647,8 @@
"notes": [
"hf mf ndefread -> shows NDEF parsed data",
"hf mf ndefread -vv -> shows NDEF parsed and raw data",
"hf mf ndefread --aid e103 -k ffffffffffff -b -> shows NDEF data with custom AID, key and with key B",
"hf mf ndefread -f myfilename -> save raw NDEF to file"
"hf mf ndefread -f myfilename -> save raw NDEF to file",
"hf mf ndefread --aid e103 -k ffffffffffff -b -> shows NDEF data with custom AID, key and with key B"
],
"offline": false,
"options": [
@ -12543,9 +12657,10 @@
"--aid <aid> replace default aid for NDEF",
"-k, --key <key> replace default key for NDEF",
"-b, --keyb use key B for access sectors (by default: key A)",
"-f, --file <fn> save raw NDEF to file"
"-f, --file <fn> save raw NDEF to file",
"--override override failed crc check"
],
"usage": "hf mf ndefread [-hvb] [--aid <aid>] [-k <key>] [-f <fn>]"
"usage": "hf mf ndefread [-hvb] [--aid <aid>] [-k <key>] [-f <fn>] [--override]"
},
"nfc mf cwrite": {
"command": "nfc mf cwrite",
@ -12587,8 +12702,8 @@
"notes": [
"hf mfp ndefread",
"hf mfp ndefread -vv -> shows NDEF parsed and raw data",
"hf mfp ndefread --aid e103 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7 -> shows NDEF data with custom AID and key",
"hf mfp ndefread -f myfilename -> save raw NDEF to file"
"hf mfp ndefread -f myfilename -> save raw NDEF to file",
"hf mfp ndefread --aid e103 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7 -> shows NDEF data with custom AID and key"
],
"offline": false,
"options": [
@ -12597,9 +12712,10 @@
"--aid <aid> replace default aid for NDEF",
"-k, --key <key> replace default key for NDEF",
"-b, --keyb use key B for access sectors (by default: key A)",
"-f, --file <fn> save raw NDEF to file"
"-f, --file <fn> save raw NDEF to file",
"--override override failed crc check"
],
"usage": "hf mfp ndefread [-hvb] [--aid <aid>] [-k <key>] [-f <fn>]"
"usage": "hf mfp ndefread [-hvb] [--aid <aid>] [-k <key>] [-f <fn>] [--override]"
},
"nfc type1 help": {
"command": "nfc type1 help",
@ -13536,8 +13652,8 @@
}
},
"metadata": {
"commands_extracted": 780,
"commands_extracted": 788,
"extracted_by": "PM3Help2JSON v1.00",
"extracted_on": "2025-08-20T08:39:30"
"extracted_on": "2025-08-29T11:56:30"
}
}

View file

@ -672,7 +672,6 @@ Check column "offline" for their availability.
|`hf mfdes getkeyversions`|N |`Get Key Versions`
|`hf mfdes getfileids `|N |`Get File IDs list`
|`hf mfdes getfileisoids `|N |`Get File ISO IDs list`
|`hf mfdes lsfile `|N |`Show all files list`
|`hf mfdes lsfiles `|N |`Show all files list`
|`hf mfdes dump `|N |`Dump all files`
|`hf mfdes createfile `|N |`Create Standard/Backup File`
@ -706,6 +705,24 @@ Check column "offline" for their availability.
|`hf ntag424 changekey `|N |`Change key`
### hf saflok
{ Saflok MFC RFIDs... }
|command |offline |description
|------- |------- |-----------
|`hf saflok help `|Y |`This help`
|`hf saflok read `|N |`Read Saflok card`
|`hf saflok provision `|N |`Provision Saflok card`
|`hf saflok encode `|Y |`Encode Saflok card data`
|`hf saflok decode `|Y |`Decode Saflok card data`
|`hf saflok modify `|Y |`Modify Saflok card data`
|`hf saflok encrypt `|Y |`Encrypt 17-byte decrypted block`
|`hf saflok decrypt `|Y |`Decrypt 17-byte encrypted block`
|`hf saflok interrogate `|N |`Interrogate saflok card`
|`hf saflok cksum `|N |`Generate checksum for data block`
### hf seos
{ SEOS RFIDs... }