mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 05:13:46 -07:00
EM 4x05 login bf
This commit is contained in:
parent
9003b96312
commit
3b83e8e703
7 changed files with 110 additions and 8 deletions
|
@ -978,6 +978,15 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
EM4xLogin(payload->password);
|
EM4xLogin(payload->password);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case CMD_LF_EM4X_BF: {
|
||||||
|
struct p {
|
||||||
|
uint32_t start_pwd;
|
||||||
|
uint32_t n;
|
||||||
|
} PACKED;
|
||||||
|
struct p *payload = (struct p *) packet->data.asBytes;
|
||||||
|
EM4xBruteforce(payload->start_pwd, payload->n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case CMD_LF_EM4X_READWORD: {
|
case CMD_LF_EM4X_READWORD: {
|
||||||
struct p {
|
struct p {
|
||||||
uint32_t password;
|
uint32_t password;
|
||||||
|
|
|
@ -2467,7 +2467,7 @@ static uint8_t Prepare_Data(uint16_t data_low, uint16_t data_hi) {
|
||||||
// Requires: forwarLink_data filled with valid bits (1 bit per byte)
|
// Requires: forwarLink_data filled with valid bits (1 bit per byte)
|
||||||
// fwd_bit_count set with number of bits to be sent
|
// fwd_bit_count set with number of bits to be sent
|
||||||
//====================================================================
|
//====================================================================
|
||||||
static void SendForward(uint8_t fwd_bit_count) {
|
static void SendForward(uint8_t fwd_bit_count, bool fast) {
|
||||||
|
|
||||||
// iceman, 21.3us increments for the USclock verification.
|
// iceman, 21.3us increments for the USclock verification.
|
||||||
// 55FC * 8us == 440us / 21.3 === 20.65 steps. could be too short. Go for 56FC instead
|
// 55FC * 8us == 440us / 21.3 === 20.65 steps. could be too short. Go for 56FC instead
|
||||||
|
@ -2480,9 +2480,10 @@ static void SendForward(uint8_t fwd_bit_count) {
|
||||||
fwd_write_ptr = forwardLink_data;
|
fwd_write_ptr = forwardLink_data;
|
||||||
fwd_bit_sz = fwd_bit_count;
|
fwd_bit_sz = fwd_bit_count;
|
||||||
|
|
||||||
// Set up FPGA, 125kHz or 95 divisor
|
if (! fast) {
|
||||||
LFSetupFPGAForADC(LF_DIVISOR_125, true);
|
// Set up FPGA, 125kHz or 95 divisor
|
||||||
|
LFSetupFPGAForADC(LF_DIVISOR_125, true);
|
||||||
|
}
|
||||||
// force 1st mod pulse (start gap must be longer for 4305)
|
// force 1st mod pulse (start gap must be longer for 4305)
|
||||||
fwd_bit_sz--; //prepare next bit modulation
|
fwd_bit_sz--; //prepare next bit modulation
|
||||||
fwd_write_ptr++;
|
fwd_write_ptr++;
|
||||||
|
@ -2505,13 +2506,59 @@ static void EM4xLoginEx(uint32_t pwd) {
|
||||||
forward_ptr = forwardLink_data;
|
forward_ptr = forwardLink_data;
|
||||||
uint8_t len = Prepare_Cmd(FWD_CMD_LOGIN);
|
uint8_t len = Prepare_Cmd(FWD_CMD_LOGIN);
|
||||||
len += Prepare_Data(pwd & 0xFFFF, pwd >> 16);
|
len += Prepare_Data(pwd & 0xFFFF, pwd >> 16);
|
||||||
SendForward(len);
|
SendForward(len, false);
|
||||||
//WaitUS(20); // no wait for login command.
|
//WaitUS(20); // no wait for login command.
|
||||||
// should receive
|
// should receive
|
||||||
// 0000 1010 ok
|
// 0000 1010 ok
|
||||||
// 0000 0001 fail
|
// 0000 0001 fail
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EM4xBruteforce(uint32_t start_pwd, uint32_t n) {
|
||||||
|
// With current timing, 18.6 ms per test = 53.8 pwds/s
|
||||||
|
reply_ng(CMD_LF_EM4X_BF, PM3_SUCCESS, NULL, 0);
|
||||||
|
StartTicks();
|
||||||
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
WaitMS(20);
|
||||||
|
LED_A_ON();
|
||||||
|
LFSetupFPGAForADC(LF_DIVISOR_125, true);
|
||||||
|
uint32_t candidates_found = 0;
|
||||||
|
for (uint32_t pwd = start_pwd; pwd < 0xFFFFFFFF; pwd++) {
|
||||||
|
if (((pwd - start_pwd) & 0x3F) == 0x00) {
|
||||||
|
WDT_HIT();
|
||||||
|
if (BUTTON_PRESS() || data_available()) {
|
||||||
|
Dbprintf("EM4x05 Bruteforce Interrupted");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Report progress every 256 attempts
|
||||||
|
if (((pwd - start_pwd) & 0xFF) == 0x00) {
|
||||||
|
Dbprintf("Trying: %06Xxx", pwd >> 8);
|
||||||
|
}
|
||||||
|
clear_trace();
|
||||||
|
|
||||||
|
forward_ptr = forwardLink_data;
|
||||||
|
uint8_t len = Prepare_Cmd(FWD_CMD_LOGIN);
|
||||||
|
len += Prepare_Data(pwd & 0xFFFF, pwd >> 16);
|
||||||
|
SendForward(len, true);
|
||||||
|
|
||||||
|
WaitUS(400);
|
||||||
|
DoPartialAcquisition(0, false, 350, 1000);
|
||||||
|
uint8_t *mem = BigBuf_get_addr();
|
||||||
|
if (mem[334] < 128) {
|
||||||
|
Dbprintf("Password candidate: " _GREEN_("%08X"), pwd);
|
||||||
|
if ((n != 0) && (candidates_found == n)) {
|
||||||
|
Dbprintf("EM4x05 Bruteforce Stopped. %i candidates found", candidates_found);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Beware: if smaller, tag might not have time to be back in listening state yet
|
||||||
|
WaitMS(1);
|
||||||
|
}
|
||||||
|
StopTicks();
|
||||||
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
LEDsoff();
|
||||||
|
}
|
||||||
|
|
||||||
void EM4xLogin(uint32_t pwd) {
|
void EM4xLogin(uint32_t pwd) {
|
||||||
|
|
||||||
StartTicks();
|
StartTicks();
|
||||||
|
@ -2558,7 +2605,7 @@ void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd) {
|
||||||
uint8_t len = Prepare_Cmd(FWD_CMD_READ);
|
uint8_t len = Prepare_Cmd(FWD_CMD_READ);
|
||||||
len += Prepare_Addr(addr);
|
len += Prepare_Addr(addr);
|
||||||
|
|
||||||
SendForward(len);
|
SendForward(len, false);
|
||||||
|
|
||||||
WaitUS(400);
|
WaitUS(400);
|
||||||
|
|
||||||
|
@ -2594,7 +2641,7 @@ void EM4xWriteWord(uint8_t addr, uint32_t data, uint32_t pwd, uint8_t usepwd) {
|
||||||
len += Prepare_Addr(addr);
|
len += Prepare_Addr(addr);
|
||||||
len += Prepare_Data(data & 0xFFFF, data >> 16);
|
len += Prepare_Data(data & 0xFFFF, data >> 16);
|
||||||
|
|
||||||
SendForward(len);
|
SendForward(len, false);
|
||||||
|
|
||||||
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured
|
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured
|
||||||
StopTicks();
|
StopTicks();
|
||||||
|
@ -2636,7 +2683,7 @@ void EM4xProtectWord(uint32_t data, uint32_t pwd, uint8_t usepwd) {
|
||||||
uint8_t len = Prepare_Cmd(FWD_CMD_PROTECT);
|
uint8_t len = Prepare_Cmd(FWD_CMD_PROTECT);
|
||||||
len += Prepare_Data(data & 0xFFFF, data >> 16);
|
len += Prepare_Data(data & 0xFFFF, data >> 16);
|
||||||
|
|
||||||
SendForward(len);
|
SendForward(len, false);
|
||||||
|
|
||||||
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured
|
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured
|
||||||
StopTicks();
|
StopTicks();
|
||||||
|
|
|
@ -57,6 +57,7 @@ void T55xxDangerousRawTest(uint8_t *data);
|
||||||
void TurnReadLFOn(uint32_t delay);
|
void TurnReadLFOn(uint32_t delay);
|
||||||
|
|
||||||
void EM4xLogin(uint32_t pwd);
|
void EM4xLogin(uint32_t pwd);
|
||||||
|
void EM4xBruteforce(uint32_t start_pwd, uint32_t n);
|
||||||
void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd);
|
void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd);
|
||||||
void EM4xWriteWord(uint8_t addr, uint32_t data, uint32_t pwd, uint8_t usepwd);
|
void EM4xWriteWord(uint8_t addr, uint32_t data, uint32_t pwd, uint8_t usepwd);
|
||||||
void EM4xProtectWord(uint32_t data, uint32_t pwd, uint8_t usepwd);
|
void EM4xProtectWord(uint32_t data, uint32_t pwd, uint8_t usepwd);
|
||||||
|
|
|
@ -647,6 +647,7 @@ static command_t CommandTable[] = {
|
||||||
{"4x05_write", CmdEM4x05Write, IfPm3Lf, "write word data to EM4x05/EM4x69"},
|
{"4x05_write", CmdEM4x05Write, IfPm3Lf, "write word data to EM4x05/EM4x69"},
|
||||||
{"4x05_unlock", CmdEM4x05Unlock, IfPm3Lf, "execute tear off against EM4x05/EM4x69"},
|
{"4x05_unlock", CmdEM4x05Unlock, IfPm3Lf, "execute tear off against EM4x05/EM4x69"},
|
||||||
{"4x05_sniff", CmdEM4x05Sniff, IfPm3Lf, "Attempt to recover em4x05 commands from sample buffer"},
|
{"4x05_sniff", CmdEM4x05Sniff, IfPm3Lf, "Attempt to recover em4x05 commands from sample buffer"},
|
||||||
|
{"4x05_brute", CmdEM4x05Brute, IfPm3Lf, "Bruteforce password"},
|
||||||
{"----------", CmdHelp, AlwaysAvailable, "----------------------- " _CYAN_("EM 4x50") " -----------------------"},
|
{"----------", CmdHelp, AlwaysAvailable, "----------------------- " _CYAN_("EM 4x50") " -----------------------"},
|
||||||
{"4x50_dump", CmdEM4x50Dump, IfPm3EM4x50, "dump EM4x50 tag"},
|
{"4x50_dump", CmdEM4x50Dump, IfPm3EM4x50, "dump EM4x50 tag"},
|
||||||
{"4x50_info", CmdEM4x50Info, IfPm3EM4x50, "tag information EM4x50"},
|
{"4x50_info", CmdEM4x50Info, IfPm3EM4x50, "tag information EM4x50"},
|
||||||
|
|
|
@ -1178,6 +1178,48 @@ int CmdEM4x05Chk(const char *Cmd) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CmdEM4x05Brute(const char *Cmd) {
|
||||||
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "lf em 4x05_brute",
|
||||||
|
"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"
|
||||||
|
"lf em 4x05_brute\n"
|
||||||
|
"lf em 4x05_brute -n 1 -> stop after first candidate found\n"
|
||||||
|
"lf em 4x05_brute -s 0x00000022B8 -> remember to use 0x for hex"
|
||||||
|
);
|
||||||
|
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_u64_0("s", "start", "<pwd>", "Start bruteforce enumeration from this password value"),
|
||||||
|
arg_int0("n", "", "<digits>", "Stop after having found n candidates. Default: 0 => infinite"),
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
uint32_t start_pwd = arg_get_u64_def(ctx, 1, 0);
|
||||||
|
uint32_t n = arg_get_int_def(ctx, 1, 0);
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint32_t start_pwd;
|
||||||
|
uint32_t n;
|
||||||
|
} PACKED payload;
|
||||||
|
|
||||||
|
payload.start_pwd = start_pwd;
|
||||||
|
payload.n = n;
|
||||||
|
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommandNG(CMD_LF_EM4X_BF, (uint8_t *)&payload, sizeof(payload));
|
||||||
|
PacketResponseNG resp;
|
||||||
|
if (!WaitForResponseTimeout(CMD_LF_EM4X_BF, &resp, 1000)) {
|
||||||
|
PrintAndLogEx(WARNING, "(EM4x05 Bruteforce) timeout while waiting for reply.");
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
PrintAndLogEx(INFO, "Bruteforce is running on device side, press button to interrupt");
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t cnt;
|
uint16_t cnt;
|
||||||
uint32_t value;
|
uint32_t value;
|
||||||
|
|
|
@ -28,5 +28,6 @@ int CmdEM4x05Info(const char *Cmd);
|
||||||
int CmdEM4x05Chk(const char *Cmd);
|
int CmdEM4x05Chk(const char *Cmd);
|
||||||
int CmdEM4x05Unlock(const char *Cmd);
|
int CmdEM4x05Unlock(const char *Cmd);
|
||||||
int CmdEM4x05Sniff(const char *Cmd);
|
int CmdEM4x05Sniff(const char *Cmd);
|
||||||
|
int CmdEM4x05Brute(const char *Cmd);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -500,6 +500,7 @@ typedef struct {
|
||||||
#define CMD_LF_EM4X_READWORD 0x0218
|
#define CMD_LF_EM4X_READWORD 0x0218
|
||||||
#define CMD_LF_EM4X_WRITEWORD 0x0219
|
#define CMD_LF_EM4X_WRITEWORD 0x0219
|
||||||
#define CMD_LF_EM4X_PROTECTWORD 0x021B
|
#define CMD_LF_EM4X_PROTECTWORD 0x021B
|
||||||
|
#define CMD_LF_EM4X_BF 0x022A
|
||||||
#define CMD_LF_IO_WATCH 0x021A
|
#define CMD_LF_IO_WATCH 0x021A
|
||||||
#define CMD_LF_EM410X_WATCH 0x021C
|
#define CMD_LF_EM410X_WATCH 0x021C
|
||||||
#define CMD_LF_EM4X50_INFO 0x0240
|
#define CMD_LF_EM4X50_INFO 0x0240
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue