Merge pull request #1339 from Guilhem7/master

Update for cmdlfnexwatch.c
This commit is contained in:
Iceman 2021-06-25 14:23:46 +02:00 committed by GitHub
commit 65e398d47f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 62 additions and 7 deletions

View file

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

View file

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