Merge pull request #3060 from aaronjamt/patch-seos-emu-client

[hf seos] Simulate support (2/2)
This commit is contained in:
Iceman
2025-12-23 11:07:33 +01:00
committed by GitHub
5 changed files with 130 additions and 6 deletions
+1
View File
@@ -30,6 +30,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
- Added ATR fingerprinting to `hf 14a/14b info` (@doegox)
- Added `Verkada 40-bit` format (@aaronmaxlevy)
- Added `hf seos write` command (@aaronjamt)
- Added `hf seos sim` command (@aaronjamt)
## [Phrack.4.20728][2025-09-11]
- Added `unofficial desfire bible` document (@mistial-dev)
+121
View File
@@ -1698,6 +1698,125 @@ static int CmdHfSeosADF(const char *Cmd) {
return seos_pacs((char *)oid, oid_len, data_tag, data_tag_len, key_index);
}
static int CmdHfSeosSim(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf seos sim",
"Simulate a SEOS card with the provided keys and data\n\n"
"By default:\n"
" - ADF OID : 2B0601040181E438010102011801010202\n"
" - Diversifier: 01020304050607\n"
" - Key Index : 2\n"
" - Data Tag : FF00\n"
" - Encryption : AES128\n"
" - Hashing : SHA256\n",
"hf seos sim -d 12345678\n"
"hf seos sim --ki 1\n"
"hf seos sim -o 2B0601040181E438010102011801010202 -u 01020304050607 --ki 2 -d 12345678\n"
"hf seos sim -o 2B0601040181E438010102011801010202 --legacy -t FF41 -d 12345678\n"
);
void *argtable[] = {
arg_param_begin,
arg_str0("t", "tag", "<hex>", "<0-100> hex bytes for tag to simulate (Default: FF00)"),
arg_str0("o", "oid", "<hex>", "<0-100> hex bytes for OID (Default: 2B0601040181E438010102011801010202)"),
arg_int0(NULL, "ki", "<dec>", "Specify key index to set key in memory"),
arg_str0(NULL, "div", "<hex>", "<0-16> hex bytes for diversifier (Equivalent of UID)"),
arg_str0("d", "data", "<hex>", "<0-128> hex bytes for data (Must be valid BER-TLV)"),
arg_str0("u", "uid", "<hex>", "<0-10> hex bytes for UID (Must be a RID i.e. [0]=0x08)"),
arg_lit0("l", "legacy", "Use legacy algorithms (3DES/SHA1)"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
int data_tag_len = 0;
uint8_t data_tag[16] = {0xff, 0x00};
CLIGetHexWithReturn(ctx, 1, data_tag, &data_tag_len);
int oid_len = 0;
uint8_t oid[256] = {0x2B, 0x06, 0x01, 0x04, 0x01, 0x81, 0xE4, 0x38, 0x01, 0x01, 0x02, 0x01, 0x18, 0x01, 0x01, 0x02, 0x02};
CLIGetHexWithReturn(ctx, 2, oid, &oid_len);
int key_index = arg_get_int_def(ctx, 3, 2);
int diversifier_len = 0;
uint8_t diversifier[256] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
CLIGetHexWithReturn(ctx, 4, diversifier, &diversifier_len);
int data_len = 0;
uint8_t data[256] = {};
CLIGetHexWithReturn(ctx, 5, data, &data_len);
int uid_len = 0;
uint8_t uid[10] = {0x08, 0x01, 0x02, 0x03};
CLIGetHexWithReturn(ctx, 6, uid, &uid_len);
uint8_t encryption_algorithm = SEOS_ENCRYPTION_AES;
uint8_t hashing_algorithm = SEOS_HASHING_SHA256;
if (arg_get_lit(ctx, 7)) { // legacy algorithms
encryption_algorithm = SEOS_ENCRYPTION_2K3DES,
hashing_algorithm = SEOS_HASHING_SHA1;
}
CLIParserFree(ctx);
// Fall back to default values
if (data_tag_len == 0) {
data_tag_len = 2;
}
if (oid_len == 0) {
oid_len = 17;
}
if (diversifier_len == 0) {
diversifier_len = 7;
}
if (uid_len == 0) {
uid_len = 4;
}
if (data_len == 0) {
PrintAndLogEx(ERR, "Data to simulate must be supplied");
return PM3_ESOFT;
}
seos_emulate_req_t request = {
.encr_alg = encryption_algorithm,
.hash_alg = hashing_algorithm,
.uid_len = uid_len,
.diversifier_len = diversifier_len,
.data_tag_len = data_tag_len,
.data_len = data_len,
.oid_len = oid_len,
};
// Copy all the provided values into the request object
memcpy(request.privenc, keys[key_index].privEncKey, 16);
memcpy(request.privmac, keys[key_index].privMacKey, 16);
memcpy(request.authkey, keys[key_index].readKey, 16);
memcpy(request.uid, uid, uid_len);
memcpy(request.diversifier, diversifier, diversifier_len);
memcpy(request.data_tag, data_tag, data_tag_len);
memcpy(request.data, data, data_len);
memcpy(request.oid, oid, oid_len);
PacketResponseNG resp;
clearCommandBuffer();
SendCommandNG(CMD_HF_SEOS_SIMULATE, (uint8_t*)&request, sizeof(request));
PrintAndLogEx(INFO, "Press " _GREEN_("pm3 button") " or " _GREEN_("<Enter>") " to abort simulation");
while (WaitForResponseTimeout(CMD_HF_SEOS_SIMULATE, &resp, 1000) == false) {
if (kbd_enter_pressed()) {
PrintAndLogEx(WARNING, "\naborted via keyboard.");
// inform device to break the sim loop since client has exited
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
return PM3_EOPABORTED;
}
}
return PM3_SUCCESS;
}
static int CmdHfSeosManageKeys(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf seos managekeys",
@@ -2010,6 +2129,8 @@ static command_t CommandTable[] = {
{"write", CmdHfSeosWrite, IfPm3Iso14443a, "Write an ADF to the card"},
{"adf", CmdHfSeosADF, IfPm3Iso14443a, "Read an ADF from the card"},
{"gdf", CmdHfSeosGDF, IfPm3Iso14443a, "Read an GDF from card"},
{"-----------", CmdHelp, IfPm3Seos, "---------------------- " _CYAN_("Simulation") " ---------------------"},
{"sim", CmdHfSeosSim, IfPm3Seos, "Simulate Seos tag"},
{"-----------", CmdHelp, AlwaysAvailable, "------------------------ " _CYAN_("Utils") " ------------------------"},
{"managekeys", CmdHfSeosManageKeys, AlwaysAvailable, "Manage keys to use with SEOS commands"},
{NULL, NULL, NULL, NULL}
+1 -6
View File
@@ -20,13 +20,8 @@
#define CMDHFSEOS_H__
#include "common.h"
#include "seos_cmd.h"
#define SEOS_ENCRYPTION_2K3DES 0x02
#define SEOS_ENCRYPTION_3K3DES 0x03
#define SEOS_ENCRYPTION_AES 0x09
#define SEOS_HASHING_SHA1 0x06
#define SEOS_HASHING_SHA256 0x07
int infoSeos(bool verbose);
int CmdHFSeos(const char *Cmd);
int seos_kdf(bool encryption, uint8_t *masterKey, uint8_t keyslot,
+6
View File
@@ -182,6 +182,12 @@ bool IfPm3Iclass(void) {
return g_pm3_capabilities.compiled_with_iclass;
}
bool IfPm3Seos(void) {
if (IfPm3Present() == false)
return false;
return g_pm3_capabilities.compiled_with_seos;
}
bool IfPm3NfcBarcode(void) {
if (IfPm3Present() == false)
return false;
+1
View File
@@ -54,6 +54,7 @@ bool IfPm3Iso15693(void);
bool IfPm3Felica(void);
bool IfPm3Legicrf(void);
bool IfPm3Iclass(void);
bool IfPm3Seos(void);
bool IfPm3NfcBarcode(void);
bool IfPm3Lcd(void);
bool IfPm3Zx8211(void);