mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-08-20 13:23:25 -07:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
8db0534ed1
28 changed files with 1587 additions and 1428 deletions
|
@ -157,9 +157,28 @@ NXP/Philips CUSTOM COMMANDS
|
|||
#define MIFARE_ULC_AUTH_1 0x1A
|
||||
#define MIFARE_ULC_AUTH_2 0xAF
|
||||
|
||||
/**
|
||||
06 00 = INITIATE
|
||||
0E xx = SELECT ID (xx = Chip-ID)
|
||||
0B = Get UID
|
||||
08 yy = Read Block (yy = block number)
|
||||
09 yy dd dd dd dd = Write Block (yy = block number; dd dd dd dd = data to be written)
|
||||
0C = Reset to Inventory
|
||||
0F = Completion
|
||||
0A 11 22 33 44 55 66 = Authenticate (11 22 33 44 55 66 = data to authenticate)
|
||||
**/
|
||||
|
||||
#define ISO14443B_REQB 0x05
|
||||
#define ISO14443B_ATTRIB 0x1D
|
||||
#define ISO14443B_HALT 0x50
|
||||
#define ISO14443B_INITIATE 0x06
|
||||
#define ISO14443B_SELECT 0x0E
|
||||
#define ISO14443B_GET_UID 0x0B
|
||||
#define ISO14443B_READ_BLK 0x08
|
||||
#define ISO14443B_WRITE_BLK 0x09
|
||||
#define ISO14443B_RESET 0x0C
|
||||
#define ISO14443B_COMPLETION 0x0F
|
||||
#define ISO14443B_AUTHENTICATE 0x0A
|
||||
|
||||
//First byte is 26
|
||||
#define ISO15693_INVENTORY 0x01
|
||||
|
@ -287,13 +306,33 @@ void annotateIso15693(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
06 00 = INITIATE
|
||||
0E xx = SELECT ID (xx = Chip-ID)
|
||||
0B = Get UID
|
||||
08 yy = Read Block (yy = block number)
|
||||
09 yy dd dd dd dd = Write Block (yy = block number; dd dd dd dd = data to be written)
|
||||
0C = Reset to Inventory
|
||||
0F = Completion
|
||||
0A 11 22 33 44 55 66 = Authenticate (11 22 33 44 55 66 = data to authenticate)
|
||||
**/
|
||||
|
||||
void annotateIso14443b(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
|
||||
{
|
||||
switch(cmd[0]){
|
||||
case ISO14443B_REQB : snprintf(exp,size,"REQB");break;
|
||||
case ISO14443B_ATTRIB : snprintf(exp,size,"ATTRIB");break;
|
||||
case ISO14443B_HALT : snprintf(exp,size,"HALT");break;
|
||||
default: snprintf(exp,size ,"?");break;
|
||||
case ISO14443B_INITIATE : snprintf(exp,size,"INITIATE");break;
|
||||
case ISO14443B_SELECT : snprintf(exp,size,"SELECT(%d)",cmd[1]);break;
|
||||
case ISO14443B_GET_UID : snprintf(exp,size,"GET UID");break;
|
||||
case ISO14443B_READ_BLK : snprintf(exp,size,"READ_BLK(%d)", cmd[1]);break;
|
||||
case ISO14443B_WRITE_BLK : snprintf(exp,size,"WRITE_BLK(%d)",cmd[1]);break;
|
||||
case ISO14443B_RESET : snprintf(exp,size,"RESET");break;
|
||||
case ISO14443B_COMPLETION : snprintf(exp,size,"COMPLETION");break;
|
||||
case ISO14443B_AUTHENTICATE : snprintf(exp,size,"AUTHENTICATE");break;
|
||||
default : snprintf(exp,size ,"?");break;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -412,15 +451,18 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
|
|||
if (tracepos + data_len + parity_len > traceLen) {
|
||||
return traceLen;
|
||||
}
|
||||
|
||||
uint8_t *frame = trace + tracepos;
|
||||
tracepos += data_len;
|
||||
uint8_t *parityBytes = trace + tracepos;
|
||||
tracepos += parity_len;
|
||||
|
||||
|
||||
//--- Draw the data column
|
||||
//char line[16][110];
|
||||
char line[16][110];
|
||||
for (int j = 0; j < data_len; j++) {
|
||||
|
||||
for (int j = 0; j < data_len && j/16 < 16; j++) {
|
||||
|
||||
int oddparity = 0x01;
|
||||
int k;
|
||||
|
||||
|
@ -429,11 +471,17 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
|
|||
}
|
||||
|
||||
uint8_t parityBits = parityBytes[j>>3];
|
||||
|
||||
if (isResponse && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
|
||||
sprintf(line[j/16]+((j%16)*4), "%02x! ", frame[j]);
|
||||
snprintf(line[j/16]+(( j % 16) * 4),110, "%02x! ", frame[j]);
|
||||
|
||||
} else {
|
||||
sprintf(line[j/16]+((j%16)*4), "%02x ", frame[j]);
|
||||
snprintf(line[j/16]+(( j % 16) * 4),110, "%02x ", frame[j]);
|
||||
}
|
||||
}
|
||||
if(data_len == 0)
|
||||
{
|
||||
if(data_len == 0){
|
||||
sprintf(line[0],"<empty trace - possible error>");
|
||||
}
|
||||
}
|
||||
//--- Draw the CRC column
|
||||
|
@ -478,8 +526,8 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
|
|||
annotateIso14443b(explanation,sizeof(explanation),frame,data_len);
|
||||
}
|
||||
|
||||
int num_lines = (data_len - 1)/16 + 1;
|
||||
for (int j = 0; j < num_lines; j++) {
|
||||
int num_lines = MIN((data_len - 1)/16 + 1, 16);
|
||||
for (int j = 0; j < num_lines ; j++) {
|
||||
if (j == 0) {
|
||||
PrintAndLog(" %9d | %9d | %s | %-64s| %s| %s",
|
||||
(timestamp - first_timestamp),
|
||||
|
|
|
@ -129,11 +129,6 @@ int CmdHF14AList(const char *Cmd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void iso14a_set_timeout(uint32_t timeout) {
|
||||
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_SET_TIMEOUT, 0, timeout}};
|
||||
SendCommand(&c);
|
||||
}
|
||||
|
||||
int CmdHF14AReader(const char *Cmd)
|
||||
{
|
||||
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}};
|
||||
|
@ -346,7 +341,7 @@ int CmdHF14AReader(const char *Cmd)
|
|||
SendCommand(&c);
|
||||
WaitForResponse(CMD_ACK,&resp);
|
||||
uint8_t isOK = resp.arg[0] & 0xff;
|
||||
PrintAndLog(" Answers to chinese magic backdoor commands: %s", (isOK ? "YES" : "NO") );
|
||||
PrintAndLog("Answers to chinese magic backdoor commands: %s", (isOK ? "YES" : "NO") );
|
||||
|
||||
// disconnect
|
||||
c.cmd = CMD_READER_ISO_14443a;
|
||||
|
@ -510,12 +505,13 @@ int CmdHF14ACmdRaw(const char *cmd) {
|
|||
uint8_t active=0;
|
||||
uint8_t active_select=0;
|
||||
uint16_t numbits=0;
|
||||
uint16_t timeout=0;
|
||||
uint32_t timeout=0;
|
||||
uint8_t bTimeout=0;
|
||||
char buf[5]="";
|
||||
int i=0;
|
||||
uint8_t data[USB_CMD_DATA_SIZE];
|
||||
unsigned int datalen=0, temp;
|
||||
uint16_t datalen=0;
|
||||
uint32_t temp;
|
||||
|
||||
if (strlen(cmd)<2) {
|
||||
PrintAndLog("Usage: hf 14a raw [-r] [-c] [-p] [-f] [-b] [-t] <number of bits> <0A 0B 0C ... hex>");
|
||||
|
@ -525,7 +521,7 @@ int CmdHF14ACmdRaw(const char *cmd) {
|
|||
PrintAndLog(" -a active signal field ON without select");
|
||||
PrintAndLog(" -s active signal field ON with select");
|
||||
PrintAndLog(" -b number of bits to send. Useful for send partial byte");
|
||||
PrintAndLog(" -t timeout");
|
||||
PrintAndLog(" -t timeout in ms");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -561,7 +557,7 @@ int CmdHF14ACmdRaw(const char *cmd) {
|
|||
case 't':
|
||||
bTimeout=1;
|
||||
sscanf(cmd+i+2,"%d",&temp);
|
||||
timeout = temp & 0xFFFF;
|
||||
timeout = temp;
|
||||
i+=3;
|
||||
while(cmd[i]!=' ' && cmd[i]!='\0') { i++; }
|
||||
i+=2;
|
||||
|
@ -610,13 +606,13 @@ int CmdHF14ACmdRaw(const char *cmd) {
|
|||
c.arg[0] |= ISO14A_NO_SELECT;
|
||||
}
|
||||
if(bTimeout){
|
||||
#define MAX_TIMEOUT 624*105 // max timeout is 624 ms
|
||||
#define MAX_TIMEOUT 40542464 // (2^32-1) * (8*16) / 13560000Hz * 1000ms/s =
|
||||
c.arg[0] |= ISO14A_SET_TIMEOUT;
|
||||
c.arg[2] = timeout * 105; // each bit is about 9.4 us
|
||||
if(c.arg[2]>MAX_TIMEOUT) {
|
||||
c.arg[2] = MAX_TIMEOUT;
|
||||
PrintAndLog("Set timeout to 624 ms. The max we can wait for response");
|
||||
if(timeout > MAX_TIMEOUT) {
|
||||
timeout = MAX_TIMEOUT;
|
||||
PrintAndLog("Set timeout to 40542 seconds (11.26 hours). The max we can wait for response");
|
||||
}
|
||||
c.arg[2] = 13560000 / 1000 / (8*16) * timeout; // timeout in ETUs (time to transfer 1 bit, approx. 9.4 us)
|
||||
}
|
||||
if(power)
|
||||
c.arg[0] |= ISO14A_NO_DISCONNECT;
|
||||
|
|
|
@ -145,97 +145,10 @@ demodError:
|
|||
|
||||
int CmdHF14BList(const char *Cmd)
|
||||
{
|
||||
uint8_t *got = malloc(USB_CMD_DATA_SIZE);
|
||||
PrintAndLog("Deprecated command, use 'hf list 14b' instead");
|
||||
|
||||
// Query for the actual size of the trace
|
||||
UsbCommand response;
|
||||
GetFromBigBuf(got, USB_CMD_DATA_SIZE, 0);
|
||||
WaitForResponse(CMD_ACK, &response);
|
||||
uint16_t traceLen = response.arg[2];
|
||||
if (traceLen > USB_CMD_DATA_SIZE) {
|
||||
uint8_t *p = realloc(got, traceLen);
|
||||
if (p == NULL) {
|
||||
PrintAndLog("Cannot allocate memory for trace");
|
||||
free(got);
|
||||
return 2;
|
||||
}
|
||||
got = p;
|
||||
GetFromBigBuf(got, traceLen, 0);
|
||||
WaitForResponse(CMD_ACK,NULL);
|
||||
}
|
||||
PrintAndLog("recorded activity: (TraceLen = %d bytes)", traceLen);
|
||||
PrintAndLog(" time :rssi: who bytes");
|
||||
PrintAndLog("---------+----+----+-----------");
|
||||
|
||||
int i = 0;
|
||||
int prev = -1;
|
||||
|
||||
for(;;) {
|
||||
|
||||
if(i >= traceLen) { break; }
|
||||
|
||||
bool isResponse;
|
||||
int timestamp = *((uint32_t *)(got+i));
|
||||
if(timestamp & 0x80000000) {
|
||||
timestamp &= 0x7fffffff;
|
||||
isResponse = 1;
|
||||
} else {
|
||||
isResponse = 0;
|
||||
}
|
||||
int metric = *((uint32_t *)(got+i+4));
|
||||
|
||||
int len = got[i+8];
|
||||
|
||||
if(len > 100) {
|
||||
break;
|
||||
}
|
||||
if(i + len >= traceLen) {
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t *frame = (got+i+9);
|
||||
|
||||
// Break and stick with current result if buffer was not completely full
|
||||
if (frame[0] == 0x44 && frame[1] == 0x44 && frame[2] == 0x44 && frame[3] == 0x44) break;
|
||||
|
||||
char line[1000] = "";
|
||||
int j;
|
||||
for(j = 0; j < len; j++) {
|
||||
sprintf(line+(j*3), "%02x ", frame[j]);
|
||||
}
|
||||
|
||||
char *crc;
|
||||
if(len > 2) {
|
||||
uint8_t b1, b2;
|
||||
ComputeCrc14443(CRC_14443_B, frame, len-2, &b1, &b2);
|
||||
if(b1 != frame[len-2] || b2 != frame[len-1]) {
|
||||
crc = "**FAIL CRC**";
|
||||
} else {
|
||||
crc = "";
|
||||
}
|
||||
} else {
|
||||
crc = "(SHORT)";
|
||||
}
|
||||
|
||||
char metricString[100];
|
||||
if(isResponse) {
|
||||
sprintf(metricString, "%3d", metric);
|
||||
} else {
|
||||
strcpy(metricString, " ");
|
||||
}
|
||||
|
||||
PrintAndLog(" +%7d: %s: %s %s %s",
|
||||
(prev < 0 ? 0 : timestamp - prev),
|
||||
metricString,
|
||||
(isResponse ? "TAG" : " "), line, crc);
|
||||
|
||||
prev = timestamp;
|
||||
i += (len + 9);
|
||||
}
|
||||
free(got);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHF14BRead(const char *Cmd)
|
||||
{
|
||||
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443, {strtol(Cmd, NULL, 0), 0, 0}};
|
||||
|
@ -473,7 +386,7 @@ static command_t CommandTable[] =
|
|||
{
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
{"demod", CmdHF14BDemod, 1, "Demodulate ISO14443 Type B from tag"},
|
||||
{"list", CmdHF14BList, 0, "List ISO 14443 history"},
|
||||
{"list", CmdHF14BList, 0, "[Deprecated] List ISO 14443b history"},
|
||||
{"read", CmdHF14BRead, 0, "Read HF tag (ISO 14443)"},
|
||||
{"sim", CmdHF14Sim, 0, "Fake ISO 14443 tag"},
|
||||
{"simlisten", CmdHFSimlisten, 0, "Get HF samples as fake tag"},
|
||||
|
|
|
@ -136,6 +136,7 @@ const productName uidmapping[] = {
|
|||
{ 0xE016040000000000LL, 24, "EM-Marin SA (Skidata Keycard-eco); EM4034? no 'read', just 'readmulti'" },
|
||||
{ 0xE0160c0000000000LL, 24, "EM-Marin SA; EM4035?" },
|
||||
{ 0xE016100000000000LL, 24, "EM-Marin SA (Skidata); EM4135; 36x64bit start page 13" },
|
||||
{ 0xE016240000000000LL, 24, "EM-Marin SA (Skidata); EM4233;" },
|
||||
{ 0xE016940000000000LL, 24, "EM-Marin SA (Skidata); 51x64bit" },
|
||||
|
||||
{ 0xE017000000000000LL, 16, "KSW Microtec GmbH Germany" },
|
||||
|
|
|
@ -34,11 +34,11 @@ static int CmdHelp(const char *Cmd);
|
|||
|
||||
int xorbits_8(uint8_t val)
|
||||
{
|
||||
uint8_t res = val ^ (val >> 1); //1st pass
|
||||
res = res ^ (res >> 1); // 2nd pass
|
||||
res = res ^ (res >> 2); // 3rd pass
|
||||
res = res ^ (res >> 4); // 4th pass
|
||||
return res & 1;
|
||||
uint8_t res = val ^ (val >> 1); //1st pass
|
||||
res = res ^ (res >> 1); // 2nd pass
|
||||
res = res ^ (res >> 2); // 3rd pass
|
||||
res = res ^ (res >> 4); // 4th pass
|
||||
return res & 1;
|
||||
}
|
||||
|
||||
int CmdHFiClassList(const char *Cmd)
|
||||
|
@ -49,44 +49,44 @@ int CmdHFiClassList(const char *Cmd)
|
|||
|
||||
int CmdHFiClassSnoop(const char *Cmd)
|
||||
{
|
||||
UsbCommand c = {CMD_SNOOP_ICLASS};
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
UsbCommand c = {CMD_SNOOP_ICLASS};
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
#define NUM_CSNS 15
|
||||
int CmdHFiClassSim(const char *Cmd)
|
||||
{
|
||||
uint8_t simType = 0;
|
||||
uint8_t CSN[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
uint8_t simType = 0;
|
||||
uint8_t CSN[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
if (strlen(Cmd)<1) {
|
||||
PrintAndLog("Usage: hf iclass sim [0 <CSN>] | x");
|
||||
PrintAndLog(" options");
|
||||
PrintAndLog(" 0 <CSN> simulate the given CSN");
|
||||
PrintAndLog(" 1 simulate default CSN");
|
||||
PrintAndLog(" 2 iterate CSNs, gather MACs");
|
||||
PrintAndLog(" sample: hf iclass sim 0 031FEC8AF7FF12E0");
|
||||
PrintAndLog(" sample: hf iclass sim 2");
|
||||
return 0;
|
||||
}
|
||||
if (strlen(Cmd)<1) {
|
||||
PrintAndLog("Usage: hf iclass sim [0 <CSN>] | x");
|
||||
PrintAndLog(" options");
|
||||
PrintAndLog(" 0 <CSN> simulate the given CSN");
|
||||
PrintAndLog(" 1 simulate default CSN");
|
||||
PrintAndLog(" 2 iterate CSNs, gather MACs");
|
||||
PrintAndLog(" sample: hf iclass sim 0 031FEC8AF7FF12E0");
|
||||
PrintAndLog(" sample: hf iclass sim 2");
|
||||
return 0;
|
||||
}
|
||||
|
||||
simType = param_get8(Cmd, 0);
|
||||
simType = param_get8(Cmd, 0);
|
||||
|
||||
if(simType == 0)
|
||||
{
|
||||
if (param_gethex(Cmd, 1, CSN, 16)) {
|
||||
PrintAndLog("A CSN should consist of 16 HEX symbols");
|
||||
return 1;
|
||||
}
|
||||
PrintAndLog("--simtype:%02x csn:%s", simType, sprint_hex(CSN, 8));
|
||||
if(simType == 0)
|
||||
{
|
||||
if (param_gethex(Cmd, 1, CSN, 16)) {
|
||||
PrintAndLog("A CSN should consist of 16 HEX symbols");
|
||||
return 1;
|
||||
}
|
||||
PrintAndLog("--simtype:%02x csn:%s", simType, sprint_hex(CSN, 8));
|
||||
|
||||
}
|
||||
if(simType > 2)
|
||||
{
|
||||
PrintAndLog("Undefined simptype %d", simType);
|
||||
return 1;
|
||||
}
|
||||
uint8_t numberOfCSNs=0;
|
||||
}
|
||||
if(simType > 2)
|
||||
{
|
||||
PrintAndLog("Undefined simptype %d", simType);
|
||||
return 1;
|
||||
}
|
||||
uint8_t numberOfCSNs=0;
|
||||
|
||||
if(simType == 2)
|
||||
{
|
||||
|
@ -103,23 +103,23 @@ int CmdHFiClassSim(const char *Cmd)
|
|||
0x00,0x73,0xd8,0x75,0x58,0xff,0x12,0xe0 ,
|
||||
0x0c,0x90,0x32,0xf3,0x5d,0xff,0x12,0xe0 };
|
||||
*/
|
||||
|
||||
uint8_t csns[8*NUM_CSNS] = {
|
||||
0x00, 0x0B, 0x0F, 0xFF, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
0x00, 0x04, 0x0E, 0x08, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
0x00, 0x09, 0x0D, 0x05, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
0x00, 0x0A, 0x0C, 0x06, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
0x00, 0x0F, 0x0B, 0x03, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
0x00, 0x08, 0x0A, 0x0C, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
0x00, 0x0D, 0x09, 0x09, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
0x00, 0x0E, 0x08, 0x0A, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
0x00, 0x03, 0x07, 0x17, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
0x00, 0x3C, 0x06, 0xE0, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
0x00, 0x01, 0x05, 0x1D, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
0x00, 0x02, 0x04, 0x1E, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
0x00, 0x07, 0x03, 0x1B, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
0x00, 0x00, 0x02, 0x24, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
0x00, 0x05, 0x01, 0x21, 0xF7, 0xFF, 0x12, 0xE0 };
|
||||
|
||||
uint8_t csns[8*NUM_CSNS] = {
|
||||
0x00, 0x0B, 0x0F, 0xFF, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
0x00, 0x04, 0x0E, 0x08, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
0x00, 0x09, 0x0D, 0x05, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
0x00, 0x0A, 0x0C, 0x06, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
0x00, 0x0F, 0x0B, 0x03, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
0x00, 0x08, 0x0A, 0x0C, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
0x00, 0x0D, 0x09, 0x09, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
0x00, 0x0E, 0x08, 0x0A, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
0x00, 0x03, 0x07, 0x17, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
0x00, 0x3C, 0x06, 0xE0, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
0x00, 0x01, 0x05, 0x1D, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
0x00, 0x02, 0x04, 0x1E, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
0x00, 0x07, 0x03, 0x1B, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
0x00, 0x00, 0x02, 0x24, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
0x00, 0x05, 0x01, 0x21, 0xF7, 0xFF, 0x12, 0xE0 };
|
||||
|
||||
memcpy(c.d.asBytes, csns, 8*NUM_CSNS);
|
||||
|
||||
|
@ -164,124 +164,124 @@ int CmdHFiClassSim(const char *Cmd)
|
|||
SendCommand(&c);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHFiClassReader(const char *Cmd)
|
||||
{
|
||||
UsbCommand c = {CMD_READER_ICLASS, {0}};
|
||||
SendCommand(&c);
|
||||
UsbCommand resp;
|
||||
while(!ukbhit()){
|
||||
if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) {
|
||||
uint8_t isOK = resp.arg[0] & 0xff;
|
||||
uint8_t * data = resp.d.asBytes;
|
||||
UsbCommand c = {CMD_READER_ICLASS, {0}};
|
||||
SendCommand(&c);
|
||||
UsbCommand resp;
|
||||
while(!ukbhit()){
|
||||
if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) {
|
||||
uint8_t isOK = resp.arg[0] & 0xff;
|
||||
uint8_t * data = resp.d.asBytes;
|
||||
|
||||
PrintAndLog("isOk:%02x", isOK);
|
||||
if( isOK == 0){
|
||||
//Aborted
|
||||
PrintAndLog("Quitting...");
|
||||
return 0;
|
||||
}
|
||||
if(isOK > 0)
|
||||
{
|
||||
PrintAndLog("CSN: %s",sprint_hex(data,8));
|
||||
}
|
||||
if(isOK >= 1)
|
||||
{
|
||||
PrintAndLog("CC: %s",sprint_hex(data+8,8));
|
||||
}else{
|
||||
PrintAndLog("No CC obtained");
|
||||
}
|
||||
} else {
|
||||
PrintAndLog("Command execute timeout");
|
||||
}
|
||||
}
|
||||
PrintAndLog("isOk:%02x", isOK);
|
||||
if( isOK == 0){
|
||||
//Aborted
|
||||
PrintAndLog("Quitting...");
|
||||
return 0;
|
||||
}
|
||||
if(isOK > 0)
|
||||
{
|
||||
PrintAndLog("CSN: %s",sprint_hex(data,8));
|
||||
}
|
||||
if(isOK >= 1)
|
||||
{
|
||||
PrintAndLog("CC: %s",sprint_hex(data+8,8));
|
||||
}else{
|
||||
PrintAndLog("No CC obtained");
|
||||
}
|
||||
} else {
|
||||
PrintAndLog("Command execute timeout");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHFiClassReader_Replay(const char *Cmd)
|
||||
{
|
||||
uint8_t readerType = 0;
|
||||
uint8_t MAC[4]={0x00, 0x00, 0x00, 0x00};
|
||||
uint8_t readerType = 0;
|
||||
uint8_t MAC[4]={0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
if (strlen(Cmd)<1) {
|
||||
PrintAndLog("Usage: hf iclass replay <MAC>");
|
||||
PrintAndLog(" sample: hf iclass replay 00112233");
|
||||
return 0;
|
||||
}
|
||||
if (strlen(Cmd)<1) {
|
||||
PrintAndLog("Usage: hf iclass replay <MAC>");
|
||||
PrintAndLog(" sample: hf iclass replay 00112233");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (param_gethex(Cmd, 0, MAC, 8)) {
|
||||
PrintAndLog("MAC must include 8 HEX symbols");
|
||||
return 1;
|
||||
}
|
||||
if (param_gethex(Cmd, 0, MAC, 8)) {
|
||||
PrintAndLog("MAC must include 8 HEX symbols");
|
||||
return 1;
|
||||
}
|
||||
|
||||
UsbCommand c = {CMD_READER_ICLASS_REPLAY, {readerType}};
|
||||
memcpy(c.d.asBytes, MAC, 4);
|
||||
SendCommand(&c);
|
||||
UsbCommand c = {CMD_READER_ICLASS_REPLAY, {readerType}};
|
||||
memcpy(c.d.asBytes, MAC, 4);
|
||||
SendCommand(&c);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHFiClassReader_Dump(const char *Cmd)
|
||||
{
|
||||
uint8_t readerType = 0;
|
||||
uint8_t MAC[4]={0x00,0x00,0x00,0x00};
|
||||
uint8_t KEY[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
//uint8_t CC_temp[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
uint8_t keytable[128] = {0};
|
||||
int elite = 0;
|
||||
uint8_t *used_key;
|
||||
int i;
|
||||
if (strlen(Cmd)<1)
|
||||
{
|
||||
PrintAndLog("Usage: hf iclass dump <Key> [e]");
|
||||
PrintAndLog(" Key - A 16 byte master key");
|
||||
PrintAndLog(" e - If 'e' is specified, the key is interpreted as the 16 byte");
|
||||
PrintAndLog(" Custom Key (KCus), which can be obtained via reader-attack");
|
||||
PrintAndLog(" See 'hf iclass sim 2'. This key should be on iclass-format");
|
||||
PrintAndLog(" sample: hf iclass dump 0011223344556677");
|
||||
uint8_t readerType = 0;
|
||||
uint8_t MAC[4]={0x00,0x00,0x00,0x00};
|
||||
uint8_t KEY[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
//uint8_t CC_temp[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
uint8_t keytable[128] = {0};
|
||||
int elite = 0;
|
||||
uint8_t *used_key;
|
||||
int i;
|
||||
if (strlen(Cmd)<1)
|
||||
{
|
||||
PrintAndLog("Usage: hf iclass dump <Key> [e]");
|
||||
PrintAndLog(" Key - A 16 byte master key");
|
||||
PrintAndLog(" e - If 'e' is specified, the key is interpreted as the 16 byte");
|
||||
PrintAndLog(" Custom Key (KCus), which can be obtained via reader-attack");
|
||||
PrintAndLog(" See 'hf iclass sim 2'. This key should be on iclass-format");
|
||||
PrintAndLog(" sample: hf iclass dump 0011223344556677");
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (param_gethex(Cmd, 0, KEY, 16))
|
||||
{
|
||||
PrintAndLog("KEY must include 16 HEX symbols");
|
||||
return 1;
|
||||
}
|
||||
if (param_gethex(Cmd, 0, KEY, 16))
|
||||
{
|
||||
PrintAndLog("KEY must include 16 HEX symbols");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (param_getchar(Cmd, 1) == 'e')
|
||||
{
|
||||
PrintAndLog("Elite switch on");
|
||||
elite = 1;
|
||||
if (param_getchar(Cmd, 1) == 'e')
|
||||
{
|
||||
PrintAndLog("Elite switch on");
|
||||
elite = 1;
|
||||
|
||||
//calc h2
|
||||
hash2(KEY, keytable);
|
||||
printarr_human_readable("keytable", keytable, 128);
|
||||
//calc h2
|
||||
hash2(KEY, keytable);
|
||||
printarr_human_readable("keytable", keytable, 128);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
UsbCommand resp;
|
||||
uint8_t key_sel[8] = {0};
|
||||
uint8_t key_sel_p[8] = { 0 };
|
||||
UsbCommand resp;
|
||||
uint8_t key_sel[8] = {0};
|
||||
uint8_t key_sel_p[8] = { 0 };
|
||||
|
||||
UsbCommand c = {CMD_READER_ICLASS, {0}};
|
||||
c.arg[0] = FLAG_ICLASS_READER_ONLY_ONCE| FLAG_ICLASS_READER_GET_CC;
|
||||
SendCommand(&c);
|
||||
|
||||
UsbCommand c = {CMD_READER_ICLASS, {0}};
|
||||
c.arg[0] = FLAG_ICLASS_READER_ONLY_ONCE| FLAG_ICLASS_READER_GET_CC;
|
||||
SendCommand(&c);
|
||||
|
||||
|
||||
if (!WaitForResponseTimeout(CMD_ACK,&resp,4500))
|
||||
{
|
||||
PrintAndLog("Command execute timeout");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!WaitForResponseTimeout(CMD_ACK,&resp,4500))
|
||||
{
|
||||
PrintAndLog("Command execute timeout");
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t isOK = resp.arg[0] & 0xff;
|
||||
uint8_t * data = resp.d.asBytes;
|
||||
|
@ -329,8 +329,8 @@ int CmdHFiClassReader_Dump(const char *Cmd)
|
|||
printvar("MAC", MAC, 4);
|
||||
|
||||
uint8_t iclass_data[32000] = {0};
|
||||
uint8_t iclass_datalen = 0;
|
||||
uint8_t iclass_blocksFailed = 0;//Set to 1 if dump was incomplete
|
||||
uint32_t iclass_datalen = 0;
|
||||
uint32_t iclass_blocksFailed = 0;//Set to 1 if dump was incomplete
|
||||
|
||||
UsbCommand d = {CMD_READER_ICLASS_REPLAY, {readerType}};
|
||||
memcpy(d.d.asBytes, MAC, 4);
|
||||
|
@ -346,11 +346,11 @@ int CmdHFiClassReader_Dump(const char *Cmd)
|
|||
}
|
||||
if(WaitForResponseTimeout(CMD_ACK,&resp,4500))
|
||||
{
|
||||
uint64_t dataLength = resp.arg[0];
|
||||
uint32_t dataLength = resp.arg[0];
|
||||
iclass_blocksFailed |= resp.arg[1];
|
||||
|
||||
if(dataLength > 0)
|
||||
{
|
||||
PrintAndLog("Got %d bytes data (total so far %d)" ,dataLength,iclass_datalen);
|
||||
memcpy(iclass_data, resp.d.asBytes,dataLength);
|
||||
iclass_datalen += dataLength;
|
||||
}else
|
||||
|
@ -366,9 +366,8 @@ int CmdHFiClassReader_Dump(const char *Cmd)
|
|||
//create a preferred filename
|
||||
snprintf(filename, 100,"iclass_tagdump-%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||
CSN[0],CSN[1],CSN[2],CSN[3],
|
||||
CSN[4],CSN[5],CSN[6],CSN[7]);
|
||||
CSN[4],CSN[5],CSN[6],CSN[7]);
|
||||
saveFile(filename,"bin",iclass_data, iclass_datalen );
|
||||
|
||||
}
|
||||
//Aaaand we're finished
|
||||
return 0;
|
||||
|
@ -377,85 +376,157 @@ int CmdHFiClassReader_Dump(const char *Cmd)
|
|||
}
|
||||
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hf_iclass_eload_usage()
|
||||
{
|
||||
PrintAndLog("Loads iclass tag-dump into emulator memory on device");
|
||||
PrintAndLog("Usage: hf iclass eload f <filename>");
|
||||
PrintAndLog("");
|
||||
PrintAndLog("Example: hf iclass eload f iclass_tagdump-aa162d30f8ff12f1.bin");
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int iclassEmlSetMem(uint8_t *data, int blockNum, int blocksCount) {
|
||||
UsbCommand c = {CMD_MIFARE_EML_MEMSET, {blockNum, blocksCount, 0}};
|
||||
memcpy(c.d.asBytes, data, blocksCount * 16);
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
int CmdHFiClassELoad(const char *Cmd)
|
||||
{
|
||||
|
||||
char opt = param_getchar(Cmd, 0);
|
||||
if (strlen(Cmd)<1 || opt == 'h')
|
||||
return hf_iclass_eload_usage();
|
||||
|
||||
//File handling and reading
|
||||
FILE *f;
|
||||
char filename[FILE_PATH_SIZE];
|
||||
if(opt == 'f' && param_getstr(Cmd, 1, filename) > 0)
|
||||
{
|
||||
f = fopen(filename, "rb");
|
||||
}else{
|
||||
return hf_iclass_eload_usage();
|
||||
}
|
||||
|
||||
if(!f) {
|
||||
PrintAndLog("Failed to read from file '%s'", filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
long fsize = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
uint8_t *dump = malloc(fsize);
|
||||
size_t bytes_read = fread(dump, 1, fsize, f);
|
||||
fclose(f);
|
||||
|
||||
//Validate
|
||||
|
||||
if (bytes_read < fsize)
|
||||
{
|
||||
prnlog("Error, could only read %d bytes (should be %d)",bytes_read, fsize );
|
||||
free(dump);
|
||||
return 1;
|
||||
}
|
||||
//Send to device
|
||||
uint32_t bytes_sent = 0;
|
||||
uint32_t bytes_remaining = bytes_read;
|
||||
|
||||
while(bytes_remaining > 0){
|
||||
uint32_t bytes_in_packet = MIN(USB_CMD_DATA_SIZE, bytes_remaining);
|
||||
UsbCommand c = {CMD_ICLASS_EML_MEMSET, {bytes_sent,bytes_in_packet,0}};
|
||||
memcpy(c.d.asBytes, dump, bytes_in_packet);
|
||||
SendCommand(&c);
|
||||
bytes_remaining -= bytes_in_packet;
|
||||
bytes_sent += bytes_in_packet;
|
||||
}
|
||||
free(dump);
|
||||
PrintAndLog("Sent %d bytes of data to device emulator memory", bytes_sent);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int CmdHFiClass_iso14443A_write(const char *Cmd)
|
||||
{
|
||||
uint8_t readerType = 0;
|
||||
uint8_t MAC[4]={0x00,0x00,0x00,0x00};
|
||||
uint8_t KEY[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
uint8_t readerType = 0;
|
||||
uint8_t MAC[4]={0x00,0x00,0x00,0x00};
|
||||
uint8_t KEY[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
|
||||
uint8_t blockNo=0;
|
||||
uint8_t bldata[8]={0};
|
||||
uint8_t blockNo=0;
|
||||
uint8_t bldata[8]={0};
|
||||
|
||||
if (strlen(Cmd)<3)
|
||||
{
|
||||
PrintAndLog("Usage: hf iclass write <Key> <Block> <Data>");
|
||||
PrintAndLog(" sample: hf iclass write 0011223344556677 10 AAAAAAAAAAAAAAAA");
|
||||
return 0;
|
||||
}
|
||||
if (strlen(Cmd)<3)
|
||||
{
|
||||
PrintAndLog("Usage: hf iclass write <Key> <Block> <Data>");
|
||||
PrintAndLog(" sample: hf iclass write 0011223344556677 10 AAAAAAAAAAAAAAAA");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (param_gethex(Cmd, 0, KEY, 16))
|
||||
{
|
||||
PrintAndLog("KEY must include 16 HEX symbols");
|
||||
return 1;
|
||||
}
|
||||
|
||||
blockNo = param_get8(Cmd, 1);
|
||||
if (blockNo>32)
|
||||
{
|
||||
PrintAndLog("Error: Maximum number of blocks is 32 for iClass 2K Cards!");
|
||||
return 1;
|
||||
}
|
||||
if (param_gethex(Cmd, 2, bldata, 8))
|
||||
{
|
||||
PrintAndLog("Block data must include 8 HEX symbols");
|
||||
return 1;
|
||||
}
|
||||
|
||||
UsbCommand c = {CMD_ICLASS_ISO14443A_WRITE, {0}};
|
||||
SendCommand(&c);
|
||||
UsbCommand resp;
|
||||
if (param_gethex(Cmd, 0, KEY, 16))
|
||||
{
|
||||
PrintAndLog("KEY must include 16 HEX symbols");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) {
|
||||
uint8_t isOK = resp.arg[0] & 0xff;
|
||||
uint8_t * data = resp.d.asBytes;
|
||||
|
||||
memcpy(CSN,data,8);
|
||||
memcpy(CCNR,data+8,8);
|
||||
PrintAndLog("DEBUG: %s",sprint_hex(CSN,8));
|
||||
PrintAndLog("DEBUG: %s",sprint_hex(CCNR,8));
|
||||
PrintAndLog("isOk:%02x", isOK);
|
||||
} else {
|
||||
PrintAndLog("Command execute timeout");
|
||||
}
|
||||
blockNo = param_get8(Cmd, 1);
|
||||
if (blockNo>32)
|
||||
{
|
||||
PrintAndLog("Error: Maximum number of blocks is 32 for iClass 2K Cards!");
|
||||
return 1;
|
||||
}
|
||||
if (param_gethex(Cmd, 2, bldata, 8))
|
||||
{
|
||||
PrintAndLog("Block data must include 8 HEX symbols");
|
||||
return 1;
|
||||
}
|
||||
|
||||
diversifyKey(CSN,KEY, div_key);
|
||||
UsbCommand c = {CMD_ICLASS_ISO14443A_WRITE, {0}};
|
||||
SendCommand(&c);
|
||||
UsbCommand resp;
|
||||
|
||||
PrintAndLog("Div Key: %s",sprint_hex(div_key,8));
|
||||
doMAC(CCNR, 12,div_key, MAC);
|
||||
if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) {
|
||||
uint8_t isOK = resp.arg[0] & 0xff;
|
||||
uint8_t * data = resp.d.asBytes;
|
||||
|
||||
UsbCommand c2 = {CMD_ICLASS_ISO14443A_WRITE, {readerType,blockNo}};
|
||||
memcpy(c2.d.asBytes, bldata, 8);
|
||||
memcpy(c2.d.asBytes+8, MAC, 4);
|
||||
SendCommand(&c2);
|
||||
memcpy(CSN,data,8);
|
||||
memcpy(CCNR,data+8,8);
|
||||
PrintAndLog("DEBUG: %s",sprint_hex(CSN,8));
|
||||
PrintAndLog("DEBUG: %s",sprint_hex(CCNR,8));
|
||||
PrintAndLog("isOk:%02x", isOK);
|
||||
} else {
|
||||
PrintAndLog("Command execute timeout");
|
||||
}
|
||||
|
||||
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
|
||||
uint8_t isOK = resp.arg[0] & 0xff;
|
||||
uint8_t * data = resp.d.asBytes;
|
||||
diversifyKey(CSN,KEY, div_key);
|
||||
|
||||
if (isOK)
|
||||
PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 4));
|
||||
else
|
||||
PrintAndLog("isOk:%02x", isOK);
|
||||
} else {
|
||||
PrintAndLog("Command execute timeout");
|
||||
}
|
||||
return 0;
|
||||
PrintAndLog("Div Key: %s",sprint_hex(div_key,8));
|
||||
doMAC(CCNR, 12,div_key, MAC);
|
||||
|
||||
UsbCommand c2 = {CMD_ICLASS_ISO14443A_WRITE, {readerType,blockNo}};
|
||||
memcpy(c2.d.asBytes, bldata, 8);
|
||||
memcpy(c2.d.asBytes+8, MAC, 4);
|
||||
SendCommand(&c2);
|
||||
|
||||
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
|
||||
uint8_t isOK = resp.arg[0] & 0xff;
|
||||
uint8_t * data = resp.d.asBytes;
|
||||
|
||||
if (isOK)
|
||||
PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 4));
|
||||
else
|
||||
PrintAndLog("isOk:%02x", isOK);
|
||||
} else {
|
||||
PrintAndLog("Command execute timeout");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int CmdHFiClass_loclass(const char *Cmd)
|
||||
{
|
||||
|
@ -479,13 +550,13 @@ int CmdHFiClass_loclass(const char *Cmd)
|
|||
char fileName[255] = {0};
|
||||
if(opt == 'f')
|
||||
{
|
||||
if(param_getstr(Cmd, 1, fileName) > 0)
|
||||
{
|
||||
return bruteforceFileNoKeys(fileName);
|
||||
}else
|
||||
{
|
||||
PrintAndLog("You must specify a filename");
|
||||
}
|
||||
if(param_getstr(Cmd, 1, fileName) > 0)
|
||||
{
|
||||
return bruteforceFileNoKeys(fileName);
|
||||
}else
|
||||
{
|
||||
PrintAndLog("You must specify a filename");
|
||||
}
|
||||
}
|
||||
else if(opt == 't')
|
||||
{
|
||||
|
@ -512,19 +583,20 @@ static command_t CommandTable[] =
|
|||
{"reader",CmdHFiClassReader, 0, "Read an iClass tag"},
|
||||
{"replay",CmdHFiClassReader_Replay, 0, "Read an iClass tag via Reply Attack"},
|
||||
{"dump", CmdHFiClassReader_Dump, 0, "Authenticate and Dump iClass tag"},
|
||||
{"write", CmdHFiClass_iso14443A_write, 0, "Authenticate and Write iClass block"},
|
||||
// {"write", CmdHFiClass_iso14443A_write, 0, "Authenticate and Write iClass block"},
|
||||
{"loclass", CmdHFiClass_loclass, 1, "Use loclass to perform bruteforce of reader attack dump"},
|
||||
{"eload", CmdHFiClassELoad, 0, "[experimental] Load data into iclass emulator memory"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
int CmdHFiClass(const char *Cmd)
|
||||
{
|
||||
CmdsParse(CommandTable, Cmd);
|
||||
return 0;
|
||||
CmdsParse(CommandTable, Cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHelp(const char *Cmd)
|
||||
{
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1433,27 +1433,60 @@ int CmdHF14AMfCSetUID(const char *Cmd)
|
|||
uint8_t wipeCard = 0;
|
||||
uint8_t uid[8] = {0x00};
|
||||
uint8_t oldUid[8] = {0x00};
|
||||
uint8_t atqa[2] = {0x00};
|
||||
uint8_t sak[1] = {0x00};
|
||||
uint8_t atqaPresent = 1;
|
||||
int res;
|
||||
char ctmp;
|
||||
int argi=0;
|
||||
|
||||
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
|
||||
PrintAndLog("Usage: hf mf csetuid <UID 8 hex symbols> <w>");
|
||||
PrintAndLog("sample: hf mf csetuid 01020304 w");
|
||||
PrintAndLog("Set UID for magic Chinese card (only works with!!!)");
|
||||
PrintAndLog("If you want wipe card then add 'w' into command line. \n");
|
||||
if (strlen(Cmd) < 1 || param_getchar(Cmd, argi) == 'h') {
|
||||
PrintAndLog("Usage: hf mf csetuid <UID 8 hex symbols> [ATQA 4 hex symbols SAK 2 hex symbols] [w]");
|
||||
PrintAndLog("sample: hf mf csetuid 01020304");
|
||||
PrintAndLog("sample: hf mf csetuid 01020304 0004 08 w");
|
||||
PrintAndLog("Set UID, ATQA, and SAK for magic Chinese card (only works with such cards)");
|
||||
PrintAndLog("If you also want to wipe the card then add 'w' at the end of the command line.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (param_getchar(Cmd, 0) && param_gethex(Cmd, 0, uid, 8)) {
|
||||
if (param_getchar(Cmd, argi) && param_gethex(Cmd, argi, uid, 8)) {
|
||||
PrintAndLog("UID must include 8 HEX symbols");
|
||||
return 1;
|
||||
}
|
||||
argi++;
|
||||
|
||||
ctmp = param_getchar(Cmd, argi);
|
||||
if (ctmp == 'w' || ctmp == 'W') {
|
||||
wipeCard = 1;
|
||||
atqaPresent = 0;
|
||||
}
|
||||
|
||||
if (atqaPresent) {
|
||||
if (param_getchar(Cmd, argi)) {
|
||||
if (param_gethex(Cmd, argi, atqa, 4)) {
|
||||
PrintAndLog("ATQA must include 4 HEX symbols");
|
||||
return 1;
|
||||
}
|
||||
argi++;
|
||||
if (!param_getchar(Cmd, argi) || param_gethex(Cmd, argi, sak, 2)) {
|
||||
PrintAndLog("SAK must include 2 HEX symbols");
|
||||
return 1;
|
||||
}
|
||||
argi++;
|
||||
} else
|
||||
atqaPresent = 0;
|
||||
}
|
||||
|
||||
if(!wipeCard) {
|
||||
ctmp = param_getchar(Cmd, argi);
|
||||
if (ctmp == 'w' || ctmp == 'W') {
|
||||
wipeCard = 1;
|
||||
}
|
||||
}
|
||||
|
||||
char ctmp = param_getchar(Cmd, 1);
|
||||
if (ctmp == 'w' || ctmp == 'W') wipeCard = 1;
|
||||
|
||||
PrintAndLog("--wipe card:%s uid:%s", (wipeCard)?"YES":"NO", sprint_hex(uid, 4));
|
||||
|
||||
res = mfCSetUID(uid, oldUid, wipeCard);
|
||||
res = mfCSetUID(uid, (atqaPresent)?atqa:NULL, (atqaPresent)?sak:NULL, oldUid, wipeCard);
|
||||
if (res) {
|
||||
PrintAndLog("Can't set UID. error=%d", res);
|
||||
return 1;
|
||||
|
|
|
@ -414,7 +414,6 @@ int CmdLFSetConfig(const char *Cmd)
|
|||
uint8_t cmdp =0;
|
||||
while(param_getchar(Cmd, cmdp) != 0x00)
|
||||
{
|
||||
PrintAndLog("working %c", param_getchar(Cmd, cmdp));
|
||||
switch(param_getchar(Cmd, cmdp))
|
||||
{
|
||||
case 'h':
|
||||
|
|
|
@ -231,28 +231,31 @@ int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount) {
|
|||
|
||||
// "MAGIC" CARD
|
||||
|
||||
int mfCSetUID(uint8_t *uid, uint8_t *oldUID, bool wantWipe) {
|
||||
|
||||
int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, bool wantWipe) {
|
||||
uint8_t oldblock0[16] = {0x00};
|
||||
uint8_t block0[16] = {0x00};
|
||||
memcpy(block0, uid, 4);
|
||||
block0[4] = block0[0]^block0[1]^block0[2]^block0[3]; // Mifare UID BCC
|
||||
// mifare classic SAK(byte 5) and ATQA(byte 6 and 7)
|
||||
//block0[5] = 0x08;
|
||||
//block0[6] = 0x04;
|
||||
//block0[7] = 0x00;
|
||||
|
||||
block0[5] = 0x01; //sak
|
||||
block0[6] = 0x01;
|
||||
block0[7] = 0x0f;
|
||||
|
||||
|
||||
int old = mfCGetBlock(0, oldblock0, CSETBLOCK_SINGLE_OPER);
|
||||
if ( old == 0) {
|
||||
memcpy(block0+8, oldblock0+8, 8);
|
||||
PrintAndLog("block 0: %s", sprint_hex(block0,16));
|
||||
if (old == 0) {
|
||||
memcpy(block0, oldblock0, 16);
|
||||
PrintAndLog("old block 0: %s", sprint_hex(block0,16));
|
||||
} else {
|
||||
PrintAndLog("Couldn't get olddata. Will write over the last bytes of Block 0.");
|
||||
PrintAndLog("Couldn't get old data. Will write over the last bytes of Block 0.");
|
||||
}
|
||||
|
||||
// fill in the new values
|
||||
// UID
|
||||
memcpy(block0, uid, 4);
|
||||
// Mifare UID BCC
|
||||
block0[4] = block0[0]^block0[1]^block0[2]^block0[3];
|
||||
// mifare classic SAK(byte 5) and ATQA(byte 6 and 7, reversed)
|
||||
if (sak!=NULL)
|
||||
block0[5]=sak[0];
|
||||
if (atqa!=NULL) {
|
||||
block0[6]=atqa[1];
|
||||
block0[7]=atqa[0];
|
||||
}
|
||||
PrintAndLog("new block 0: %s", sprint_hex(block0,16));
|
||||
return mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER);
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ int mfCheckKeys (uint8_t blockNo, uint8_t keyType, uint8_t keycnt, uint8_t * key
|
|||
int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount);
|
||||
int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount);
|
||||
|
||||
int mfCSetUID(uint8_t *uid, uint8_t *oldUID, bool wantWipe);
|
||||
int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, bool wantWipe);
|
||||
int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, bool wantWipe, uint8_t params);
|
||||
int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params);
|
||||
|
||||
|
|
|
@ -237,7 +237,6 @@ uint8_t param_get8(const char *line, int paramnum)
|
|||
uint8_t param_getdec(const char *line, int paramnum, uint8_t *destination)
|
||||
{
|
||||
uint8_t val = param_get8ex(line, paramnum, 255, 10);
|
||||
printf("read %i", (int8_t ) val);
|
||||
if( (int8_t) val == -1) return 1;
|
||||
(*destination) = val;
|
||||
return 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue