Merge pull request #11 from RfidResearchGroup/master

Update with master
This commit is contained in:
mwalker33 2019-09-30 22:40:13 +10:00 committed by GitHub
commit 5d0a944210
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
33 changed files with 590 additions and 608 deletions

View file

@ -1032,7 +1032,13 @@ static void PacketReceived(PacketCommandNG *packet) {
break;
}
case CMD_HF_MIFARE_READER: {
ReaderMifare(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2]);
struct p {
uint8_t first_run;
uint8_t blockno;
uint8_t key_type;
} PACKED;
struct p *payload = (struct p *) packet->data.asBytes;
ReaderMifare(payload->first_run, payload->blockno, payload->key_type);
break;
}
case CMD_HF_MIFARE_READBL: {

View file

@ -2791,6 +2791,8 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
static uint8_t par_low = 0;
static uint8_t mf_nr_ar3 = 0;
int return_status = PM3_SUCCESS;
AddCrc14A(mf_auth, 2);
if (first_try) {
@ -2807,6 +2809,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
}
LED_C_ON();
uint16_t checkbtn_cnt = 0;
uint16_t i;
for (i = 0; true; ++i) {
@ -2815,10 +2818,15 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
WDT_HIT();
// Test if the action was cancelled
if (BUTTON_PRESS()) {
isOK = -1;
break;
if (checkbtn_cnt == 2000) {
if (BUTTON_PRESS() || data_available()) {
isOK = -1;
return_status = PM3_EOPABORTED;
break;
}
checkbtn_cnt = 0;
}
++checkbtn_cnt;
// this part is from Piwi's faster nonce collecting part in Hardnested.
if (!have_uid) { // need a full select cycle to get the uid first
@ -2876,8 +2884,16 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
ReaderTransmitPar(mf_nr_ar, sizeof(mf_nr_ar), par, NULL);
// Receive answer. This will be a 4 Bit NACK when the 8 parity bits are OK after decoding
if (ReaderReceive(receivedAnswer, receivedAnswerPar))
int resp_res = ReaderReceive(receivedAnswer, receivedAnswerPar);
if (resp_res == 1)
received_nack = true;
else if (resp_res == 4) {
// did we get lucky and got our dummykey to be valid?
// however we dont feed key w uid it the prng..
isOK = -6;
break;
}
// we didn't calibrate our clock yet,
// iceman: has to be calibrated every time.
@ -3000,26 +3016,36 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("Number of sent auth requests: %u", i);
uint8_t buf[32] = {0x00};
memset(buf, 0x00, sizeof(buf));
num_to_bytes(cuid, 4, buf);
num_to_bytes(nt, 4, buf + 4);
memcpy(buf + 8, par_list, 8);
memcpy(buf + 16, ks_list, 8);
memcpy(buf + 24, mf_nr_ar, 8);
struct {
int32_t isOK;
uint8_t cuid[4];
uint8_t nt[4];
uint8_t par_list[8];
uint8_t ks_list[8];
uint8_t nr[4];
uint8_t ar[4];
} PACKED payload;
reply_mix(CMD_ACK, isOK, 0, 0, buf, sizeof(buf));
payload.isOK = isOK;
num_to_bytes(cuid, 4, payload.cuid);
num_to_bytes(nt, 4, payload.nt);
memcpy(payload.par_list, par_list, sizeof(payload.par_list));
memcpy(payload.ks_list, ks_list, sizeof(payload.ks_list));
memcpy(payload.nr, mf_nr_ar, sizeof(payload.nr));
memcpy(payload.ar, mf_nr_ar + 4, sizeof(payload.ar));
reply_ng(CMD_HF_MIFARE_READER, return_status, (uint8_t*)&payload, sizeof(payload));
hf_field_off();
set_tracing(false);
}
/*
* Mifare Classic NACK-bug detection
* Thanks to @doegox for the feedback and new approaches.
* Mifare Classic NACK-bug detection
* Thanks to @doegox for the feedback and new approaches.
*/
void DetectNACKbug(void) {
uint8_t mf_auth[] = {0x60, 0x00, 0xF5, 0x7B};
uint8_t mf_auth[] = {0x60, 0x00, 0xF5, 0x7B};
uint8_t mf_nr_ar[] = {0, 0, 0, 0, 0, 0, 0, 0};
uint8_t uid[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00};
@ -3050,6 +3076,8 @@ void DetectNACKbug(void) {
sync_time = GetCountSspClk() & 0xfffffff8;
LED_C_ON();
uint16_t checkbtn_cnt = 0;
uint16_t i;
for (i = 1; true; ++i) {
@ -3064,10 +3092,14 @@ void DetectNACKbug(void) {
WDT_HIT();
// Test if the action was cancelled
if (BUTTON_PRESS() || data_available()) {
status = PM3_EOPABORTED;
break;
if (checkbtn_cnt == 2000) {
if (BUTTON_PRESS() || data_available()) {
status = PM3_EOPABORTED;
break;
}
checkbtn_cnt = 0;
}
++checkbtn_cnt;
// this part is from Piwi's faster nonce collecting part in Hardnested.
if (!have_uid) { // need a full select cycle to get the uid first
@ -3127,10 +3159,11 @@ void DetectNACKbug(void) {
// Transmit reader nonce with fake par
ReaderTransmitPar(mf_nr_ar, sizeof(mf_nr_ar), par, NULL);
// Receive answer. This will be a 4 Bit NACK when the 8 parity bits are OK after decoding
if (ReaderReceive(receivedAnswer, receivedAnswerPar)) {
received_nack = true;
num_nacks++;
// ALWAYS leak Detection.
// ALWAYS leak Detection. Well, we could be lucky and get a response nack on first try.
if (i == num_nacks) {
continue;
}
@ -3247,7 +3280,6 @@ void DetectNACKbug(void) {
num_to_bytes(i, 2, data + 2);
reply_ng(CMD_HF_MIFARE_NACK_DETECT, status, data, 4);
//reply_mix(CMD_ACK, isOK, num_nacks, i, 0, 0);
BigBuf_free();
hf_field_off();
set_tracing(false);

View file

@ -532,7 +532,7 @@ int ASKDemod_ext(const char *Cmd, bool verbose, bool emSearch, uint8_t askType,
invert = 1;
clk = 0;
}
uint8_t *bits = calloc(MAX_GRAPH_TRACE_LEN, sizeof(uint8_t));
uint8_t *bits = calloc(MAX_GRAPH_TRACE_LEN, sizeof(uint8_t));
if (bits == NULL) {
return PM3_EMALLOC;
}
@ -1119,13 +1119,13 @@ int FSKrawDemod(const char *Cmd, bool verbose) {
if (bits == NULL) {
return PM3_EMALLOC;
}
size_t BitLen = getFromGraphBuf(bits);
if (BitLen == 0) {
free(bits);
return PM3_ESOFT;
}
//get field clock lengths
if (!fchigh || !fclow) {
uint16_t fcs = countFC(bits, BitLen, true);
@ -2243,7 +2243,7 @@ static command_t CommandTable[] = {
{"tune", CmdTuneSamples, IfPm3Present, "Get hw tune samples for graph window"},
{"undec", CmdUndec, AlwaysAvailable, "Un-decimate samples by 2"},
{"zerocrossings", CmdZerocrossings, AlwaysAvailable, "Count time between zero-crossings"},
{"iir", CmdDataIIR, IfPm3Present, "apply IIR buttersworth filter on plotdata"},
{"iir", CmdDataIIR, AlwaysAvailable, "apply IIR buttersworth filter on plotdata"},
{NULL, NULL, NULL, NULL}
};

View file

@ -467,10 +467,14 @@ static int CmdSetMux(const char *Cmd) {
str_lower((char *)Cmd);
uint8_t arg = 0;
if (strcmp(Cmd, "lopkd") == 0) arg = 0;
else if (strcmp(Cmd, "loraw") == 0) arg = 1;
else if (strcmp(Cmd, "hipkd") == 0) arg = 2;
else if (strcmp(Cmd, "hiraw") == 0) arg = 3;
if (strcmp(Cmd, "lopkd") == 0)
arg = 0;
else if (strcmp(Cmd, "loraw") == 0)
arg = 1;
else if (strcmp(Cmd, "hipkd") == 0)
arg = 2;
else if (strcmp(Cmd, "hiraw") == 0)
arg = 3;
else {
usage_hw_setmux();
return PM3_EINVARG;
@ -570,8 +574,6 @@ static int CmdConnect(const char *Cmd) {
memcpy(port, conn.serial_port_name, sizeof(port));
}
printf("Port:: %s Baud:: %u\n", port, baudrate);
if (session.pm3_present) {
CloseProxmark();
}
@ -582,14 +584,15 @@ static int CmdConnect(const char *Cmd) {
if (session.pm3_present && (TestProxmark() != PM3_SUCCESS)) {
PrintAndLogEx(ERR, _RED_("ERROR:") "cannot communicate with the Proxmark3\n");
CloseProxmark();
return PM3_ENOTTY;
}
return PM3_SUCCESS;
}
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"dbg", CmdDbg, IfPm3Present, "Set Proxmark3 debug level"},
{"connect", CmdConnect, AlwaysAvailable, "connect Proxmark3 to serial port"},
{"dbg", CmdDbg, IfPm3Present, "Set Proxmark3 debug level"},
{"detectreader", CmdDetectReader, IfPm3Present, "['l'|'h'] -- Detect external reader field (option 'l' or 'h' to limit to LF or HF)"},
{"fpgaoff", CmdFPGAOff, IfPm3Present, "Set FPGA off"},
{"lcd", CmdLCD, IfPm3Lcd, "<HEX command> <count> -- Send command/data to LCD"},
@ -690,14 +693,22 @@ void pm3_version(bool verbose, bool oneliner) {
PrintAndLogEx(NORMAL, "\n [ CLIENT ]");
PrintAndLogEx(NORMAL, " client: RRG/Iceman"); // TODO version info?
PrintAndLogEx(NORMAL, " compiled with " PM3CLIENTCOMPILER __VERSION__ PM3HOSTOS PM3HOSTARCH);
PrintAndLogEx(NORMAL, "\n [ PROXMARK RDV4 ]");
PrintAndLogEx(NORMAL, " external flash: %s", IfPm3Flash() ? _GREEN_("present") : _YELLOW_("absent"));
PrintAndLogEx(NORMAL, " smartcard reader: %s", IfPm3Smartcard() ? _GREEN_("present") : _YELLOW_("absent"));
PrintAndLogEx(NORMAL, "\n [ PROXMARK RDV4 Extras ]");
PrintAndLogEx(NORMAL, " FPC USART for BT add-on support: %s", IfPm3FpcUsartHost() ? _GREEN_("present") : _YELLOW_("absent"));
if (IfPm3FpcUsartDevFromUsb())
PrintAndLogEx(NORMAL, " FPC USART for developer support: %s", _GREEN_("present"));
//#if PLATFORM == PM3RDV4
if ( IfPm3Flash() == false && IfPm3Smartcard() == false && IfPm3FpcUsartHost() == false) {
PrintAndLogEx(NORMAL, "\n [ PROXMARK3 ]");
} else {
PrintAndLogEx(NORMAL, "\n [ PROXMARK3 RDV4 ]");
PrintAndLogEx(NORMAL, " external flash: %s", IfPm3Flash() ? _GREEN_("present") : _YELLOW_("absent"));
PrintAndLogEx(NORMAL, " smartcard reader: %s", IfPm3Smartcard() ? _GREEN_("present") : _YELLOW_("absent"));
PrintAndLogEx(NORMAL, "\n [ PROXMARK3 RDV4 Extras ]");
PrintAndLogEx(NORMAL, " FPC USART for BT add-on support: %s", IfPm3FpcUsartHost() ? _GREEN_("present") : _YELLOW_("absent"));
if (IfPm3FpcUsartDevFromUsb()) {
PrintAndLogEx(NORMAL, " FPC USART for developer support: %s", _GREEN_("present"));
}
}
//#endif
PrintAndLogEx(NORMAL, "");

View file

@ -264,12 +264,7 @@ static int CmdFdxRead(const char *Cmd) {
static int CmdFdxClone(const char *Cmd) {
uint32_t countryid = 0;
uint64_t animalid = 0;
uint32_t blocks[5] = {T55x7_MODULATION_DIPHASE | T55x7_BITRATE_RF_32 | 4 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0, 0};
uint8_t bits[128];
uint8_t *bs = bits;
memset(bs, 0, sizeof(bits));
uint64_t animalid = 0;
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_fdx_clone();
@ -278,63 +273,32 @@ static int CmdFdxClone(const char *Cmd) {
verify_values(countryid, animalid);
// getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t isextended, uint32_t extended, uint8_t *bits)
if (getFDXBits(animalid, countryid, 1, 0, 0, bs) != PM3_SUCCESS) {
uint8_t *bits = calloc(128, sizeof(uint8_t));
if (getFDXBits(animalid, countryid, 1, 0, 0, bits) != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Error with tag bitstream generation.");
free(bits);
return PM3_ESOFT;
}
uint32_t blocks[5] = {T55x7_MODULATION_DIPHASE | T55x7_BITRATE_RF_32 | 4 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0, 0};
//Q5
if (param_getchar(Cmd, 2) == 'Q' || param_getchar(Cmd, 2) == 'q')
blocks[0] = T5555_MODULATION_BIPHASE | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(32) | 4 << T5555_MAXBLOCK_SHIFT;
// convert from bit stream to block data
blocks[1] = bytebits_to_byte(bs, 32);
blocks[2] = bytebits_to_byte(bs + 32, 32);
blocks[3] = bytebits_to_byte(bs + 64, 32);
blocks[4] = bytebits_to_byte(bs + 96, 32);
blocks[1] = bytebits_to_byte(bits, 32);
blocks[2] = bytebits_to_byte(bits + 32, 32);
blocks[3] = bytebits_to_byte(bits + 64, 32);
blocks[4] = bytebits_to_byte(bits + 96, 32);
free(bits);
PrintAndLogEx(INFO, "Preparing to clone FDX-B to T55x7 with animal ID: %04u-%"PRIu64, countryid, animalid);
print_blocks(blocks, 5);
print_blocks(blocks, ARRAYLEN(blocks));
uint8_t res = 0;
PacketResponseNG resp;
// fast push mode
conn.block_after_ACK = true;
for (int i = 4; i >= 0; --i) {
if (i == 0) {
// Disable fast mode on last packet
conn.block_after_ACK = false;
}
clearCommandBuffer();
t55xx_write_block_t ng;
ng.data = blocks[i];
ng.pwd = 0;
ng.blockno = i;
ng.flags = 0;
SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng));
if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) {
PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
return PM3_ETIMEOUT;
}
if (i == 0) {
SetConfigWithBlock0(blocks[0]);
if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false))
continue;
}
if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false)
res++;
}
if (res == 0)
PrintAndLogEx(SUCCESS, "Success writing to tag");
return PM3_SUCCESS;
return clone_t55xx_tag(blocks, ARRAYLEN(blocks));
}
static int CmdFdxSim(const char *Cmd) {

View file

@ -14,6 +14,7 @@
#include <stdlib.h>
#include <ctype.h>
#include "commonutil.h" // ARRAYLEN
#include "cmdparser.h" // command_t
#include "comms.h"
#include "ui.h"
@ -156,20 +157,20 @@ static int CmdGuardClone(const char *Cmd) {
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_guard_clone();
uint32_t facilitycode = 0, cardnumber = 0, fc = 0, cn = 0, fmtlen = 0;
uint8_t bs[96];
memset(bs, 0x00, sizeof(bs));
//GuardProxII - compat mode, ASK/Biphase, data rate 64, 3 data blocks
uint32_t blocks[4] = {T55x7_MODULATION_BIPHASE | T55x7_BITRATE_RF_64 | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0};
if (sscanf(Cmd, "%u %u %u", &fmtlen, &fc, &cn) != 3) return usage_lf_guard_clone();
fmtlen &= 0x7f;
facilitycode = (fc & 0x000000FF);
cardnumber = (cn & 0x0000FFFF);
//GuardProxII - compat mode, ASK/Biphase, data rate 64, 3 data blocks
uint32_t blocks[4] = {T55x7_MODULATION_BIPHASE | T55x7_BITRATE_RF_64 | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0};
uint8_t *bs = calloc(96, sizeof(uint8_t));
if (getGuardBits(fmtlen, facilitycode, cardnumber, bs) != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Error with tag bitstream generation.");
free(bs);
return PM3_ESOFT;
}
@ -181,47 +182,12 @@ static int CmdGuardClone(const char *Cmd) {
blocks[2] = bytebits_to_byte(bs + 32, 32);
blocks[3] = bytebits_to_byte(bs + 64, 32);
free(bs);
PrintAndLogEx(INFO, "Preparing to clone Guardall to T55x7 with Facility Code: %u, Card Number: %u", facilitycode, cardnumber);
print_blocks(blocks, 4);
print_blocks(blocks, ARRAYLEN(blocks));
uint8_t res = 0;
PacketResponseNG resp;
// fast push mode
conn.block_after_ACK = true;
for (uint8_t i = 0; i < 4; i++) {
if (i == 3) {
// Disable fast mode on last packet
conn.block_after_ACK = false;
}
clearCommandBuffer();
t55xx_write_block_t ng;
ng.data = blocks[i];
ng.pwd = 0;
ng.blockno = i;
ng.flags = 0;
SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng));
if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) {
PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
return PM3_ETIMEOUT;
}
if (i == 0) {
SetConfigWithBlock0(blocks[0]);
if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false))
continue;
}
if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false)
res++;
}
if (res == 0)
PrintAndLogEx(SUCCESS, "Success writing to tag");
return PM3_SUCCESS;
return clone_t55xx_tag(blocks, ARRAYLEN(blocks));
}
static int CmdGuardSim(const char *Cmd) {

View file

@ -16,6 +16,5 @@
int CmdLFHID(const char *Cmd);
int demodHID(void);
//void calc26(uint16_t fc, uint32_t cardno, uint8_t *out);
void calcWiegand(uint8_t fmtlen, uint16_t fc, uint64_t cardno, uint8_t *bits, uint8_t oem);
#endif

View file

@ -505,43 +505,7 @@ static int CmdIndalaClone(const char *Cmd) {
print_blocks(blocks, max);
uint8_t res = 0;
PacketResponseNG resp;
// fast push mode
conn.block_after_ACK = true;
for (uint8_t i = 0; i < max; i++) {
if (i == max - 1) {
// Disable fast mode on last packet
conn.block_after_ACK = false;
}
clearCommandBuffer();
t55xx_write_block_t ng;
ng.data = blocks[i];
ng.pwd = 0;
ng.blockno = i;
ng.flags = 0;
SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng));
if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) {
PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
return PM3_ETIMEOUT;
}
if (i == 0) {
SetConfigWithBlock0(blocks[0]);
if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false))
continue;
}
if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false)
res++;
}
if (res == 0)
PrintAndLogEx(SUCCESS, "Success writing to tag");
return PM3_SUCCESS;
return clone_t55xx_tag(blocks, max);
}
static command_t CommandTable[] = {

View file

@ -16,6 +16,7 @@
#include <ctype.h>
#include "commonutil.h" //ARRAYLEN
#include "cmdparser.h" // command_t
#include "comms.h"
#include "graph.h"
@ -272,45 +273,9 @@ static int CmdIOProxClone(const char *Cmd) {
blocks[2] = bytebits_to_byte(bits + 32, 32);
PrintAndLogEx(INFO, "Preparing to clone IOProx to T55x7 with Version: %u FC: %u, CN: %u", version, fc, cn);
print_blocks(blocks, 3);
print_blocks(blocks, ARRAYLEN(blocks));
uint8_t res = 0;
PacketResponseNG resp;
// fast push mode
conn.block_after_ACK = true;
for (uint8_t i = 0; i < 3; i++) {
if (i == 2) {
// Disable fast mode on last packet
conn.block_after_ACK = false;
}
clearCommandBuffer();
t55xx_write_block_t ng;
ng.data = blocks[i];
ng.pwd = 0;
ng.blockno = i;
ng.flags = 0;
SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng));
if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) {
PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
return PM3_ETIMEOUT;
}
if (i == 0) {
SetConfigWithBlock0(blocks[0]);
if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false))
continue;
}
if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false)
res++;
}
if (res == 0)
PrintAndLogEx(SUCCESS, "Success writing to tag");
return PM3_SUCCESS;
return clone_t55xx_tag(blocks, ARRAYLEN(blocks));
}
static command_t CommandTable[] = {

View file

@ -18,7 +18,7 @@
#include "cmdparser.h" // command_t
#include "comms.h"
#include "commonutil.h"
#include "commonutil.h" // ARRAYLEN
#include "ui.h"
#include "cmddata.h"
#include "cmdlf.h"
@ -169,46 +169,9 @@ static int CmdJablotronClone(const char *Cmd) {
blocks[2] = bytebits_to_byte(bits + 32, 32);
PrintAndLogEx(INFO, "Preparing to clone Jablotron to T55x7 with FullCode: %"PRIx64, fullcode);
print_blocks(blocks, 3);
print_blocks(blocks, ARRAYLEN(blocks));
uint8_t res = 0;
PacketResponseNG resp;
// fast push mode
conn.block_after_ACK = true;
for (uint8_t i = 0; i < 3; i++) {
if (i == 2) {
// Disable fast mode on last packet
conn.block_after_ACK = false;
}
clearCommandBuffer();
t55xx_write_block_t ng;
ng.data = blocks[i];
ng.pwd = 0;
ng.blockno = i;
ng.flags = 0;
SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng));
if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) {
PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
return PM3_ETIMEOUT;
}
if (i == 0) {
SetConfigWithBlock0(blocks[0]);
if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false))
continue;
}
if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false)
res++;
}
if (res == 0)
PrintAndLogEx(SUCCESS, "Success writing to tag");
return PM3_SUCCESS;
return clone_t55xx_tag(blocks, ARRAYLEN(blocks));
}
static int CmdJablotronSim(const char *Cmd) {

View file

@ -15,6 +15,7 @@
#include <ctype.h>
#include <stdlib.h>
#include "commonutil.h" // ARRAYLEN
#include "cmdparser.h" // command_t
#include "comms.h"
#include "ui.h"
@ -155,49 +156,12 @@ static int CmdKeriClone(const char *Cmd) {
uint64_t data = ((uint64_t)internalid << 3) + 7;
PrintAndLogEx(INFO, "Preparing to clone KERI to T55x7 with Internal Id: %" PRIx64, internalid);
//
blocks[1] = data >> 32;
blocks[2] = data & 0xFFFFFFFF;
print_blocks(blocks, 3);
uint8_t res = 0;
PacketResponseNG resp;
print_blocks(blocks, ARRAYLEN(blocks));
// fast push mode
conn.block_after_ACK = true;
for (uint8_t i = 0; i < 3; i++) {
if (i == 2) {
// Disable fast mode on last packet
conn.block_after_ACK = false;
}
clearCommandBuffer();
t55xx_write_block_t ng;
ng.data = blocks[i];
ng.pwd = 0;
ng.blockno = i;
ng.flags = 0;
SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng));
if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) {
PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
return PM3_ETIMEOUT;
}
if (i == 0) {
SetConfigWithBlock0(blocks[0]);
if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false))
continue;
}
if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false)
res++;
}
if (res == 0)
PrintAndLogEx(SUCCESS, "Success writing to tag");
return PM3_SUCCESS;
return clone_t55xx_tag(blocks, ARRAYLEN(blocks));
}
static int CmdKeriSim(const char *Cmd) {

View file

@ -9,6 +9,19 @@
#include "cmdlfnedap.h"
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include "cmdparser.h" // command_t
#include "comms.h"
#include "crc16.h"
#include "cmdlft55xx.h" // verifywrite
#include "ui.h"
#include "cmddata.h"
#include "cmdlf.h"
#include "lfdemod.h"
#define FIXED_71 0x71
#define FIXED_40 0x40
#define UNKNOWN_A 0x00
@ -431,7 +444,7 @@ int CmdLFNedapClone(const char *Cmd) {
return PM3_ESOFT;
}
CmdPrintDemodBuff("x");
//CmdPrintDemodBuff("x");
// What we had before in commented code:
//NEDAP - compat mode, ASK/DIphase, data rate 64, 4 data blocks
@ -455,47 +468,14 @@ int CmdLFNedapClone(const char *Cmd) {
PrintAndLogEx(SUCCESS, "Preparing to clone NEDAP to T55x7");
print_blocks(blocks, max);
uint8_t res = 0;
PacketResponseNG resp;
// fast push mode
conn.block_after_ACK = true;
for (uint8_t i = 0; i < max; i++) {
if (i == max - 1) {
// Disable fast mode on last packet
conn.block_after_ACK = false;
}
clearCommandBuffer();
t55xx_write_block_t ng;
ng.data = blocks[i];
ng.pwd = 0;
ng.blockno = i;
ng.flags = 0;
SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng));
if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) {
PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
return PM3_ETIMEOUT;
}
if (i == 0) {
SetConfigWithBlock0(blocks[0]);
if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false))
continue;
}
if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false)
res++;
}
if (res == 0)
PrintAndLogEx(SUCCESS, "Success writing to tag");
else {
PrintAndLogEx(NORMAL, "");
int res = clone_t55xx_tag(blocks, max);
if (res == PM3_SUCCESS) {
PrintAndLogEx(INFO, "The block 0 was changed (eXtended) which can be hard to detect.");
PrintAndLogEx(INFO, " Configure it manually " _YELLOW_("`lf t55xx config b 64 d BI i 1 o 32`"));
} else {
PrintAndLogEx(NORMAL, "");
}
return PM3_SUCCESS;
return res;
}
static int CmdLFNedapSim(const char *Cmd) {

View file

@ -11,19 +11,6 @@
#include "common.h"
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include "cmdparser.h" // command_t
#include "comms.h"
#include "crc16.h"
#include "cmdlft55xx.h" // verifywrite
#include "ui.h"
#include "cmddata.h"
#include "cmdlf.h"
#include "lfdemod.h"
int CmdLFNedap(const char *Cmd);
int demodNedap(void);

View file

@ -9,16 +9,33 @@
//-----------------------------------------------------------------------------
#include "cmdlfnexwatch.h"
#include <ctype.h> // tolower
#include "commonutil.h" // ARRAYLEN
#include "cmdparser.h" // command_t
#include "comms.h"
#include "ui.h"
#include "cmddata.h" // preamblesearch
#include "cmdlf.h"
#include "lfdemod.h"
#include "protocols.h" // t55xx defines
#include "cmdlft55xx.h" // clone..
static int CmdHelp(const char *Cmd);
static int usage_lf_nexwatch_clone(void) {
PrintAndLogEx(NORMAL, "clone a Nexwatch tag to a T55x7 tag.");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf nexwatch clone [h] [b <raw hex>]");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h : this help");
PrintAndLogEx(NORMAL, " b <raw hex> : raw hex data. 12 bytes max");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " lf nexwatch clone b 5600000000213C9F8F150C0000000000");
return PM3_SUCCESS;
}
static int CmdNexWatchDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
@ -37,7 +54,7 @@ static int CmdNexWatchDemod(const char *Cmd) {
// else if (idx == -3)
// PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch problem during PSK demod");
else if (idx == -4)
PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch preamble not found");
PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch preamble not found");
// else if (idx == -5)
// PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch size not correct: %d", size);
else
@ -47,7 +64,7 @@ static int CmdNexWatchDemod(const char *Cmd) {
}
setDemodBuff(DemodBuffer, size, idx + 4);
setClockGrid(g_DemodClock, g_DemodStartIdx + ((idx + 4)*g_DemodClock));
setClockGrid(g_DemodClock, g_DemodStartIdx + ((idx + 4) * g_DemodClock));
// idx = 8 + 32; // 8 = preamble, 32 = reserved bits (always 0)
@ -82,10 +99,47 @@ static int CmdNexWatchRead(const char *Cmd) {
}
static int CmdNexWatchClone(const char *Cmd) {
// 56000000 00213C9F 8F150C00 00000000
uint32_t blocks[5];
bool errors = false;
uint8_t cmdp = 0;
int datalen = 0;
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_lf_nexwatch_clone();
case 'b': {
// skip first block, 4*4 = 16 bytes left
uint8_t rawhex[16] = {0};
int res = param_gethex_to_eol(Cmd, cmdp + 1, rawhex, sizeof(rawhex), &datalen);
if ( res != 0 )
errors = true;
for(uint8_t i = 1; i < ARRAYLEN(blocks); i++) {
blocks[i] = bytes_to_num(rawhex + ( (i - 1) * 4 ), sizeof(uint32_t));
}
cmdp += 2;
break;
}
default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
if (errors || cmdp == 0) return usage_lf_nexwatch_clone();
//Nexwatch - compat mode, PSK, data rate 40, 3 data blocks
blocks[0] = T55x7_MODULATION_PSK1 | T55x7_BITRATE_RF_32 | 4 << T55x7_MAXBLOCK_SHIFT;
PrintAndLogEx(INFO, "Preparing to clone NexWatch to T55x7 with raw hex");
print_blocks(blocks, ARRAYLEN(blocks));
return clone_t55xx_tag(blocks, ARRAYLEN(blocks));
// should be able to clone the raw hex.
PrintAndLogEx(INFO, " To be implemented, feel free to contribute!");
return PM3_SUCCESS;
}
static int CmdNexWatchSim(const char *Cmd) {

View file

@ -9,6 +9,20 @@
//-----------------------------------------------------------------------------
#include "cmdlfnoralsy.h"
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "commonutil.h" // ARRAYLEN
#include "cmdparser.h" // command_t
#include "comms.h"
#include "ui.h"
#include "cmddata.h"
#include "cmdlf.h"
#include "protocols.h" // for T55xx config register definitions
#include "lfdemod.h" // parityTest
#include "cmdlft55xx.h" // verifywrite
static int CmdHelp(const char *Cmd);
static int usage_lf_noralsy_clone(void) {
@ -128,8 +142,7 @@ static int CmdNoralsyClone(const char *Cmd) {
uint16_t year = 0;
uint32_t id = 0;
uint32_t blocks[4] = {T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_32 | T55x7_ST_TERMINATOR | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0};
uint8_t bits[96];
memset(bits, 0, sizeof(bits));
uint8_t *bits = calloc(96, sizeof(uint8_t));
char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_noralsy_clone();
@ -146,52 +159,16 @@ static int CmdNoralsyClone(const char *Cmd) {
return PM3_ESOFT;
}
//
blocks[1] = bytebits_to_byte(bits, 32);
blocks[2] = bytebits_to_byte(bits + 32, 32);
blocks[3] = bytebits_to_byte(bits + 64, 32);
free(bits);
PrintAndLogEx(INFO, "Preparing to clone Noralsy to T55x7 with CardId: %u", id);
print_blocks(blocks, 4);
print_blocks(blocks, ARRAYLEN(blocks));
uint8_t res = 0;
PacketResponseNG resp;
// fast push mode
conn.block_after_ACK = true;
for (uint8_t i = 0; i < 4; i++) {
if (i == 3) {
// Disable fast mode on last packet
conn.block_after_ACK = false;
}
clearCommandBuffer();
t55xx_write_block_t ng;
ng.data = blocks[i];
ng.pwd = 0;
ng.blockno = i;
ng.flags = 0;
SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng));
if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) {
PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
return PM3_ETIMEOUT;
}
if (i == 0) {
SetConfigWithBlock0(blocks[0]);
if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false))
continue;
}
if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false)
res++;
}
if (res == 0)
PrintAndLogEx(SUCCESS, "Success writing to tag");
return PM3_SUCCESS;
}
return clone_t55xx_tag(blocks, ARRAYLEN(blocks));}
static int CmdNoralsySim(const char *Cmd) {

View file

@ -11,19 +11,6 @@
#include "common.h"
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "cmdparser.h" // command_t
#include "comms.h"
#include "ui.h"
#include "cmddata.h"
#include "cmdlf.h"
#include "protocols.h" // for T55xx config register definitions
#include "lfdemod.h" // parityTest
#include "cmdlft55xx.h" // verifywrite
int CmdLFNoralsy(const char *Cmd);
int demodNoralsy(void);

View file

@ -9,8 +9,34 @@
//-----------------------------------------------------------------------------
#include "cmdlfpac.h"
#include <ctype.h> //tolower
#include "commonutil.h" // ARRAYLEN
#include "common.h"
#include "cmdparser.h" // command_t
#include "comms.h"
#include "ui.h"
#include "cmddata.h"
#include "cmdlf.h"
#include "lfdemod.h" // preamble test
#include "protocols.h" // t55xx defines
#include "cmdlft55xx.h" // clone..
static int CmdHelp(const char *Cmd);
static int usage_lf_pac_clone(void) {
PrintAndLogEx(NORMAL, "clone a Stanley/PAC tag to a T55x7 tag.");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf pac clone [h] [b <raw hex>]");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h : this help");
PrintAndLogEx(NORMAL, " b <raw hex> : raw hex data. 12 bytes max");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " lf pac clone b FF2049906D8511C593155B56D5B2649F ");
return PM3_SUCCESS;
}
//see NRZDemod for what args are accepted
static int CmdPacDemod(const char *Cmd) {
@ -46,8 +72,8 @@ static int CmdPacDemod(const char *Cmd) {
// 11111111001000000 10 01001100 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 10001100 10 100000001
// unknown checksum 9 bits at the end
PrintAndLogEx(NORMAL, "PAC/Stanley Tag Found -- Raw: %08X%08X%08X%08X", raw1, raw2, raw3, raw4);
PrintAndLogEx(NORMAL, "\nHow the Raw ID is translated by the reader is unknown");
PrintAndLogEx(SUCCESS, "PAC/Stanley Tag Found -- Raw: %08X%08X%08X%08X", raw1, raw2, raw3, raw4);
PrintAndLogEx(INFO, "How the Raw ID is translated by the reader is unknown. Share your trace file on forum");
return PM3_SUCCESS;
}
@ -57,9 +83,45 @@ static int CmdPacRead(const char *Cmd) {
}
static int CmdPacClone(const char *Cmd) {
// possible to raw hex and clone
PrintAndLogEx(INFO, " To be implemented, feel free to contribute!");
return PM3_SUCCESS;
uint32_t blocks[5];
bool errors = false;
uint8_t cmdp = 0;
int datalen = 0;
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_lf_pac_clone();
case 'b': {
// skip first block, 4*4 = 16 bytes left
uint8_t rawhex[16] = {0};
int res = param_gethex_to_eol(Cmd, cmdp + 1, rawhex, sizeof(rawhex), &datalen);
if ( res != 0 )
errors = true;
for(uint8_t i = 1; i < ARRAYLEN(blocks); i++) {
blocks[i] = bytes_to_num(rawhex + ( (i - 1) * 4 ), sizeof(uint32_t));
}
cmdp += 2;
break;
}
default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
if (errors || cmdp == 0) return usage_lf_pac_clone();
//Pac - compat mode, NRZ, data rate 40, 3 data blocks
blocks[0] = T55x7_MODULATION_DIRECT | T55x7_BITRATE_RF_40 | 4 << T55x7_MAXBLOCK_SHIFT;
PrintAndLogEx(INFO, "Preparing to clone Securakey to T55x7 with raw hex");
print_blocks(blocks, ARRAYLEN(blocks));
return clone_t55xx_tag(blocks, ARRAYLEN(blocks));
}
static int CmdPacSim(const char *Cmd) {

View file

@ -10,12 +10,6 @@
#define CMDLFPAC_H__
#include "common.h"
#include "cmdparser.h" // command_t
#include "comms.h"
#include "ui.h"
#include "cmddata.h"
#include "cmdlf.h"
#include "lfdemod.h" // preamble test
int CmdLFPac(const char *Cmd);

View file

@ -14,6 +14,7 @@
#include <stdlib.h>
#include <ctype.h>
#include "commonutil.h" // ARRAYLEN
#include "cmdparser.h" // command_t
#include "comms.h"
#include "ui.h"
@ -21,7 +22,24 @@
#include "cmddata.h"
#include "cmdlf.h"
#include "lfdemod.h"
#include "protocols.h" // t55xx defines
#include "cmdlft55xx.h" // clone..
static int CmdHelp(const char *Cmd);
static int usage_lf_paradox_clone(void) {
PrintAndLogEx(NORMAL, "clone a Paradox tag to a T55x7 tag.");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf paradox clone [h] [b <raw hex>]");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h : this help");
PrintAndLogEx(NORMAL, " b <raw hex> : raw hex data. 12 bytes max");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " lf paradox clone 0f55555695596a6a9999a59a");
return PM3_SUCCESS;
}
/*
static int usage_lf_paradox_sim(void) {
PrintAndLogEx(NORMAL, "Enables simulation of Paradox card with specified card number.");
@ -113,8 +131,45 @@ static int CmdParadoxRead(const char *Cmd) {
}
static int CmdParadoxClone(const char *Cmd) {
PrintAndLogEx(INFO, " To be implemented, feel free to contribute!");
return PM3_SUCCESS;
uint32_t blocks[4];
bool errors = false;
uint8_t cmdp = 0;
int datalen = 0;
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_lf_paradox_clone();
case 'b': {
// skip first block, 3*4 =12 bytes left
uint8_t rawhex[12] = {0};
int res = param_gethex_to_eol(Cmd, cmdp + 1, rawhex, sizeof(rawhex), &datalen);
if ( res != 0 )
errors = true;
for(uint8_t i = 1; i < ARRAYLEN(blocks); i++) {
blocks[i] = bytes_to_num(rawhex + ( (i - 1) * 4 ), sizeof(uint32_t));
}
cmdp += 2;
break;
}
default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
if (errors || cmdp == 0) return usage_lf_paradox_clone();
//Securakey - compat mode, ASK/Man, data rate 40, 3 data blocks
blocks[0] = T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_50 | 3 << T55x7_MAXBLOCK_SHIFT;
PrintAndLogEx(INFO, "Preparing to clone Paradox to T55x7 with raw hex");
print_blocks(blocks, ARRAYLEN(blocks));
return clone_t55xx_tag(blocks, ARRAYLEN(blocks));
}
static int CmdParadoxSim(const char *Cmd) {

View file

@ -9,6 +9,21 @@
#include "cmdlfpresco.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "commonutil.h" // ARRAYLEN
#include "cmdparser.h" // command_t
#include "comms.h"
#include "ui.h"
#include "cmddata.h"
#include "cmdlf.h"
#include "protocols.h" // for T55xx config register definitions
#include "lfdemod.h" // parityTest
#include "cmdlft55xx.h" // verifywrite
static int CmdHelp(const char *Cmd);
static int usage_lf_presco_clone(void) {
@ -119,46 +134,9 @@ static int CmdPrescoClone(const char *Cmd) {
blocks[4] = fullcode;
PrintAndLogEx(INFO, "Preparing to clone Presco to T55x7 with SiteCode: %u, UserCode: %u, FullCode: %08x", sitecode, usercode, fullcode);
print_blocks(blocks, 5);
print_blocks(blocks, ARRAYLEN(blocks));
uint8_t res = 0;
PacketResponseNG resp;
// fast push mode
conn.block_after_ACK = true;
for (uint8_t i = 0; i < 5; i++) {
if (i == 4) {
// Disable fast mode on last packet
conn.block_after_ACK = false;
}
clearCommandBuffer();
t55xx_write_block_t ng;
ng.data = blocks[i];
ng.pwd = 0;
ng.blockno = i;
ng.flags = 0;
SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng));
if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) {
PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
return PM3_ETIMEOUT;
}
if (i == 0) {
SetConfigWithBlock0(blocks[0]);
if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false))
continue;
}
if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false)
res++;
}
if (res == 0)
PrintAndLogEx(SUCCESS, "Success writing to tag");
return PM3_SUCCESS;
return clone_t55xx_tag(blocks, ARRAYLEN(blocks));
}
// takes base 12 ID converts to hex

View file

@ -11,20 +11,6 @@
#include "common.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "cmdparser.h" // command_t
#include "comms.h"
#include "ui.h"
#include "cmddata.h"
#include "cmdlf.h"
#include "protocols.h" // for T55xx config register definitions
#include "lfdemod.h" // parityTest
#include "cmdlft55xx.h" // verifywrite
int CmdLFPresco(const char *Cmd);
int demodPresco(void);

View file

@ -8,6 +8,23 @@
// FSK2a, rf/50, 128 bits (complete)
//-----------------------------------------------------------------------------
#include "cmdlfpyramid.h"
#include "common.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include "commonutil.h" // ARRAYLEN
#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 "crc.h"
#include "cmdlft55xx.h" // verifywrite
static int CmdHelp(const char *Cmd);
@ -203,8 +220,10 @@ static int CmdPyramidClone(const char *Cmd) {
uint32_t facilitycode = 0, cardnumber = 0, fc = 0, cn = 0;
uint32_t blocks[5];
uint8_t bs[128];
memset(bs, 0x00, sizeof(bs));
uint8_t *bs = calloc(128, sizeof(uint8_t));
if (bs == NULL) {
return PM3_EMALLOC;
}
if (sscanf(Cmd, "%u %u", &fc, &cn) != 2) return usage_lf_pyramid_clone();
@ -228,47 +247,12 @@ static int CmdPyramidClone(const char *Cmd) {
blocks[3] = bytebits_to_byte(bs + 64, 32);
blocks[4] = bytebits_to_byte(bs + 96, 32);
free(bs);
PrintAndLogEx(INFO, "Preparing to clone Farpointe/Pyramid to T55x7 with Facility Code: %u, Card Number: %u", facilitycode, cardnumber);
print_blocks(blocks, 5);
print_blocks(blocks, ARRAYLEN(blocks));
uint8_t res = 0;
PacketResponseNG resp;
// fast push mode
conn.block_after_ACK = true;
for (int8_t i = 0; i < 5; i++) {
if (i == 4) {
// Disable fast mode on last packet
conn.block_after_ACK = false;
}
clearCommandBuffer();
t55xx_write_block_t ng;
ng.data = blocks[i];
ng.pwd = 0;
ng.blockno = i;
ng.flags = 0;
SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng));
if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) {
PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
return PM3_ETIMEOUT;
}
if (i == 0) {
SetConfigWithBlock0(blocks[0]);
if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false))
continue;
}
if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false)
res++;
}
if (res == 0)
PrintAndLogEx(SUCCESS, "Success writing to tag");
return PM3_SUCCESS;
return clone_t55xx_tag(blocks, ARRAYLEN(blocks));
}
static int CmdPyramidSim(const char *Cmd) {

View file

@ -10,21 +10,6 @@
#define CMDLFPYRAMID_H__
#include "common.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#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 "crc.h"
#include "cmdlft55xx.h" // verifywrite
int CmdLFPyramid(const char *Cmd);

View file

@ -9,18 +9,35 @@
//-----------------------------------------------------------------------------
#include "cmdlfsecurakey.h"
#include <string.h>
#include <string.h> // memcpy
#include <ctype.h> // tolower
#include "cmdparser.h" // command_t
#include "commonutil.h" // ARRAYLEN
#include "cmdparser.h" // command_t
#include "comms.h"
#include "ui.h"
#include "cmddata.h"
#include "cmdlf.h"
#include "lfdemod.h" // preamble test
#include "parity.h" // for wiegand parity test
#include "protocols.h" // t55xx defines
#include "cmdlft55xx.h" // clone..
static int CmdHelp(const char *Cmd);
static int usage_lf_securakey_clone(void) {
PrintAndLogEx(NORMAL, "clone a Securakey tag to a T55x7 tag.");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf securakey clone [h] [b <raw hex>]");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h : this help");
PrintAndLogEx(NORMAL, " b <raw hex> : raw hex data. 12 bytes max");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " lf securakey clone 7FCB400001ADEA5344300000");
return PM3_SUCCESS;
}
//see ASKDemod for what args are accepted
static int CmdSecurakeyDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
@ -100,6 +117,7 @@ static int CmdSecurakeyDemod(const char *Cmd) {
PrintAndLogEx(SUCCESS, "Securakey Tag Found--BitLen: %u, Card ID: %u, FC: 0x%X, Raw: %08X%08X%08X", bitLen, cardid, fc, raw1, raw2, raw3);
if (bitLen <= 32)
PrintAndLogEx(SUCCESS, "Wiegand: %08X, Parity: %s", (lWiegand << (bitLen / 2)) | rWiegand, parity ? "Passed" : "Failed");
PrintAndLogEx(INFO, "\nHow the FC translates to printed FC is unknown");
PrintAndLogEx(INFO, "How the checksum is calculated is unknown");
PrintAndLogEx(INFO, "Help the community identify this format further\n by sharing your tag on the pm3 forum or with forum members");
@ -112,8 +130,45 @@ static int CmdSecurakeyRead(const char *Cmd) {
}
static int CmdSecurakeyClone(const char *Cmd) {
PrintAndLogEx(INFO, " To be implemented, feel free to contribute!");
return PM3_SUCCESS;
uint32_t blocks[4];
bool errors = false;
uint8_t cmdp = 0;
int datalen = 0;
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_lf_securakey_clone();
case 'b': {
// skip first block, 3*4 = 12 bytes left
uint8_t rawhex[12] = {0};
int res = param_gethex_to_eol(Cmd, cmdp + 1, rawhex, sizeof(rawhex), &datalen);
if ( res != 0 )
errors = true;
for(uint8_t i = 1; i < ARRAYLEN(blocks); i++) {
blocks[i] = bytes_to_num(rawhex + ( (i - 1) * 4 ), sizeof(uint32_t));
}
cmdp += 2;
break;
}
default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
if (errors || cmdp == 0) return usage_lf_securakey_clone();
//Securakey - compat mode, ASK/Man, data rate 40, 3 data blocks
blocks[0] = T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_40 | 3 << T55x7_MAXBLOCK_SHIFT;
PrintAndLogEx(INFO, "Preparing to clone Securakey to T55x7 with raw hex");
print_blocks(blocks, ARRAYLEN(blocks));
return clone_t55xx_tag(blocks, ARRAYLEN(blocks));
}
static int CmdSecurakeySim(const char *Cmd) {

View file

@ -338,6 +338,59 @@ static int usage_t55xx_protect() {
static int CmdHelp(const char *Cmd);
int clone_t55xx_tag(uint32_t *blockdata, uint8_t numblocks) {
if (blockdata == NULL)
return PM3_EINVARG;
if (numblocks < 1 || numblocks > 7)
return PM3_EINVARG;
PacketResponseNG resp;
// fast push mode
conn.block_after_ACK = true;
for (int8_t i = 0; i < numblocks; i++) {
// Disable fast mode on last packet
if (i == numblocks - 1) {
conn.block_after_ACK = false;
}
clearCommandBuffer();
t55xx_write_block_t ng;
ng.data = blockdata[i];
ng.pwd = 0;
ng.blockno = i;
ng.flags = 0;
SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng));
if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) {
PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
return PM3_ETIMEOUT;
}
}
uint8_t res = 0;
for (int8_t i = 0; i < numblocks; i++) {
if (i == 0) {
SetConfigWithBlock0(blockdata[0]);
if (t55xxAquireAndCompareBlock0(false, 0, blockdata[0], false))
continue;
}
if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blockdata[i]) == false)
res++;
}
if (res == 0)
PrintAndLogEx(SUCCESS, "Success writing to tag");
return PM3_SUCCESS;
}
static bool t55xxProtect(bool lock, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t new_password) {
PrintAndLogEx(INFO, "Checking current configuration");

View file

@ -169,4 +169,5 @@ uint8_t tryOnePassword(uint32_t password, uint8_t downlink_mode);
void printT55x7Trace(t55x7_tracedata_t data, uint8_t repeat);
void printT5555Trace(t5555_tracedata_t data, uint8_t repeat);
int clone_t55xx_tag(uint32_t *blockdata, uint8_t numblocks);
#endif

View file

@ -9,6 +9,20 @@
//-----------------------------------------------------------------------------
#include "cmdlfviking.h"
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "common.h"
#include "cmdparser.h" // command_t
#include "comms.h"
#include "ui.h"
#include "cmddata.h"
#include "cmdlf.h"
#include "lfdemod.h"
#include "commonutil.h" // num_to_bytes
static int CmdHelp(const char *Cmd);
static int usage_lf_viking_clone(void) {

View file

@ -9,21 +9,8 @@
#ifndef CMDLFVIKING_H__
#define CMDLFVIKING_H__
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "common.h"
#include "cmdparser.h" // command_t
#include "comms.h"
#include "ui.h"
#include "cmddata.h"
#include "cmdlf.h"
#include "lfdemod.h"
#include "commonutil.h" // num_to_bytes
int CmdLFViking(const char *Cmd);
int demodViking(void);

View file

@ -11,6 +11,22 @@
#include "cmdlfvisa2000.h"
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include "commonutil.h" // ARRAYLEN
#include "common.h"
#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 "cmdlft55xx.h" // write verify
#define BL0CK1 0x56495332
static int CmdHelp(const char *Cmd);
@ -165,46 +181,9 @@ static int CmdVisa2kClone(const char *Cmd) {
blocks[3] = (visa_parity(id) << 4) | visa_chksum(id);
PrintAndLogEx(INFO, "Preparing to clone Visa2000 to T55x7 with CardId: %u", id);
print_blocks(blocks, 4);
print_blocks(blocks, ARRAYLEN(blocks));
uint8_t res = 0;
PacketResponseNG resp;
// fast push mode
conn.block_after_ACK = true;
for (uint8_t i = 0; i < 4; i++) {
if (i == 3) {
// Disable fast mode on last packet
conn.block_after_ACK = false;
}
clearCommandBuffer();
t55xx_write_block_t ng;
ng.data = blocks[i];
ng.pwd = 0;
ng.blockno = i;
ng.flags = 0;
SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng));
if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) {
PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
return PM3_ETIMEOUT;
}
if (i == 0) {
SetConfigWithBlock0(blocks[0]);
if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false))
continue;
}
if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false)
res++;
}
if (res == 0)
PrintAndLogEx(SUCCESS, "Success writing to tag");
return PM3_SUCCESS;
return clone_t55xx_tag(blocks, ARRAYLEN(blocks));
}
static int CmdVisa2kSim(const char *Cmd) {

View file

@ -9,19 +9,7 @@
#ifndef CMDLFVISA2000_H__
#define CMDLFVISA2000_H__
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include "common.h"
#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 "cmdlft55xx.h" // write verify
int CmdLFVisa2k(const char *Cmd);

View file

@ -1020,3 +1020,9 @@ e6849fcc324b
39ad2963d3d1
34b16cd59ff8 # Hotel Berlin Classic room A KEY
bb2c0007d022 # Hotel Berlin Classic room B KEY
#
# Coinmatic laundry Smart card
# data from: https://pastebin.com/XZQiLtUf
#
0734bfb93dab
85a438f72a8a

View file

@ -84,6 +84,8 @@ void setGraphBuf(uint8_t *buff, size_t size) {
size_t getFromGraphBuf(uint8_t *buff) {
if (buff == NULL) return 0;
if (GraphTraceLen == 0) return 0;
size_t i;
for (i = 0; i < GraphTraceLen; ++i) {
//trim
@ -134,6 +136,11 @@ void convertGraphFromBitstreamEx(int hi, int low) {
}
size_t size = getFromGraphBuf(bits);
if (size == 0) {
PrintAndLogEx(WARNING, "Failed to copy from graphbuffer");
free(bits);
return;
}
// set signal properties low/high/mean/amplitude and is_noise detection
computeSignalProperties(bits, size);

View file

@ -30,7 +30,7 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
uint32_t nt = 0, nr = 0, ar = 0;
uint64_t par_list = 0, ks_list = 0;
uint64_t *keylist = NULL, *last_keylist = NULL;
bool arg0 = true;
bool first_run = true;
// message
PrintAndLogEx(NORMAL, "--------------------------------------------------------------------------------\n");
@ -40,7 +40,15 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
while (true) {
clearCommandBuffer();
SendCommandMIX(CMD_HF_MIFARE_READER, arg0, blockno, key_type, NULL, 0);
struct {
uint8_t first_run;
uint8_t blockno;
uint8_t key_type;
} PACKED payload;
payload.first_run = first_run;
payload.blockno = blockno;
payload.key_type = key_type;
SendCommandNG(CMD_HF_MIFARE_READER, (uint8_t*)&payload, sizeof(payload));
//flush queue
while (kbd_enter_pressed()) {
@ -56,26 +64,47 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
}
PacketResponseNG resp;
if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
int16_t isOK = resp.oldarg[0];
if (isOK < 0)
return isOK;
if (WaitForResponseTimeout(CMD_HF_MIFARE_READER, &resp, 2000)) {
if (resp.status == PM3_EOPABORTED) {
return -1;
}
uid = (uint32_t)bytes_to_num(resp.data.asBytes + 0, 4);
nt = (uint32_t)bytes_to_num(resp.data.asBytes + 4, 4);
par_list = bytes_to_num(resp.data.asBytes + 8, 8);
ks_list = bytes_to_num(resp.data.asBytes + 16, 8);
nr = (uint32_t)bytes_to_num(resp.data.asBytes + 24, 4);
ar = (uint32_t)bytes_to_num(resp.data.asBytes + 28, 4);
struct p {
int32_t isOK;
uint8_t cuid[4];
uint8_t nt[4];
uint8_t par_list[8];
uint8_t ks_list[8];
uint8_t nr[4];
uint8_t ar[4];
} PACKED;
struct p* package = (struct p*) resp.data.asBytes;
if (package->isOK == -6) {
*key = 0101;
return 1;
}
if (package->isOK < 0)
return package->isOK;
uid = (uint32_t)bytes_to_num(package->cuid, sizeof(package->cuid));
nt = (uint32_t)bytes_to_num(package->nt, sizeof(package->nr));
par_list = bytes_to_num(package->par_list, sizeof(package->par_list));
ks_list = bytes_to_num(package->ks_list, sizeof(package->ks_list));
nr = (uint32_t)bytes_to_num(package->nr, 4);
ar = (uint32_t)bytes_to_num(package->ar, 4);
break;
}
}
PrintAndLogEx(NORMAL, "\n");
if (par_list == 0 && arg0 == true) {
if (par_list == 0 && first_run == true) {
PrintAndLogEx(SUCCESS, "Parity is all zero. Most likely this card sends NACK on every authentication.");
}
arg0 = false;
first_run = false;
uint32_t keycount = nonce2key(uid, nt, nr, ar, par_list, ks_list, &keylist);
@ -124,7 +153,7 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
PrintAndLogEx(FAILED, "all candidate keys failed. Restarting darkside attack");
free(last_keylist);
last_keylist = keylist;
arg0 = true;
first_run = true;
}
}
free(last_keylist);