Merge pull request #1301 from chunkystew/patch-1

Rewrote getIndalaBits()
This commit is contained in:
Iceman 2021-07-14 14:49:08 +02:00 committed by GitHub
commit 5fd951f7d4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 45383 additions and 29 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...
## [unreleased][unreleased]
- Added `-4041x` option to lf indala clone for the Indala 4041X format (@chunkystew)
- Added a new client preference, delay of execution, a delay in ms before a cmd is sent. Good for implants (@iceman1001)
- Fix `lf t55xx brute` - now correctly prints last key if it was correct (@scott4290)
- Added support python scripts (@salmg)

View file

@ -112,6 +112,17 @@ static void decodeHeden2L(uint8_t *bits) {
PrintAndLogEx(SUCCESS, " Heden-2L | %u", cardnumber);
}
bool parityEven(uint16_t x) {
x ^= x >> 1;
x ^= x >> 2;
x ^= x >> 4;
x ^= x >> 8;
x ^= x >> 16;
return (x & 0x01);
}
bool parityOdd(uint16_t x) { return(!parityEven(x)); }
// Indala 26 bit decode
// by marshmellow, martinbeier
// optional arguments - same as PSKDemod (clock & invert & maxerr)
@ -194,18 +205,19 @@ int demodIndalaEx(int clk, int invert, int maxErr, bool verbose) {
csn |= DemodBuffer[50] << 1; // b2
csn |= DemodBuffer[41] << 0; // b1
uint8_t checksum = 0;
checksum |= DemodBuffer[62] << 1; // b2
checksum |= DemodBuffer[63] << 0; // b1
uint8_t parity = 0;
parity |= DemodBuffer[34] << 1; // b2
parity |= DemodBuffer[38] << 0; // b1
PrintAndLogEx(SUCCESS, "Fmt " _GREEN_("26") " FC: " _GREEN_("%u") " Card: " _GREEN_("%u") " checksum: " _GREEN_("%1d%1d")
PrintAndLogEx(SUCCESS, "Fmt " _GREEN_("26") " FC: " _GREEN_("%u") " Card: " _GREEN_("%u") " Parity: " _GREEN_("%1d%1d")
, fc
, csn
, checksum >> 1 & 0x01
, checksum & 0x01
, parity >> 1 & 0x01
, parity & 0x01
);
PrintAndLogEx(SUCCESS, "Possible de-scramble patterns");
// This doesn't seem to line up with the hot-stamp numbers on any HID cards I have seen, but, leaving it alone since I do not know how those work. -MS
PrintAndLogEx(SUCCESS, " Printed | __%04d__ [0x%X]", p1, p1);
PrintAndLogEx(SUCCESS, " Internal ID | %" PRIu64, foo);
decodeHeden2L(DemodBuffer);
@ -245,7 +257,7 @@ static int CmdIndalaDemod(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf indala demod",
"Tries to psk demodulate the graphbuffer as Indala",
"Tries to PSK demodulate the graphbuffer as Indala",
"lf indala demod\n"
"lf indala demod --clock 32 -> demod a Indala tag from GraphBuffer using a clock of RF/32\n"
"lf indala demod --clock 32 -i -> demod a Indala tag from GraphBuffer using a clock of RF/32 and inverting data\n"
@ -276,7 +288,7 @@ static int CmdIndalaDemodAlt(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf indala altdemod",
"Tries to psk demodulate the graphbuffer as Indala\n"
"Tries to PSK demodulate the graphbuffer as Indala\n"
"This is uses a alternative way to demodulate and was used from the beginning in the Pm3 client.\n"
"It's now considered obsolete but remains because it has sometimes its advantages.",
"lf indala altdemod\n"
@ -345,7 +357,7 @@ static int CmdIndalaDemodAlt(const char *Cmd) {
if (rawbit > 0) {
PrintAndLogEx(INFO, "Recovered %d raw bits, expected: %zu", rawbit, GraphTraceLen / 32);
PrintAndLogEx(INFO, "worst metric (0=best..7=worst): %d at pos %d", worst, worstPos);
PrintAndLogEx(INFO, "Worst metric (0=best..7=worst): %d at pos %d", worst, worstPos);
} else {
return PM3_ESOFT;
}
@ -375,7 +387,7 @@ static int CmdIndalaDemodAlt(const char *Cmd) {
}
if (start == rawbit - uidlen + 1) {
PrintAndLogEx(FAILED, "nothing to wait for");
PrintAndLogEx(FAILED, "Nothing to wait for");
return PM3_ESOFT;
}
@ -527,7 +539,7 @@ static int CmdIndalaSim(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf indala sim",
"Enables simulation of Indala card with specified facility-code and card number.\n"
"Enables simulation of Indala card with specified facility code and card number.\n"
"Simulation runs until the button is pressed or another USB command is issued.",
"lf indala sim --heden 888\n"
"lf indala sim --raw a0000000a0002021\n"
@ -633,11 +645,12 @@ static int CmdIndalaClone(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_strx0("r", "raw", "<hex>", "raw bytes"),
arg_int0(NULL, "heden", "<decimal>", "Cardnumber for Heden 2L format"),
arg_int0(NULL, "fc", "<decimal>", "Facility Code (26 bit H10301 format)"),
arg_int0(NULL, "cn", "<decimal>", "Cardnumber (26 bit H10301 format)"),
arg_lit0(NULL, "q5", "optional - specify writing to Q5/T5555 tag"),
arg_lit0(NULL, "em", "optional - specify writing to EM4305/4469 tag"),
arg_int0(NULL, "heden", "<decimal>", "Card number for Heden 2L format"),
arg_int0(NULL, "fc", "<decimal>", "Facility code (26 bit H10301 format)"),
arg_int0(NULL, "cn", "<decimal>", "Card number (26 bit H10301 format)"),
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, "4041x", "Optional - specify Indala 4041X format, must use with fc and cn"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
@ -649,6 +662,7 @@ static int CmdIndalaClone(const char *Cmd) {
bool is_long_uid = (raw_len == 28);
bool q5 = arg_get_lit(ctx, 5);
bool em = arg_get_lit(ctx, 6);
bool fmt4041x = arg_get_lit(ctx, 7);
bool got_cn = false, got_26 = false;
if (is_long_uid == false) {
@ -669,6 +683,11 @@ static int CmdIndalaClone(const char *Cmd) {
return PM3_EINVARG;
}
if( !got_26 & fmt4041x ) {
PrintAndLogEx(FAILED, "You must specify a facility code and card number when using 4041X format");
return PM3_EINVARG;
}
uint8_t max = 0;
uint32_t blocks[8] = {0};
char cardtype[16] = {"T55x7"};
@ -697,12 +716,11 @@ static int CmdIndalaClone(const char *Cmd) {
// 224 BIT UID
// config for Indala (RF/32;PSK2 with RF/2;Maxblock=7)
PrintAndLogEx(INFO, "Preparing to clone Indala 224bit to " _YELLOW_("%s") " raw " _GREEN_("%s")
PrintAndLogEx(INFO, "Preparing to clone Indala 224 bit to " _YELLOW_("%s") " raw " _GREEN_("%s")
, cardtype
, sprint_hex_inrow(raw, raw_len)
);
} else {
// 64 BIT UID
if (got_cn) {
@ -710,7 +728,7 @@ static int CmdIndalaClone(const char *Cmd) {
raw_len = 8;
} else if (got_26) {
PrintAndLogEx(INFO, "Using Indala 26b FC " _GREEN_("%u") " CN " _GREEN_("%u"), fc, cn);
PrintAndLogEx(INFO, "Using Indala 64 bit, FC " _GREEN_("%u") " CN " _GREEN_("%u"), fc, cn);
// Used with the 26bit FC/CSN
uint8_t *bits = calloc(INDALA_ARR_LEN, sizeof(uint8_t));
@ -719,10 +737,18 @@ static int CmdIndalaClone(const char *Cmd) {
return PM3_EMALLOC;
}
if (getIndalaBits(fc, cn, bits) != PM3_SUCCESS) {
// Bitstream generation, format select
int indalaReturn = PM3_ESOFT;
if(fmt4041x){
indalaReturn = getIndalaBits4041x(fc, cn, bits);
} else {
indalaReturn = getIndalaBits(fc, cn, bits);
}
if (indalaReturn != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Error with tag bitstream generation.");
free(bits);
return PM3_ESOFT;
return indalaReturn;
}
raw[0] = bytebits_to_byte(bits, 8);
@ -755,7 +781,7 @@ static int CmdIndalaClone(const char *Cmd) {
max = 3;
// config for Indala 64 format (RF/32;PSK1 with RF/2;Maxblock=2)
PrintAndLogEx(INFO, "Preparing to clone Indala 64bit to " _YELLOW_("%s") " raw " _GREEN_("%s")
PrintAndLogEx(INFO, "Preparing to clone Indala 64 bit to " _YELLOW_("%s") " raw " _GREEN_("%s")
, cardtype
, sprint_hex_inrow(raw, raw_len)
);
@ -775,12 +801,12 @@ static int CmdIndalaClone(const char *Cmd) {
}
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "this help"},
{"demod", CmdIndalaDemod, AlwaysAvailable, "demodulate an Indala tag (PSK1) from GraphBuffer"},
{"altdemod", CmdIndalaDemodAlt, AlwaysAvailable, "alternative method to demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"},
{"reader", CmdIndalaReader, IfPm3Lf, "read an Indala tag from the antenna"},
{"clone", CmdIndalaClone, IfPm3Lf, "clone Indala tag to T55x7 or Q5/T5555"},
{"sim", CmdIndalaSim, IfPm3Lf, "simulate Indala tag"},
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"demod", CmdIndalaDemod, AlwaysAvailable, "Demodulate an Indala tag (PSK1) from GraphBuffer"},
{"altdemod", CmdIndalaDemodAlt, AlwaysAvailable, "Alternative method to demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"},
{"reader", CmdIndalaReader, IfPm3Lf, "Read an Indala tag from the antenna"},
{"clone", CmdIndalaClone, IfPm3Lf, "Clone Indala 4041X tag to T55x7 or Q5/T5555"},
{"sim", CmdIndalaSim, IfPm3Lf, "Simulate Indala tag"},
{NULL, NULL, NULL, NULL}
};
@ -860,6 +886,58 @@ int getIndalaBits(uint8_t fc, uint16_t cn, uint8_t *bits) {
return PM3_SUCCESS;
}
/*
Permutation table for this format, lower 4 bytes of card data.
0x40 | 1 | CN 6 | P Hi | CN 9 | CN A | CN 5 | P Lo | FC 1 |
0x50 | CN C | CN 0 | CN 5 | CN D | FC 5 | CN E | CN 7 | FC 4 |
0x60 | FC 3 | FC 6 | CN 1 | CN 8 | CN B | FC 2 | CN 4 | 1 |
0x70 | CN 3 | FC 7 | FC 0 | CN 2 | 0 | 0 | 0 | 0 |
*/
int getIndalaBits4041x(uint8_t fc, uint16_t cn, uint8_t *bits) {
// Preamble and required values
bits[0] = 0x01;
bits[2] = 0x01;
bits[32] = 0x01;
bits[40] = 0x01;
bits[55] = 0x01;
// Facility code
bits[57] = ((fc >> 7) & 0x01); // MSB
bits[49] = ((fc >> 6) & 0x01);
bits[44] = ((fc >> 5) & 0x01);
bits[47] = ((fc >> 4) & 0x01);
bits[48] = ((fc >> 3) & 0x01);
bits[53] = ((fc >> 2) & 0x01);
bits[39] = ((fc >> 1) & 0x01);
bits[58] = (fc & 0x01); // LSB
// Serial number
bits[42] = ((cn >> 15) & 0x01); // MSB H
bits[45] = ((cn >> 14) & 0x01);
bits[43] = ((cn >> 13) & 0x01);
bits[40] = ((cn >> 12) & 0x01);
bits[52] = ((cn >> 11) & 0x01);
bits[36] = ((cn >> 10) & 0x01);
bits[35] = ((cn >> 9) & 0x01);
bits[51] = ((cn >> 8) & 0x01); // LSB H
bits[46] = ((cn >> 7) & 0x01); // MSB L
bits[33] = ((cn >> 6) & 0x01);
bits[37] = ((cn >> 5) & 0x01);
bits[54] = ((cn >> 4) & 0x01);
bits[56] = ((cn >> 3) & 0x01);
bits[59] = ((cn >> 2) & 0x01);
bits[50] = ((cn >> 1) & 0x01);
bits[41] = (cn & 0x01); // LSB L
// Parity
bits[34] = parityEven((fc << 4) | (cn >> 12));
bits[38] = parityOdd(cn & 0x0fff);
return PM3_SUCCESS;
}
// redesigned by marshmellow adjusted from existing decode functions
// indala id decoding
int detectIndala(uint8_t *dest, size_t *size, uint8_t *invert) {

View file

@ -21,5 +21,8 @@ int detectIndala(uint8_t *dest, size_t *size, uint8_t *invert);
int demodIndalaEx(int clk, int invert, int maxErr, bool verbose);
int demodIndala(bool verbose);
int getIndalaBits(uint8_t fc, uint16_t cn, uint8_t *bits);
int getIndalaBits4041x(uint8_t fc, uint16_t cn, uint8_t *bits);
bool parityOdd(uint16_t x);
bool parityEven(uint16_t x);
#endif

View file

@ -30,6 +30,7 @@
|lf_IDTECK_4944544B351FBE4B.pm3 |IDTECK raw 4944544B351FBE4B , PSK, printed "708 082 14087"|
|lf_IDTECK_idk50_PSK.pm3 |IDTECK (?)|
|lf_Indala-00002-12345678-1A.pm3 |Indala credit-card style card|
|lf_indala_4041x_234_21801.pm3 |Indala 4041X 26-bit|
|lf_Indala-504278295.pm3 |PSK 26 bit indala|
|lf_IOProx-XSF-01-3B-44725.pm3 |IO Prox FSK RF/64 ID in name|
|lf_IOProx-XSF-01-BE-03011.pm3 |IO Prox FSK RF/64 ID in name|
@ -91,4 +92,4 @@
|hf_14a_mfu-sim.trace |Trace seen from a Proxmark3 simulating a MFU|
|hf_14b_reader.trace |Execution of `hf 14b reader` against a card|
|hf_14b_cryptorf_select.trace |Sniff of libnfc select / anticollision ofa cryptoRF tag|
|hf_15_reader.trace |Execution of `hf 15 reader` against a card|
|hf_15_reader.trace |Execution of `hf 15 reader` against a card|

File diff suppressed because it is too large Load diff