mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 22:03:42 -07:00
Merge branch 'master' into update_4x50
merged 201206
This commit is contained in:
commit
894d973d69
21 changed files with 502 additions and 410 deletions
|
@ -248,7 +248,8 @@ set (TARGET_SOURCES
|
||||||
${PM3_ROOT}/client/src/cmdlfawid.c
|
${PM3_ROOT}/client/src/cmdlfawid.c
|
||||||
${PM3_ROOT}/client/src/cmdlfcotag.c
|
${PM3_ROOT}/client/src/cmdlfcotag.c
|
||||||
${PM3_ROOT}/client/src/cmdlfdestron.c
|
${PM3_ROOT}/client/src/cmdlfdestron.c
|
||||||
${PM3_ROOT}/client/src/cmdlfem4x.c
|
${PM3_ROOT}/client/src/cmdlfem.c
|
||||||
|
${PM3_ROOT}/client/src/cmdlfem410x.c
|
||||||
${PM3_ROOT}/client/src/cmdlfem4x05.c
|
${PM3_ROOT}/client/src/cmdlfem4x05.c
|
||||||
${PM3_ROOT}/client/src/cmdlfem4x50.c
|
${PM3_ROOT}/client/src/cmdlfem4x50.c
|
||||||
${PM3_ROOT}/client/src/cmdlffdxb.c
|
${PM3_ROOT}/client/src/cmdlffdxb.c
|
||||||
|
|
|
@ -489,7 +489,8 @@ SRCS = aiddesfire.c \
|
||||||
cmdlfawid.c \
|
cmdlfawid.c \
|
||||||
cmdlfcotag.c \
|
cmdlfcotag.c \
|
||||||
cmdlfdestron.c \
|
cmdlfdestron.c \
|
||||||
cmdlfem4x.c \
|
cmdlfem.c \
|
||||||
|
cmdlfem410x.c \
|
||||||
cmdlfem4x05.c \
|
cmdlfem4x05.c \
|
||||||
cmdlfem4x50.c \
|
cmdlfem4x50.c \
|
||||||
cmdlffdxb.c \
|
cmdlffdxb.c \
|
||||||
|
|
|
@ -3,7 +3,14 @@
|
||||||
51243648
|
51243648
|
||||||
000D8787
|
000D8787
|
||||||
19920427
|
19920427
|
||||||
65857569 //chinese "handheld RFID writer" blue cloner from circa 2013 (also sold by xfpga.com)
|
# ZX-copy3 T55xx / EM4305
|
||||||
|
# ref. http://www.proxmark.org/forum/viewtopic.php?pid=40662#p40662
|
||||||
|
# default PROX
|
||||||
|
50524F58
|
||||||
|
# blue gun EM4305
|
||||||
|
F9DCEBA0
|
||||||
|
# chinese "handheld RFID writer" blue cloner from circa 2013 (also sold by xfpga.com)
|
||||||
|
65857569
|
||||||
# ref. http://kazus.ru/forums/showpost.php?p=1045937&postcount=77
|
# ref. http://kazus.ru/forums/showpost.php?p=1045937&postcount=77
|
||||||
05D73B9F
|
05D73B9F
|
||||||
# ref. http://www.proxmark.org/forum/viewtopic.php?=
|
# ref. http://www.proxmark.org/forum/viewtopic.php?=
|
||||||
|
@ -20,19 +27,10 @@ A5B4C3D2
|
||||||
00434343
|
00434343
|
||||||
44B44CAE
|
44B44CAE
|
||||||
88661858
|
88661858
|
||||||
#
|
|
||||||
# ZX-copy3 T55xx / EM4305
|
|
||||||
# ref. http://www.proxmark.org/forum/viewtopic.php?pid=40662#p40662
|
|
||||||
19920427
|
|
||||||
84AC15E2
|
|
||||||
# paxton bullit?
|
# paxton bullit?
|
||||||
575F4F4B
|
575F4F4B
|
||||||
#
|
#
|
||||||
50520901
|
50520901
|
||||||
# default PROX
|
|
||||||
50524F58
|
|
||||||
# blue gun EM4305
|
|
||||||
F9DCEBA0
|
|
||||||
# Default pwd, simple:
|
# Default pwd, simple:
|
||||||
00000000
|
00000000
|
||||||
11111111
|
11111111
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#include "comms.h"
|
#include "comms.h"
|
||||||
#include "lfdemod.h" // for demod code
|
#include "lfdemod.h" // for demod code
|
||||||
#include "loclass/cipherutils.h" // for decimating samples in getsamples
|
#include "loclass/cipherutils.h" // for decimating samples in getsamples
|
||||||
#include "cmdlfem4x.h" // askem410xdecode
|
#include "cmdlfem410x.h" // askem410xdecode
|
||||||
#include "fileutils.h" // searchFile
|
#include "fileutils.h" // searchFile
|
||||||
#include "mifare/ndef.h"
|
#include "mifare/ndef.h"
|
||||||
#include "cliparser.h"
|
#include "cliparser.h"
|
||||||
|
|
|
@ -354,7 +354,7 @@ static int CmdHFiClassSniff(const char *Cmd) {
|
||||||
WaitForResponse(CMD_HF_ICLASS_SNIFF, &resp);
|
WaitForResponse(CMD_HF_ICLASS_SNIFF, &resp);
|
||||||
|
|
||||||
PrintAndLogEx(HINT, "Try `" _YELLOW_("hf iclass list") "` to view captured tracelog");
|
PrintAndLogEx(HINT, "Try `" _YELLOW_("hf iclass list") "` to view captured tracelog");
|
||||||
PrintAndLogEx(HINT, "Try `" _YELLOW_("trace save h") "` to save tracelog for later analysing");
|
PrintAndLogEx(HINT, "Try `" _YELLOW_("trace save -f hf_iclass_mytrace") "` to save tracelog for later analysing");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,8 +371,8 @@ static int CmdHFiClassSim(const char *Cmd) {
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_int1("t", "type", NULL, "Simulation type to use"),
|
arg_int1("t", "type", "<0-4> ", "Simulation type to use"),
|
||||||
arg_str0(NULL, "csn", "<hex>", "Specify CSN as 8 bytes (16 hex symbols) to use with sim type 0"),
|
arg_str0(NULL, "csn", "<hex>", "Specify CSN as 8 hex bytes to use with sim type 0"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
@ -807,7 +807,7 @@ static int CmdHFiClassESave(const char *Cmd) {
|
||||||
saveFileJSON(filename, jsfIclass, dump, bytes, NULL);
|
saveFileJSON(filename, jsfIclass, dump, bytes, NULL);
|
||||||
free(dump);
|
free(dump);
|
||||||
|
|
||||||
PrintAndLogEx(HINT, "Try `" _YELLOW_("hf iclass readtagfile ") "` to view dump file");
|
PrintAndLogEx(HINT, "Try `" _YELLOW_("hf iclass view") "` to view dump file");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -917,7 +917,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) {
|
||||||
|
|
||||||
if (enc_data_len > 0) {
|
if (enc_data_len > 0) {
|
||||||
if (enc_data_len != 8) {
|
if (enc_data_len != 8) {
|
||||||
PrintAndLogEx(ERR, "Data must be 8 bytes (16 HEX characters)");
|
PrintAndLogEx(ERR, "Data must be 8 hex bytes (16 HEX symbols)");
|
||||||
CLIParserFree(clictx);
|
CLIParserFree(clictx);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
@ -933,7 +933,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) {
|
||||||
|
|
||||||
if (key_len > 0) {
|
if (key_len > 0) {
|
||||||
if (key_len != 16) {
|
if (key_len != 16) {
|
||||||
PrintAndLogEx(ERR, "Transport key must be 16 bytes (32 HEX characters)");
|
PrintAndLogEx(ERR, "Transport key must be 16 hex bytes (32 HEX characters)");
|
||||||
CLIParserFree(clictx);
|
CLIParserFree(clictx);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
@ -1116,7 +1116,7 @@ static int CmdHFiClassEncryptBlk(const char *Cmd) {
|
||||||
CLIParserInit(&clictx, "hf iclass encrypt",
|
CLIParserInit(&clictx, "hf iclass encrypt",
|
||||||
"3DES encrypt data\n"
|
"3DES encrypt data\n"
|
||||||
"OBS! In order to use this function, the file 'iclass_decryptionkey.bin' must reside\n"
|
"OBS! In order to use this function, the file 'iclass_decryptionkey.bin' must reside\n"
|
||||||
"in the resources directory. The file should be 16 bytes binary data",
|
"in the resources directory. The file should be 16 hex bytes of binary data",
|
||||||
"hf iclass encrypt -d 0102030405060708\n"
|
"hf iclass encrypt -d 0102030405060708\n"
|
||||||
"hf iclass encrypt -d 0102030405060708 -k 00112233445566778899AABBCCDDEEFF");
|
"hf iclass encrypt -d 0102030405060708 -k 00112233445566778899AABBCCDDEEFF");
|
||||||
|
|
||||||
|
@ -1135,7 +1135,7 @@ static int CmdHFiClassEncryptBlk(const char *Cmd) {
|
||||||
CLIGetHexWithReturn(clictx, 1, blk_data, &blk_data_len);
|
CLIGetHexWithReturn(clictx, 1, blk_data, &blk_data_len);
|
||||||
|
|
||||||
if (blk_data_len != 8) {
|
if (blk_data_len != 8) {
|
||||||
PrintAndLogEx(ERR, "Block data must be 8 bytes (16 HEX characters)");
|
PrintAndLogEx(ERR, "Block data must be 8 hex bytes (16 HEX symbols)");
|
||||||
CLIParserFree(clictx);
|
CLIParserFree(clictx);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
@ -1149,7 +1149,7 @@ static int CmdHFiClassEncryptBlk(const char *Cmd) {
|
||||||
|
|
||||||
if (key_len > 0) {
|
if (key_len > 0) {
|
||||||
if (key_len != 16) {
|
if (key_len != 16) {
|
||||||
PrintAndLogEx(ERR, "Transport key must be 16 bytes (32 HEX characters)");
|
PrintAndLogEx(ERR, "Transport key must be 16 hex ytes (32 HEX characters)");
|
||||||
CLIParserFree(clictx);
|
CLIParserFree(clictx);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
@ -1231,9 +1231,9 @@ static int CmdHFiClassDump(const char *Cmd) {
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_str0("f", "file", "<filename>", "filename to save dump to"),
|
arg_str0("f", "file", "<filename>", "filename to save dump to"),
|
||||||
arg_str0("k", "key", "<hex>", "debit key as 16 hex symbols OR NR/MAC for replay"),
|
arg_str0("k", "key", "<hex>", "debit key or NR/MAC for replay as 8 hex bytes"),
|
||||||
arg_int0(NULL, "ki", "<dec>", "debit key index to select key from memory 'hf iclass managekeys'"),
|
arg_int0(NULL, "ki", "<dec>", "debit key index to select key from memory 'hf iclass managekeys'"),
|
||||||
arg_str0(NULL, "credit", "<hex>", "credit key as 16 hex symbols"),
|
arg_str0(NULL, "credit", "<hex>", "credit key as 8 hex bytes"),
|
||||||
arg_int0(NULL, "ci", "<dec>", "credit key index to select key from memory 'hf iclass managekeys'"),
|
arg_int0(NULL, "ci", "<dec>", "credit key index to select key from memory 'hf iclass managekeys'"),
|
||||||
arg_lit0(NULL, "elite", "elite computations applied to key"),
|
arg_lit0(NULL, "elite", "elite computations applied to key"),
|
||||||
arg_lit0(NULL, "raw", "raw, the key is interpreted as raw block 3/4"),
|
arg_lit0(NULL, "raw", "raw, the key is interpreted as raw block 3/4"),
|
||||||
|
@ -1598,18 +1598,18 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) {
|
||||||
CLIParserInit(&ctx, "hf iclass wrbl",
|
CLIParserInit(&ctx, "hf iclass wrbl",
|
||||||
"Write data to an iCLASS tag",
|
"Write data to an iCLASS tag",
|
||||||
"hf iclass wrbl -b 10 -d AAAAAAAAAAAAAAAA -k 001122334455667B\n"
|
"hf iclass wrbl -b 10 -d AAAAAAAAAAAAAAAA -k 001122334455667B\n"
|
||||||
"hf iclass wrbl -b 27 -d AAAAAAAAAAAAAAAA -k 001122334455667B --credit\n"
|
"hf iclass wrbl -b 10 -d AAAAAAAAAAAAAAAA -k 001122334455667B --credit\n"
|
||||||
"hf iclass wrbl -b 11 -d AAAAAAAAAAAAAAAA --ki 0");
|
"hf iclass wrbl -b 10 -d AAAAAAAAAAAAAAAA --ki 0");
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_str0("k", "key", "<hex>", "Access key as 16 hex symbols"),
|
arg_str0("k", "key", "<hex>", "Access key as 8 hex bytes"),
|
||||||
arg_int0(NULL, "ki", "<dec>", "Key index to select key from memory 'hf iclass managekeys'"),
|
arg_int0(NULL, "ki", "<dec>", "Key index to select key from memory 'hf iclass managekeys'"),
|
||||||
arg_int1("b", "block", "<dec>", "The block number to read as an integer"),
|
arg_int1("b", "block", "<dec>", "The block number to read"),
|
||||||
arg_str1("d", "data", "<hex>", "data to write as 16 hex symbols"),
|
arg_str1("d", "data", "<hex>", "data to write as 8 hex bytes"),
|
||||||
arg_lit0(NULL, "credit", "key is assumed to be the credit key"),
|
arg_lit0(NULL, "credit", "key is assumed to be the credit key"),
|
||||||
arg_lit0(NULL, "elite", "elite computations applied to key"),
|
arg_lit0(NULL, "elite", "elite computations applied to key"),
|
||||||
arg_lit0(NULL, "raw", "no computations applied to key (raw)"),
|
arg_lit0(NULL, "raw", "no computations applied to key"),
|
||||||
arg_lit0(NULL, "nr", "replay of NR/MAC"),
|
arg_lit0(NULL, "nr", "replay of NR/MAC"),
|
||||||
arg_lit0("v", "verbose", "verbose output"),
|
arg_lit0("v", "verbose", "verbose output"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
|
@ -1657,7 +1657,7 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) {
|
||||||
CLIGetHexWithReturn(ctx, 4, data, &data_len);
|
CLIGetHexWithReturn(ctx, 4, data, &data_len);
|
||||||
|
|
||||||
if (data_len != 8) {
|
if (data_len != 8) {
|
||||||
PrintAndLogEx(ERR, "Data must be 8 bytes (16 hex characters)");
|
PrintAndLogEx(ERR, "Data must be 8 hex bytes (16 hex symbols)");
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
@ -1695,20 +1695,21 @@ static int CmdHFiClassRestore(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "hf iclass restore",
|
CLIParserInit(&ctx, "hf iclass restore",
|
||||||
"Restore data from dumpfile onto a iCLASS tag",
|
"Restore data from dumpfile onto a iCLASS tag",
|
||||||
"hf iclass restore -f hf-iclass-AA162D30F8FF12F1-dump.bin --first 06 --last 1A -k 1122334455667788 --elite\n"
|
"hf iclass restore -f hf-iclass-AA162D30F8FF12F1-dump.bin --first 6 --last 18 --ki 0\n"
|
||||||
"hf iclass restore -f hf-iclass-AA162D30F8FF12F1-dump.bin --first 05 --last 19 --ki 0\n"
|
"hf iclass restore -f hf-iclass-AA162D30F8FF12F1-dump.bin --first 6 --last 18 --ki 0 --elite"
|
||||||
"hf iclass restore -f hf-iclass-AA162D30F8FF12F1-dump.bin --first 06 --last 19 --ki 0 --elite");
|
"hf iclass restore -f hf-iclass-AA162D30F8FF12F1-dump.bin --first 6 --last 18 -k 1122334455667788 --elite\n"
|
||||||
|
);
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_str1("f", "file", "<filename>", "specify a filename to restore"),
|
arg_str1("f", "file", "<filename>", "specify a filename to restore"),
|
||||||
arg_str0("k", "key", "<hex>", "Access key as 16 hex symbols"),
|
arg_str0("k", "key", "<hex>", "Access key as 8 hex bytes"),
|
||||||
arg_int0(NULL, "ki", "<dec>", "Key index to select key from memory 'hf iclass managekeys'"),
|
arg_int0(NULL, "ki", "<dec>", "Key index to select key from memory 'hf iclass managekeys'"),
|
||||||
arg_int1(NULL, "first", "<dec>", "The first block number to restore as an integer"),
|
arg_int1(NULL, "first", "<dec>", "The first block number to restore"),
|
||||||
arg_int1(NULL, "last", "<dec>", "The last block number to restore as an integer"),
|
arg_int1(NULL, "last", "<dec>", "The last block number to restore"),
|
||||||
arg_lit0(NULL, "credit", "key is assumed to be the credit key"),
|
arg_lit0(NULL, "credit", "key is assumed to be the credit key"),
|
||||||
arg_lit0(NULL, "elite", "elite computations applied to key"),
|
arg_lit0(NULL, "elite", "elite computations applied to key"),
|
||||||
arg_lit0(NULL, "raw", "no computations applied to key (raw)"),
|
arg_lit0(NULL, "raw", "no computations applied to key"),
|
||||||
arg_lit0("v", "verbose", "verbose output"),
|
arg_lit0("v", "verbose", "verbose output"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
|
@ -1916,12 +1917,12 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) {
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_str0("k", "key", "<hex>", "Access key as 16 hex symbols"),
|
arg_str0("k", "key", "<hex>", "Access key as 8 hex bytes"),
|
||||||
arg_int0(NULL, "ki", "<dec>", "Key index to select key from memory 'hf iclass managekeys'"),
|
arg_int0(NULL, "ki", "<dec>", "Key index to select key from memory 'hf iclass managekeys'"),
|
||||||
arg_int1("b", "block", "<dec>", "The block number to read as an integer"),
|
arg_int1("b", "block", "<dec>", "The block number to read"),
|
||||||
arg_lit0(NULL, "credit", "key is assumed to be the credit key"),
|
arg_lit0(NULL, "credit", "key is assumed to be the credit key"),
|
||||||
arg_lit0(NULL, "elite", "elite computations applied to key"),
|
arg_lit0(NULL, "elite", "elite computations applied to key"),
|
||||||
arg_lit0(NULL, "raw", "no computations applied to key (raw)"),
|
arg_lit0(NULL, "raw", "no computations applied to key"),
|
||||||
arg_lit0(NULL, "nr", "replay of NR/MAC"),
|
arg_lit0(NULL, "nr", "replay of NR/MAC"),
|
||||||
arg_lit0("v", "verbose", "verbose output"),
|
arg_lit0("v", "verbose", "verbose output"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
|
@ -2232,12 +2233,12 @@ static int CmdHFiClassView(const char *Cmd) {
|
||||||
CLIParserInit(&ctx, "hf iclass view",
|
CLIParserInit(&ctx, "hf iclass view",
|
||||||
"Print a iCLASS tag dump file",
|
"Print a iCLASS tag dump file",
|
||||||
"hf iclass view -f hf-iclass-AA162D30F8FF12F1-dump.bin\n"
|
"hf iclass view -f hf-iclass-AA162D30F8FF12F1-dump.bin\n"
|
||||||
"hf iclass view --first 1 --file hf-iclass-AA162D30F8FF12F1-dump.bin\n");
|
"hf iclass view --first 1 -f hf-iclass-AA162D30F8FF12F1-dump.bin\n");
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_str1("f", "file", "<filename>", "filename of dump"),
|
arg_str1("f", "file", "<filename>", "filename of dump"),
|
||||||
arg_int0(NULL, "first", "<dec>", "Begin printing from this block (default block6)"),
|
arg_int0(NULL, "first", "<dec>", "Begin printing from this block (default block 6)"),
|
||||||
arg_int0(NULL, "last", "<dec>", "End printing at this block (default 0, ALL)"),
|
arg_int0(NULL, "last", "<dec>", "End printing at this block (default 0, ALL)"),
|
||||||
arg_lit0("v", "verbose", "verbose output"),
|
arg_lit0("v", "verbose", "verbose output"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
|
@ -2325,9 +2326,9 @@ static int CmdHFiClassCalcNewKey(const char *Cmd) {
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_str0(NULL, "old", "<hex>", "Specify key as 8 bytes (16 hex symbols)"),
|
arg_str0(NULL, "old", "<hex>", "Specify key as 8 hex bytes"),
|
||||||
arg_int0(NULL, "oki", "<dec>", "Old key index to select key from memory 'hf iclass managekeys'"),
|
arg_int0(NULL, "oki", "<dec>", "Old key index to select key from memory 'hf iclass managekeys'"),
|
||||||
arg_str0(NULL, "new", "<hex>", "Specify key as 8 bytes (16 hex symbols)"),
|
arg_str0(NULL, "new", "<hex>", "Specify key as 8 hex bytes"),
|
||||||
arg_int0(NULL, "nki", "<dec>", "New key index to select key from memory 'hf iclass managekeys'"),
|
arg_int0(NULL, "nki", "<dec>", "New key index to select key from memory 'hf iclass managekeys'"),
|
||||||
arg_str0(NULL, "csn", "<hex>", "Specify a Card Serial Number (CSN) to diversify the key (if omitted will attempt to read a CSN)"),
|
arg_str0(NULL, "csn", "<hex>", "Specify a Card Serial Number (CSN) to diversify the key (if omitted will attempt to read a CSN)"),
|
||||||
arg_lit0(NULL, "elite", "Elite computations applied to new key"),
|
arg_lit0(NULL, "elite", "Elite computations applied to new key"),
|
||||||
|
@ -2500,7 +2501,7 @@ static int CmdHFiClassManageKeys(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "hf iclass managekeys",
|
CLIParserInit(&ctx, "hf iclass managekeys",
|
||||||
"Manage iCLASS Keys in client memory",
|
"Manage iCLASS Keys in client memory",
|
||||||
"hf iclass managekeys --ki 0 -k 1122334455667788 -> set key\n"
|
"hf iclass managekeys --ki 0 -k 1122334455667788 -> set key 1122334455667788 at index 0\n"
|
||||||
"hf iclass managekeys -f mykeys.bin --save -> save key file\n"
|
"hf iclass managekeys -f mykeys.bin --save -> save key file\n"
|
||||||
"hf iclass managekeys -f mykeys.bin --load -> load key file\n"
|
"hf iclass managekeys -f mykeys.bin --load -> load key file\n"
|
||||||
"hf iclass managekeys -p -> print keys");
|
"hf iclass managekeys -p -> print keys");
|
||||||
|
@ -2508,7 +2509,7 @@ static int CmdHFiClassManageKeys(const char *Cmd) {
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_str0("f", "file", "<filename>", "Specify a filename to use with load or save operations"),
|
arg_str0("f", "file", "<filename>", "Specify a filename to use with load or save operations"),
|
||||||
arg_str0("k", "key", "<hex>", "Access key as 16 hex symbols"),
|
arg_str0("k", "key", "<hex>", "Access key as 8 hex bytes"),
|
||||||
arg_int0(NULL, "ki", "<dec>", "Specify key index to set key in memory"),
|
arg_int0(NULL, "ki", "<dec>", "Specify key index to set key in memory"),
|
||||||
arg_lit0(NULL, "save", "Save keys in memory to file specified by filename"),
|
arg_lit0(NULL, "save", "Save keys in memory to file specified by filename"),
|
||||||
arg_lit0(NULL, "load", "Load keys to memory from file specified by filename"),
|
arg_lit0(NULL, "load", "Load keys to memory from file specified by filename"),
|
||||||
|
@ -2908,10 +2909,10 @@ static int CmdHFiClassLookUp(const char *Cmd) {
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_str1("f", "file", "<filename>", "Dictionary file with default iclass keys"),
|
arg_str1("f", "file", "<filename>", "Dictionary file with default iclass keys"),
|
||||||
arg_str1(NULL, "csn", "<hex>", "Specify CSN as 8 bytes (16 hex symbols)"),
|
arg_str1(NULL, "csn", "<hex>", "Specify CSN as 8 hex bytes"),
|
||||||
arg_str1(NULL, "epurse", "<hex>", "Specify ePurse as 8 bytes (16 hex symbols)"),
|
arg_str1(NULL, "epurse", "<hex>", "Specify ePurse as 8 hex bytes"),
|
||||||
arg_str1(NULL, "macs", "<hex>", "MACs"),
|
arg_str1(NULL, "macs", "<hex>", "MACs"),
|
||||||
arg_lit0(NULL, "raw", "no computations applied to key (raw)"),
|
arg_lit0(NULL, "raw", "no computations applied to key"),
|
||||||
arg_lit0(NULL, "elite", "Elite computations applied to key"),
|
arg_lit0(NULL, "elite", "Elite computations applied to key"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
|
@ -3289,15 +3290,12 @@ static int CmdHFiClassPermuteKey(const char *Cmd) {
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_lit0("r", "reverse", "reverse permuted key"),
|
arg_lit0("r", "reverse", "reverse permuted key"),
|
||||||
arg_str1(NULL, "key", "<hex>", "input key"),
|
arg_str1(NULL, "key", "<hex>", "input key, 8 hex bytes"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
|
||||||
bool isReverse = arg_get_lit(ctx, 1);
|
bool isReverse = arg_get_lit(ctx, 1);
|
||||||
|
|
||||||
CLIGetHexWithReturn(ctx, 2, data, &len);
|
CLIGetHexWithReturn(ctx, 2, data, &len);
|
||||||
|
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
memcpy(key, data, 8);
|
memcpy(key, data, 8);
|
||||||
|
@ -3371,7 +3369,6 @@ static command_t CommandTable[] = {
|
||||||
{"managekeys", CmdHFiClassManageKeys, AlwaysAvailable, "[options..] Manage keys to use with iclass commands"},
|
{"managekeys", CmdHFiClassManageKeys, AlwaysAvailable, "[options..] Manage keys to use with iclass commands"},
|
||||||
{"permutekey", CmdHFiClassPermuteKey, IfPm3Iclass, " Permute function from 'heart of darkness' paper"},
|
{"permutekey", CmdHFiClassPermuteKey, IfPm3Iclass, " Permute function from 'heart of darkness' paper"},
|
||||||
{"view", CmdHFiClassView, AlwaysAvailable, "[options..] Display content from tag dump file"},
|
{"view", CmdHFiClassView, AlwaysAvailable, "[options..] Display content from tag dump file"},
|
||||||
|
|
||||||
{NULL, NULL, NULL, NULL}
|
{NULL, NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -12,24 +12,23 @@
|
||||||
// Low frequency commands
|
// Low frequency commands
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
#include "cmdlf.h"
|
#include "cmdlf.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "cmdparser.h" // command_t
|
#include "cmdparser.h" // command_t
|
||||||
#include "comms.h"
|
#include "comms.h"
|
||||||
#include "commonutil.h" // ARRAYLEN
|
#include "commonutil.h" // ARRAYLEN
|
||||||
|
|
||||||
#include "lfdemod.h" // device/client demods of LF signals
|
#include "lfdemod.h" // device/client demods of LF signals
|
||||||
#include "ui.h" // for show graph controls
|
#include "ui.h" // for show graph controls
|
||||||
#include "proxgui.h"
|
#include "proxgui.h"
|
||||||
|
#include "cliparser.h" // args parsing
|
||||||
#include "graph.h" // for graph data
|
#include "graph.h" // for graph data
|
||||||
#include "cmddata.h" // for `lf search`
|
#include "cmddata.h" // for `lf search`
|
||||||
#include "cmdlfawid.h" // for awid menu
|
#include "cmdlfawid.h" // for awid menu
|
||||||
#include "cmdlfem4x.h" // for em4x menu
|
#include "cmdlfem.h" // for em menu
|
||||||
|
#include "cmdlfem410x.h" // for em4x menu
|
||||||
#include "cmdlfem4x05.h" // for em4x05 / 4x69
|
#include "cmdlfem4x05.h" // for em4x05 / 4x69
|
||||||
#include "cmdlfem4x50.h" // for em4x50
|
#include "cmdlfem4x50.h" // for em4x50
|
||||||
#include "cmdlfhid.h" // for hid menu
|
#include "cmdlfhid.h" // for hid menu
|
||||||
|
@ -1530,7 +1529,7 @@ static command_t CommandTable[] = {
|
||||||
{"awid", CmdLFAWID, AlwaysAvailable, "{ AWID RFIDs... }"},
|
{"awid", CmdLFAWID, AlwaysAvailable, "{ AWID RFIDs... }"},
|
||||||
{"cotag", CmdLFCOTAG, AlwaysAvailable, "{ COTAG CHIPs... }"},
|
{"cotag", CmdLFCOTAG, AlwaysAvailable, "{ COTAG CHIPs... }"},
|
||||||
{"destron", CmdLFDestron, AlwaysAvailable, "{ FDX-A Destron RFIDs... }"},
|
{"destron", CmdLFDestron, AlwaysAvailable, "{ FDX-A Destron RFIDs... }"},
|
||||||
{"em", CmdLFEM4X, AlwaysAvailable, "{ EM4X CHIPs & RFIDs... }"},
|
{"em", CmdLFEM, AlwaysAvailable, "{ EM CHIPs & RFIDs... }"},
|
||||||
{"fdxb", CmdLFFdxB, AlwaysAvailable, "{ FDX-B RFIDs... }"},
|
{"fdxb", CmdLFFdxB, AlwaysAvailable, "{ FDX-B RFIDs... }"},
|
||||||
{"gallagher", CmdLFGallagher, AlwaysAvailable, "{ GALLAGHER RFIDs... }"},
|
{"gallagher", CmdLFGallagher, AlwaysAvailable, "{ GALLAGHER RFIDs... }"},
|
||||||
{"gproxii", CmdLFGuard, AlwaysAvailable, "{ Guardall Prox II RFIDs... }"},
|
{"gproxii", CmdLFGuard, AlwaysAvailable, "{ Guardall Prox II RFIDs... }"},
|
||||||
|
|
40
client/src/cmdlfem.c
Normal file
40
client/src/cmdlfem.c
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 2020 iceman <iceman at icesql.net>
|
||||||
|
//
|
||||||
|
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||||
|
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||||
|
// the license.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Low frequency EM4x commands
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "cmdlfem.h"
|
||||||
|
#include "cmdlfem410x.h"
|
||||||
|
#include "cmdlfem4x05.h"
|
||||||
|
#include "cmdlfem4x50.h"
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "cmdparser.h" // command_t
|
||||||
|
#include "comms.h" // clearCommandBuffer
|
||||||
|
#include "cmdlf.h"
|
||||||
|
|
||||||
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
|
static command_t CommandTable[] = {
|
||||||
|
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||||
|
{"410x", CmdLFEM410X, AlwaysAvailable, "EM 4102 commands..."},
|
||||||
|
{"4x05", CmdLFEM4X05, AlwaysAvailable, "EM 4205 / 4305 / 4369 / 4469 commands..."},
|
||||||
|
{"4x50", CmdLFEM4X50, AlwaysAvailable, "EM 4350 / 4450 commands..."},
|
||||||
|
{NULL, NULL, NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int CmdHelp(const char *Cmd) {
|
||||||
|
(void)Cmd; // Cmd is not used so far
|
||||||
|
CmdsHelp(CommandTable);
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CmdLFEM(const char *Cmd) {
|
||||||
|
clearCommandBuffer();
|
||||||
|
return CmdsParse(CommandTable, Cmd);
|
||||||
|
}
|
17
client/src/cmdlfem.h
Normal file
17
client/src/cmdlfem.h
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 2020 iceman <iceman at icesql.net>
|
||||||
|
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||||
|
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||||
|
// the license.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Low frequency EM commands
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef CMDLFEM4X_H__
|
||||||
|
#define CMDLFEM4X_H__
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
int CmdLFEM(const char *Cmd);
|
||||||
|
|
||||||
|
#endif
|
|
@ -8,8 +8,7 @@
|
||||||
// Low frequency EM4x commands
|
// Low frequency EM4x commands
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include "cmdlfem4x.h"
|
#include "cmdlfem410x.h"
|
||||||
#include "cmdlfem4x05.h"
|
|
||||||
#include "cmdlfem4x50.h"
|
#include "cmdlfem4x50.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -631,41 +630,14 @@ static int CmdEM410xClone(const char *Cmd) {
|
||||||
|
|
||||||
static command_t CommandTable[] = {
|
static command_t CommandTable[] = {
|
||||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||||
{"----------", CmdHelp, AlwaysAvailable, "----------------------- " _CYAN_("EM 410x") " -----------------------"},
|
//{"demod", CmdEMdemodASK, IfPm3Lf, "Extract ID from EM410x tag on antenna)"},
|
||||||
//{"410x_demod", CmdEMdemodASK, IfPm3Lf, "Extract ID from EM410x tag on antenna)"},
|
{"demod", CmdEM410xDemod, AlwaysAvailable, "demodulate a EM410x tag from the GraphBuffer"},
|
||||||
{"410x_demod", CmdEM410xDemod, AlwaysAvailable, "demodulate a EM410x tag from the GraphBuffer"},
|
{"read", CmdEM410xRead, IfPm3Lf, "attempt to read and extract tag data"},
|
||||||
{"410x_read", CmdEM410xRead, IfPm3Lf, "attempt to read and extract tag data"},
|
{"sim", CmdEM410xSim, IfPm3Lf, "simulate EM410x tag"},
|
||||||
{"410x_sim", CmdEM410xSim, IfPm3Lf, "simulate EM410x tag"},
|
{"brute", CmdEM410xBrute, IfPm3Lf, "reader bruteforce attack by simulating EM410x tags"},
|
||||||
{"410x_brute", CmdEM410xBrute, IfPm3Lf, "reader bruteforce attack by simulating EM410x tags"},
|
{"watch", CmdEM410xWatch, IfPm3Lf, "watches for EM410x 125/134 kHz tags (option 'h' for 134)"},
|
||||||
{"410x_watch", CmdEM410xWatch, IfPm3Lf, "watches for EM410x 125/134 kHz tags (option 'h' for 134)"},
|
{"spoof", CmdEM410xWatchnSpoof, IfPm3Lf, "watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)" },
|
||||||
{"410x_spoof", CmdEM410xWatchnSpoof, IfPm3Lf, "watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)" },
|
{"clone", CmdEM410xClone, IfPm3Lf, "write EM410x UID to T55x7 or Q5/T5555 tag"},
|
||||||
{"410x_clone", CmdEM410xClone, IfPm3Lf, "write EM410x UID to T55x7 or Q5/T5555 tag"},
|
|
||||||
{"----------", CmdHelp, AlwaysAvailable, "-------------------- " _CYAN_("EM 4x05 / 4x69") " -------------------"},
|
|
||||||
{"4x05_chk", CmdEM4x05Chk, IfPm3Lf, "Check passwords from dictionary"},
|
|
||||||
{"4x05_demod", CmdEM4x05Demod, AlwaysAvailable, "demodulate a EM4x05/EM4x69 tag from the GraphBuffer"},
|
|
||||||
{"4x05_dump", CmdEM4x05Dump, IfPm3Lf, "dump EM4x05/EM4x69 tag"},
|
|
||||||
{"4x05_wipe", CmdEM4x05Wipe, IfPm3Lf, "wipe EM4x05/EM4x69 tag"},
|
|
||||||
{"4x05_info", CmdEM4x05Info, IfPm3Lf, "tag information EM4x05/EM4x69"},
|
|
||||||
{"4x05_read", CmdEM4x05Read, IfPm3Lf, "read word data from EM4x05/EM4x69"},
|
|
||||||
{"4x05_write", CmdEM4x05Write, IfPm3Lf, "write word data to EM4x05/EM4x69"},
|
|
||||||
{"4x05_unlock", CmdEM4x05Unlock, IfPm3Lf, "execute tear off against EM4x05/EM4x69"},
|
|
||||||
{"4x05_sniff", CmdEM4x05Sniff, AlwaysAvailable, "Attempt to recover em4x05 commands from sample buffer"},
|
|
||||||
{"4x05_brute", CmdEM4x05Brute, IfPm3Lf, "Bruteforce password"},
|
|
||||||
{"----------", CmdHelp, AlwaysAvailable, "----------------------- " _CYAN_("EM 4x50") " -----------------------"},
|
|
||||||
{"4x50_dump", CmdEM4x50Dump, IfPm3EM4x50, "dump EM4x50 tag"},
|
|
||||||
{"4x50_info", CmdEM4x50Info, IfPm3EM4x50, "tag information EM4x50"},
|
|
||||||
{"4x50_write", CmdEM4x50Write, IfPm3EM4x50, "write word data to EM4x50"},
|
|
||||||
{"4x50_writepwd",CmdEM4x50WritePwd, IfPm3EM4x50, "change password of EM4x50"},
|
|
||||||
{"4x50_read", CmdEM4x50Read, IfPm3EM4x50, "read word data from EM4x50"},
|
|
||||||
{"4x50_wipe", CmdEM4x50Wipe, IfPm3EM4x50, "wipe EM4x50 tag"},
|
|
||||||
{"4x50_brute", CmdEM4x50Brute, IfPm3EM4x50, "guess password of EM4x50"},
|
|
||||||
{"4x50_login", CmdEM4x50Login, IfPm3EM4x50, "login into EM4x50"},
|
|
||||||
{"4x50_restore",CmdEM4x50Restore, IfPm3EM4x50, "restore EM4x50 dump to tag"},
|
|
||||||
{"4x50_sim", CmdEM4x50Sim, IfPm3EM4x50, "simulate EM4x50 tag"},
|
|
||||||
{"4x50_reader", CmdEM4x50Reader, IfPm3EM4x50, "show standard read mode data of EM4x50"},
|
|
||||||
{"4x50_eload", CmdEM4x50ELoad, IfPm3EM4x50, "upload dump of EM4x50 to flash memory"},
|
|
||||||
{"4x50_esave", CmdEM4x50ESave, IfPm3EM4x50, "save flash memory to file"},
|
|
||||||
{"4x50_chk", CmdEM4x50Chk, IfPm3EM4x50, "check passwords from dictionary"},
|
|
||||||
{NULL, NULL, NULL, NULL}
|
{NULL, NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -675,7 +647,7 @@ static int CmdHelp(const char *Cmd) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdLFEM4X(const char *Cmd) {
|
int CmdLFEM410X(const char *Cmd) {
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
return CmdsParse(CommandTable, Cmd);
|
return CmdsParse(CommandTable, Cmd);
|
||||||
}
|
}
|
|
@ -5,15 +5,15 @@
|
||||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||||
// the license.
|
// the license.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Low frequency EM4x commands
|
// Low frequency EM 410x commands
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifndef CMDLFEM4X_H__
|
#ifndef CMDLFEM410X_H__
|
||||||
#define CMDLFEM4X_H__
|
#define CMDLFEM410X_H__
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
int CmdLFEM4X(const char *Cmd);
|
int CmdLFEM410X(const char *Cmd);
|
||||||
|
|
||||||
int demodEM410x(bool verbose);
|
int demodEM410x(bool verbose);
|
||||||
void printEM410x(uint32_t hi, uint64_t id);
|
void printEM410x(uint32_t hi, uint64_t id);
|
|
@ -38,59 +38,7 @@
|
||||||
|
|
||||||
#define EM_PREAMBLE_LEN 8
|
#define EM_PREAMBLE_LEN 8
|
||||||
|
|
||||||
static int usage_lf_em4x05_wipe(void) {
|
static int CmdHelp(const char *Cmd);
|
||||||
PrintAndLogEx(NORMAL, "Wipe EM4x05/EM4x69. Tag must be on antenna. ");
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
|
||||||
PrintAndLogEx(NORMAL, "Usage: lf em 4x05_wipe [h] <pwd>");
|
|
||||||
PrintAndLogEx(NORMAL, "Options:");
|
|
||||||
PrintAndLogEx(NORMAL, " h - this help");
|
|
||||||
PrintAndLogEx(NORMAL, " c - chip type : 0 em4205");
|
|
||||||
PrintAndLogEx(NORMAL, " 1 em4305 (default)");
|
|
||||||
PrintAndLogEx(NORMAL, " pwd - password (hex) (optional)");
|
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
|
||||||
PrintAndLogEx(NORMAL, " lf em 4x05_wipe");
|
|
||||||
PrintAndLogEx(NORMAL, " lf em 4x05_wipe 11223344");
|
|
||||||
return PM3_SUCCESS;
|
|
||||||
}
|
|
||||||
static int usage_lf_em4x05_read(void) {
|
|
||||||
PrintAndLogEx(NORMAL, "Read EM4x05/EM4x69. Tag must be on antenna. ");
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
|
||||||
PrintAndLogEx(NORMAL, "Usage: lf em 4x05_read [h] <address> <pwd>");
|
|
||||||
PrintAndLogEx(NORMAL, "Options:");
|
|
||||||
PrintAndLogEx(NORMAL, " h - this help");
|
|
||||||
PrintAndLogEx(NORMAL, " address - memory address to read. (0-15)");
|
|
||||||
PrintAndLogEx(NORMAL, " pwd - password (hex) (optional)");
|
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
|
||||||
PrintAndLogEx(NORMAL, " lf em 4x05_read 1");
|
|
||||||
PrintAndLogEx(NORMAL, " lf em 4x05_read 1 11223344");
|
|
||||||
return PM3_SUCCESS;
|
|
||||||
}
|
|
||||||
static int usage_lf_em4x05_write(void) {
|
|
||||||
PrintAndLogEx(NORMAL, "Write EM4x05/4x69. Tag must be on antenna. ");
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
|
||||||
PrintAndLogEx(NORMAL, "Usage: lf em 4x05_write [h] <address> <data> <pwd>");
|
|
||||||
PrintAndLogEx(NORMAL, "Options:");
|
|
||||||
PrintAndLogEx(NORMAL, " h - this help");
|
|
||||||
PrintAndLogEx(NORMAL, " address - memory address to write to. (0-13, 99 for Protection Words)");
|
|
||||||
PrintAndLogEx(NORMAL, " data - data to write (hex)");
|
|
||||||
PrintAndLogEx(NORMAL, " pwd - password (hex) (optional)");
|
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
|
||||||
PrintAndLogEx(NORMAL, " lf em 4x05_write 1 deadc0de");
|
|
||||||
PrintAndLogEx(NORMAL, " lf em 4x05_write 1 deadc0de 11223344");
|
|
||||||
return PM3_SUCCESS;
|
|
||||||
}
|
|
||||||
static int usage_lf_em4x05_info(void) {
|
|
||||||
PrintAndLogEx(NORMAL, "Tag information EM4205/4305/4469//4569 tags. Tag must be on antenna.");
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
|
||||||
PrintAndLogEx(NORMAL, "Usage: lf em 4x05_info [h] <pwd>");
|
|
||||||
PrintAndLogEx(NORMAL, "Options:");
|
|
||||||
PrintAndLogEx(NORMAL, " h - this help");
|
|
||||||
PrintAndLogEx(NORMAL, " pwd - password (hex) (optional)");
|
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
|
||||||
PrintAndLogEx(NORMAL, " lf em 4x05_info");
|
|
||||||
PrintAndLogEx(NORMAL, " lf em 4x05_info deadc0de");
|
|
||||||
return PM3_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1 = EM4x69
|
// 1 = EM4x69
|
||||||
// 2 = EM4x05
|
// 2 = EM4x05
|
||||||
|
@ -140,7 +88,6 @@ static bool em4x05_col_parity_test(uint8_t *bs, size_t size, uint8_t rows, uint8
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// download samples from device and copy to Graphbuffer
|
// download samples from device and copy to Graphbuffer
|
||||||
static bool em4x05_download_samples(void) {
|
static bool em4x05_download_samples(void) {
|
||||||
|
|
||||||
|
@ -387,6 +334,7 @@ static bool em4x05_verify_write(uint8_t addr, uint32_t pwd, bool use_pwd, uint32
|
||||||
uint32_t r = 0;
|
uint32_t r = 0;
|
||||||
int res = em4x05_read_word_ext(addr, pwd, use_pwd, &r);
|
int res = em4x05_read_word_ext(addr, pwd, use_pwd, &r);
|
||||||
if (res == PM3_SUCCESS) {
|
if (res == PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(INFO, "%08x == %08x", r, data);
|
||||||
return (r == data);
|
return (r == data);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -506,7 +454,40 @@ int em4x05_write_word_ext(uint8_t addr, uint32_t pwd, bool use_pwd, uint32_t dat
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int em4x05_protect(uint32_t pwd, bool use_pwd, uint32_t data) {
|
||||||
|
struct {
|
||||||
|
uint32_t password;
|
||||||
|
uint32_t data;
|
||||||
|
uint8_t usepwd;
|
||||||
|
} PACKED payload;
|
||||||
|
|
||||||
|
payload.password = pwd;
|
||||||
|
payload.data = data;
|
||||||
|
payload.usepwd = use_pwd;
|
||||||
|
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommandNG(CMD_LF_EM4X_PROTECTWORD, (uint8_t *)&payload, sizeof(payload));
|
||||||
|
PacketResponseNG resp;
|
||||||
|
if (!WaitForResponseTimeout(CMD_LF_EM4X_PROTECTWORD, &resp, 2000)) {
|
||||||
|
PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
int CmdEM4x05Demod(const char *Cmd) {
|
int CmdEM4x05Demod(const char *Cmd) {
|
||||||
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "lf em 4x05 demod",
|
||||||
|
"Try to find EM 4x05 preamble, if found decode / descramble data",
|
||||||
|
"lf em 4x05 demod"
|
||||||
|
);
|
||||||
|
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
CLIParserFree(ctx);
|
||||||
uint32_t dummy = 0;
|
uint32_t dummy = 0;
|
||||||
return em4x05_demod_resp(&dummy, false);
|
return em4x05_demod_resp(&dummy, false);
|
||||||
}
|
}
|
||||||
|
@ -514,11 +495,11 @@ int CmdEM4x05Demod(const char *Cmd) {
|
||||||
int CmdEM4x05Dump(const char *Cmd) {
|
int CmdEM4x05Dump(const char *Cmd) {
|
||||||
|
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "lf em dump",
|
CLIParserInit(&ctx, "lf em 4x05 dump",
|
||||||
"Dump EM4x05/EM4x69. Tag must be on antenna.",
|
"Dump EM4x05/EM4x69. Tag must be on antenna.",
|
||||||
"lf em dump\n"
|
"lf em 4x05 dump\n"
|
||||||
"lf em dump -p 11223344\n"
|
"lf em 4x05 dump -p 11223344\n"
|
||||||
"lf em dump -f myfile -p 11223344"
|
"lf em 4x05 dump -f myfile -p 11223344"
|
||||||
);
|
);
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
|
@ -734,29 +715,43 @@ int CmdEM4x05Dump(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdEM4x05Read(const char *Cmd) {
|
int CmdEM4x05Read(const char *Cmd) {
|
||||||
uint8_t addr;
|
|
||||||
uint32_t pwd;
|
|
||||||
bool usePwd = false;
|
|
||||||
|
|
||||||
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
|
CLIParserContext *ctx;
|
||||||
if (strlen(Cmd) == 0 || ctmp == 'h') return usage_lf_em4x05_read();
|
CLIParserInit(&ctx, "lf em 4x05 read",
|
||||||
|
"Read EM4x05/EM4x69. Tag must be on antenna.",
|
||||||
|
"lf em 4x05 read -a 1\n"
|
||||||
|
"lf em 4x05 read --addr 1 --pwd 11223344"
|
||||||
|
);
|
||||||
|
|
||||||
addr = param_get8ex(Cmd, 0, 50, 10);
|
void *argtable[] = {
|
||||||
pwd = param_get32ex(Cmd, 1, 0xFFFFFFFF, 16);
|
arg_param_begin,
|
||||||
|
arg_int1("a", "addr", "<dec>", "memory address to read. (0-15)"),
|
||||||
|
arg_str0("p", "pwd", "<hex>", "optional - password, 4 bytes hex"),
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
uint8_t addr = (uint8_t)arg_get_int_def(ctx, 1, 50);
|
||||||
|
uint64_t inputpwd = arg_get_u64_hexstr_def(ctx, 2, 0xFFFFFFFFFFFFFFFF);
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
uint32_t pwd = 0;
|
||||||
|
bool use_pwd = false;
|
||||||
|
|
||||||
if (addr > 15) {
|
if (addr > 15) {
|
||||||
PrintAndLogEx(WARNING, "Address must be between 0 and 15");
|
PrintAndLogEx(ERR, "Address must be between 0 and 15");
|
||||||
return PM3_ESOFT;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
if (pwd == 0xFFFFFFFF) {
|
|
||||||
|
if (inputpwd == 0xFFFFFFFFFFFFFFFF) {
|
||||||
PrintAndLogEx(INFO, "Reading address %02u", addr);
|
PrintAndLogEx(INFO, "Reading address %02u", addr);
|
||||||
} else {
|
} else {
|
||||||
usePwd = true;
|
pwd = (inputpwd & 0xFFFFFFFF);
|
||||||
|
use_pwd = true;
|
||||||
PrintAndLogEx(INFO, "Reading address %02u using password %08X", addr, pwd);
|
PrintAndLogEx(INFO, "Reading address %02u using password %08X", addr, pwd);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t word = 0;
|
uint32_t word = 0;
|
||||||
int status = em4x05_read_word_ext(addr, pwd, usePwd, &word);
|
int status = em4x05_read_word_ext(addr, pwd, use_pwd, &word);
|
||||||
if (status == PM3_SUCCESS)
|
if (status == PM3_SUCCESS)
|
||||||
PrintAndLogEx(SUCCESS, "Address %02d | %08X - %s", addr, word, (addr > 13) ? "Lock" : "");
|
PrintAndLogEx(SUCCESS, "Address %02d | %08X - %s", addr, word, (addr > 13) ? "Lock" : "");
|
||||||
else if (status == PM3_EFAILED)
|
else if (status == PM3_EFAILED)
|
||||||
|
@ -767,55 +762,61 @@ int CmdEM4x05Read(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdEM4x05Write(const char *Cmd) {
|
int CmdEM4x05Write(const char *Cmd) {
|
||||||
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
|
CLIParserContext *ctx;
|
||||||
if (strlen(Cmd) == 0 || ctmp == 'h') return usage_lf_em4x05_write();
|
CLIParserInit(&ctx, "lf em 4x05 write",
|
||||||
|
"Write EM4x05/EM4x69. Tag must be on antenna.",
|
||||||
|
"lf em 4x05 write -a 1 -d deadc0de\n"
|
||||||
|
"lf em 4x05 write --addr 1 --pwd 11223344 --data deadc0de\n"
|
||||||
|
"lf em 4x05 write --po --pwd 11223344 --data deadc0de\n"
|
||||||
|
);
|
||||||
|
|
||||||
bool usePwd = false;
|
void *argtable[] = {
|
||||||
uint8_t addr;
|
arg_param_begin,
|
||||||
uint32_t data, pwd;
|
arg_int0("a", "addr", "<dec>", "memory address to write to. (0-13)"),
|
||||||
|
arg_str1("d", "data", "<hex>", "data to write, 4 bytes hex"),
|
||||||
|
arg_str0("p", "pwd", "<hex>", "optional - password, 4 bytes hex"),
|
||||||
|
arg_lit0(NULL, "po", "protect operation"),
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
uint8_t addr = (uint8_t)arg_get_int_def(ctx, 1, 50);
|
||||||
|
uint32_t data = arg_get_u32(ctx, 2);
|
||||||
|
uint64_t inputpwd = arg_get_u64_hexstr_def(ctx, 3, 0xFFFFFFFFFFFFFFFF);
|
||||||
|
bool protect_operation = arg_get_lit(ctx, 4);
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
addr = param_get8ex(Cmd, 0, 50, 10);
|
if ((addr > 13) && (protect_operation == false)) {
|
||||||
data = param_get32ex(Cmd, 1, 0, 16);
|
|
||||||
pwd = param_get32ex(Cmd, 2, 0xFFFFFFFF, 16);
|
|
||||||
bool protectOperation = addr == 99; // will do better with cliparser...
|
|
||||||
|
|
||||||
if ((addr > 13) && (!protectOperation)) {
|
|
||||||
PrintAndLogEx(WARNING, "Address must be between 0 and 13");
|
PrintAndLogEx(WARNING, "Address must be between 0 and 13");
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool use_pwd = false;
|
||||||
|
uint32_t pwd = ( inputpwd != 0xFFFFFFFFFFFFFFFF) ? (inputpwd & 0xFFFFFFFF) : 0;
|
||||||
if (pwd == 0xFFFFFFFF) {
|
if (pwd == 0xFFFFFFFF) {
|
||||||
if (protectOperation)
|
if (protect_operation)
|
||||||
PrintAndLogEx(INFO, "Writing protection words data %08X", data);
|
PrintAndLogEx(INFO, "Writing protection words data %08X", data);
|
||||||
else
|
else
|
||||||
PrintAndLogEx(INFO, "Writing address %d data %08X", addr, data);
|
PrintAndLogEx(INFO, "Writing address %d data %08X", addr, data);
|
||||||
} else {
|
} else {
|
||||||
usePwd = true;
|
use_pwd = true;
|
||||||
if (protectOperation)
|
if (protect_operation)
|
||||||
PrintAndLogEx(INFO, "Writing protection words data %08X using password %08X", data, pwd);
|
PrintAndLogEx(INFO, "Writing protection words data %08X using password %08X", data, pwd);
|
||||||
else
|
else
|
||||||
PrintAndLogEx(INFO, "Writing address %d data %08X using password %08X", addr, data, pwd);
|
PrintAndLogEx(INFO, "Writing address %d data %08X using password %08X", addr, data, pwd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (protectOperation) { // set Protect Words
|
int res = PM3_SUCCESS;
|
||||||
struct {
|
// set Protect Words
|
||||||
uint32_t password;
|
if (protect_operation) {
|
||||||
uint32_t data;
|
res = em4x05_protect(pwd, use_pwd, data);
|
||||||
uint8_t usepwd;
|
if ( res != PM3_SUCCESS) {
|
||||||
} PACKED payload;
|
return res;
|
||||||
|
|
||||||
payload.password = pwd;
|
|
||||||
payload.data = data;
|
|
||||||
payload.usepwd = usePwd;
|
|
||||||
|
|
||||||
clearCommandBuffer();
|
|
||||||
SendCommandNG(CMD_LF_EM4X_PROTECTWORD, (uint8_t *)&payload, sizeof(payload));
|
|
||||||
PacketResponseNG resp;
|
|
||||||
if (!WaitForResponseTimeout(CMD_LF_EM4X_PROTECTWORD, &resp, 2000)) {
|
|
||||||
PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
|
|
||||||
return PM3_ETIMEOUT;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
em4x05_write_word_ext(addr, pwd, usePwd, data);
|
res = em4x05_write_word_ext(addr, pwd, use_pwd, data);
|
||||||
|
if ( res != PM3_SUCCESS) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (em4x05_download_samples() == false)
|
if (em4x05_download_samples() == false)
|
||||||
|
@ -826,86 +827,111 @@ int CmdEM4x05Write(const char *Cmd) {
|
||||||
if (status == PM3_SUCCESS)
|
if (status == PM3_SUCCESS)
|
||||||
PrintAndLogEx(SUCCESS, "Data written and verified");
|
PrintAndLogEx(SUCCESS, "Data written and verified");
|
||||||
else if (status == PM3_EFAILED)
|
else if (status == PM3_EFAILED)
|
||||||
PrintAndLogEx(ERR, "Tag denied %s operation", protectOperation ? "Protect" : "Write");
|
PrintAndLogEx(ERR, "Tag denied %s operation", protect_operation ? "Protect" : "Write");
|
||||||
else
|
else
|
||||||
PrintAndLogEx(DEBUG, "No answer from tag");
|
PrintAndLogEx(DEBUG, "No answer from tag");
|
||||||
|
|
||||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf em 4x05_read`") " to verify");
|
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf em 4x05 read`") " to verify");
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdEM4x05Wipe(const char *Cmd) {
|
int CmdEM4x05Wipe(const char *Cmd) {
|
||||||
uint8_t addr = 0;
|
|
||||||
uint32_t pwd = 0;
|
|
||||||
uint8_t cmdp = 0;
|
|
||||||
uint8_t chipType = 1; // em4305
|
|
||||||
uint32_t chipInfo = 0x00040072; // Chip info/User Block normal 4305 Chip Type
|
|
||||||
uint32_t chipUID = 0x614739AE; // UID normally readonly, but just in case
|
|
||||||
uint32_t blockData = 0x00000000; // UserBlock/Password (set to 0x00000000 for a wiped card1
|
|
||||||
uint32_t config = 0x0001805F; // Default config (no password)
|
|
||||||
int success = PM3_SUCCESS;
|
|
||||||
char cmdStr [100];
|
|
||||||
char optchk[10];
|
|
||||||
|
|
||||||
while (param_getchar(Cmd, cmdp) != 0x00) {
|
CLIParserContext *ctx;
|
||||||
// check if cmd is a 1 byte option
|
CLIParserInit(&ctx, "lf em 4x05 wipe",
|
||||||
param_getstr(Cmd, cmdp, optchk, sizeof(optchk));
|
"Wipe EM4x05/EM4x69. Tag must be on antenna.",
|
||||||
if (strlen(optchk) == 1) { // Have a single character so option not part of password
|
"lf em 4x05 wipe --4305 -p 11223344 -> wipe EM 4305 w pwd\n"
|
||||||
switch (tolower(param_getchar(Cmd, cmdp))) {
|
"lf em 4x05 wipe --4205 -> wipe EM 4205\n"
|
||||||
case 'c': // chip type
|
"lf em 4x05 wipe --4369 -> wipe EM 4369"
|
||||||
if (param_getchar(Cmd, cmdp) != 0x00)
|
);
|
||||||
chipType = param_get8ex(Cmd, cmdp + 1, 0, 10);
|
|
||||||
cmdp += 2;
|
void *argtable[] = {
|
||||||
break;
|
arg_param_begin,
|
||||||
case 'h': // return usage_lf_em4x05_wipe();
|
arg_lit0(NULL, "4205", "target chip type EM 4205"),
|
||||||
default : // Unknown or 'h' send help
|
arg_lit0(NULL, "4305", "target chip type EM 4305 (default)"),
|
||||||
return usage_lf_em4x05_wipe();
|
arg_lit0(NULL, "4369", "target chip type EM 4369"),
|
||||||
break;
|
arg_lit0(NULL, "4369", "target chip type EM 4469"),
|
||||||
|
arg_str0("p", "pwd", "<hex>", "optional - password, 4 bytes hex"),
|
||||||
|
arg_param_end
|
||||||
};
|
};
|
||||||
} else { // Not a single character so assume password
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
pwd = param_get32ex(Cmd, cmdp, 1, 16);
|
|
||||||
cmdp++;
|
bool target_4205 = arg_get_lit(ctx, 1);
|
||||||
}
|
bool target_4305 = arg_get_lit(ctx, 2);
|
||||||
|
bool target_4369 = arg_get_lit(ctx, 3);
|
||||||
|
bool target_4469 = arg_get_lit(ctx, 4);
|
||||||
|
uint64_t inputpwd = arg_get_u64_hexstr_def(ctx, 5, 0xFFFFFFFFFFFFFFFF);
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
uint8_t foo = target_4205 + target_4305 + target_4369 + target_4469;
|
||||||
|
|
||||||
|
if (foo > 1) {
|
||||||
|
PrintAndLogEx(ERR, "Can't target multiple chip types at the same time");
|
||||||
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (chipType) {
|
uint8_t addr = 0;
|
||||||
case 0 : // em4205
|
uint32_t chip_info = 0x00040072; // Chip info/User Block normal 4305 Chip Type
|
||||||
chipInfo = 0x00040070;
|
uint32_t chip_UID = 0x614739AE; // UID normally readonly, but just in case
|
||||||
config = 0x0001805F;
|
uint32_t block_data = 0x00000000; // UserBlock/Password (set to 0x00000000 for a wiped card1
|
||||||
break;
|
uint32_t config = 0x0001805F; // Default config (no password)
|
||||||
case 1 : // em4305
|
|
||||||
chipInfo = 0x00040072;
|
if (target_4205) {
|
||||||
config = 0x0001805F;
|
chip_info = 0x00040070;
|
||||||
break;
|
}
|
||||||
default : // Type 0/Default : EM4305
|
if (target_4369) {
|
||||||
chipInfo = 0x00040072;
|
chip_info = 0x00020078; // found on HID Prox
|
||||||
config = 0x0001805F;
|
}
|
||||||
|
if (target_4469) {
|
||||||
|
// chip_info = 0x00020078; // need to get a normal 4469 chip info block
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool use_pwd = false;
|
||||||
|
uint32_t pwd = 0;
|
||||||
|
if ( inputpwd != 0xFFFFFFFFFFFFFFFF) {
|
||||||
|
pwd = (inputpwd & 0xFFFFFFFF);
|
||||||
|
use_pwd = true;
|
||||||
|
}
|
||||||
// block 0 : User Data or Chip Info
|
// block 0 : User Data or Chip Info
|
||||||
sprintf(cmdStr, "%d %08X %08X", 0, chipInfo, pwd);
|
int res = em4x05_write_word_ext(0, pwd, use_pwd, chip_info);
|
||||||
CmdEM4x05Write(cmdStr);
|
if ( res != PM3_SUCCESS) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
// block 1 : UID - this should be read only for EM4205 and EM4305 not sure about others
|
// block 1 : UID - this should be read only for EM4205 and EM4305 not sure about others
|
||||||
sprintf(cmdStr, "%d %08X %08X", 1, chipUID, pwd);
|
res = em4x05_write_word_ext(1, pwd, use_pwd, chip_UID);
|
||||||
CmdEM4x05Write(cmdStr);
|
if ( res != PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(INFO, "UID block write failed");
|
||||||
|
}
|
||||||
|
|
||||||
// block 2 : password
|
// block 2 : password
|
||||||
sprintf(cmdStr, "%d %08X %08X", 2, blockData, pwd);
|
res = em4x05_write_word_ext(2, pwd, use_pwd, block_data);
|
||||||
CmdEM4x05Write(cmdStr);
|
if ( res != PM3_SUCCESS) {
|
||||||
pwd = blockData; // Password should now have changed, so use new password
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Password should now have changed, so use new password
|
||||||
|
pwd = block_data;
|
||||||
// block 3 : user data
|
// block 3 : user data
|
||||||
sprintf(cmdStr, "%d %08X %08X", 3, blockData, pwd);
|
res = em4x05_write_word_ext(3, pwd, use_pwd, block_data);
|
||||||
CmdEM4x05Write(cmdStr);
|
if ( res != PM3_SUCCESS) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
// block 4 : config
|
// block 4 : config
|
||||||
sprintf(cmdStr, "%d %08X %08X", 4, config, pwd);
|
res = em4x05_write_word_ext(4, pwd, use_pwd, config);
|
||||||
CmdEM4x05Write(cmdStr);
|
if ( res != PM3_SUCCESS) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
// Remainder of user/data blocks
|
// Remainder of user/data blocks
|
||||||
for (addr = 5; addr < 14; addr++) {// Clear user data blocks
|
for (addr = 5; addr < 14; addr++) {// Clear user data blocks
|
||||||
sprintf(cmdStr, "%d %08X %08X", addr, blockData, pwd);
|
res = em4x05_write_word_ext(addr, pwd, use_pwd, block_data);
|
||||||
CmdEM4x05Write(cmdStr);
|
if ( res != PM3_SUCCESS) {
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return success;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *printEM4x05_known(uint32_t word) {
|
static const char *printEM4x05_known(uint32_t word) {
|
||||||
|
@ -1174,24 +1200,37 @@ static void printEM4x05ProtectionBits(uint32_t word, uint8_t addr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//quick test for EM4x05/EM4x69 tag
|
//quick test for EM4x05/EM4x69 tag
|
||||||
bool em4x05_isblock0(uint32_t *word) {
|
bool em4x05_isblock0(uint32_t *word) {
|
||||||
return (em4x05_read_word_ext(0, 0, false, word) == PM3_SUCCESS);
|
return (em4x05_read_word_ext(0, 0, false, word) == PM3_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdEM4x05Info(const char *Cmd) {
|
int CmdEM4x05Info(const char *Cmd) {
|
||||||
uint32_t pwd;
|
|
||||||
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "lf em 4x05 info",
|
||||||
|
"Tag information EM4205/4305/4469//4569 tags. Tag must be on antenna.",
|
||||||
|
"lf em 4x05 info\n"
|
||||||
|
"lf em 4x05 info -p 11223344"
|
||||||
|
);
|
||||||
|
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_str0("p", "pwd", "<hex>", "optional - password, 4 hex bytes"),
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
uint64_t inputpwd = arg_get_u64_hexstr_def(ctx, 1, 0xFFFFFFFFFFFFFFFF);
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
bool use_pwd = false;
|
||||||
|
uint32_t pwd = 0;
|
||||||
|
if (inputpwd != 0xFFFFFFFFFFFFFFFF) {
|
||||||
|
pwd = inputpwd & 0xFFFFFFFF;
|
||||||
|
use_pwd = true;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t word = 0, block0 = 0, serial = 0;
|
uint32_t word = 0, block0 = 0, serial = 0;
|
||||||
bool usePwd = false;
|
|
||||||
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
|
|
||||||
if (ctmp == 'h') return usage_lf_em4x05_info();
|
|
||||||
|
|
||||||
// for now use default input of 1 as invalid (unlikely 1 will be a valid password...)
|
|
||||||
pwd = param_get32ex(Cmd, 0, 0xFFFFFFFF, 16);
|
|
||||||
|
|
||||||
if (pwd != 0xFFFFFFFF)
|
|
||||||
usePwd = true;
|
|
||||||
|
|
||||||
// read word 0 (chip info)
|
// read word 0 (chip info)
|
||||||
// block 0 can be read even without a password.
|
// block 0 can be read even without a password.
|
||||||
|
@ -1209,7 +1248,7 @@ int CmdEM4x05Info(const char *Cmd) {
|
||||||
|
|
||||||
// read word 4 (config block)
|
// read word 4 (config block)
|
||||||
// needs password if one is set
|
// needs password if one is set
|
||||||
if (em4x05_read_word_ext(EM_CONFIG_BLOCK, pwd, usePwd, &word) != PM3_SUCCESS) {
|
if (em4x05_read_word_ext(EM_CONFIG_BLOCK, pwd, use_pwd, &word) != PM3_SUCCESS) {
|
||||||
PrintAndLogEx(DEBUG, "(CmdEM4x05Info) failed to read CONFIG BLOCK");
|
PrintAndLogEx(DEBUG, "(CmdEM4x05Info) failed to read CONFIG BLOCK");
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
@ -1221,7 +1260,7 @@ int CmdEM4x05Info(const char *Cmd) {
|
||||||
if (card_type == EM_4205 || card_type == EM_4305) {
|
if (card_type == EM_4205 || card_type == EM_4305) {
|
||||||
|
|
||||||
// read word 14 and 15 to see which is being used for the protection bits
|
// read word 14 and 15 to see which is being used for the protection bits
|
||||||
if (em4x05_read_word_ext(EM4305_PROT1_BLOCK, pwd, usePwd, &word) != PM3_SUCCESS) {
|
if (em4x05_read_word_ext(EM4305_PROT1_BLOCK, pwd, use_pwd, &word) != PM3_SUCCESS) {
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1229,7 +1268,7 @@ int CmdEM4x05Info(const char *Cmd) {
|
||||||
printEM4x05ProtectionBits(word, EM4305_PROT1_BLOCK);
|
printEM4x05ProtectionBits(word, EM4305_PROT1_BLOCK);
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
} else { // if status bit says this is not the used protection word
|
} else { // if status bit says this is not the used protection word
|
||||||
if (em4x05_read_word_ext(EM4305_PROT2_BLOCK, pwd, usePwd, &word) != PM3_SUCCESS)
|
if (em4x05_read_word_ext(EM4305_PROT2_BLOCK, pwd, use_pwd, &word) != PM3_SUCCESS)
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
if (word & 0x8000) {
|
if (word & 0x8000) {
|
||||||
printEM4x05ProtectionBits(word, EM4305_PROT2_BLOCK);
|
printEM4x05ProtectionBits(word, EM4305_PROT2_BLOCK);
|
||||||
|
@ -1238,7 +1277,7 @@ int CmdEM4x05Info(const char *Cmd) {
|
||||||
}
|
}
|
||||||
} else if (card_type == EM_4369 || card_type == EM_4469) {
|
} else if (card_type == EM_4369 || card_type == EM_4469) {
|
||||||
// read word 3 to see which is being used for the protection bits
|
// read word 3 to see which is being used for the protection bits
|
||||||
if (em4x05_read_word_ext(EM4469_PROT_BLOCK, pwd, usePwd, &word) != PM3_SUCCESS) {
|
if (em4x05_read_word_ext(EM4469_PROT_BLOCK, pwd, use_pwd, &word) != PM3_SUCCESS) {
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
printEM4x05ProtectionBits(word, EM4469_PROT_BLOCK);
|
printEM4x05ProtectionBits(word, EM4469_PROT_BLOCK);
|
||||||
|
@ -1259,11 +1298,11 @@ static bool is_cancelled(void) {
|
||||||
int CmdEM4x05Chk(const char *Cmd) {
|
int CmdEM4x05Chk(const char *Cmd) {
|
||||||
|
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "lf em 4x05_chk",
|
CLIParserInit(&ctx, "lf em 4x05 chk",
|
||||||
"This command uses a dictionary attack against EM4205/4305/4469/4569",
|
"This command uses a dictionary attack against EM4205/4305/4469/4569",
|
||||||
"lf em 4x05_chk\n"
|
"lf em 4x05 chk\n"
|
||||||
"lf em 4x05_chk -e 000022B8 -> remember to use 0x for hex\n"
|
"lf em 4x05 chk -e 000022B8 -> remember to use 0x for hex\n"
|
||||||
"lf em 4x05_chk -f t55xx_default_pwds -> use T55xx default dictionary"
|
"lf em 4x05 chk -f t55xx_default_pwds -> use T55xx default dictionary"
|
||||||
);
|
);
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
|
@ -1360,12 +1399,12 @@ int CmdEM4x05Chk(const char *Cmd) {
|
||||||
|
|
||||||
int CmdEM4x05Brute(const char *Cmd) {
|
int CmdEM4x05Brute(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "lf em 4x05_brute",
|
CLIParserInit(&ctx, "lf em 4x05 brute",
|
||||||
"This command tries to bruteforce the password of a EM4205/4305/4469/4569\n",
|
"This command tries to bruteforce the password of a EM4205/4305/4469/4569\n",
|
||||||
"Note: if you get many false positives, change position on the antenna"
|
"Note: if you get many false positives, change position on the antenna"
|
||||||
"lf em 4x05_brute\n"
|
"lf em 4x05 brute\n"
|
||||||
"lf em 4x05_brute -n 1 -> stop after first candidate found\n"
|
"lf em 4x05 brute -n 1 -> stop after first candidate found\n"
|
||||||
"lf em 4x05_brute -s 000022B8 -> remember to use 0x for hex"
|
"lf em 4x05 brute -s 000022B8 -> remember to use 0x for hex"
|
||||||
);
|
);
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
|
@ -1464,11 +1503,11 @@ static void unlock_add_item(em4x05_unlock_item_t *array, uint8_t len, uint32_t v
|
||||||
int CmdEM4x05Unlock(const char *Cmd) {
|
int CmdEM4x05Unlock(const char *Cmd) {
|
||||||
|
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "lf em 4x05_unlock",
|
CLIParserInit(&ctx, "lf em 4x05 unlock",
|
||||||
"execute tear off against EM4205/4305/4469/4569",
|
"execute tear off against EM4205/4305/4469/4569",
|
||||||
"lf em 4x05_unlock\n"
|
"lf em 4x05 unlock\n"
|
||||||
"lf em 4x05_unlock -s 4100 -e 4100 -> lock on and autotune at 4100us\n"
|
"lf em 4x05 unlock -s 4100 -e 4100 -> lock on and autotune at 4100us\n"
|
||||||
"lf em 4x05_unlock -n 10 -s 3000 -e 4400 -> scan delays 3000us -> 4400us"
|
"lf em 4x05 unlock -n 10 -s 3000 -e 4400 -> scan delays 3000us -> 4400us"
|
||||||
);
|
);
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
|
@ -2082,3 +2121,29 @@ int CmdEM4x05Sniff(const char *Cmd) {
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static command_t CommandTable[] = {
|
||||||
|
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||||
|
{"brute", CmdEM4x05Brute, IfPm3Lf, "Bruteforce password"},
|
||||||
|
{"chk", CmdEM4x05Chk, IfPm3Lf, "Check passwords from dictionary"},
|
||||||
|
{"demod", CmdEM4x05Demod, AlwaysAvailable, "demodulate a EM4x05/EM4x69 tag from the GraphBuffer"},
|
||||||
|
{"dump", CmdEM4x05Dump, IfPm3Lf, "dump EM4x05/EM4x69 tag"},
|
||||||
|
{"info", CmdEM4x05Info, IfPm3Lf, "tag information EM4x05/EM4x69"},
|
||||||
|
{"read", CmdEM4x05Read, IfPm3Lf, "read word data from EM4x05/EM4x69"},
|
||||||
|
{"sniff", CmdEM4x05Sniff, AlwaysAvailable, "Attempt to recover em4x05 commands from sample buffer"},
|
||||||
|
{"unlock", CmdEM4x05Unlock, IfPm3Lf, "execute tear off against EM4x05/EM4x69"},
|
||||||
|
{"wipe", CmdEM4x05Wipe, IfPm3Lf, "wipe EM4x05/EM4x69 tag"},
|
||||||
|
{"write", CmdEM4x05Write, IfPm3Lf, "write word data to EM4x05/EM4x69"},
|
||||||
|
{NULL, NULL, NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int CmdHelp(const char *Cmd) {
|
||||||
|
(void)Cmd; // Cmd is not used so far
|
||||||
|
CmdsHelp(CommandTable);
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CmdLFEM4X05(const char *Cmd) {
|
||||||
|
clearCommandBuffer();
|
||||||
|
return CmdsParse(CommandTable, Cmd);
|
||||||
|
}
|
|
@ -1,6 +1,8 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 2020 tharexde
|
// Copyright (C) 2020 tharexde
|
||||||
//
|
//
|
||||||
|
// modified iceman, 2020
|
||||||
|
//
|
||||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||||
// the license.
|
// the license.
|
||||||
|
@ -10,11 +12,12 @@
|
||||||
|
|
||||||
#include "cliparser.h"
|
#include "cliparser.h"
|
||||||
#include "cmdlfem4x50.h"
|
#include "cmdlfem4x50.h"
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "cmdparser.h" // command_t
|
||||||
#include "fileutils.h"
|
#include "fileutils.h"
|
||||||
#include "commonutil.h"
|
#include "commonutil.h"
|
||||||
#include "pmflash.h"
|
#include "pmflash.h"
|
||||||
#include "cmdflashmemspiffs.h"
|
#include "cmdflashmemspiffs.h"
|
||||||
#include "cmdparser.h"
|
|
||||||
|
|
||||||
#define BYTES2UINT32(x) ((x[0] << 24) | (x[1] << 16) | (x[2] << 8) | (x[3]))
|
#define BYTES2UINT32(x) ((x[0] << 24) | (x[1] << 16) | (x[2] << 8) | (x[3]))
|
||||||
|
|
||||||
|
@ -22,6 +25,8 @@
|
||||||
// output functions
|
// output functions
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
static void prepare_result(const uint8_t *data, int fwr, int lwr, em4x50_word_t *words) {
|
static void prepare_result(const uint8_t *data, int fwr, int lwr, em4x50_word_t *words) {
|
||||||
|
|
||||||
// restructure received result in "em4x50_word_t" structure
|
// restructure received result in "em4x50_word_t" structure
|
||||||
|
@ -1210,3 +1215,25 @@ int CmdEM4x50Sim(const char *Cmd) {
|
||||||
|
|
||||||
return resp.status;
|
return resp.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static command_t CommandTable[] = {
|
||||||
|
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||||
|
{"dump", CmdEM4x50Dump, IfPm3EM4x50, "dump EM4x50 tag"},
|
||||||
|
{"info", CmdEM4x50Info, IfPm3EM4x50, "tag information EM4x50"},
|
||||||
|
{"write", CmdEM4x50Write, IfPm3EM4x50, "write word data to EM4x50"},
|
||||||
|
{"write_password", CmdEM4x50WritePassword, IfPm3EM4x50, "change password of EM4x50 tag"},
|
||||||
|
{"read", CmdEM4x50Read, IfPm3EM4x50, "read word data from EM4x50"},
|
||||||
|
{"wipe", CmdEM4x50Wipe, IfPm3EM4x50, "wipe data from EM4x50"},
|
||||||
|
{NULL, NULL, NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int CmdHelp(const char *Cmd) {
|
||||||
|
(void)Cmd; // Cmd is not used so far
|
||||||
|
CmdsHelp(CommandTable);
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CmdLFEM4X50(const char *Cmd) {
|
||||||
|
clearCommandBuffer();
|
||||||
|
return CmdsParse(CommandTable, Cmd);
|
||||||
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
|
|
||||||
#include "em4x50.h"
|
#include "em4x50.h"
|
||||||
|
|
||||||
|
int CmdLFEM4X50(const char *Cmd);
|
||||||
|
|
||||||
int read_em4x50_uid(void);
|
int read_em4x50_uid(void);
|
||||||
bool detect_4x50_block(void);
|
bool detect_4x50_block(void);
|
||||||
int em4x50_read(em4x50_data_t *etd, em4x50_word_t *out);
|
int em4x50_read(em4x50_data_t *etd, em4x50_word_t *out);
|
||||||
|
|
|
@ -63,13 +63,20 @@ static int sendTry(uint8_t format_idx, wiegand_card_t *card, uint32_t delay, boo
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose)
|
if (verbose) {
|
||||||
PrintAndLogEx(INFO, "Trying FC: %u; CN: %"PRIu64"; Issue level: %u; OEM: %u", card->FacilityCode, card->CardNumber, card->IssueLevel, card->OEM);
|
PrintAndLogEx(INFO, "Trying FC: " _YELLOW_("%u") " CN: " _YELLOW_("%"PRIu64) " Issue level: " _YELLOW_("%u") " OEM: " _YELLOW_("%u")
|
||||||
|
, card->FacilityCode
|
||||||
|
, card->CardNumber
|
||||||
|
, card->IssueLevel
|
||||||
|
, card->OEM
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
lf_hidsim_t payload;
|
lf_hidsim_t payload;
|
||||||
payload.hi2 = packed.Top;
|
payload.hi2 = packed.Top;
|
||||||
payload.hi = packed.Mid;
|
payload.hi = packed.Mid;
|
||||||
payload.lo = packed.Bot;
|
payload.lo = packed.Bot;
|
||||||
|
payload.longFMT = (packed.Mid > 0xFFF);
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
|
|
||||||
|
@ -240,8 +247,8 @@ static int CmdHIDSim(const char *Cmd) {
|
||||||
arg_str0("w", "wiegand", "<format>", "see " _YELLOW_("`wiegand list`") " for available formats"),
|
arg_str0("w", "wiegand", "<format>", "see " _YELLOW_("`wiegand list`") " for available formats"),
|
||||||
arg_u64_0(NULL, "fc", "<dec>", "facility code"),
|
arg_u64_0(NULL, "fc", "<dec>", "facility code"),
|
||||||
arg_u64_0(NULL, "cn", "<dec>", "card number"),
|
arg_u64_0(NULL, "cn", "<dec>", "card number"),
|
||||||
arg_int0("i", NULL, "<dec>", "issue level"),
|
arg_u64_0("i", NULL, "<dec>", "issue level"),
|
||||||
arg_int0("o", "oem", "<dec>", "OEM code"),
|
arg_u64_0("o", "oem", "<dec>", "OEM code"),
|
||||||
arg_strx0("r", "raw", "<hex>", "raw bytes"),
|
arg_strx0("r", "raw", "<hex>", "raw bytes"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
|
@ -318,16 +325,15 @@ static int CmdHIDClone(const char *Cmd) {
|
||||||
CLIParserInit(&ctx, "lf hid clone",
|
CLIParserInit(&ctx, "lf hid clone",
|
||||||
"clone a HID Prox tag to a T55x7, Q5/T5555 or EM4305/4469 tag.\n"
|
"clone a HID Prox tag to a T55x7, Q5/T5555 or EM4305/4469 tag.\n"
|
||||||
"Tag must be on the antenna when issuing this command.",
|
"Tag must be on the antenna when issuing this command.",
|
||||||
"lf hid clone -r 2006ec0c86 -> HID 10301 26 bit\n"
|
"lf hid clone -r 2006ec0c86 -> write raw value (HID 10301 26 bit)\n"
|
||||||
"lf hid clone -r 2e0ec00c87 -> HID Corporate 35 bit\n"
|
"lf hid clone -r 2e0ec00c87 -> write raw value (HID Corporate 35 bit)\n"
|
||||||
"lf hid clone -r 01f0760643c3 -> HID P10001 40 bit\n"
|
"lf hid clone -r 01f0760643c3 -> write raw value (HID P10001 40 bit)\n"
|
||||||
"lf hid clone -r 01400076000c86 -> HID Corporate 48 bit\n"
|
"lf hid clone -r 01400076000c86 -> write raw value (HID Corporate 48 bit)\n"
|
||||||
"lf hid clone -w H10301 --fc 118 --cn 1603 -> HID 10301 26 bit\n"
|
"lf hid clone -w H10301 --fc 118 --cn 1603 -> write raw value (HID 10301 26 bit)\n"
|
||||||
"lf hid clone -w H10301 --fc 118 --cn 1603 --q5 -> HID 10301 26 bit, encode for Q5/T5555 tag\n"
|
"lf hid clone -w H10301 --fc 118 --cn 1603 --q5 -> HID 10301 26 bit, encode for Q5/T5555 tag\n"
|
||||||
"lf hid clone -w H10301 --fc 118 --cn 1603 --em -> HID 10301 26 bit, encode for EM4305/4469"
|
"lf hid clone -w H10301 --fc 118 --cn 1603 --em -> HID 10301 26 bit, encode for EM4305/4469"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_str0("w", "wiegand", "<format>", "see " _YELLOW_("`wiegand list`") " for available formats"),
|
arg_str0("w", "wiegand", "<format>", "see " _YELLOW_("`wiegand list`") " for available formats"),
|
||||||
|
@ -465,17 +471,18 @@ static int CmdHIDBrute(const char *Cmd) {
|
||||||
"lf hid brute -w H10301 --fc 224\n"
|
"lf hid brute -w H10301 --fc 224\n"
|
||||||
"lf hid brute -w H10301 --fc 21 -d 2000\n"
|
"lf hid brute -w H10301 --fc 21 -d 2000\n"
|
||||||
"lf hid brute -v -w H10301 --fc 21 --cn 200 -d 2000\n"
|
"lf hid brute -v -w H10301 --fc 21 --cn 200 -d 2000\n"
|
||||||
|
"lf hid brute -v -w H10301 --fc 21 --cn 200 -d 2000 --up\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_lit0("v", "verbose", "verbose logging, show all tries"),
|
arg_lit0("v", "verbose", "verbose logging, show all tries"),
|
||||||
arg_str1("w", "wiegand", "<format>", "see " _YELLOW_("`wiegand list`") " for available formats"),
|
arg_str1("w", "wiegand", "<format>", "see " _YELLOW_("`wiegand list`") " for available formats"),
|
||||||
arg_int0(NULL, "fn", "<dec>", "facility code"),
|
arg_u64_0(NULL, "fc", "<dec>", "facility code"),
|
||||||
arg_int0(NULL, "cn", "<dec>", "card number to start with"),
|
arg_u64_0(NULL, "cn", "<dec>", "card number to start with"),
|
||||||
arg_int0("i", "issue", "<dec>", "issue level"),
|
arg_u64_0("i", "issue", "<dec>", "issue level"),
|
||||||
arg_int0("o", "oem", "<dec>", "OEM code"),
|
arg_u64_0("o", "oem", "<dec>", "OEM code"),
|
||||||
arg_int0("d", "delay", "<dec>", "delay betweens attempts in ms. Default 1000ms"),
|
arg_u64_0("d", "delay", "<dec>", "delay betweens attempts in ms. Default 1000ms"),
|
||||||
arg_lit0(NULL, "up", "direction to increment card number. (default is both directions)"),
|
arg_lit0(NULL, "up", "direction to increment card number. (default is both directions)"),
|
||||||
arg_lit0(NULL, "down", "direction to decrement card number. (default is both directions)"),
|
arg_lit0(NULL, "down", "direction to decrement card number. (default is both directions)"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
|
@ -493,11 +500,11 @@ static int CmdHIDBrute(const char *Cmd) {
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
cn_hi.FacilityCode = arg_get_int_def(ctx, 3, 0);
|
cn_hi.FacilityCode = arg_get_u32_def(ctx, 3, 0);
|
||||||
cn_hi.CardNumber = arg_get_int_def(ctx, 4, 0);
|
cn_hi.CardNumber = arg_get_u32_def(ctx, 4, 0);
|
||||||
cn_hi.IssueLevel = arg_get_int_def(ctx, 5, 0);
|
cn_hi.IssueLevel = arg_get_u32_def(ctx, 5, 0);
|
||||||
cn_hi.OEM = arg_get_int_def(ctx, 6, 0);
|
cn_hi.OEM = arg_get_u32_def(ctx, 6, 0);
|
||||||
delay = arg_get_int_def(ctx, 7, 1000);
|
delay = arg_get_u32_def(ctx, 7, 1000);
|
||||||
|
|
||||||
if (arg_get_lit(ctx, 8) && arg_get_lit(ctx, 9)) {
|
if (arg_get_lit(ctx, 8) && arg_get_lit(ctx, 9)) {
|
||||||
direction = 0;
|
direction = 0;
|
||||||
|
@ -517,20 +524,20 @@ static int CmdHIDBrute(const char *Cmd) {
|
||||||
PrintAndLogEx(INFO, "Card#............ %" PRIu64, cn_hi.CardNumber);
|
PrintAndLogEx(INFO, "Card#............ %" PRIu64, cn_hi.CardNumber);
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
case 0:
|
case 0:
|
||||||
PrintAndLogEx(INFO, "Brute-forcing direction: " _YELLOW_("BOTH"));
|
PrintAndLogEx(INFO, "Brute-forcing direction: " _YELLOW_("BOTH") " delay " _YELLOW_("%d"), delay);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
PrintAndLogEx(INFO, "Brute-forcing direction: " _YELLOW_("UP"));
|
PrintAndLogEx(INFO, "Brute-forcing direction: " _YELLOW_("UP") " delay " _YELLOW_("%d"), delay);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
PrintAndLogEx(INFO, "Brute-forcing direction: " _YELLOW_("DOWN"));
|
PrintAndLogEx(INFO, "Brute-forcing direction: " _YELLOW_("DOWN") " delay " _YELLOW_("%d"), delay);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PrintAndLogEx(INFO, "Brute-forcing HID reader");
|
PrintAndLogEx(INFO, "Started brute-forcing HID Prox reader");
|
||||||
PrintAndLogEx(INFO, "Press pm3-button to abort simulation or press `enter` to exit");
|
PrintAndLogEx(INFO, "Press pm3-button to abort simulation or press " _GREEN_("`<enter>`") " to exit");
|
||||||
|
|
||||||
// copy values to low.
|
// copy values to low.
|
||||||
cn_low = cn_hi;
|
cn_low = cn_hi;
|
||||||
|
@ -556,7 +563,9 @@ static int CmdHIDBrute(const char *Cmd) {
|
||||||
if (direction != 2) {
|
if (direction != 2) {
|
||||||
if (cn_hi.CardNumber < 0xFFFF) {
|
if (cn_hi.CardNumber < 0xFFFF) {
|
||||||
cn_hi.CardNumber++;
|
cn_hi.CardNumber++;
|
||||||
if (sendTry(format_idx, &cn_hi, delay, verbose) != PM3_SUCCESS) return PM3_ESOFT;
|
if (sendTry(format_idx, &cn_hi, delay, verbose) != PM3_SUCCESS) {
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
fin_hi = true;
|
fin_hi = true;
|
||||||
}
|
}
|
||||||
|
@ -566,7 +575,9 @@ static int CmdHIDBrute(const char *Cmd) {
|
||||||
if (direction != 1) {
|
if (direction != 1) {
|
||||||
if (cn_low.CardNumber > 0) {
|
if (cn_low.CardNumber > 0) {
|
||||||
cn_low.CardNumber--;
|
cn_low.CardNumber--;
|
||||||
if (sendTry(format_idx, &cn_low, delay, verbose) != PM3_SUCCESS) return PM3_ESOFT;
|
if (sendTry(format_idx, &cn_low, delay, verbose) != PM3_SUCCESS) {
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
fin_low = true;
|
fin_low = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,7 @@ static void encodeHeden2L(uint8_t *dest, uint32_t cardnumber) {
|
||||||
dest[i / 8] = bytebits_to_byte(template + i, 8);
|
dest[i / 8] = bytebits_to_byte(template + i, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "Heden-2L card number " _GREEN_("%u"), cardnumber);
|
PrintAndLogEx(INFO, "Heden-2L card number %u", cardnumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decodeHeden2L(uint8_t *bits) {
|
static void decodeHeden2L(uint8_t *bits) {
|
||||||
|
@ -109,7 +109,7 @@ static void decodeHeden2L(uint8_t *bits) {
|
||||||
if (bits[offset + 7]) cardnumber += 16384;
|
if (bits[offset + 7]) cardnumber += 16384;
|
||||||
if (bits[offset + 23]) cardnumber += 32768;
|
if (bits[offset + 23]) cardnumber += 32768;
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "\tHeden-2L | " _GREEN_("%u"), cardnumber);
|
PrintAndLogEx(SUCCESS, " Heden-2L | %u", cardnumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Indala 26 bit decode
|
// Indala 26 bit decode
|
||||||
|
@ -151,7 +151,7 @@ int demodIndalaEx(int clk, int invert, int maxErr, bool verbose) {
|
||||||
uint64_t foo = uid2 & 0x7FFFFFFF;
|
uint64_t foo = uid2 & 0x7FFFFFFF;
|
||||||
|
|
||||||
if (DemodBufferLen == 64) {
|
if (DemodBufferLen == 64) {
|
||||||
PrintAndLogEx(SUCCESS, "Indala - len " _GREEN_("%zu") " Raw: %x%08x", DemodBufferLen, uid1, uid2);
|
PrintAndLogEx(SUCCESS, "Indala (len %zu) Raw: " _GREEN_("%x%08x"), DemodBufferLen, uid1, uid2);
|
||||||
|
|
||||||
uint16_t p1 = 0;
|
uint16_t p1 = 0;
|
||||||
p1 |= DemodBuffer[32 + 3] << 8;
|
p1 |= DemodBuffer[32 + 3] << 8;
|
||||||
|
@ -206,8 +206,8 @@ int demodIndalaEx(int clk, int invert, int maxErr, bool verbose) {
|
||||||
);
|
);
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "Possible de-scramble patterns");
|
PrintAndLogEx(SUCCESS, "Possible de-scramble patterns");
|
||||||
PrintAndLogEx(SUCCESS, "\tPrinted | __%04d__ [0x%X]", p1, p1);
|
PrintAndLogEx(SUCCESS, " Printed | __%04d__ [0x%X]", p1, p1);
|
||||||
PrintAndLogEx(SUCCESS, "\tInternal ID | %" PRIu64, foo);
|
PrintAndLogEx(SUCCESS, " Internal ID | %" PRIu64, foo);
|
||||||
decodeHeden2L(DemodBuffer);
|
decodeHeden2L(DemodBuffer);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -218,7 +218,7 @@ int demodIndalaEx(int clk, int invert, int maxErr, bool verbose) {
|
||||||
uint32_t uid7 = bytebits_to_byte(DemodBuffer + 192, 32);
|
uint32_t uid7 = bytebits_to_byte(DemodBuffer + 192, 32);
|
||||||
PrintAndLogEx(
|
PrintAndLogEx(
|
||||||
SUCCESS
|
SUCCESS
|
||||||
, "Indala - len " _GREEN_("%zu") " Raw: %x%08x%08x%08x%08x%08x%08x"
|
, "Indala (len %zu) Raw: " _GREEN_("%x%08x%08x%08x%08x%08x%08x")
|
||||||
, DemodBufferLen
|
, DemodBufferLen
|
||||||
, uid1
|
, uid1
|
||||||
, uid2
|
, uid2
|
||||||
|
@ -245,7 +245,7 @@ static int CmdIndalaDemod(const char *Cmd) {
|
||||||
|
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "lf indala demod",
|
CLIParserInit(&ctx, "lf indala demod",
|
||||||
"Tries to psk demodulate the graphbuffer as Indala Prox",
|
"Tries to psk demodulate the graphbuffer as Indala",
|
||||||
"lf indala demod\n"
|
"lf indala demod\n"
|
||||||
"lf indala demod --clock 32 -> demod a Indala tag from GraphBuffer using a clock of RF/32\n"
|
"lf indala demod --clock 32 -> demod a Indala tag from GraphBuffer using a clock of RF/32\n"
|
||||||
"lf indala demod --clock 32 -i -> demod a Indala tag from GraphBuffer using a clock of RF/32 and inverting data\n"
|
"lf indala demod --clock 32 -i -> demod a Indala tag from GraphBuffer using a clock of RF/32 and inverting data\n"
|
||||||
|
@ -276,7 +276,7 @@ static int CmdIndalaDemodAlt(const char *Cmd) {
|
||||||
|
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "lf indala altdemod",
|
CLIParserInit(&ctx, "lf indala altdemod",
|
||||||
"Tries to psk demodulate the graphbuffer as Indala Prox\n"
|
"Tries to psk demodulate the graphbuffer as Indala\n"
|
||||||
"This is uses a alternative way to demodulate and was used from the beginning in the Pm3 client.\n"
|
"This is uses a alternative way to demodulate and was used from the beginning in the Pm3 client.\n"
|
||||||
"It's now considered obsolete but remains because it has sometimes its advantages.",
|
"It's now considered obsolete but remains because it has sometimes its advantages.",
|
||||||
"lf indala altdemod\n"
|
"lf indala altdemod\n"
|
||||||
|
@ -493,7 +493,7 @@ static int CmdIndalaDemodAlt(const char *Cmd) {
|
||||||
static int CmdIndalaReader(const char *Cmd) {
|
static int CmdIndalaReader(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "lf indala reader",
|
CLIParserInit(&ctx, "lf indala reader",
|
||||||
"read a Indala Prox tag",
|
"read a Indala tag",
|
||||||
"lf indala reader -@ -> continuous reader mode"
|
"lf indala reader -@ -> continuous reader mode"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -527,7 +527,7 @@ static int CmdIndalaSim(const char *Cmd) {
|
||||||
|
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "lf indala sim",
|
CLIParserInit(&ctx, "lf indala sim",
|
||||||
"Enables simulation of IOProx card with specified facility-code and card number.\n"
|
"Enables simulation of Indala card with specified facility-code and card number.\n"
|
||||||
"Simulation runs until the button is pressed or another USB command is issued.",
|
"Simulation runs until the button is pressed or another USB command is issued.",
|
||||||
"lf indala sim --heden 888\n"
|
"lf indala sim --heden 888\n"
|
||||||
"lf indala sim --raw a0000000a0002021\n"
|
"lf indala sim --raw a0000000a0002021\n"
|
||||||
|
@ -616,7 +616,8 @@ static int CmdIndalaClone(const char *Cmd) {
|
||||||
|
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "lf indala clone",
|
CLIParserInit(&ctx, "lf indala clone",
|
||||||
"clone INDALA UID to T55x7 or Q5/T5555 tag",
|
"clone Indala UID to T55x7 or Q5/T5555 tag\n"
|
||||||
|
_RED_("\nWarning, encoding with FC/CN doesn't always work"),
|
||||||
"lf indala clone --heden 888\n"
|
"lf indala clone --heden 888\n"
|
||||||
"lf indala clone --fc 123 --cn 1337\n"
|
"lf indala clone --fc 123 --cn 1337\n"
|
||||||
"lf indala clone -r a0000000a0002021\n"
|
"lf indala clone -r a0000000a0002021\n"
|
||||||
|
@ -626,8 +627,8 @@ static int CmdIndalaClone(const char *Cmd) {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_strx0("r", "raw", "<hex>", "raw bytes"),
|
arg_strx0("r", "raw", "<hex>", "raw bytes"),
|
||||||
arg_int0(NULL, "heden", "<decimal>", "Cardnumber for Heden 2L format"),
|
arg_int0(NULL, "heden", "<decimal>", "Cardnumber for Heden 2L format"),
|
||||||
arg_int0(NULL, "fc", "<decimal>", "Facility Code (26 bit format)"),
|
arg_int0(NULL, "fc", "<decimal>", "Facility Code (26 bit H10301 format)"),
|
||||||
arg_int0(NULL, "cn", "<decimal>", "Cardnumber (26 bit format)"),
|
arg_int0(NULL, "cn", "<decimal>", "Cardnumber (26 bit H10301 format)"),
|
||||||
arg_lit0(NULL, "q5", "optional - specify writing to Q5/T5555 tag"),
|
arg_lit0(NULL, "q5", "optional - specify writing to Q5/T5555 tag"),
|
||||||
arg_lit0(NULL, "em", "optional - specify writing to EM4305/4469 tag"),
|
arg_lit0(NULL, "em", "optional - specify writing to EM4305/4469 tag"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
|
@ -768,9 +769,9 @@ static int CmdIndalaClone(const char *Cmd) {
|
||||||
|
|
||||||
static command_t CommandTable[] = {
|
static command_t CommandTable[] = {
|
||||||
{"help", CmdHelp, AlwaysAvailable, "this help"},
|
{"help", CmdHelp, AlwaysAvailable, "this help"},
|
||||||
{"demod", CmdIndalaDemod, AlwaysAvailable, "demodulate an indala tag (PSK1) from GraphBuffer"},
|
{"demod", CmdIndalaDemod, AlwaysAvailable, "demodulate an Indala tag (PSK1) from GraphBuffer"},
|
||||||
{"altdemod", CmdIndalaDemodAlt, AlwaysAvailable, "alternative method to Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"},
|
{"altdemod", CmdIndalaDemodAlt, AlwaysAvailable, "alternative method to demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"},
|
||||||
{"reader", CmdIndalaReader, IfPm3Lf, "read an Indala Prox tag from the antenna"},
|
{"reader", CmdIndalaReader, IfPm3Lf, "read an Indala tag from the antenna"},
|
||||||
{"clone", CmdIndalaClone, IfPm3Lf, "clone Indala tag to T55x7 or Q5/T5555"},
|
{"clone", CmdIndalaClone, IfPm3Lf, "clone Indala tag to T55x7 or Q5/T5555"},
|
||||||
{"sim", CmdIndalaSim, IfPm3Lf, "simulate Indala tag"},
|
{"sim", CmdIndalaSim, IfPm3Lf, "simulate Indala tag"},
|
||||||
{NULL, NULL, NULL, NULL}
|
{NULL, NULL, NULL, NULL}
|
||||||
|
|
|
@ -34,7 +34,7 @@ static int CmdHelp(const char *Cmd);
|
||||||
static int CmdIOProxWatch(const char *Cmd) {
|
static int CmdIOProxWatch(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "lf io watch",
|
CLIParserInit(&ctx, "lf io watch",
|
||||||
"Enables IOProx compatible reader mode printing details.\n"
|
"Enables ioProx compatible reader mode printing details.\n"
|
||||||
"By default, values are printed and logged until the button is pressed or another USB command is issued.",
|
"By default, values are printed and logged until the button is pressed or another USB command is issued.",
|
||||||
"lf io watch"
|
"lf io watch"
|
||||||
);
|
);
|
||||||
|
@ -57,7 +57,7 @@ static int CmdIOProxWatch(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//IO-Prox demod - FSK RF/64 with preamble of 000000001
|
//IO-Prox demod - FSK RF/64 with preamble of 000000001
|
||||||
//print ioprox ID and some format details
|
//print ioProx ID and some format details
|
||||||
int demodIOProx(bool verbose) {
|
int demodIOProx(bool verbose) {
|
||||||
(void) verbose; // unused so far
|
(void) verbose; // unused so far
|
||||||
int idx = 0, retval = PM3_SUCCESS;
|
int idx = 0, retval = PM3_SUCCESS;
|
||||||
|
@ -157,7 +157,7 @@ int demodIOProx(bool verbose) {
|
||||||
static int CmdIOProxDemod(const char *Cmd) {
|
static int CmdIOProxDemod(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "lf io demod",
|
CLIParserInit(&ctx, "lf io demod",
|
||||||
"Try to find IOProx preamble, if found decode / descramble data",
|
"Try to find ioProx preamble, if found decode / descramble data",
|
||||||
"lf io demod"
|
"lf io demod"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ static int CmdIOProxDemod(const char *Cmd) {
|
||||||
static int CmdIOProxReader(const char *Cmd) {
|
static int CmdIOProxReader(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "lf io reader",
|
CLIParserInit(&ctx, "lf io reader",
|
||||||
"read a IOProx tag",
|
"read a ioProx tag",
|
||||||
"lf io reader -@ -> continuous reader mode"
|
"lf io reader -@ -> continuous reader mode"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -198,7 +198,7 @@ static int CmdIOProxSim(const char *Cmd) {
|
||||||
|
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "lf io sim",
|
CLIParserInit(&ctx, "lf io sim",
|
||||||
"Enables simulation of IOProx card with specified facility-code and card number.\n"
|
"Enables simulation of ioProx card with specified facility-code and card number.\n"
|
||||||
"Simulation runs until the button is pressed or another USB command is issued.",
|
"Simulation runs until the button is pressed or another USB command is issued.",
|
||||||
"lf io sim --vn 1 --fc 101 --cn 1337"
|
"lf io sim --vn 1 --fc 101 --cn 1337"
|
||||||
);
|
);
|
||||||
|
@ -220,10 +220,10 @@ static int CmdIOProxSim(const char *Cmd) {
|
||||||
|
|
||||||
if ((cn & 0xFFFF) != cn) {
|
if ((cn & 0xFFFF) != cn) {
|
||||||
cn &= 0xFFFF;
|
cn &= 0xFFFF;
|
||||||
PrintAndLogEx(INFO, "Card Number Truncated to 16-bits (IOProx): %u", cn);
|
PrintAndLogEx(INFO, "Card Number Truncated to 16-bits (ioProx): %u", cn);
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "Simulating IOProx version: " _YELLOW_("%u") " FC: " _YELLOW_("%u (0x%02x)") " CN: " _YELLOW_("%u"), version, fc, fc, cn);
|
PrintAndLogEx(SUCCESS, "Simulating ioProx version: " _YELLOW_("%u") " FC: " _YELLOW_("%u (0x%02x)") " CN: " _YELLOW_("%u"), version, fc, fc, cn);
|
||||||
PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation or run another command");
|
PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation or run another command");
|
||||||
|
|
||||||
uint8_t bs[64];
|
uint8_t bs[64];
|
||||||
|
@ -233,7 +233,7 @@ static int CmdIOProxSim(const char *Cmd) {
|
||||||
PrintAndLogEx(ERR, "Error with tag bitstream generation.");
|
PrintAndLogEx(ERR, "Error with tag bitstream generation.");
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
// IOProx uses: fcHigh: 10, fcLow: 8, clk: 64, invert: 1
|
// ioProx uses: fcHigh: 10, fcLow: 8, clk: 64, invert: 1
|
||||||
// arg1 --- fcHigh<<8 + fcLow
|
// arg1 --- fcHigh<<8 + fcLow
|
||||||
// arg2 --- Invert and clk setting
|
// arg2 --- Invert and clk setting
|
||||||
// size --- 64 bits == 8 bytes
|
// size --- 64 bits == 8 bytes
|
||||||
|
@ -259,7 +259,7 @@ static int CmdIOProxClone(const char *Cmd) {
|
||||||
|
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "lf io clone",
|
CLIParserInit(&ctx, "lf io clone",
|
||||||
"Enables simulation of IOProx card with specified facility-code and card number.\n"
|
"Enables simulation of ioProx card with specified facility-code and card number.\n"
|
||||||
"Tag must be on the antenna when issuing this command.",
|
"Tag must be on the antenna when issuing this command.",
|
||||||
"lf io clone --vn 1 --fc 101 --cn 1337"
|
"lf io clone --vn 1 --fc 101 --cn 1337"
|
||||||
);
|
);
|
||||||
|
@ -292,7 +292,7 @@ static int CmdIOProxClone(const char *Cmd) {
|
||||||
|
|
||||||
if ((cn & 0xFFFF) != cn) {
|
if ((cn & 0xFFFF) != cn) {
|
||||||
cn &= 0xFFFF;
|
cn &= 0xFFFF;
|
||||||
PrintAndLogEx(INFO, "Card Number Truncated to 16-bits (IOProx): %u", cn);
|
PrintAndLogEx(INFO, "Card Number Truncated to 16-bits (ioProx): %u", cn);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getIOProxBits(version, fc, cn, bits) != PM3_SUCCESS) {
|
if (getIOProxBits(version, fc, cn, bits) != PM3_SUCCESS) {
|
||||||
|
@ -317,7 +317,7 @@ static int CmdIOProxClone(const char *Cmd) {
|
||||||
blocks[1] = bytebits_to_byte(bits, 32);
|
blocks[1] = bytebits_to_byte(bits, 32);
|
||||||
blocks[2] = bytebits_to_byte(bits + 32, 32);
|
blocks[2] = bytebits_to_byte(bits + 32, 32);
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "Preparing to clone IOProx to " _YELLOW_("%s") " with Version: " _GREEN_("%u") " FC: " _GREEN_("%u (0x%02x)") " CN: " _GREEN_("%u")
|
PrintAndLogEx(INFO, "Preparing to clone ioProx to " _YELLOW_("%s") " with Version: " _GREEN_("%u") " FC: " _GREEN_("%u (0x%02x)") " CN: " _GREEN_("%u")
|
||||||
, cardtype
|
, cardtype
|
||||||
, version
|
, version
|
||||||
, fc
|
, fc
|
||||||
|
@ -339,10 +339,10 @@ static int CmdIOProxClone(const char *Cmd) {
|
||||||
|
|
||||||
static command_t CommandTable[] = {
|
static command_t CommandTable[] = {
|
||||||
{"help", CmdHelp, AlwaysAvailable, "this help"},
|
{"help", CmdHelp, AlwaysAvailable, "this help"},
|
||||||
{"demod", CmdIOProxDemod, AlwaysAvailable, "demodulate an IOProx tag from the GraphBuffer"},
|
{"demod", CmdIOProxDemod, AlwaysAvailable, "demodulate an ioProx tag from the GraphBuffer"},
|
||||||
{"reader", CmdIOProxReader, IfPm3Lf, "attempt to read and extract tag data"},
|
{"reader", CmdIOProxReader, IfPm3Lf, "attempt to read and extract tag data"},
|
||||||
{"clone", CmdIOProxClone, IfPm3Lf, "clone IOProx tag to T55x7 or Q5/T5555"},
|
{"clone", CmdIOProxClone, IfPm3Lf, "clone ioProx tag to T55x7 or Q5/T5555"},
|
||||||
{"sim", CmdIOProxSim, IfPm3Lf, "simulate IOProx tag"},
|
{"sim", CmdIOProxSim, IfPm3Lf, "simulate ioProx tag"},
|
||||||
{"watch", CmdIOProxWatch, IfPm3Lf, "continuously watch for cards. Reader mode"},
|
{"watch", CmdIOProxWatch, IfPm3Lf, "continuously watch for cards. Reader mode"},
|
||||||
{NULL, NULL, NULL, NULL}
|
{NULL, NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
|
@ -519,8 +519,8 @@ static int CmdTraceLoad(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "trace load",
|
CLIParserInit(&ctx, "trace load",
|
||||||
"Load protocol data from binary file to trace buffer\n"
|
"Load protocol data from binary file to trace buffer\n"
|
||||||
"File extension is (.trace)",
|
"File extension is <.trace>",
|
||||||
"trace load -f mytracefile"
|
"trace load -f mytracefile -> w/o file extension"
|
||||||
);
|
);
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
|
@ -555,13 +555,13 @@ static int CmdTraceSave(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "trace save",
|
CLIParserInit(&ctx, "trace save",
|
||||||
"Save protocol data from trace buffer to binary file\n"
|
"Save protocol data from trace buffer to binary file\n"
|
||||||
"File extension is (.trace)",
|
"File extension is <.trace>",
|
||||||
"trace save -f mytracefile"
|
"trace save -f mytracefile -> w/o file extension"
|
||||||
);
|
);
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_strx0("f", "file", "<filename>", "trace file to load"),
|
arg_strx0("f", "file", "<filename>", "trace file to save"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
|
|
@ -151,8 +151,8 @@ int CmdWiegandDecode(const char *Cmd) {
|
||||||
static command_t CommandTable[] = {
|
static command_t CommandTable[] = {
|
||||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||||
{"list", CmdWiegandList, AlwaysAvailable, "List available wiegand formats"},
|
{"list", CmdWiegandList, AlwaysAvailable, "List available wiegand formats"},
|
||||||
{"encode", CmdWiegandEncode, AlwaysAvailable, "Encode to wiegand raw hex"},
|
{"encode", CmdWiegandEncode, AlwaysAvailable, "Encode to wiegand raw hex (currently for HID Prox)"},
|
||||||
{"decode", CmdWiegandDecode, AlwaysAvailable, "Convert raw hex to decoded wiegand format"},
|
{"decode", CmdWiegandDecode, AlwaysAvailable, "Convert raw hex to decoded wiegand format (currently for HID Prox)"},
|
||||||
{NULL, NULL, NULL, NULL}
|
{NULL, NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -174,30 +174,11 @@ lf simfsk
|
||||||
lf simpsk
|
lf simpsk
|
||||||
lf simbidir
|
lf simbidir
|
||||||
lf sniff
|
lf sniff
|
||||||
lf tune
|
lf em 410x
|
||||||
lf em 410x_demod
|
lf em 4x05
|
||||||
lf em 410x_read
|
lf em 4x50
|
||||||
lf em 410x_sim
|
|
||||||
lf em 410x_brute
|
|
||||||
lf em 410x_watch
|
|
||||||
lf em 410x_spoof
|
|
||||||
lf em 410x_clone
|
|
||||||
lf em 4x05_demod
|
|
||||||
lf em 4x05_dump
|
|
||||||
lf em 4x05_wipe
|
|
||||||
lf em 4x05_info
|
|
||||||
lf em 4x05_read
|
|
||||||
lf em 4x05_write
|
|
||||||
lf em 4x50_dump
|
|
||||||
lf em 4x50_info
|
|
||||||
lf em 4x50_write
|
|
||||||
lf em 4x50_write_password
|
|
||||||
lf em 4x50_read
|
|
||||||
lf em 4x50_wipe
|
|
||||||
lf hitag info
|
|
||||||
lf hitag reader
|
lf hitag reader
|
||||||
lf hitag sim
|
lf hitag sim
|
||||||
lf hitag sniff
|
|
||||||
lf hitag writer
|
lf hitag writer
|
||||||
lf hitag dump
|
lf hitag dump
|
||||||
lf hitag cc
|
lf hitag cc
|
||||||
|
|
|
@ -572,34 +572,14 @@ Check column "offline" for their availability.
|
||||||
|
|
||||||
### lf em
|
### lf em
|
||||||
|
|
||||||
{ EM4X CHIPs & RFIDs... }
|
{ EM CHIPs & RFIDs... }
|
||||||
|
|
||||||
|command |offline |description
|
|command |offline |description
|
||||||
|------- |------- |-----------
|
|------- |------- |-----------
|
||||||
|`lf em help `|Y |`This help`
|
|`lf em help `|Y |`This help`
|
||||||
|`lf em 410x_demod `|Y |`demodulate a EM410x tag from the GraphBuffer`
|
|`lf em 410x `|Y |`EM 410x commands...`
|
||||||
|`lf em 410x_read `|N |`attempt to read and extract tag data`
|
|`lf em 4x05 `|Y |`EM 4x05 commands...`
|
||||||
|`lf em 410x_sim `|N |`simulate EM410x tag`
|
|`lf em 4x50 `|Y |`EM 4x50 commands...`
|
||||||
|`lf em 410x_brute `|N |`reader bruteforce attack by simulating EM410x tags`
|
|
||||||
|`lf em 410x_watch `|N |`watches for EM410x 125/134 kHz tags (option 'h' for 134)`
|
|
||||||
|`lf em 410x_spoof `|N |`watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)`
|
|
||||||
|`lf em 410x_clone `|N |`write EM410x UID to T55x7 or Q5/T5555 tag`
|
|
||||||
|`lf em 4x05_chk `|N |`Check passwords from dictionary`
|
|
||||||
|`lf em 4x05_demod `|Y |`demodulate a EM4x05/EM4x69 tag from the GraphBuffer`
|
|
||||||
|`lf em 4x05_dump `|N |`dump EM4x05/EM4x69 tag`
|
|
||||||
|`lf em 4x05_wipe `|N |`wipe EM4x05/EM4x69 tag`
|
|
||||||
|`lf em 4x05_info `|N |`tag information EM4x05/EM4x69`
|
|
||||||
|`lf em 4x05_read `|N |`read word data from EM4x05/EM4x69`
|
|
||||||
|`lf em 4x05_write `|N |`write word data to EM4x05/EM4x69`
|
|
||||||
|`lf em 4x05_unlock `|N |`execute tear off against EM4x05/EM4x69`
|
|
||||||
|`lf em 4x05_sniff `|Y |`Attempt to recover em4x05 commands from sample buffer`
|
|
||||||
|`lf em 4x05_brute `|N |`Bruteforce password`
|
|
||||||
|`lf em 4x50_dump `|N |`dump EM4x50 tag`
|
|
||||||
|`lf em 4x50_info `|N |`tag information EM4x50`
|
|
||||||
|`lf em 4x50_write `|N |`write word data to EM4x50`
|
|
||||||
|`lf em 4x50_write_password`|N |`change password of EM4x50 tag`
|
|
||||||
|`lf em 4x50_read `|N |`read word data from EM4x50`
|
|
||||||
|`lf em 4x50_wipe `|N |`wipe data from EM4x50`
|
|
||||||
|
|
||||||
|
|
||||||
### lf fdxb
|
### lf fdxb
|
||||||
|
|
|
@ -363,7 +363,7 @@ while true; do
|
||||||
if ! CheckExecute slow "lf T55 awid 50 test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_awid_50.pm3; lf awid demod'" \
|
if ! CheckExecute slow "lf T55 awid 50 test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_awid_50.pm3; lf awid demod'" \
|
||||||
"AWID - len: 50 FC: 2001 Card: 13371337 - Wiegand: 20fa201980f92, Raw: 0128b12eb1811d7117e22111"; then break; fi
|
"AWID - len: 50 FC: 2001 Card: 13371337 - Wiegand: 20fa201980f92, Raw: 0128b12eb1811d7117e22111"; then break; fi
|
||||||
if ! CheckExecute slow "lf T55 em410x test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_em410x.pm3; lf search 1'" "EM410x ID found"; then break; fi
|
if ! CheckExecute slow "lf T55 em410x test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_em410x.pm3; lf search 1'" "EM410x ID found"; then break; fi
|
||||||
if ! CheckExecute slow "lf T55 em410x test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_em410x.pm3; lf em 410x_demod demod'" \
|
if ! CheckExecute slow "lf T55 em410x test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_em410x.pm3; lf em 410x demod'" \
|
||||||
"EM TAG ID : 0F0368568B"; then break; fi
|
"EM TAG ID : 0F0368568B"; then break; fi
|
||||||
if ! CheckExecute slow "lf T55 fdxb_animal test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_fdxb_animal.pm3; lf search 1'" "FDX-B ID found"; then break; fi
|
if ! CheckExecute slow "lf T55 fdxb_animal test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_fdxb_animal.pm3; lf search 1'" "FDX-B ID found"; then break; fi
|
||||||
if ! CheckExecute slow "lf T55 fdxb_animal test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_fdxb_animal.pm3; lf fdxb demod'" \
|
if ! CheckExecute slow "lf T55 fdxb_animal test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_fdxb_animal.pm3; lf fdxb demod'" \
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue