mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 05:13:46 -07:00
add u64_from_hex, no need to use 0x, thanks @mwalker33!\n reverse blocks when cloning for em4305/4469
This commit is contained in:
parent
0ccbd6e0fb
commit
be8d2fbd25
6 changed files with 85 additions and 47 deletions
|
@ -11,8 +11,10 @@
|
|||
#include "cliparser.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <util.h> // Get color constants
|
||||
#include <ui.h> // get PrintAndLogEx
|
||||
#include <util.h> // Get color constants
|
||||
#include <ui.h> // get PrintAndLogEx
|
||||
#include <ctype.h> // tolower
|
||||
#include <inttypes.h> // PRIu64
|
||||
|
||||
#ifndef ARRAYLEN
|
||||
# define ARRAYLEN(x) (sizeof(x)/sizeof((x)[0]))
|
||||
|
@ -125,7 +127,6 @@ int CLIParserParseArg(CLIParserContext *ctx, int argc, char **argv, void *vargta
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
enum ParserState {
|
||||
PS_FIRST,
|
||||
PS_ARGUMENT,
|
||||
|
@ -272,4 +273,20 @@ int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int
|
|||
return 0;
|
||||
}
|
||||
|
||||
uint64_t arg_get_u64_hexstr_def(CLIParserContext *ctx, uint8_t paramnum, uint64_t def) {
|
||||
uint64_t rv = 0;
|
||||
uint8_t data[8];
|
||||
int datalen = 0;
|
||||
int res = CLIParamHexToBuf(arg_get_str(ctx, paramnum), data, sizeof(data), &datalen);
|
||||
if (res == 0) {
|
||||
for (uint8_t i = 0; i < datalen; i++) {
|
||||
rv <<= 8;
|
||||
rv |= data[i];
|
||||
}
|
||||
} else {
|
||||
rv = def;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -66,4 +66,6 @@ int CLIParserParseArg(CLIParserContext *ctx, int argc, char **argv, void *vargta
|
|||
|
||||
int CLIParamHexToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen);
|
||||
int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen);
|
||||
|
||||
uint64_t arg_get_u64_hexstr_def(CLIParserContext *ctx, uint8_t paramnum, uint64_t def);
|
||||
#endif
|
||||
|
|
|
@ -374,19 +374,17 @@ int em4x05_clone_tag(uint32_t *blockdata, uint8_t numblocks, uint32_t pwd, bool
|
|||
|
||||
// fast push mode
|
||||
conn.block_after_ACK = true;
|
||||
|
||||
int res = em4x05_write_word_ext(EM_CONFIG_BLOCK, pwd, use_pwd, blockdata[0]);
|
||||
if (res != PM3_SUCCESS) {
|
||||
PrintAndLogEx(FAILED, "(em4x05_clone_tag) Time out writing to tag");
|
||||
return res;
|
||||
}
|
||||
|
||||
for (int8_t i = 1; i < numblocks; i++) {
|
||||
int res = 0;
|
||||
for (int8_t i = 0; i < numblocks; i++) {
|
||||
|
||||
// Disable fast mode on last packet
|
||||
if (i == numblocks - 1) {
|
||||
conn.block_after_ACK = false;
|
||||
}
|
||||
|
||||
if (i != 0) {
|
||||
blockdata[i] = reflect(blockdata[i], 32);
|
||||
}
|
||||
|
||||
res = em4x05_write_word_ext(4 + i, pwd, use_pwd, blockdata[i]);
|
||||
if (res != PM3_SUCCESS) {
|
||||
|
@ -396,19 +394,14 @@ int em4x05_clone_tag(uint32_t *blockdata, uint8_t numblocks, uint32_t pwd, bool
|
|||
}
|
||||
|
||||
res = 0;
|
||||
if (em4x05_verify_write(EM_CONFIG_BLOCK, use_pwd, pwd, blockdata[0]) == false) {
|
||||
res++;
|
||||
}
|
||||
|
||||
for (int8_t i = 1; i < numblocks; i++) {
|
||||
for (int8_t i = 0; i < numblocks; i++) {
|
||||
if (em4x05_verify_write(4 + i, use_pwd, pwd, blockdata[i]) == false) {
|
||||
res++;
|
||||
}
|
||||
}
|
||||
|
||||
if (res == 0) {
|
||||
if (res == 0)
|
||||
PrintAndLogEx(SUCCESS, "Success writing to tag");
|
||||
}
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
@ -496,19 +489,19 @@ int CmdEM4x05Dump(const char *Cmd) {
|
|||
CLIParserInit(&ctx, "lf em dump",
|
||||
"Dump EM4x05/EM4x69. Tag must be on antenna.",
|
||||
"lf em dump\n"
|
||||
"lf em dump -p 0x11223344\n"
|
||||
"lf em dump -f myfile -p 0x11223344"
|
||||
"lf em dump -p 11223344\n"
|
||||
"lf em dump -f myfile -p 11223344"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_u64_0("p", "pwd", "<hex>", "password (0x00000000)"),
|
||||
arg_str0("p", "pwd", "<hex>", "password (00000000)"),
|
||||
arg_str0("f", "file", "<filename>", "override filename prefix (optional). Default is based on UID"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
uint64_t inputpwd = arg_get_u64_def(ctx, 1, 0xFFFFFFFFFFFFFFFF);
|
||||
uint64_t inputpwd = arg_get_u64_hexstr_def(ctx, 1, 0xFFFFFFFFFFFFFFFF);
|
||||
int fnlen = 0;
|
||||
char filename[FILE_PATH_SIZE] = {0};
|
||||
CLIParamStrToBuf(arg_get_str(ctx, 2), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
|
||||
|
@ -1139,21 +1132,22 @@ int CmdEM4x05Chk(const char *Cmd) {
|
|||
CLIParserInit(&ctx, "lf em 4x05_chk",
|
||||
"This command uses a dictionary attack against EM4205/4305/4469/4569",
|
||||
"lf em 4x05_chk\n"
|
||||
"lf em 4x05_chk -e 0x00000022B8 -> 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"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_strx0("f", "file", "<*.dic>", "loads a default keys dictionary file <*.dic>"),
|
||||
arg_u64_0("e", "em", "<EM4100>", "try the calculated password from some cloners based on EM4100 ID"),
|
||||
arg_str0("e", "em", "<EM4100>", "try the calculated password from some cloners based on EM4100 ID"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
int fnlen = 0;
|
||||
char filename[FILE_PATH_SIZE] = {0};
|
||||
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
|
||||
uint64_t card_id = arg_get_u64_def(ctx, 2, 0);
|
||||
|
||||
uint64_t card_id = arg_get_u64_hexstr_def(ctx, 2, 0);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (strlen(filename) == 0) {
|
||||
|
@ -1241,7 +1235,7 @@ int CmdEM4x05Brute(const char *Cmd) {
|
|||
"Note: if you get many false positives, change position on the antenna"
|
||||
"lf em 4x05_brute\n"
|
||||
"lf em 4x05_brute -n 1 -> stop after first candidate found\n"
|
||||
"lf em 4x05_brute -s 0x000022B8 -> remember to use 0x for hex"
|
||||
"lf em 4x05_brute -s 000022B8 -> remember to use 0x for hex"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
|
@ -1251,7 +1245,7 @@ int CmdEM4x05Brute(const char *Cmd) {
|
|||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
uint32_t start_pwd = arg_get_u64_def(ctx, 1, 0);
|
||||
uint32_t start_pwd = arg_get_u64_hexstr_def(ctx, 1, 0);
|
||||
uint32_t n = arg_get_int_def(ctx, 2, 0);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
|
@ -1352,7 +1346,7 @@ int CmdEM4x05Unlock(const char *Cmd) {
|
|||
arg_int0("n", NULL, NULL, "steps to skip"),
|
||||
arg_int0("s", "start", "<us>", "start scan from delay (us)"),
|
||||
arg_int0("e", "end", "<us>", "end scan at delay (us)"),
|
||||
arg_u64_0("p", "pwd", "", "password (0x00000000)"),
|
||||
arg_str0("p", "pwd", "", "password (00000000)"),
|
||||
arg_lit0("v", "verbose", "verbose output"),
|
||||
arg_param_end
|
||||
};
|
||||
|
@ -1360,7 +1354,7 @@ int CmdEM4x05Unlock(const char *Cmd) {
|
|||
double n = (double)arg_get_int_def(ctx, 1, 0);
|
||||
double start = (double)arg_get_int_def(ctx, 2, 2000);
|
||||
double end = (double)arg_get_int_def(ctx, 3, 6000);
|
||||
uint64_t inputpwd = arg_get_u64_def(ctx, 4, 0xFFFFFFFFFFFFFFFF);
|
||||
uint64_t inputpwd = arg_get_u64_hexstr_def(ctx, 4, 0xFFFFFFFFFFFFFFFF);
|
||||
bool verbose = arg_get_lit(ctx, 5);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
|
|
|
@ -205,7 +205,7 @@ static int CmdKeriClone(const char *Cmd) {
|
|||
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf keri clone",
|
||||
"clone a KERI tag to a T55x7, Q5/T5555 or EM4305 tag",
|
||||
"clone a KERI tag to a T55x7, Q5/T5555 or EM4305/4469 tag",
|
||||
"lf keri clone -t i --id 12345\n"
|
||||
"lf keri clone -t m --fc 6 --id 12345\n");
|
||||
|
||||
|
@ -215,17 +215,20 @@ static int CmdKeriClone(const char *Cmd) {
|
|||
arg_str0("t", "type", "<m|i>", "Type m - MS, i - Internal ID"),
|
||||
arg_int0(NULL, "fc", "<dec>", "Facility Code"),
|
||||
arg_int1(NULL, "id", "<dec>", "Keri ID"),
|
||||
arg_lit0(NULL, "em4305", "specify writing to EM5405 tag"),
|
||||
arg_lit0(NULL, "em", "specify writing to EM4305/4469 tag"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
char cardtype[16] = {"T55x7"};
|
||||
if (arg_get_lit(ctx, 1)) {
|
||||
blocks[0] = T5555_FIXED | T5555_MODULATION_PSK1 | T5555_SET_BITRATE(32) | T5555_PSK_RF_2 | 2 << T5555_MAXBLOCK_SHIFT;
|
||||
snprintf(cardtype, sizeof(cardtype) ,"Q5/T5555");
|
||||
q5 = true;
|
||||
}
|
||||
if (arg_get_lit(ctx, 5)) {
|
||||
blocks[0] = EM4305_KERI_CONFIG_BLOCK;
|
||||
blocks[0] = EM4305_KERI_CONFIG_BLOCK;
|
||||
snprintf(cardtype, sizeof(cardtype) ,"EM4305/4469");
|
||||
em4305 = true;
|
||||
}
|
||||
|
||||
|
@ -258,7 +261,7 @@ static int CmdKeriClone(const char *Cmd) {
|
|||
// Prepare and write to card
|
||||
// 3 LSB is ONE
|
||||
uint64_t data = ((uint64_t)internalid << 3) + 7;
|
||||
PrintAndLogEx(INFO, "Preparing to clone KERI to " _YELLOW_("%s") " with Internal Id " _YELLOW_("%" PRIx32), (q5) ? "Q5/T5555" : "T55x7", internalid);
|
||||
PrintAndLogEx(INFO, "Preparing to clone KERI to " _YELLOW_("%s") " with Internal Id " _YELLOW_("%" PRIx32), cardtype, internalid);
|
||||
|
||||
blocks[1] = data >> 32;
|
||||
blocks[2] = data & 0xFFFFFFFF;
|
||||
|
|
|
@ -10,23 +10,23 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdlfvisa2000.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "commonutil.h" // ARRAYLEN
|
||||
#include <stdio.h>
|
||||
#include "commonutil.h" // ARRAYLEN
|
||||
#include "common.h"
|
||||
#include "cmdparser.h" // command_t
|
||||
#include "cmdparser.h" // command_t
|
||||
#include "comms.h"
|
||||
#include "ui.h"
|
||||
#include "graph.h"
|
||||
#include "cmddata.h"
|
||||
#include "cmdlf.h"
|
||||
#include "protocols.h" // for T55xx config register definitions
|
||||
#include "lfdemod.h" // parityTest
|
||||
#include "protocols.h" // for T55xx config register definitions
|
||||
#include "lfdemod.h" // parityTest
|
||||
#include "cmdlft55xx.h" // write verify
|
||||
#include "cmdlfem4x05.h" //
|
||||
|
||||
#define BL0CK1 0x56495332
|
||||
|
||||
|
@ -39,10 +39,12 @@ static int usage_lf_visa2k_clone(void) {
|
|||
PrintAndLogEx(NORMAL, " h : This help");
|
||||
PrintAndLogEx(NORMAL, " <card ID> : Visa2k card ID");
|
||||
PrintAndLogEx(NORMAL, " <Q5> : specify writing to Q5/T5555 tag");
|
||||
PrintAndLogEx(NORMAL, " <em4305> : specify writing to EM4305/4469 tag");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" lf visa2000 clone 112233"));
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" lf visa2000 clone 112233 q5") " -- encode for Q5/T5555");
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" lf visa2000 clone 112233 em4305") " -- encode for EM4305/4469");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -180,18 +182,38 @@ static int CmdVisa2kClone(const char *Cmd) {
|
|||
|
||||
id = param_get32ex(Cmd, 0, 0, 10);
|
||||
|
||||
//Q5
|
||||
char cardtype[16] = {"T55x7"};
|
||||
// Q5
|
||||
bool q5 = tolower(param_getchar(Cmd, 1)) == 'q';
|
||||
if (q5)
|
||||
if (q5) {
|
||||
blocks[0] = T5555_FIXED | T5555_MODULATION_MANCHESTER | T5555_SET_BITRATE(64) | T5555_ST_TERMINATOR | 3 << T5555_MAXBLOCK_SHIFT;
|
||||
snprintf(cardtype, sizeof(cardtype) ,"Q5/T5555");
|
||||
}
|
||||
|
||||
// EM4305
|
||||
bool em4305 = tolower(param_getchar(Cmd, 1)) == 'e';
|
||||
if (em4305) {
|
||||
blocks[0] = EM4305_VISA2000_CONFIG_BLOCK;
|
||||
snprintf(cardtype, sizeof(cardtype) ,"EM4305/4469");
|
||||
}
|
||||
|
||||
if (q5 && em4305) {
|
||||
PrintAndLogEx(FAILED, "Can't specify both Q5 and EM4305 at the same time");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
blocks[2] = id;
|
||||
blocks[3] = (visa_parity(id) << 4) | visa_chksum(id);
|
||||
|
||||
PrintAndLogEx(INFO, "Preparing to clone Visa2000 to " _YELLOW_("%s") " with CardId: %"PRIu64, (q5) ? "Q5/T5555" : "T55x7", id);
|
||||
PrintAndLogEx(INFO, "Preparing to clone Visa2000 to " _YELLOW_("%s") " with CardId: %"PRIu64, cardtype, id);
|
||||
print_blocks(blocks, ARRAYLEN(blocks));
|
||||
|
||||
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||
int res;
|
||||
if (em4305) {
|
||||
res = em4x05_clone_tag(blocks, ARRAYLEN(blocks), 0, false);
|
||||
} else {
|
||||
res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||
}
|
||||
PrintAndLogEx(SUCCESS, "Done");
|
||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf visa2000 read`") " to verify");
|
||||
return res;
|
||||
|
|
|
@ -541,8 +541,8 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
|
|||
#define T55XX_WRITE_TIMEOUT 1500
|
||||
|
||||
// em4x05 & em4x69 chip configuration register definitions
|
||||
#define EM4x05_GET_BITRATE(x) (((x & 0x3F)*2)+2)
|
||||
#define EM4x05_SET_BITRATE(x) ((x-2)/2)
|
||||
#define EM4x05_GET_BITRATE(x) ((((x) & 0x3F) * 2) + 2)
|
||||
#define EM4x05_SET_BITRATE(x) (((x) - 2) / 2)
|
||||
#define EM4x05_MODULATION_NRZ 0x00000000
|
||||
#define EM4x05_MODULATION_MANCHESTER 0x00000040
|
||||
#define EM4x05_MODULATION_BIPHASE 0x00000080
|
||||
|
@ -557,8 +557,8 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
|
|||
#define EM4x05_PSK_RF_8 0x00000800
|
||||
#define EM4x05_MAXBLOCK_SHIFT 14
|
||||
#define EM4x05_FIRST_USER_BLOCK 5
|
||||
#define EM4x05_SET_NUM_BLOCKS(x) ((x+5-1)<<14) //# of blocks sent during default read mode
|
||||
#define EM4x05_GET_NUM_BLOCKS(x) (((x>>14) & 0xF)-5+1)
|
||||
#define EM4x05_SET_NUM_BLOCKS(x) (( (x) + 4) << 14) //# of blocks sent during default read mode
|
||||
#define EM4x05_GET_NUM_BLOCKS(x) ((( (x) >> 14) & 0xF) - 4)
|
||||
#define EM4x05_READ_LOGIN_REQ (1 << 18)
|
||||
#define EM4x05_READ_HK_LOGIN_REQ (1 << 19)
|
||||
#define EM4x05_WRITE_LOGIN_REQ (1 << 20)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue