Merge branch 'master' into update_4x50

merged 201206
This commit is contained in:
tharexde 2020-12-06 20:40:46 +01:00
commit 894d973d69
21 changed files with 502 additions and 410 deletions

View file

@ -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

View file

@ -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 \

View file

@ -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

View file

@ -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"

View file

@ -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}
}; };

View file

@ -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
View 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
View 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

View file

@ -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);
} }

View file

@ -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);

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);

View file

@ -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;
} }

View file

@ -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}

View file

@ -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}
}; };

View file

@ -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);

View file

@ -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}
}; };

View file

@ -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

View file

@ -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

View file

@ -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'" \