From 096dee178438c0a722eaf112c8b63ad4eaa9064a Mon Sep 17 00:00:00 2001 From: t0m4 Date: Sun, 14 Jul 2019 12:31:33 +0200 Subject: [PATCH] Add 'hf 15 csetuid' command to set UID on ISO15693 Magic tags (#842) --- CHANGELOG.md | 1 + armsrc/appmain.c | 5 +++ armsrc/iso15693.c | 79 +++++++++++++++++++++++++++++++++++++++++ armsrc/iso15693.h | 1 + client/cmdhf15.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++- client/cmdhf15.h | 1 + include/usb_cmd.h | 1 + 7 files changed, 177 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 037bab99..d5cd979d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - `hf 15 sim` now works as expected (piwi) ### Added +- Added `hf 15 csetuid` - set UID on ISO-15693 Magic tags (t0m4) - Added `lf config s xxxx` option to allow skipping x samples before capture (marshmellow) - Added `lf em 4x05protect` to support changing protection blocks on em4x05 chips (marshmellow) - Support Standard Communication Mode in HITAG S diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 5169383e..9b9acb6f 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1158,9 +1158,14 @@ void UsbPacketReceived(uint8_t *packet, int len) case CMD_READER_ISO_15693: ReaderIso15693(c->arg[0]); break; + case CMD_SIMTAG_ISO_15693: SimTagIso15693(c->arg[0], c->d.asBytes); break; + + case CMD_CSETUID_ISO_15693: + SetTag15693Uid(c->d.asBytes); + break; #endif #ifdef WITH_LEGICRF diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index e3524375..f4120512 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -1591,6 +1591,85 @@ void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint LED_A_OFF(); } +//----------------------------------------------------------------------------- +// Work with "magic Chinese" card. +// +//----------------------------------------------------------------------------- + +// Set the UID to the tag (based on Iceman work). +void SetTag15693Uid(uint8_t *uid) +{ + uint8_t cmd[4][9] = {0x00}; + + uint16_t crc; + + int recvlen = 0; + uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH]; + + LED_A_ON(); + + // Command 1 : 02213E00000000 + cmd[0][0] = 0x02; + cmd[0][1] = 0x21; + cmd[0][2] = 0x3e; + cmd[0][3] = 0x00; + cmd[0][4] = 0x00; + cmd[0][5] = 0x00; + cmd[0][6] = 0x00; + + // Command 2 : 02213F69960000 + cmd[1][0] = 0x02; + cmd[1][1] = 0x21; + cmd[1][2] = 0x3f; + cmd[1][3] = 0x69; + cmd[1][4] = 0x96; + cmd[1][5] = 0x00; + cmd[1][6] = 0x00; + + // Command 3 : 022138u8u7u6u5 (where uX = uid byte X) + cmd[2][0] = 0x02; + cmd[2][1] = 0x21; + cmd[2][2] = 0x38; + cmd[2][3] = uid[7]; + cmd[2][4] = uid[6]; + cmd[2][5] = uid[5]; + cmd[2][6] = uid[4]; + + // Command 4 : 022139u4u3u2u1 (where uX = uid byte X) + cmd[3][0] = 0x02; + cmd[3][1] = 0x21; + cmd[3][2] = 0x39; + cmd[3][3] = uid[3]; + cmd[3][4] = uid[2]; + cmd[3][5] = uid[1]; + cmd[3][6] = uid[0]; + + for (int i=0; i<4; i++) { + // Add the CRC + crc = Crc(cmd[i], 7); + cmd[i][7] = crc & 0xff; + cmd[i][8] = crc >> 8; + + if (DEBUG) { + Dbprintf("SEND:"); + Dbhexdump(sizeof(cmd[i]), cmd[i], false); + } + + recvlen = SendDataTag(cmd[i], sizeof(cmd[i]), true, 1, recvbuf, sizeof(recvbuf), 0); + + if (DEBUG) { + Dbprintf("RECV:"); + Dbhexdump(recvlen, recvbuf, false); + DbdecodeIso15693Answer(recvlen, recvbuf); + } + + cmd_send(CMD_ACK, recvlen>ISO15693_MAX_RESPONSE_LENGTH?ISO15693_MAX_RESPONSE_LENGTH:recvlen, 0, 0, recvbuf, ISO15693_MAX_RESPONSE_LENGTH); + } + + LED_D_OFF(); + + LED_A_OFF(); +} diff --git a/armsrc/iso15693.h b/armsrc/iso15693.h index e5b78a8a..68df2693 100644 --- a/armsrc/iso15693.h +++ b/armsrc/iso15693.h @@ -19,6 +19,7 @@ void ReaderIso15693(uint32_t parameter); void SimTagIso15693(uint32_t parameter, uint8_t *uid); void BruteforceIso15693Afi(uint32_t speed); void DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8_t data[]); +void SetTag15693Uid(uint8_t *uid); void SetDebugIso15693(uint32_t flag); #endif diff --git a/client/cmdhf15.c b/client/cmdhf15.c index 5a7973f6..c2a13354 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -382,6 +382,7 @@ static command_t CommandTable15[] = {"cmd", CmdHF15Cmd, 0, "Send direct commands to ISO15693 tag"}, {"findafi", CmdHF15Afi, 0, "Brute force AFI of an ISO15693 tag"}, {"dumpmemory", CmdHF15DumpMem, 0, "Read all memory pages of an ISO15693 tag"}, + {"csetuid", CmdHF15CSetUID, 0, "Set UID for magic Chinese card"}, {NULL, NULL, 0, NULL} }; @@ -954,6 +955,92 @@ int CmdHF15CmdWrite(const char *Cmd) { return 0; } +int CmdHF15CSetUID(const char *Cmd) +{ + uint8_t uid[8] = {0x00}; + uint8_t oldUid[8], newUid[8] = {0x00}; + + uint8_t needHelp = 0; + char cmdp = 1; + + if (param_getchar(Cmd, 0) && param_gethex(Cmd, 0, uid, 16)) { + PrintAndLog("UID must include 16 HEX symbols"); + return 1; + } + + if (uid[0] != 0xe0) { + PrintAndLog("UID must begin with the byte 'E0'"); + return 1; + } + + while(param_getchar(Cmd, cmdp) != 0x00) + { + switch(param_getchar(Cmd, cmdp)) + { + case 'h': + case 'H': + needHelp = 1; + break; + default: + PrintAndLog("ERROR: Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + needHelp = 1; + break; + } + cmdp++; + } + + if (strlen(Cmd) < 1 || needHelp) { + PrintAndLog(""); + PrintAndLog("Usage: hf 15 csetuid "); + PrintAndLog("sample: hf 15 csetuid E004013344556677"); + PrintAndLog("Set UID for magic Chinese card (only works with such cards)"); + return 0; + } + + PrintAndLog(""); + PrintAndLog("new UID | %s", sprint_hex(uid, 8)); + PrintAndLog("Using backdoor Magic tag function"); + + if (!getUID(oldUid)) { + PrintAndLog("Can't get old UID."); + return 1; + } + + UsbCommand resp; + uint8_t *recv; + char *hexout; + UsbCommand c = {CMD_CSETUID_ISO_15693, {0, 0, 0}}; + memcpy(c.d.asBytes, uid, 8); + + SendCommand(&c); + + for (int i=0; i<4; i++) { + if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) { + recv = resp.d.asBytes; + PrintAndLog("received %i octets",resp.arg[0]); + hexout = (char *)malloc(resp.arg[0] * 3 + 1); + if (hexout != NULL) { + for (int i = 0; i < resp.arg[0]; i++) { // data in hex + sprintf(&hexout[i * 3], "%02X ", recv[i]); + } + PrintAndLog("%s", hexout); + free(hexout); + } + } else { + PrintAndLog("timeout while waiting for reply."); + } + } + + if (!getUID(newUid)) { + PrintAndLog("Can't get new UID."); + return 1; + } + + PrintAndLog(""); + PrintAndLog("old UID : %02X %02X %02X %02X %02X %02X %02X %02X", oldUid[7], oldUid[6], oldUid[5], oldUid[4], oldUid[3], oldUid[2], oldUid[1], oldUid[0]); + PrintAndLog("new UID : %02X %02X %02X %02X %02X %02X %02X %02X", newUid[7], newUid[6], newUid[5], newUid[4], newUid[3], newUid[2], newUid[1], newUid[0]); + return 0; +} static command_t CommandTable15Cmd[] = @@ -967,7 +1054,8 @@ static command_t CommandTable15Cmd[] = {"write", CmdHF15CmdWrite, 0, "Write a block"}, {"readmulti",CmdHF15CmdReadmulti, 0, "Reads multiple Blocks"}, {"sysinfo",CmdHF15CmdSysinfo, 0, "Get Card Information"}, - {"raw", CmdHF15CmdRaw, 0, "Send raw hex data to tag"}, + {"raw", CmdHF15CmdRaw, 0, "Send raw hex data to tag"}, + {"csetuid", CmdHF15CSetUID, 0, "Set UID for magic Chinese card"}, {"debug", CmdHF15CmdDebug, 0, "Turn debugging on/off"}, {NULL, NULL, 0, NULL} }; diff --git a/client/cmdhf15.h b/client/cmdhf15.h index d0517fe5..ddaa4f71 100644 --- a/client/cmdhf15.h +++ b/client/cmdhf15.h @@ -22,6 +22,7 @@ int CmdHF15Reader(const char *Cmd); int CmdHF15Sim(const char *Cmd); int CmdHF15Record(const char *Cmd); int CmdHF15Cmd(const char*Cmd); +int CmdHF15CSetUID(const char *Cmd); int CmdHF15CmdHelp(const char*Cmd); int CmdHF15Help(const char*Cmd); diff --git a/include/usb_cmd.h b/include/usb_cmd.h index 82981acf..c998bf94 100644 --- a/include/usb_cmd.h +++ b/include/usb_cmd.h @@ -132,6 +132,7 @@ typedef struct{ #define CMD_ISO_15693_FIND_AFI 0x0315 #define CMD_ISO_15693_DEBUG 0x0316 #define CMD_LF_SNOOP_RAW_ADC_SAMPLES 0x0317 +#define CMD_CSETUID_ISO_15693 0x0318 // For Hitag2 transponders #define CMD_SNOOP_HITAG 0x0370 -- 2.39.5