Merge remote-tracking branch 'Proxmark/master' into iclass

Conflicts:
	CHANGELOG.md
This commit is contained in:
marshmellow42 2015-10-07 09:34:47 -04:00
commit c54dff4f4a
26 changed files with 869 additions and 185 deletions

View file

@ -24,6 +24,7 @@
#include "usb_cmd.h"
#include "crc.h"
#include "crc16.h"
#include "loclass/cipherutils.h"
uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
uint8_t g_debugMode=0;
@ -1943,26 +1944,14 @@ int CmdHpf(const char *Cmd)
RepaintGraphWindow();
return 0;
}
typedef struct {
uint8_t * buffer;
uint32_t numbits;
uint32_t position;
}BitstreamOut;
bool _headBit( BitstreamOut *stream)
{
int bytepos = stream->position >> 3; // divide by 8
int bitpos = (stream->position++) & 7; // mask out 00000111
return (*(stream->buffer + bytepos) >> (7-bitpos)) & 1;
}
uint8_t getByte(uint8_t bits_per_sample, BitstreamOut* b)
uint8_t getByte(uint8_t bits_per_sample, BitstreamIn* b)
{
int i;
uint8_t val = 0;
for(i =0 ; i < bits_per_sample; i++)
{
val |= (_headBit(b) << (7-i));
val |= (headBit(b) << (7-i));
}
return val;
}
@ -2002,7 +1991,7 @@ int getSamples(const char *Cmd, bool silent)
if(bits_per_sample < 8)
{
PrintAndLog("Unpacking...");
BitstreamOut bout = { got, bits_per_sample * n, 0};
BitstreamIn bout = { got, bits_per_sample * n, 0};
int j =0;
for (j = 0; j * bits_per_sample < n * 8 && j < n; j++) {
uint8_t sample = getByte(bits_per_sample, &bout);
@ -2265,6 +2254,99 @@ int CmdZerocrossings(const char *Cmd)
return 0;
}
int usage_data_bin2hex(){
PrintAndLog("Usage: data bin2hex <binary_digits>");
PrintAndLog(" This function will ignore all characters not 1 or 0 (but stop reading on whitespace)");
return 0;
}
/**
* @brief Utility for conversion via cmdline.
* @param Cmd
* @return
*/
int Cmdbin2hex(const char *Cmd)
{
int bg =0, en =0;
if(param_getptr(Cmd, &bg, &en, 0))
{
return usage_data_bin2hex();
}
//Number of digits supplied as argument
size_t length = en - bg +1;
size_t bytelen = (length+7) / 8;
uint8_t* arr = (uint8_t *) malloc(bytelen);
memset(arr, 0, bytelen);
BitstreamOut bout = { arr, 0, 0 };
for(; bg <= en ;bg++)
{
char c = Cmd[bg];
if( c == '1') pushBit(&bout, 1);
else if( c == '0') pushBit(&bout, 0);
else PrintAndLog("Ignoring '%c'", c);
}
if(bout.numbits % 8 != 0)
{
printf("[padded with %d zeroes]\n", 8-(bout.numbits % 8));
}
//Uses printf instead of PrintAndLog since the latter
// adds linebreaks to each printout - this way was more convenient since we don't have to
// allocate a string and write to that first...
for(size_t x = 0; x < bytelen ; x++)
{
printf("%02X", arr[x]);
}
printf("\n");
free(arr);
return 0;
}
int usage_data_hex2bin(){
PrintAndLog("Usage: data bin2hex <binary_digits>");
PrintAndLog(" This function will ignore all non-hexadecimal characters (but stop reading on whitespace)");
return 0;
}
int Cmdhex2bin(const char *Cmd)
{
int bg =0, en =0;
if(param_getptr(Cmd, &bg, &en, 0))
{
return usage_data_hex2bin();
}
while(bg <= en )
{
char x = Cmd[bg++];
// capitalize
if (x >= 'a' && x <= 'f')
x -= 32;
// convert to numeric value
if (x >= '0' && x <= '9')
x -= '0';
else if (x >= 'A' && x <= 'F')
x -= 'A' - 10;
else
continue;
//Uses printf instead of PrintAndLog since the latter
// adds linebreaks to each printout - this way was more convenient since we don't have to
// allocate a string and write to that first...
for(int i= 0 ; i < 4 ; ++i)
printf("%d",(x >> (3 - i)) & 1);
}
printf("\n");
return 0;
}
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
@ -2273,6 +2355,7 @@ static command_t CommandTable[] =
{"askgproxiidemod", CmdG_Prox_II_Demod, 1, "Demodulate a G Prox II tag from GraphBuffer"},
{"autocorr", CmdAutoCorr, 1, "[window length] [g] -- Autocorrelation over window - g to save back to GraphBuffer (overwrite)"},
{"biphaserawdecode",CmdBiphaseDecodeRaw,1, "[offset] [invert<0|1>] [maxErr] -- Biphase decode bin stream in DemodBuffer (offset = 0|1 bits to shift the decode start)"},
{"bin2hex", Cmdbin2hex, 1, "bin2hex <digits> -- Converts binary to hexadecimal"},
{"bitsamples", CmdBitsamples, 0, "Get raw samples as bitstring"},
{"buffclear", CmdBuffClear, 1, "Clear sample buffer and graph window"},
{"dec", CmdDec, 1, "Decimate samples"},
@ -2287,6 +2370,7 @@ static command_t CommandTable[] =
{"getbitstream", CmdGetBitStream, 1, "Convert GraphBuffer's >=1 values to 1 and <1 to 0"},
{"grid", CmdGrid, 1, "<x> <y> -- overlay grid on graph window, use zero value to turn off either"},
{"hexsamples", CmdHexsamples, 0, "<bytes> [<offset>] -- Dump big buffer as hex bytes"},
{"hex2bin", Cmdhex2bin, 1, "hex2bin <hexadecimal> -- Converts hexadecimal to binary"},
{"hide", CmdHide, 1, "Hide graph window"},
{"hpf", CmdHpf, 1, "Remove DC offset from trace"},
{"load", CmdLoad, 1, "<filename> -- Load trace (to graph window"},

View file

@ -58,6 +58,7 @@ start:
case -1 : PrintAndLog("Button pressed. Aborted.\n"); break;
case -2 : PrintAndLog("Card is not vulnerable to Darkside attack (doesn't send NACK on authentication requests).\n"); break;
case -3 : PrintAndLog("Card is not vulnerable to Darkside attack (its random number generator is not predictable).\n"); break;
case -4 : PrintAndLog("The card's random number generator is vulnerable but behaves somewhat weird (Mifare clone?). This needs to be fixed.\n"); break;
default: ;
}
break;

View file

@ -18,6 +18,7 @@
#include "cmdhw.h"
#include "cmdmain.h"
#include "cmddata.h"
#include "data.h"
/* low-level hardware control */
@ -405,33 +406,72 @@ int CmdTune(const char *Cmd)
int CmdVersion(const char *Cmd)
{
clearCommandBuffer();
UsbCommand c = {CMD_VERSION};
UsbCommand resp = {0, {0, 0, 0}};
static UsbCommand resp = {0, {0, 0, 0}};
SendCommand(&c);
if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
if (resp.arg[0] == 0 && resp.arg[1] == 0) { // no cached information available
SendCommand(&c);
if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
PrintAndLog("Prox/RFID mark3 RFID instrument");
PrintAndLog((char*)resp.d.asBytes);
lookupChipID(resp.arg[0], resp.arg[1]);
}
} else {
PrintAndLog("[[[ Cached information ]]]\n");
PrintAndLog("Prox/RFID mark3 RFID instrument");
PrintAndLog((char*)resp.d.asBytes);
lookupChipID(resp.arg[0], resp.arg[1]);
PrintAndLog("");
}
return 0;
}
int CmdStatus(const char *Cmd)
{
uint8_t speed_test_buffer[USB_CMD_DATA_SIZE];
sample_buf = speed_test_buffer;
clearCommandBuffer();
UsbCommand c = {CMD_STATUS};
SendCommand(&c);
if (!WaitForResponseTimeout(CMD_ACK,&c,1900)) {
PrintAndLog("Status command failed. USB Speed Test timed out");
}
return 0;
}
int CmdPing(const char *Cmd)
{
clearCommandBuffer();
UsbCommand resp;
UsbCommand c = {CMD_PING};
SendCommand(&c);
if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
PrintAndLog("Ping successfull");
}else{
PrintAndLog("Ping failed");
}
return 0;
}
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"detectreader", CmdDetectReader,0, "['l'|'h'] -- Detect external reader field (option 'l' or 'h' to limit to LF or HF)"},
{"fpgaoff", CmdFPGAOff, 0, "Set FPGA off"},
{"lcd", CmdLCD, 0, "<HEX command> <count> -- Send command/data to LCD"},
{"lcdreset", CmdLCDReset, 0, "Hardware reset LCD"},
{"readmem", CmdReadmem, 0, "[address] -- Read memory at decimal address from flash"},
{"reset", CmdReset, 0, "Reset the Proxmark3"},
{"setlfdivisor", CmdSetDivisor, 0, "<19 - 255> -- Drive LF antenna at 12Mhz/(divisor+1)"},
{"setmux", CmdSetMux, 0, "<loraw|hiraw|lopkd|hipkd> -- Set the ADC mux to a specific value"},
{"tune", CmdTune, 0, "Measure antenna tuning"},
{"version", CmdVersion, 0, "Show version information about the connected Proxmark"},
{NULL, NULL, 0, NULL}
{"help", CmdHelp, 1, "This help"},
{"detectreader", CmdDetectReader,0, "['l'|'h'] -- Detect external reader field (option 'l' or 'h' to limit to LF or HF)"},
{"fpgaoff", CmdFPGAOff, 0, "Set FPGA off"},
{"lcd", CmdLCD, 0, "<HEX command> <count> -- Send command/data to LCD"},
{"lcdreset", CmdLCDReset, 0, "Hardware reset LCD"},
{"readmem", CmdReadmem, 0, "[address] -- Read memory at decimal address from flash"},
{"reset", CmdReset, 0, "Reset the Proxmark3"},
{"setlfdivisor", CmdSetDivisor, 0, "<19 - 255> -- Drive LF antenna at 12Mhz/(divisor+1)"},
{"setmux", CmdSetMux, 0, "<loraw|hiraw|lopkd|hipkd> -- Set the ADC mux to a specific value"},
{"tune", CmdTune, 0, "Measure antenna tuning"},
{"version", CmdVersion, 0, "Show version information about the connected Proxmark"},
{"status", CmdStatus, 0, "Show runtime status information about the connected Proxmark"},
{"ping", CmdPing, 0, "Test if the pm3 is responsive"},
{NULL, NULL, 0, NULL}
};
int CmdHW(const char *Cmd)

View file

@ -1,6 +1,7 @@
//-----------------------------------------------------------------------------
// Copyright (C) 2012 Chalk <chalk.secu at gmail.com>
//
// 2015 Dake <thomas.cayrou at gmail.com>
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
@ -21,6 +22,8 @@
static int CmdHelp(const char *Cmd);
struct pcf7931_config configPcf = {{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},17500,{0,0}};
int CmdLFPCF7931Read(const char *Cmd)
{
UsbCommand c = {CMD_PCF7931_READ};
@ -30,10 +33,93 @@ int CmdLFPCF7931Read(const char *Cmd)
return 0;
}
int CmdLFPCF7931Config(const char *Cmd)
{
int res = 0;
res = sscanf(Cmd, "%02x %02x %02x %02x %02x %02x %02x %d %d %d", &configPcf.password[0], &configPcf.password[1], &configPcf.password[2], &configPcf.password[3], &configPcf.password[4], &configPcf.password[5], &configPcf.password[6], &configPcf.init_delay, &configPcf.offset[0], &configPcf.offset[1]);
if (res >= 7 || res < 1){
if(res == 7) configPcf.init_delay = 17500; //default value
if(res<=8){
configPcf.offset[0] = 0; //default value
configPcf.offset[1] = 0; //default value
}
if(res < 1){
PrintAndLog("Usage: <password byte 1 (in hex, lsb first)> <password byte 2 (in hex, lsb first)> [...] <password byte 7 (in hex, lsb first)> <tag initialization delay (in us)> <optional : offset on the low pulses width (in us)> <optional : offset on the low pulses position (in us)>");
PrintAndLog("The time offsets could be usefull to correct slew rate generated by the antenna.");
}
PrintAndLog("Current configuration :");
PrintAndLog("Password (LSB first on each byte) : %02x %02x %02x %02x %02x %02x %02x", configPcf.password[0], configPcf.password[1], configPcf.password[2], configPcf.password[3], configPcf.password[4], configPcf.password[5], configPcf.password[6]);
PrintAndLog("Tag initialization delay : %d us", configPcf.init_delay);
PrintAndLog("Offsets : %d us on the low pulses width, %d us on the low pulses positions", configPcf.offset[0], configPcf.offset[1]);
return 0;
}
//default values
configPcf.password[0] = 0xFF;
configPcf.password[1] = 0xFF;
configPcf.password[2] = 0xFF;
configPcf.password[3] = 0xFF;
configPcf.password[4] = 0xFF;
configPcf.password[5] = 0xFF;
configPcf.password[6] = 0xFF;
configPcf.init_delay = 17500;
configPcf.offset[0] = 0;
configPcf.offset[1] = 0;
PrintAndLog("Incorrect format");
PrintAndLog("Examples of right usage : lf pcf7931 config 11 22 33 44 55 66 77 20000");
PrintAndLog(" lf pcf7931 config FF FF FF FF FF FF FF 17500 -10 30");
return 0;
}
int CmdLFPCF7931Write(const char *Cmd)
{
UsbCommand c = {CMD_PCF7931_WRITE};
int res = 0;
res = sscanf(Cmd, "%x %x %x", &c.arg[0], &c.arg[1], &c.arg[2]);
if(res < 1) {
PrintAndLog("Please specify the block address in hex");
return 0;
}
if (res == 1){
PrintAndLog("Please specify the byte address in hex");
return 0;
}
if(res == 2) {
PrintAndLog("Please specify the data in hex (1 byte)");
return 0;
}
if(res == 3) {
uint8_t n=0;
for(n=0;n<7;n++) c.d.asDwords[n] = configPcf.password[n];
c.d.asDwords[7] = (configPcf.offset[0]+128);
c.d.asDwords[8] = (configPcf.offset[1]+128);
c.d.asDwords[9] = configPcf.init_delay;
SendCommand(&c);
return 0;
}
PrintAndLog("INCORRECT FORMAT");
return 0;
}
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"read", CmdLFPCF7931Read, 1, "Read content of a PCF7931 transponder"},
{"write", CmdLFPCF7931Write, 1, "Write data on a PCF7931 transponder. Usage : lf pcf7931 write <bloc address> <byte address> <data>"},
{"config", CmdLFPCF7931Config, 1, "Configure the password, the tags initialization delay and time offsets (optional)"},
{NULL, NULL, 0, NULL}
};

View file

@ -1,6 +1,7 @@
//-----------------------------------------------------------------------------
// Copyright (C) 2012 Chalk <chalk.secu at gmail.com>
//
// 2015 Dake <thomas.cayrou at gmail.com>
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
@ -11,8 +12,18 @@
#ifndef CMDLFPCF7931_H__
#define CMDLFPCF7931_H__
struct pcf7931_config{
uint8_t password[7];
uint16_t init_delay;
int16_t offset[2];
};
int CmdLFPCF7931(const char *Cmd);
int CmdLFPCF7931Read(const char *Cmd);
int CmdLFPCF7931Write(const char *Cmd);
int CmdLFPCF7931Config(const char *Cmd);
#endif

View file

@ -97,8 +97,9 @@ void storeCommand(UsbCommand *command)
memcpy(destination, command, sizeof(UsbCommand));
cmd_head = (cmd_head +1) % CMD_BUFFER_SIZE; //increment head and wrap
}
/**
* @brief getCommand gets a command from an internal circular buffer.
* @param response location to write command
@ -117,9 +118,9 @@ int getCommand(UsbCommand* response)
cmd_tail = (cmd_tail +1 ) % CMD_BUFFER_SIZE;
return 1;
}
/**
* Waits for a certain response type. This method waits for a maximum of
* ms_timeout milliseconds for a specified response command.
@ -131,33 +132,34 @@ int getCommand(UsbCommand* response)
*/
bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout) {
UsbCommand resp;
UsbCommand resp;
if (response == NULL)
response = &resp;
// Wait until the command is received
for(size_t dm_seconds=0; dm_seconds < ms_timeout/10; dm_seconds++) {
while(getCommand(response)) {
if(response->cmd == cmd){
return true;
}
}
msleep(10); // XXX ugh
if (dm_seconds == 200) { // Two seconds elapsed
PrintAndLog("Waiting for a response from the proxmark...");
PrintAndLog("Don't forget to cancel its operation first by pressing on the button");
}
if (response == NULL) {
response = &resp;
}
return false;
// Wait until the command is received
for(size_t dm_seconds=0; dm_seconds < ms_timeout/10; dm_seconds++) {
while(getCommand(response)) {
if(response->cmd == cmd){
return true;
}
}
msleep(10); // XXX ugh
if (dm_seconds == 200) { // Two seconds elapsed
PrintAndLog("Waiting for a response from the proxmark...");
PrintAndLog("Don't forget to cancel its operation first by pressing on the button");
}
}
return false;
}
bool WaitForResponse(uint32_t cmd, UsbCommand* response) {
return WaitForResponseTimeout(cmd,response,-1);
}
//-----------------------------------------------------------------------------
// Entry point into our code: called whenever the user types a command and
// then presses Enter, which the full command line that they typed.
@ -166,6 +168,7 @@ void CommandReceived(char *Cmd) {
CmdsParse(CommandTable, Cmd);
}
//-----------------------------------------------------------------------------
// Entry point into our code: called whenever we received a packet over USB
// that we weren't necessarily expecting, for example a debug print.
@ -189,12 +192,13 @@ void UsbCommandReceived(UsbCommand *UC)
case CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K: {
memcpy(sample_buf+(UC->arg[0]),UC->d.asBytes,UC->arg[1]);
return;
} break;
default:
storeCommand(UC);
break;
}
storeCommand(UC);
}

View file

@ -20,7 +20,8 @@ local _commands = {
CMD_BUFF_CLEAR = 0x0105,
CMD_READ_MEM = 0x0106,
CMD_VERSION = 0x0107,
CMD_STATUS = 0x0108,
CMD_PING = 0x0109,
--// For low-frequency tags
CMD_READ_TI_TYPE = 0x0202,
CMD_WRITE_TI_TYPE = 0x0203,

View file

@ -112,6 +112,8 @@ function mfcrack_inner()
return nil, "Card is not vulnerable to Darkside attack (doesn't send NACK on authentication requests). You can try 'script run mfkeys' or 'hf mf chk' to test various known keys."
elseif isOK == 0xFFFFFFFD then
return nil, "Card is not vulnerable to Darkside attack (its random number generator is not predictable). You can try 'script run mfkeys' or 'hf mf chk' to test various known keys."
elseif isOK == 0xFFFFFFFC then
return nil, "The card's random number generator is vulnerable but behaves somewhat weird (Mifare clone?). You can try 'script run mfkeys' or 'hf mf chk' to test various known keys."
elseif isOK ~= 1 then
return nil, "Error occurred"
end

View file

@ -47,6 +47,7 @@ char * printBits(size_t const size, void const * const ptr);
uint8_t *SwapEndian64(const uint8_t *src, const size_t len, const uint8_t blockSize);
char param_getchar(const char *line, int paramnum);
int param_getptr(const char *line, int *bg, int *en, int paramnum);
uint8_t param_get8(const char *line, int paramnum);
uint8_t param_get8ex(const char *line, int paramnum, int deflt, int base);
uint32_t param_get32ex(const char *line, int paramnum, int deflt, int base);