mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 22:03:42 -07:00
Merge pull request #1339 from Guilhem7/master
Update for cmdlfnexwatch.c
This commit is contained in:
commit
65e398d47f
2 changed files with 62 additions and 7 deletions
|
@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file.
|
||||||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||||
|
|
||||||
## [unreleased][unreleased]
|
## [unreleased][unreleased]
|
||||||
|
- Added bruteforce function for the magic byte in `cmdlfnexwatch.c` and ability to clone with psk2 modulation (@Guilhem7, @MaximeBosca)
|
||||||
- Changed `hw setmux` - improve user feedback for special case (@iceman1001)
|
- Changed `hw setmux` - improve user feedback for special case (@iceman1001)
|
||||||
- Changed 'filename' - unified file name param across client (@iceman1001)
|
- Changed 'filename' - unified file name param across client (@iceman1001)
|
||||||
- Fix `lf em 4x05 brute/chk` - fixed input params crash (@iceman1001)
|
- Fix `lf em 4x05 brute/chk` - fixed input params crash (@iceman1001)
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
#include "cmdlft55xx.h" // clone..
|
#include "cmdlft55xx.h" // clone..
|
||||||
#include "cmdlfem4x05.h" //
|
#include "cmdlfem4x05.h" //
|
||||||
#include "cliparser.h"
|
#include "cliparser.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SCRAMBLE,
|
SCRAMBLE,
|
||||||
|
@ -52,7 +54,7 @@ static uint8_t nexwatch_parity(uint8_t hexid[5]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// NETWATCH checksum
|
/// NETWATCH checksum
|
||||||
/// @param magic = 0xBE Quadrakey, 0x88 Nexkey
|
/// @param magic = 0xBE Quadrakey, 0x88 Nexkey, 0x86 Honeywell
|
||||||
/// @param id = descrambled id (printed card number)
|
/// @param id = descrambled id (printed card number)
|
||||||
/// @param parity = the parity based upon the scrambled raw id.
|
/// @param parity = the parity based upon the scrambled raw id.
|
||||||
static uint8_t nexwatch_checksum(uint8_t magic, uint32_t id, uint8_t parity) {
|
static uint8_t nexwatch_checksum(uint8_t magic, uint32_t id, uint8_t parity) {
|
||||||
|
@ -108,6 +110,20 @@ static int nexwatch_scamble(NexWatchScramble_t action, uint32_t *id, uint32_t *s
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int nexwatch_magic_bruteforce(uint32_t cn, uint8_t calc_parity, uint8_t chk) {
|
||||||
|
for (uint8_t magic = 0; magic < 255; magic++) {
|
||||||
|
uint8_t temp_checksum;
|
||||||
|
temp_checksum = nexwatch_checksum(magic, cn, calc_parity);
|
||||||
|
if (temp_checksum == chk) {
|
||||||
|
PrintAndLogEx(SUCCESS, " Magic number : " _GREEN_("0x%X"), magic);
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PrintAndLogEx(DEBUG, "DEBUG: Error - Magic number not found");
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int demodNexWatch(bool verbose) {
|
int demodNexWatch(bool verbose) {
|
||||||
(void) verbose; // unused so far
|
(void) verbose; // unused so far
|
||||||
if (PSKDemod(0, 0, 100, false) != PM3_SUCCESS) {
|
if (PSKDemod(0, 0, 100, false) != PM3_SUCCESS) {
|
||||||
|
@ -204,10 +220,13 @@ int demodNexWatch(bool verbose) {
|
||||||
|
|
||||||
if (m_idx < ARRAYLEN(items)) {
|
if (m_idx < ARRAYLEN(items)) {
|
||||||
PrintAndLogEx(SUCCESS, " fingerprint : " _GREEN_("%s"), items[m_idx].desc);
|
PrintAndLogEx(SUCCESS, " fingerprint : " _GREEN_("%s"), items[m_idx].desc);
|
||||||
|
} else {
|
||||||
|
nexwatch_magic_bruteforce(cn, calc_parity, chk);
|
||||||
}
|
}
|
||||||
PrintAndLogEx(SUCCESS, " 88bit id : " _YELLOW_("%"PRIu32) " (" _YELLOW_("0x%08"PRIx32)")", cn, cn);
|
PrintAndLogEx(SUCCESS, " 88bit id : " _YELLOW_("%"PRIu32) " (" _YELLOW_("0x%08"PRIx32)")", cn, cn);
|
||||||
PrintAndLogEx(SUCCESS, " mode : %x", mode);
|
PrintAndLogEx(SUCCESS, " mode : %x", mode);
|
||||||
|
|
||||||
|
|
||||||
if (parity == calc_parity) {
|
if (parity == calc_parity) {
|
||||||
PrintAndLogEx(DEBUG, " parity : %s (0x%X)", _GREEN_("ok"), parity);
|
PrintAndLogEx(DEBUG, " parity : %s (0x%X)", _GREEN_("ok"), parity);
|
||||||
} else {
|
} else {
|
||||||
|
@ -285,6 +304,8 @@ static int CmdNexWatchClone(const char *Cmd) {
|
||||||
arg_lit0(NULL, "hc", "Honeywell credential"),
|
arg_lit0(NULL, "hc", "Honeywell credential"),
|
||||||
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_str0(NULL, "magic", "<hex>", "optional - magic hex data. 1 byte"),
|
||||||
|
arg_lit0(NULL, "psk2", "optional - specify writing a tag in psk2 modulation"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
@ -301,6 +322,10 @@ static int CmdNexWatchClone(const char *Cmd) {
|
||||||
bool use_unk = arg_get_lit(ctx, 6);
|
bool use_unk = arg_get_lit(ctx, 6);
|
||||||
bool q5 = arg_get_lit(ctx, 7);
|
bool q5 = arg_get_lit(ctx, 7);
|
||||||
bool em = arg_get_lit(ctx, 8);
|
bool em = arg_get_lit(ctx, 8);
|
||||||
|
bool use_psk2 = arg_get_lit(ctx, 10);
|
||||||
|
uint8_t magic_arg;
|
||||||
|
int magic_len = 0;
|
||||||
|
CLIGetHexWithReturn(ctx, 9, &magic_arg, &magic_len);
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
if (use_nexkey && use_quadrakey) {
|
if (use_nexkey && use_quadrakey) {
|
||||||
|
@ -316,6 +341,13 @@ static int CmdNexWatchClone(const char *Cmd) {
|
||||||
// 56000000 00213C9F 8F150C00
|
// 56000000 00213C9F 8F150C00
|
||||||
bool use_raw = (raw_len != 0);
|
bool use_raw = (raw_len != 0);
|
||||||
|
|
||||||
|
bool use_custom_magic = (magic_len != 0);
|
||||||
|
|
||||||
|
if (magic_len > 1) {
|
||||||
|
PrintAndLogEx(FAILED, "Can't specify a magic number bigger than one byte");
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
|
||||||
if (use_raw && cn != -1) {
|
if (use_raw && cn != -1) {
|
||||||
PrintAndLogEx(FAILED, "Can't specify both Raw and Card id at the same time");
|
PrintAndLogEx(FAILED, "Can't specify both Raw and Card id at the same time");
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
|
@ -336,20 +368,27 @@ static int CmdNexWatchClone(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t magic = 0xBE;
|
uint8_t magic = 0xBE;
|
||||||
if (use_nexkey)
|
if (use_custom_magic) {
|
||||||
magic = 0x88;
|
magic = magic_arg;
|
||||||
|
} else {
|
||||||
|
if (use_nexkey)
|
||||||
|
magic = 0x88;
|
||||||
|
|
||||||
if (use_quadrakey)
|
if (use_quadrakey)
|
||||||
magic = 0xBE;
|
magic = 0xBE;
|
||||||
|
|
||||||
if (use_unk)
|
if (use_unk)
|
||||||
magic = 0x86;
|
magic = 0x86;
|
||||||
|
|
||||||
|
}
|
||||||
|
PrintAndLogEx(INFO, "Magic byte selected : 0x%X", magic);
|
||||||
|
|
||||||
uint32_t blocks[4];
|
uint32_t blocks[4];
|
||||||
|
|
||||||
//Nexwatch - compat mode, PSK, data rate 40, 3 data blocks
|
//Nexwatch - compat mode, PSK, data rate 40, 3 data blocks
|
||||||
blocks[0] = T55x7_MODULATION_PSK1 | T55x7_BITRATE_RF_32 | 3 << T55x7_MAXBLOCK_SHIFT;
|
blocks[0] = T55x7_MODULATION_PSK1 | T55x7_BITRATE_RF_32 | 3 << T55x7_MAXBLOCK_SHIFT;
|
||||||
char cardtype[16] = {"T55x7"};
|
char cardtype[16] = {"T55x7"};
|
||||||
|
|
||||||
// Q5
|
// Q5
|
||||||
if (q5) {
|
if (q5) {
|
||||||
blocks[0] = T5555_FIXED | T5555_MODULATION_MANCHESTER | T5555_SET_BITRATE(64) | T5555_ST_TERMINATOR | 3 << T5555_MAXBLOCK_SHIFT;
|
blocks[0] = T5555_FIXED | T5555_MODULATION_MANCHESTER | T5555_SET_BITRATE(64) | T5555_ST_TERMINATOR | 3 << T5555_MAXBLOCK_SHIFT;
|
||||||
|
@ -368,6 +407,19 @@ static int CmdNexWatchClone(const char *Cmd) {
|
||||||
raw[10] |= nexwatch_checksum(magic, cn, parity);
|
raw[10] |= nexwatch_checksum(magic, cn, parity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (use_psk2) {
|
||||||
|
blocks[0] = 270464;
|
||||||
|
uint8_t * res_shifted = calloc(96, sizeof(uint8_t));
|
||||||
|
uint8_t * res = calloc(96, sizeof(uint8_t));
|
||||||
|
bytes_to_bytebits(raw, 12, res);
|
||||||
|
psk1TOpsk2(res, 96);
|
||||||
|
memcpy(res_shifted, &res[1], 95 * sizeof(uint8_t));
|
||||||
|
free(res);
|
||||||
|
bits_to_array(res_shifted, 96, raw);
|
||||||
|
free(res_shifted);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
for (uint8_t i = 1; i < ARRAYLEN(blocks); i++) {
|
for (uint8_t i = 1; i < ARRAYLEN(blocks); i++) {
|
||||||
blocks[i] = bytes_to_num(raw + ((i - 1) * 4), sizeof(uint32_t));
|
blocks[i] = bytes_to_num(raw + ((i - 1) * 4), sizeof(uint32_t));
|
||||||
}
|
}
|
||||||
|
@ -408,6 +460,8 @@ static int CmdNexWatchSim(const char *Cmd) {
|
||||||
arg_lit0(NULL, "nc", "Nexkey credential"),
|
arg_lit0(NULL, "nc", "Nexkey credential"),
|
||||||
arg_lit0(NULL, "qc", "Quadrakey credential"),
|
arg_lit0(NULL, "qc", "Quadrakey credential"),
|
||||||
arg_lit0(NULL, "hc", "Honeywell credential"),
|
arg_lit0(NULL, "hc", "Honeywell credential"),
|
||||||
|
arg_str0(NULL, "magic", "<hex>", "optional - magic hex data. 1 byte"),
|
||||||
|
arg_lit0(NULL, "psk2", "optional - specify writing a tag in psk2 modulation"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue