adding asn1 tvl decoding of SIO in decrypt, view, eview commands. Available when giving the -v verbose flag

This commit is contained in:
iceman1001 2022-07-11 06:44:07 +02:00
parent 1faca20f5e
commit e7f7925dec
3 changed files with 115 additions and 1 deletions

View file

@ -37,6 +37,8 @@
#include "cmdsmartcard.h" // smart select fct
#include "proxendian.h"
#include "iclass_cmd.h"
#include "crypto/asn1utils.h" // ASN1 decoder
#define PICOPASS_BLOCK_SIZE 8
#define NUM_CSNS 9
@ -56,6 +58,7 @@ static uint8_t empty[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
static uint8_t zeros[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static int CmdHelp(const char *Cmd);
static void printIclassSIO(uint8_t *iclass_dump);
static uint8_t iClass_Key_Table[ICLASS_KEYS_MAX][8] = {
{ 0xAE, 0xA6, 0x84, 0xA6, 0xDA, 0xB2, 0x32, 0x78 },
@ -1139,6 +1142,11 @@ static int CmdHFiClassEView(const char *Cmd) {
PrintAndLogEx(NORMAL, "");
printIclassDumpContents(dump, 1, blocks, bytes);
if (verbose) {
printIclassSIO(dump);
}
free(dump);
return PM3_SUCCESS;
}
@ -1328,6 +1336,10 @@ static int CmdHFiClassDecrypt(const char *Cmd) {
printIclassDumpContents(decrypted, 1, (decryptedlen / 8), decryptedlen);
if (verbose) {
printIclassSIO(decrypted);
}
PrintAndLogEx(NORMAL, "");
// decode block 6
@ -2440,6 +2452,48 @@ static void detect_credential(uint8_t *data, bool *legacy, bool *se, bool *sr) {
r1 = NULL, r2 = NULL;
}
// print ASN1 decoded array in TLV view
static void printIclassSIO(uint8_t *iclass_dump) {
bool isLegacy, isSE, isSR;
detect_credential(iclass_dump, &isLegacy, &isSE, &isSR);
uint8_t pattern[] = {0x05, 0x00, 0x05, 0x00};
if (isSE) {
int dlen = byte_strstr(iclass_dump + (6 * 8), 8*8, pattern, sizeof(pattern));
if (dlen) {
dlen += sizeof(pattern);
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "---------------------------- " _CYAN_("SIO - RAW") " ----------------------------");
print_hex_noascii_break(iclass_dump + (6*8), dlen, 32);
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "------------------------- " _CYAN_("SIO - ASN1 TLV") " --------------------------");
asn1_print(iclass_dump + (6 * 8), dlen, " ");
PrintAndLogEx(NORMAL, "");
}
}
if (isSR) {
int dlen = byte_strstr(iclass_dump + (10 * 8), 8*8, pattern, sizeof(pattern));
if (dlen) {
dlen += sizeof(pattern);
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "---------------------------- " _CYAN_("SIO - RAW") " ----------------------------");
print_hex_noascii_break(iclass_dump + (10*8), dlen, 32);
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "------------------------- " _CYAN_("SIO - ASN1 TLV") " --------------------------");
asn1_print(iclass_dump + (10 * 8), dlen, " ");
PrintAndLogEx(NORMAL, "");
}
}
}
void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t endblock, size_t filesize) {
picopass_hdr_t *hdr = (picopass_hdr_t *)iclass_dump;
@ -2599,7 +2653,10 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e
if (isLegacy)
PrintAndLogEx(HINT, _YELLOW_("yellow") " = legacy credential");
if (isSE || isSR)
if (isSE)
PrintAndLogEx(HINT, _CYAN_("cyan") " = SIO / SE credential");
if (isSR)
PrintAndLogEx(HINT, _CYAN_("cyan") " = SIO / SR credential");
PrintAndLogEx(NORMAL, "");
@ -2650,6 +2707,11 @@ static int CmdHFiClassView(const char *Cmd) {
print_picopass_header((picopass_hdr_t *) dump);
print_picopass_info((picopass_hdr_t *) dump);
printIclassDumpContents(dump, startblock, endblock, bytes_read);
if (verbose) {
printIclassSIO(dump);
}
free(dump);
return PM3_SUCCESS;
}

View file

@ -276,6 +276,31 @@ void print_hex_break(const uint8_t *data, const size_t len, uint8_t breaks) {
}
}
void print_hex_noascii_break(const uint8_t *data, const size_t len, uint8_t breaks) {
if (data == NULL || len == 0 || breaks == 0) return;
int i;
for (i = 0; i < len; i += breaks) {
if (len - i < breaks) { // incomplete block, will be treated out of the loop
break;
}
PrintAndLogEx(INFO, "%s", sprint_hex_inrow_spaces(data + i, breaks, 0));
}
// the last odd bytes
uint8_t mod = len % breaks;
if (mod) {
char buf[UTIL_BUFFER_SIZE_SPRINT + 3];
hex_to_buffer((uint8_t *)buf, data + i, mod, (sizeof(buf) - 1), 0, 0, true);
// add the spaces...
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%*s", ((breaks - mod) * 3), " ");
PrintAndLogEx(INFO, "%s", buf);
}
}
static void print_buffer_ex(const uint8_t *data, const size_t len, int level, uint8_t breaks) {
if (len < 1)
@ -1209,3 +1234,27 @@ inline uint64_t leadingzeros64(uint64_t a) {
return 0;
#endif
}
int byte_strstr(uint8_t* src, size_t srclen, uint8_t* pattern, size_t plen) {
size_t max = srclen - plen + 1;
for (size_t i = 0; i < max; i++) {
// compare only first byte
if (src[i] != pattern[0])
continue;
// try to match rest of the pattern
for (int j = plen - 1; j >= 1; j--) {
if (src[i + j] != pattern[j])
break;
if (j == 1)
return i;
}
}
return -1;
}

View file

@ -67,6 +67,8 @@ void hex_to_buffer(uint8_t *buf, const uint8_t *hex_data, const size_t hex_len,
void print_hex(const uint8_t *data, const size_t len);
void print_hex_break(const uint8_t *data, const size_t len, const uint8_t breaks);
void print_hex_noascii_break(const uint8_t *data, const size_t len, uint8_t breaks);
char *sprint_hex(const uint8_t *data, const size_t len);
char *sprint_hex_inrow(const uint8_t *data, const size_t len);
char *sprint_hex_inrow_ex(const uint8_t *data, const size_t len, const size_t min_str_len);
@ -143,4 +145,5 @@ uint64_t bitcount64(uint64_t a);
uint32_t leadingzeros32(uint32_t a);
uint64_t leadingzeros64(uint64_t a);
int byte_strstr(uint8_t* src, size_t srclen, uint8_t* pattern, size_t plen);
#endif