Merge branch 'master' into emv_scan

This commit is contained in:
Oleg Moiseenko 2018-10-10 23:35:26 +03:00 committed by GitHub
commit acda830056
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 250 additions and 5 deletions

View file

@ -2,19 +2,26 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
## [unreleased][unreleased] ## [unreleased][unreleased]
### Changed
### Fixed
### Added
## [v3.1.0][2018-10-10]
### Changed ### Changed
- Adjusted `lf cmdread` to respond to client when complete and the client will then automatically call `data samples` - Adjusted `lf cmdread` to respond to client when complete and the client will then automatically call `data samples`
- Improved backdoor detection missbehaving magic s50/1k tag (Fl0-0) - Improved backdoor detection misbehaving magic s50/1k tag (Fl0-0)
- Deleted wipe functionality from `hf mf csetuid` (Merlok) - Deleted wipe functionality from `hf mf csetuid` (Merlok)
- Changed `hf mf nested` logic (Merlok) - Changed `hf mf nested` logic (Merlok)
- Added `hf mf nested` mode: autosearch keys for attack (from well known keys) (Merlok) - Added `hf mf nested` mode: autosearch keys for attack (from well known keys) (Merlok)
- `hf mf nested` Check keys after they have found (Merlok) - `hf mf nested` Check keys after they have found (Merlok)
- `hf mf chk` Move main cycle to arm (Merlok) - `hf mf chk` Move main cycle to arm (Merlok)
- Changed proxmark command line parameter `flush` to `-f` or `-flush` (Merlok) - Changed proxmark command line parameter `flush` to `-f` or `-flush` (Merlok)
- Changed `hf 14a reader` to just reqest-anticilission-select sequence (Merlok) - Changed `hf 14a reader` to just request-anticolission-select sequence (Merlok)
- Changed `hf 14a raw` - works with LED's and some exchange logic (Merlok) - Changed `hf 14a raw` - works with LED's and some exchange logic (Merlok)
- Changed TLV parser messages to more convenient (Merlok) - Changed TLV parser messages to more convenient (Merlok)
- Rewritten Legic Prime reader (`hf legic reader`, `write` and `fill`) - it is using xcorrelation now (AntiCat) - Rewritten Legic Prime reader (`hf legic reader`, `write` and `fill`) - it is using xcorrelation now (AntiCat)
@ -33,14 +40,14 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
- Added a bitbang mode to `lf cmdread` if delay is 0 the cmd bits turn off and on the antenna with 0 and 1 respectively (marshmellow) - Added a bitbang mode to `lf cmdread` if delay is 0 the cmd bits turn off and on the antenna with 0 and 1 respectively (marshmellow)
- Added PAC/Stanley detection to lf search (marshmellow) - Added PAC/Stanley detection to lf search (marshmellow)
- Added lf pac demod and lf pac read - extracts the raw blocks from a PAC/Stanley tag (marshmellow) - Added lf pac demod and lf pac read - extracts the raw blocks from a PAC/Stanley tag (marshmellow)
- Added hf mf c* commands compatibity for 4k and gen1b backdoor (Fl0-0) - Added hf mf c* commands compatibility for 4k and gen1b backdoor (Fl0-0)
- Added backdoor detection for gen1b magic s70/4k tag (Fl0-0) - Added backdoor detection for gen1b magic s70/4k tag (Fl0-0)
- Added data fsktonrz, a fsk cleaning/demodulating routine for weak fsk signal. Note: follow this up with a `data rawdemod nr` to finish demoding your signal. (marshmellow) - Added data fsktonrz, a fsk cleaning/demodulating routine for weak fsk signal. Note: follow this up with a `data rawdemod nr` to finish demoding your signal. (marshmellow)
- Added lf em 410xbrute, LF EM410x reader bruteforce attack by simulating UIDs from a file (Fl0-0) - Added lf em 410xbrute, LF EM410x reader bruteforce attack by simulating UIDs from a file (Fl0-0)
- Added `hf mf cwipe` command. It wipes "magic Chinese" card. For 1a generation it uses card's "wipe" command. For gen1a and gen1b it uses a write command. (Merlok) - Added `hf mf cwipe` command. It wipes "magic Chinese" card. For 1a generation it uses card's "wipe" command. For gen1a and gen1b it uses a write command. (Merlok)
- Added to `hf mf nested` source key check before attack (Merlok) - Added to `hf mf nested` source key check before attack (Merlok)
- Added to `hf mf nested` after attack it checks all found keys on non-open sectors (Merlok) - Added to `hf mf nested` after attack it checks all found keys on non-open sectors (Merlok)
- `hf mf chk` Added setings to set iso14443a operations timeout. default timeout set to 500us (Merlok) - `hf mf chk` Added settings to set iso14443a operations timeout. default timeout set to 500us (Merlok)
- Added to `hf mf nested` parameters `s` and `ss` for checking slow cards (Merlok) - Added to `hf mf nested` parameters `s` and `ss` for checking slow cards (Merlok)
- Added to proxmark command line parameters `w` - wait 20s for serial port (Merlok) - Added to proxmark command line parameters `w` - wait 20s for serial port (Merlok)
- Added to proxmark command line parameters `c` and `l` - execute command and lua script from command line (Merlok) - Added to proxmark command line parameters `c` and `l` - execute command and lua script from command line (Merlok)

View file

@ -687,6 +687,95 @@ void DropField() {
SendCommand(&c); SendCommand(&c);
} }
int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) {
uint16_t cmdc = 0;
*dataoutlen = 0;
if (activateField) {
UsbCommand resp;
// Anticollision + SELECT card
UsbCommand ca = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT | ISO14A_CLEAR_TRACE, 0, 0}};
SendCommand(&ca);
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
PrintAndLog("14aRAW ERROR: Proxmark connection timeout.");
return 1;
}
// check result
if (resp.arg[0] == 0) {
PrintAndLog("14aRAW ERROR: No card in field.");
return 1;
}
if (resp.arg[0] != 1 && resp.arg[0] != 2) {
PrintAndLog("14aRAW ERROR: card not in iso14443-4. res=%d.", resp.arg[0]);
return 1;
}
if (resp.arg[0] == 2) { // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision
// get ATS
UsbCommand cr = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT, 2, 0}};
uint8_t rats[] = { 0xE0, 0x80 }; // FSDI=8 (FSD=256), CID=0
memcpy(cr.d.asBytes, rats, 2);
SendCommand(&cr);
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
PrintAndLog("14aRAW ERROR: Proxmark connection timeout.");
return 1;
}
if (resp.arg[0] <= 0) { // ats_len
PrintAndLog("14aRAW ERROR: Can't get ATS.");
return 1;
}
}
}
if (leaveSignalON)
cmdc |= ISO14A_NO_DISCONNECT;
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_APPEND_CRC | cmdc, (datainlen & 0xFFFF), 0}};
memcpy(c.d.asBytes, datain, datainlen);
SendCommand(&c);
uint8_t *recv;
UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
recv = resp.d.asBytes;
int iLen = resp.arg[0];
*dataoutlen = iLen - 2;
if (*dataoutlen < 0)
*dataoutlen = 0;
if (maxdataoutlen && *dataoutlen > maxdataoutlen) {
PrintAndLog("14aRAW ERROR: Buffer too small(%d). Needs %d bytes", *dataoutlen, maxdataoutlen);
return 2;
}
memcpy(dataout, recv, *dataoutlen);
if(!iLen) {
PrintAndLog("14aRAW ERROR: No card response.");
return 1;
}
// CRC Check
if (iLen == -1) {
PrintAndLog("14aRAW ERROR: ISO 14443A CRC error.");
return 3;
}
} else {
PrintAndLog("14aRAW ERROR: Reply timeout.");
return 4;
}
return 0;
}
int ExchangeAPDU14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) { int ExchangeAPDU14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) {
uint16_t cmdc = 0; uint16_t cmdc = 0;

View file

@ -26,7 +26,9 @@ int CmdHF14ASnoop(const char *Cmd);
char* getTagInfo(uint8_t uid); char* getTagInfo(uint8_t uid);
extern void DropField(); extern void DropField();
extern int Hf14443_4aGetCardData(iso14a_card_select_t * card); extern int Hf14443_4aGetCardData(iso14a_card_select_t * card);
extern int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen);
extern int ExchangeAPDU14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); extern int ExchangeAPDU14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen);
#endif #endif

View file

@ -27,6 +27,9 @@
#include "mifare.h" #include "mifare.h"
#include "mfkey.h" #include "mfkey.h"
#include "hardnested/hardnested_bf_core.h" #include "hardnested/hardnested_bf_core.h"
#include "cliparser/cliparser.h"
#include "cmdhf14a.h"
#include <polarssl/aes.h>
#define NESTED_SECTOR_RETRY 10 // how often we try mfested() until we give up #define NESTED_SECTOR_RETRY 10 // how often we try mfested() until we give up
@ -2634,6 +2637,149 @@ int CmdDecryptTraceCmds(const char *Cmd){
return tryDecryptWord(param_get32ex(Cmd,0,0,16),param_get32ex(Cmd,1,0,16),param_get32ex(Cmd,2,0,16),data,len/2); return tryDecryptWord(param_get32ex(Cmd,0,0,16),param_get32ex(Cmd,1,0,16),param_get32ex(Cmd,2,0,16),data,len/2);
} }
int aes_encode(uint8_t *iv, uint8_t *key, uint8_t *input, uint8_t *output, int length){
uint8_t iiv[16] = {0};
if (iv)
memcpy(iiv, iv, 16);
aes_context aes;
aes_init(&aes);
if (aes_setkey_enc(&aes, key, 128))
return 1;
if (aes_crypt_cbc(&aes, AES_ENCRYPT, length, iiv, input, output))
return 2;
aes_free(&aes);
return 0;
}
int aes_decode(uint8_t *iv, uint8_t *key, uint8_t *input, uint8_t *output, int length){
uint8_t iiv[16] = {0};
if (iv)
memcpy(iiv, iv, 16);
aes_context aes;
aes_init(&aes);
if (aes_setkey_dec(&aes, key, 128))
return 1;
if (aes_crypt_cbc(&aes, AES_DECRYPT, length, iiv, input, output))
return 2;
aes_free(&aes);
return 0;
}
int CmdHF14AMfAuth4(const char *cmd) {
uint8_t keyn[20] = {0};
int keynlen = 0;
uint8_t key[16] = {0};
int keylen = 0;
uint8_t data[257] = {0};
int datalen = 0;
uint8_t Rnd1[17] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00};
uint8_t Rnd2[17] = {0};
CLIParserInit("hf mf auth4",
"Executes AES authentication command in ISO14443-4",
"Usage:\n\thf mf auth4 4000 000102030405060708090a0b0c0d0e0f -> executes authentication\n"
"\thf mf auth4 9003 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> executes authentication\n");
void* argtable[] = {
arg_param_begin,
arg_str1(NULL, NULL, "<Key Num (HEX 2 bytes)>", NULL),
arg_str1(NULL, NULL, "<Key Value (HEX 16 bytes)>", NULL),
arg_param_end
};
CLIExecWithReturn(cmd, argtable, true);
CLIGetStrWithReturn(1, keyn, &keynlen);
CLIGetStrWithReturn(2, key, &keylen);
CLIParserFree();
if (keynlen != 2) {
PrintAndLog("ERROR: <Key Num> must be 2 bytes long instead of: %d", keynlen);
return 1;
}
if (keylen != 16) {
PrintAndLog("ERROR: <Key Value> must be 16 bytes long instead of: %d", keylen);
return 1;
}
uint8_t cmd1[] = {0x0a, 0x00, 0x70, keyn[1], keyn[0], 0x00};
int res = ExchangeRAW14a(cmd1, sizeof(cmd1), true, true, data, sizeof(data), &datalen);
if (res) {
PrintAndLog("ERROR exchande raw error: %d", res);
return 2;
}
PrintAndLog("<phase1: %s", sprint_hex(data, datalen));
if (datalen < 3) {
PrintAndLog("ERROR: card response length: %d", datalen);
return 3;
}
if (data[0] != 0x0a || data[1] != 0x00) {
PrintAndLog("ERROR: card response. Framing error. :%s", sprint_hex(data, 2));
return 3;
}
if (data[2] != 0x90) {
PrintAndLog("ERROR: card response error: %02x", data[2]);
return 3;
}
if (datalen != 19) {
PrintAndLog("ERROR: card response must be 16 bytes long instead of: %d", datalen);
return 3;
}
aes_decode(NULL, key, &data[3], Rnd2, 16);
Rnd2[16] = Rnd2[0];
PrintAndLog("Rnd2: %s", sprint_hex(Rnd2, 16));
uint8_t cmd2[35] = {0};
cmd2[0] = 0x0b;
cmd2[1] = 0x00;
cmd2[2] = 0x72;
uint8_t raw[32] = {0};
memmove(raw, Rnd1, 16);
memmove(&raw[16], &Rnd2[1], 16);
aes_encode(NULL, key, raw, &cmd2[3], 32);
PrintAndLog(">phase2: %s", sprint_hex(cmd2, 35));
res = ExchangeRAW14a(cmd2, sizeof(cmd2), false, false, data, sizeof(data), &datalen);
if (res) {
PrintAndLog("ERROR exchande raw error: %d", res);
DropField();
return 4;
}
PrintAndLog("<phase2: %s", sprint_hex(data, datalen));
aes_decode(NULL, key, &data[3], raw, 32);
PrintAndLog("res: %s", sprint_hex(raw, 32));
PrintAndLog("Rnd1`: %s", sprint_hex(&raw[4], 16));
if (memcmp(&raw[4], &Rnd1[1], 16)) {
PrintAndLog("\nERROR: Authentication FAILED. rnd not equal");
PrintAndLog("rnd1 reader: %s", sprint_hex(&Rnd1[1], 16));
PrintAndLog("rnd1 card: %s", sprint_hex(&raw[4], 16));
DropField();
return 5;
}
DropField();
PrintAndLog("\nAuthentication OK");
return 0;
}
static command_t CommandTable[] = static command_t CommandTable[] =
{ {
{"help", CmdHelp, 1, "This help"}, {"help", CmdHelp, 1, "This help"},
@ -2643,6 +2789,7 @@ static command_t CommandTable[] =
{"dump", CmdHF14AMfDump, 0, "Dump MIFARE classic tag to binary file"}, {"dump", CmdHF14AMfDump, 0, "Dump MIFARE classic tag to binary file"},
{"restore", CmdHF14AMfRestore, 0, "Restore MIFARE classic binary file to BLANK tag"}, {"restore", CmdHF14AMfRestore, 0, "Restore MIFARE classic binary file to BLANK tag"},
{"wrbl", CmdHF14AMfWrBl, 0, "Write MIFARE classic block"}, {"wrbl", CmdHF14AMfWrBl, 0, "Write MIFARE classic block"},
{"auth4", CmdHF14AMfAuth4, 0, "ISO14443-4 AES authentication"},
{"chk", CmdHF14AMfChk, 0, "Test block keys"}, {"chk", CmdHF14AMfChk, 0, "Test block keys"},
{"mifare", CmdHF14AMifare, 0, "Read parity error messages."}, {"mifare", CmdHF14AMifare, 0, "Read parity error messages."},
{"hardnested", CmdHF14AMfNestedHard, 0, "Nested attack for hardened Mifare cards"}, {"hardnested", CmdHF14AMfNestedHard, 0, "Nested attack for hardened Mifare cards"},