mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-14 18:48:13 -07:00
Merge branch 'master' into master
This commit is contained in:
commit
5e277caa0b
1022 changed files with 41092 additions and 20565 deletions
|
@ -81,12 +81,12 @@
|
|||
|
||||
*/
|
||||
|
||||
uint8_t cjuid[10];
|
||||
uint32_t cjcuid;
|
||||
iso14a_card_select_t p_card;
|
||||
int currline;
|
||||
int currfline;
|
||||
int curlline;
|
||||
static uint8_t cjuid[10];
|
||||
static uint32_t cjcuid;
|
||||
static iso14a_card_select_t p_card;
|
||||
static int currline;
|
||||
static int currfline;
|
||||
static int curlline;
|
||||
|
||||
// TODO : Implement fast read of KEYS like in RFIdea
|
||||
// also http://ext.delaat.net/rp/2015-2016/p04/report.pdf
|
||||
|
@ -104,12 +104,7 @@ static const uint8_t is_hex[] = {
|
|||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
// Note: inlining this function would fail with -Os
|
||||
#ifdef __OPTIMIZE_SIZE__
|
||||
static uint64_t hex2i(const char *s) {
|
||||
#else
|
||||
static inline uint64_t hex2i(const char *s) {
|
||||
#endif
|
||||
uint64_t val = 0;
|
||||
if (s == NULL || s[0] == 0)
|
||||
return 0;
|
||||
|
@ -167,7 +162,7 @@ static void scan_keys(const char *str, int len, uint64_t *user_data) {
|
|||
}
|
||||
}
|
||||
|
||||
MFC1KSchema Schemas[MAX_SCHEMAS];
|
||||
static MFC1KSchema Schemas[MAX_SCHEMAS];
|
||||
|
||||
/*MFC1KSchema Noralsy = {
|
||||
.name = "Noralsy",
|
||||
|
@ -201,7 +196,7 @@ MFC1KSchema InfiHexact = {.name = "Infineon/Hexact",
|
|||
0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76}};
|
||||
*/
|
||||
|
||||
int total_schemas = 0;
|
||||
static int total_schemas = 0;
|
||||
|
||||
static void add_schema(MFC1KSchema *p, MFC1KSchema a, int *schemas_counter) {
|
||||
if (*schemas_counter < MAX_SCHEMAS) {
|
||||
|
@ -237,14 +232,6 @@ static void cjSetCursLeft(void) {
|
|||
|
||||
static void cjTabulize(void) { DbprintfEx(FLAG_RAWPRINT, "\t\t\t"); }
|
||||
|
||||
/*
|
||||
void cjPrintKey(uint64_t key, uint8_t *foundKey, uint16_t sectorNo, uint8_t type) {
|
||||
char tosendkey[13];
|
||||
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[0], foundKey[1], foundKey[2], foundKey[3], foundKey[4],
|
||||
foundKey[5]); cjSetCursRight(); DbprintfEx(FLAG_NEWLINE, "SEC: %02x | KEY : %s | TYP: %d", sectorNo, tosendkey, type);
|
||||
}
|
||||
*/
|
||||
|
||||
static char *ReadSchemasFromSPIFFS(char *filename) {
|
||||
SpinOff(0);
|
||||
|
||||
|
@ -297,6 +284,7 @@ static void ReadLastTagFromFlash(void) {
|
|||
// this one will handle filetype (symlink or not) and resolving by itself
|
||||
rdv40_spiffs_read_as_filetype((char *)HFCOLIN_LASTTAG_SYMLINK, (uint8_t *)mem, len, RDV40_SPIFFS_SAFETY_SAFE);
|
||||
|
||||
// copy 64blocks (16bytes) starting w block0, to emulator mem.
|
||||
emlSetMem(mem, 0, 64);
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "[OK] Last tag recovered from FLASHMEM set to emulator");
|
||||
|
@ -335,16 +323,22 @@ void WriteTagToFlash(uint32_t uid, size_t size) {
|
|||
return;
|
||||
}
|
||||
|
||||
void ModInfo(void) { DbpString(" HF Mifare ultra fast sniff/sim/clone - aka VIGIKPWN (Colin Brigato)"); }
|
||||
void ModInfo(void) {
|
||||
DbpString(" HF Mifare ultra fast sniff/sim/clone - aka VIGIKPWN (Colin Brigato)");
|
||||
}
|
||||
|
||||
void RunMod(void) {
|
||||
StandAloneMode();
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
Dbprintf(">> HF Mifare ultra fast sniff/sim/clone a.k.a VIGIKPWN Started <<");
|
||||
|
||||
// turn off all debugging.
|
||||
DBGLEVEL = DBG_NONE;
|
||||
|
||||
// add_schema(Schemas, Noralsy, &total_schemas);
|
||||
// add_schema(Schemas, InfiHexact, &total_schemas);
|
||||
// add_schema_from_json_in_spiffs((char *)HFCOLIN_URMETCAPTIVE_JSON);
|
||||
// add_schema(Schemas, UrmetCaptive, &total_schemas);
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
|
||||
currline = 20;
|
||||
curlline = 20;
|
||||
|
@ -391,11 +385,11 @@ void RunMod(void) {
|
|||
ACCBITS : 796788[00]+VALUE
|
||||
*/
|
||||
|
||||
//----------------------------
|
||||
// ----------------------------
|
||||
// Set of keys to be used.
|
||||
// This should cover ~98% of
|
||||
// French VIGIK system @2017
|
||||
//----------------------------
|
||||
// ----------------------------
|
||||
|
||||
const uint64_t mfKeys[] = {
|
||||
0xffffffffffff, // TRANSPORTS
|
||||
|
@ -464,7 +458,6 @@ void RunMod(void) {
|
|||
bool err = 0;
|
||||
bool trapped = 0;
|
||||
bool allKeysFound = true;
|
||||
|
||||
uint32_t size = mfKeysCnt;
|
||||
|
||||
// banner:
|
||||
|
@ -492,7 +485,7 @@ failtag:
|
|||
SpinOff(50);
|
||||
LED_A_ON();
|
||||
uint8_t ticker = 0;
|
||||
// while (!BUTTON_PRESS() && !iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true))
|
||||
|
||||
while (!iso14443a_select_card(cjuid, &p_card, &cjcuid, true, 0, true)) {
|
||||
WDT_HIT();
|
||||
|
||||
|
@ -510,8 +503,8 @@ failtag:
|
|||
}
|
||||
|
||||
SpinOff(50);
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
|
||||
vtsend_cursor_position_restore(NULL);
|
||||
DbprintfEx(FLAG_NEWLINE, "\t\t\t%s[ GOT a Tag ! ]%s", _XGREEN_, _XWHITE_);
|
||||
cjSetCursLeft();
|
||||
|
@ -539,7 +532,7 @@ failtag:
|
|||
uint32_t start_time = GetTickCount();
|
||||
uint32_t delta_time = 0;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
// WE SHOULD FIND A WAY TO GET UID TO AVOID THIS "TESTRUN"
|
||||
// --------------------------------------------------------
|
||||
// + HERE IS TO BE THOUGHT AS ONLY A KEY SHOULD BE CHECK
|
||||
|
@ -549,7 +542,7 @@ failtag:
|
|||
// `-+ THEN FILL EMULATOR WITH B KEEY
|
||||
// `-+ THEN EMULATOR WITH CARD WITH B KEY
|
||||
// `-+ IF IT HAS FAILED OF ANY OF SORT THEN WE ARE MARRON LIKE POMALO.
|
||||
//----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
// AN EVEN BETTER IMPLEMENTATION IS TO CHECK EVERY KEY FOR SECTOR 0 KEY A
|
||||
// THEN IF FOUND CHECK THE SAME KEY FOR NEXT SECTOR ONLY KEY A
|
||||
// THEN IF FAIL CHECK EVERY SECTOR A KEY FOR EVERY OTHER KEY BUT NOT THE BLOCK
|
||||
|
@ -563,7 +556,7 @@ failtag:
|
|||
// DERIVATION
|
||||
// THEN IF B KEY IS NOT OF THIS SCHEME CHECK EVERY REMAINING B KEYED SECTOR
|
||||
// WITH EVERY REMAINING KEYS, BUT DISCARDING ANY DEFAULT TRANSPORT KEYS.
|
||||
//-----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
// also we could avoid first UID check for every block
|
||||
|
||||
// then let's expose this optimal case of well known vigik schemes :
|
||||
|
@ -630,7 +623,6 @@ failtag:
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* etc etc for testing schemes quick schemes */
|
||||
}
|
||||
}
|
||||
|
@ -646,7 +638,7 @@ failtag:
|
|||
return;
|
||||
}
|
||||
|
||||
/* Settings keys to emulator */
|
||||
// Settings keys to emulator
|
||||
emlClearMem();
|
||||
uint8_t mblock[16];
|
||||
for (uint8_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
|
||||
|
@ -660,7 +652,7 @@ failtag:
|
|||
|
||||
DbprintfEx(FLAG_NEWLINE, "%s>>%s Setting Keys->Emulator MEM...[%sOK%s]", _XYELLOW_, _XWHITE_, _XGREEN_, _XWHITE_);
|
||||
|
||||
/* filling TAG to emulator */
|
||||
// filling TAG to emulator
|
||||
int filled;
|
||||
cjSetCursLeft();
|
||||
|
||||
|
@ -671,11 +663,10 @@ failtag:
|
|||
|
||||
DbprintfEx(FLAG_NEWLINE, "%s>>%s W_FAILURE ! %sTrying fallback B keys....", _XRED_, _XORANGE_, _XWHITE_);
|
||||
|
||||
/* no trace, no dbg */
|
||||
// no trace, no dbg
|
||||
filled = e_MifareECardLoad(sectorsCnt, 1);
|
||||
if (filled != PM3_SUCCESS) {
|
||||
cjSetCursLeft();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "FATAL:EML_FALLBACKFILL_B");
|
||||
SpinErr(LED_C, 100, 8);
|
||||
SpinOff(100);
|
||||
|
@ -722,10 +713,9 @@ readysim:
|
|||
SpinOff(100);
|
||||
LED_C_ON();
|
||||
|
||||
DBGLEVEL = DBG_NONE;
|
||||
|
||||
//uint16_t flags=0;
|
||||
/*switch (p_card.uidlen) {
|
||||
/*
|
||||
uint16_t flags = 0;
|
||||
switch (p_card.uidlen) {
|
||||
case 10:
|
||||
flags = FLAG_10B_UID_IN_DATA;
|
||||
break;
|
||||
|
@ -738,19 +728,18 @@ readysim:
|
|||
default:
|
||||
flags = FLAG_UID_IN_EMUL;
|
||||
break;
|
||||
}*/
|
||||
|
||||
}
|
||||
// Use UID, SAK, ATQA from EMUL, if uid not defined
|
||||
// if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) {
|
||||
//flags |= FLAG_UID_IN_EMUL;
|
||||
//}
|
||||
//flags |= FLAG_MF_1K;
|
||||
//if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) {
|
||||
// flags |= FLAG_UID_IN_EMUL;
|
||||
//}
|
||||
//flags = 0x10;
|
||||
uint16_t flags = 0;
|
||||
flags = 16;
|
||||
if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) {
|
||||
flags |= FLAG_UID_IN_EMUL;
|
||||
}
|
||||
flags |= FLAG_MF_1K;
|
||||
if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) {
|
||||
flags |= FLAG_UID_IN_EMUL;
|
||||
}
|
||||
flags = 0x10;
|
||||
*/
|
||||
uint16_t flags = FLAG_UID_IN_EMUL;
|
||||
DbprintfEx(FLAG_NEWLINE, "\n\n\n\n\n\n\n\nn\n\nn\n\n\nflags: %d (0x%02x)", flags, flags);
|
||||
cjSetCursLeft();
|
||||
SpinOff(1000);
|
||||
|
@ -794,8 +783,6 @@ readysim:
|
|||
* - tracing is falsed
|
||||
*/
|
||||
int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
|
||||
DBGLEVEL = DBG_NONE;
|
||||
|
||||
uint8_t numSectors = numofsectors;
|
||||
uint8_t keyType = keytype;
|
||||
|
||||
|
@ -807,7 +794,6 @@ int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
|
|||
uint8_t dataoutbuf2[16];
|
||||
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
|
||||
clear_trace();
|
||||
set_tracing(false);
|
||||
|
||||
|
@ -815,24 +801,17 @@ int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
|
|||
|
||||
if (!iso14443a_select_card(cjuid, &p_card, &cjcuid, true, 0, true)) {
|
||||
isOK = false;
|
||||
if (DBGLEVEL >= 1)
|
||||
DbprintfEx(FLAG_RAWPRINT, "Can't select card");
|
||||
}
|
||||
|
||||
for (uint8_t s = 0; isOK && s < numSectors; s++) {
|
||||
uint64_t ui64Key = emlGetKey(s, keyType);
|
||||
if (s == 0) {
|
||||
if (isOK && mifare_classic_auth(pcs, cjcuid, FirstBlockOfSector(s), keyType, ui64Key, AUTH_FIRST)) {
|
||||
|
||||
if (DBGLEVEL >= 1)
|
||||
DbprintfEx(FLAG_NEWLINE, "Sector[%2d]. Auth error", s);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (isOK && mifare_classic_auth(pcs, cjcuid, FirstBlockOfSector(s), keyType, ui64Key, AUTH_NESTED)) {
|
||||
isOK = false;
|
||||
if (DBGLEVEL >= 1)
|
||||
DbprintfEx(FLAG_NEWLINE, "Sector[%2d]. Auth nested error", s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -840,8 +819,6 @@ int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
|
|||
for (uint8_t blockNo = 0; isOK && blockNo < NumBlocksPerSector(s); blockNo++) {
|
||||
if (isOK && mifare_classic_readblock(pcs, cjcuid, FirstBlockOfSector(s) + blockNo, dataoutbuf)) {
|
||||
isOK = false;
|
||||
if (DBGLEVEL >= 1)
|
||||
DbprintfEx(FLAG_NEWLINE, "Error reading sector %2d block %2d", s, blockNo);
|
||||
break;
|
||||
};
|
||||
if (isOK) {
|
||||
|
@ -857,23 +834,18 @@ int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
|
|||
}
|
||||
}
|
||||
|
||||
if (mifare_classic_halt(pcs, cjcuid)) {
|
||||
if (DBGLEVEL >= 1)
|
||||
DbprintfEx(FLAG_NEWLINE, "Halt error");
|
||||
};
|
||||
int res = mifare_classic_halt(pcs, cjcuid);
|
||||
(void)res;
|
||||
|
||||
crypto1_deinit(pcs);
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
|
||||
return (isOK) ? PM3_SUCCESS : PM3_EUNDEF;
|
||||
}
|
||||
|
||||
/* the chk function is a piwi'ed(tm) check that will try all keys for
|
||||
a particular sector. also no tracing no dbg */
|
||||
int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, uint8_t keyCount, uint8_t *datain,
|
||||
uint64_t *key) {
|
||||
DBGLEVEL = DBG_NONE;
|
||||
int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace,
|
||||
uint8_t keyCount, uint8_t *datain, uint64_t *key) {
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
set_tracing(false);
|
||||
|
||||
|
@ -881,14 +853,16 @@ int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui
|
|||
struct Crypto1State *pcs;
|
||||
pcs = &mpcs;
|
||||
|
||||
for (int i = 0; i < keyCount; ++i) {
|
||||
int retval = -1;
|
||||
|
||||
for (uint8_t i = 0; i < keyCount; i++) {
|
||||
|
||||
/* no need for anticollision. just verify tag is still here */
|
||||
// if (!iso14443a_fast_select_card(cjuid, 0)) {
|
||||
if (!iso14443a_select_card(cjuid, &p_card, &cjcuid, true, 0, true)) {
|
||||
cjSetCursLeft();
|
||||
DbprintfEx(FLAG_NEWLINE, "%sFATAL%s : E_MF_LOSTTAG", _XRED_, _XWHITE_);
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
uint64_t ui64Key = bytes_to_num(datain + i * 6, 6);
|
||||
|
@ -899,15 +873,13 @@ int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui
|
|||
SpinDelayUs(AUTHENTICATION_TIMEOUT);
|
||||
continue;
|
||||
}
|
||||
crypto1_deinit(pcs);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
*key = ui64Key;
|
||||
return i;
|
||||
retval = i;
|
||||
break;
|
||||
}
|
||||
crypto1_deinit(pcs);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
|
||||
return -1;
|
||||
return retval;
|
||||
}
|
||||
|
||||
void saMifareMakeTag(void) {
|
||||
|
@ -925,7 +897,6 @@ void saMifareMakeTag(void) {
|
|||
int flags = 0;
|
||||
for (int blockNum = 0; blockNum < 16 * 4; blockNum++) {
|
||||
uint8_t mblock[16];
|
||||
// cnt = 0;
|
||||
emlGetMem(mblock, blockNum, 1);
|
||||
// switch on field and send magic sequence
|
||||
if (blockNum == 0)
|
||||
|
@ -940,21 +911,15 @@ void saMifareMakeTag(void) {
|
|||
flags = 0x04 + 0x10;
|
||||
|
||||
if (saMifareCSetBlock(0, flags & 0xFE, blockNum, mblock)) {
|
||||
//&& cnt <= retry) {
|
||||
// cnt++;
|
||||
cjSetCursFRight();
|
||||
if (currfline > 53) {
|
||||
currfline = 54;
|
||||
}
|
||||
DbprintfEx(FLAG_NEWLINE, "Block :%02x %sOK%s", blockNum, _XGREEN_, _XWHITE_);
|
||||
// DbprintfEx(FLAG_RAWPRINT,"FATAL:E_MF_CHINESECOOK_NORICE");
|
||||
// cfail=1;
|
||||
// return;
|
||||
continue;
|
||||
} else {
|
||||
cjSetCursLeft();
|
||||
cjSetCursLeft();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "`--> %sFAIL%s : CHN_FAIL_BLK_%02x_NOK", _XRED_, _XWHITE_, blockNum);
|
||||
cjSetCursFRight();
|
||||
DbprintfEx(FLAG_NEWLINE, "%s>>>>%s STOP AT %02x", _XRED_, _XWHITE_, blockNum);
|
||||
|
@ -962,14 +927,9 @@ void saMifareMakeTag(void) {
|
|||
break;
|
||||
}
|
||||
cjSetCursFRight();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "%s>>>>>>>> END <<<<<<<<%s", _XYELLOW_, _XWHITE_);
|
||||
// break;
|
||||
/*if (cfail == 1) {
|
||||
DbprintfEx(FLAG_RAWPRINT,"FATAL: E_MF_HARA_KIRI_\r\n");
|
||||
break;
|
||||
} */
|
||||
}
|
||||
|
||||
if (cfail == 0) {
|
||||
SpinUp(50);
|
||||
SpinUp(50);
|
||||
|
|
|
@ -49,19 +49,16 @@ on a blank card.
|
|||
#include "mifaresim.h" // mifare1ksim
|
||||
#include "mifareutil.h"
|
||||
|
||||
uint8_t uid[10];
|
||||
uint32_t cuid;
|
||||
iso14a_card_select_t p_card;
|
||||
static uint8_t uid[10];
|
||||
static uint32_t cuid;
|
||||
static iso14a_card_select_t p_card;
|
||||
|
||||
/*
|
||||
Pseudo-configuration block.
|
||||
*/
|
||||
bool printKeys = false; // Prints keys
|
||||
bool transferToEml = true; // Transfer keys to emulator memory
|
||||
bool ecfill = true; // Fill emulator memory with cards content.
|
||||
bool simulation = true; // Simulates an exact copy of the target tag
|
||||
bool fillFromEmulator = false; // Dump emulator memory.
|
||||
uint8_t stKeyBlock = 20; // Set the quantity of keys in the block.
|
||||
// Pseudo-configuration block.
|
||||
static bool printKeys = false; // Prints keys
|
||||
static bool transferToEml = true; // Transfer keys to emulator memory
|
||||
static bool ecfill = true; // Fill emulator memory with cards content.
|
||||
static bool simulation = true; // Simulates an exact copy of the target tag
|
||||
static bool fillFromEmulator = false; // Dump emulator memory.
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Matt's StandAlone mod.
|
||||
|
@ -179,7 +176,8 @@ static int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_
|
|||
|
||||
/* the chk function is a piwi’ed(tm) check that will try all keys for
|
||||
a particular sector. also no tracing no dbg */
|
||||
static int saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, uint8_t keyCount, uint8_t *datain, uint64_t *key) {
|
||||
static int saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace,
|
||||
uint8_t keyCount, uint8_t *datain, uint64_t *key) {
|
||||
DBGLEVEL = DBG_NONE;
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
set_tracing(false);
|
||||
|
@ -188,13 +186,15 @@ static int saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui
|
|||
struct Crypto1State *pcs;
|
||||
pcs = &mpcs;
|
||||
|
||||
for (int i = 0; i < keyCount; ++i) {
|
||||
int retval = -1;
|
||||
|
||||
for (uint8_t i = 0; i < keyCount; i++) {
|
||||
|
||||
/* no need for anticollision. just verify tag is still here */
|
||||
// if (!iso14443a_fast_select_card(cjuid, 0)) {
|
||||
if (!iso14443a_select_card(uid, &p_card, &cuid, true, 0, true)) {
|
||||
DbprintfEx(FLAG_NEWLINE, "FATAL : E_MF_LOSTTAG");
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
uint64_t ui64Key = bytes_to_num(datain + i * 6, 6);
|
||||
|
@ -205,45 +205,111 @@ static int saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui
|
|||
SpinDelayUs(AUTHENTICATION_TIMEOUT);
|
||||
continue;
|
||||
}
|
||||
crypto1_deinit(pcs);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
*key = ui64Key;
|
||||
return i;
|
||||
retval = i;
|
||||
break;
|
||||
}
|
||||
crypto1_deinit(pcs);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
|
||||
return -1;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Abusive microgain on original MifareECardLoad :
|
||||
* - *datain used as error return
|
||||
* - tracing is falsed
|
||||
*/
|
||||
static int saMifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
|
||||
DBGLEVEL = DBG_NONE;
|
||||
|
||||
uint8_t numSectors = numofsectors;
|
||||
uint8_t keyType = keytype;
|
||||
|
||||
struct Crypto1State mpcs = {0, 0};
|
||||
struct Crypto1State *pcs;
|
||||
pcs = &mpcs;
|
||||
|
||||
uint8_t dataoutbuf[16];
|
||||
uint8_t dataoutbuf2[16];
|
||||
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
clear_trace();
|
||||
set_tracing(false);
|
||||
|
||||
int retval = PM3_SUCCESS;
|
||||
|
||||
if (!iso14443a_select_card(uid, &p_card, &cuid, true, 0, true)) {
|
||||
retval = PM3_ESOFT;
|
||||
DbprintfEx(FLAG_RAWPRINT, "Can't select card");
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (uint8_t s = 0; s < numSectors; s++) {
|
||||
uint64_t ui64Key = emlGetKey(s, keyType);
|
||||
if (s == 0) {
|
||||
if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(s), keyType, ui64Key, AUTH_FIRST)) {
|
||||
retval = PM3_ESOFT;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(s), keyType, ui64Key, AUTH_NESTED)) {
|
||||
retval = PM3_ESOFT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// failure to read one block, skips to next sector.
|
||||
for (uint8_t blockNo = 0; blockNo < NumBlocksPerSector(s); blockNo++) {
|
||||
if (mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(s) + blockNo, dataoutbuf)) {
|
||||
retval = PM3_ESOFT;
|
||||
break;
|
||||
};
|
||||
|
||||
if (blockNo < NumBlocksPerSector(s) - 1) {
|
||||
emlSetMem(dataoutbuf, FirstBlockOfSector(s) + blockNo, 1);
|
||||
} else {
|
||||
// sector trailer, keep the keys, set only the AC
|
||||
emlGetMem(dataoutbuf2, FirstBlockOfSector(s) + blockNo, 1);
|
||||
memcpy(&dataoutbuf2[6], &dataoutbuf[6], 4);
|
||||
emlSetMem(dataoutbuf2, FirstBlockOfSector(s) + blockNo, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int res = mifare_classic_halt(pcs, cuid);
|
||||
(void)res;
|
||||
|
||||
out:
|
||||
crypto1_deinit(pcs);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
void ModInfo(void) {
|
||||
DbpString(" HF Mifare sniff/clone - aka MattyRun (Matías A. Ré Medina)");
|
||||
}
|
||||
|
||||
/*
|
||||
It will check if the keys from the attacked tag are a subset from
|
||||
the hardcoded set of keys inside of the ARM. If this is the case
|
||||
then it will load the keys into the emulator memory and also the
|
||||
content of the victim tag, to finally simulate it.
|
||||
|
||||
Alternatively, it can be dumped into a blank card.
|
||||
|
||||
This source code has been tested only in Mifare 1k.
|
||||
|
||||
If you're using the proxmark connected to a device that has an OS, and you're not using the proxmark3 client to see the debug
|
||||
messages, you MUST uncomment usb_disable().
|
||||
*/
|
||||
void RunMod(void) {
|
||||
StandAloneMode();
|
||||
Dbprintf(">> Matty mifare chk/dump/sim a.k.a MattyRun Started <<");
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
|
||||
/*
|
||||
It will check if the keys from the attacked tag are a subset from
|
||||
the hardcoded set of keys inside of the ARM. If this is the case
|
||||
then it will load the keys into the emulator memory and also the
|
||||
content of the victim tag, to finally simulate it.
|
||||
|
||||
Alternatively, it can be dumped into a blank card.
|
||||
|
||||
This source code has been tested only in Mifare 1k.
|
||||
|
||||
If you're using the proxmark connected to a device that has an OS, and you're not using the proxmark3 client to see the debug
|
||||
messages, you MUST uncomment usb_disable().
|
||||
*/
|
||||
Dbprintf(">> Matty mifare chk/dump/sim a.k.a MattyRun Started <<");
|
||||
|
||||
// Comment this line below if you want to see debug messages.
|
||||
// usb_disable();
|
||||
|
||||
|
||||
|
||||
uint16_t mifare_size = 1024; // Mifare 1k (only 1k supported for now)
|
||||
uint8_t sectorSize = 64; // 1k's sector size is 64 bytes.
|
||||
uint8_t blockNo = 3; // Security block is number 3 for each sector.
|
||||
|
@ -252,9 +318,7 @@ void RunMod(void) {
|
|||
uint8_t *keyBlock; // Where the keys will be held in memory.
|
||||
bool keyFound = false;
|
||||
|
||||
/*
|
||||
Set of keys to be used.
|
||||
*/
|
||||
// Set of keys to be used.
|
||||
uint64_t mfKeys[] = {
|
||||
0xffffffffffff, // Default key
|
||||
0x000000000000, // Blank key
|
||||
|
@ -269,22 +333,73 @@ void RunMod(void) {
|
|||
0xa0478cc39091,
|
||||
0x533cb6c723f6,
|
||||
0x8fd0a4f256e9,
|
||||
0x484558414354, // INFINEONON A / 0F SEC B / INTRATONE / HEXACT...
|
||||
0x414c41524f4e, // ALARON NORALSY
|
||||
0x424c41524f4e, // BLARON NORALSY
|
||||
0x4a6352684677, // COMELIT A General Key / 08 [2] 004
|
||||
0x536653644c65, // COMELIT B General Key / 08 [2] 004
|
||||
0x8829da9daf76, // URMET CAPTIV IF A => ALL A/B / BTICINO
|
||||
0x314B49474956, // "1KIGIV" VIGIK'S SERVICE BADGE A KEY
|
||||
0x021209197591, // BTCINO UNDETERMINED SPREAKD 0x01->0x13 key
|
||||
0x010203040506, // VIGIK's B Derivative
|
||||
0xa22ae129c013, // INFINEON B 00
|
||||
0x49fae4e3849f, // INFINEON B 01
|
||||
0x38fcf33072e0, // INFINEON B 02
|
||||
0x8ad5517b4b18, // INFINEON B 03
|
||||
0x509359f131b1, // INFINEON B 04
|
||||
0x6c78928e1317, // INFINEON B 05
|
||||
0xaa0720018738, // INFINEON B 06
|
||||
0xa6cac2886412, // INFINEON B 07
|
||||
0x62d0c424ed8e, // INFINEON B 08
|
||||
0xe64a986a5d94, // INFINEON B 09
|
||||
0x8fa1d601d0a2, // INFINEON B 0A
|
||||
0x89347350bd36, // INFINEON B 0B
|
||||
0x66d2b7dc39ef, // INFINEON B 0C
|
||||
0x6bc1e1ae547d, // INFINEON B 0D
|
||||
0x22729a9bd40f, // INFINEON B 0E
|
||||
0xd2ece8b9395e, // lib / Nat Bieb
|
||||
0x1494E81663D7, // # NSCP default key
|
||||
0x569369c5a0e5, // # kiev
|
||||
0x632193be1c3c, // # kiev
|
||||
0x644672bd4afe, // # kiev
|
||||
0x8fe644038790, // # kiev
|
||||
0x9de89e070277, // # kiev
|
||||
0xb5ff67cba951, // # kiev / ov-chipkaart
|
||||
0xeff603e1efe9, // # kiev
|
||||
0xf14ee7cae863, // # kiev
|
||||
0xfc00018778f7, // # Västtrafiken KeyA, RKF ÖstgötaTrafiken KeyA
|
||||
0x0297927c0f77, // # Västtrafiken KeyA
|
||||
0x54726176656c, // # Västtrafiken KeyA
|
||||
0x00000ffe2488, // # Västtrafiken KeyB
|
||||
0x776974687573, // # Västtrafiken KeyB
|
||||
0xee0042f88840, // # Västtrafiken KeyB
|
||||
0x26940b21ff5d, // # RKF SLKeyA
|
||||
0xa64598a77478, // # RKF SLKeyA
|
||||
0x5c598c9c58b5, // # RKF SLKeyB
|
||||
0xe4d2770a89be, // # RKF SLKeyB
|
||||
0x722bfcc5375f, // # RKF RejskortDanmark KeyA
|
||||
0xf1d83f964314, // # RKF RejskortDanmark KeyB
|
||||
0x505249564141, // # RKF JOJOPRIVAKeyA
|
||||
0x505249564142, // # RKF JOJOPRIVAKeyB
|
||||
0x47524f555041, // # RKF JOJOGROUPKeyA
|
||||
0x47524f555042, // # RKF JOJOGROUPKeyB
|
||||
0x434f4d4d4f41, // # RKF JOJOGROUPKeyA
|
||||
0x434f4d4d4f42, // # RKF JOJOGROUPKeyB
|
||||
0x4b0b20107ccb, // # TNP3xxx
|
||||
};
|
||||
|
||||
/*
|
||||
This part allocates the byte representation of the
|
||||
keys in keyBlock's memory space .
|
||||
*/
|
||||
keyBlock = BigBuf_malloc(stKeyBlock * 6);
|
||||
keyBlock = BigBuf_malloc(ARRAYLEN(mfKeys) * 6);
|
||||
int mfKeysCnt = ARRAYLEN(mfKeys);
|
||||
|
||||
for (int mfKeyCounter = 0; mfKeyCounter < mfKeysCnt; mfKeyCounter++) {
|
||||
num_to_bytes(mfKeys[mfKeyCounter], 6, (uint8_t *)(keyBlock + mfKeyCounter * 6));
|
||||
}
|
||||
|
||||
/*
|
||||
Pretty print of the keys to be checked.
|
||||
*/
|
||||
// Pretty print of the keys to be checked.
|
||||
if (printKeys) {
|
||||
Dbprintf("[+] Printing mf keys");
|
||||
for (uint8_t keycnt = 0; keycnt < mfKeysCnt; keycnt++)
|
||||
|
@ -301,18 +416,19 @@ void RunMod(void) {
|
|||
*/
|
||||
bool validKey[2][40];
|
||||
uint8_t foundKey[2][40][6];
|
||||
for (uint16_t t = 0; t < 2; t++) {
|
||||
for (uint8_t i = 0; i < 2; i++) {
|
||||
for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
|
||||
validKey[t][sectorNo] = false;
|
||||
for (uint16_t i = 0; i < 6; i++) {
|
||||
foundKey[t][sectorNo][i] = 0xff;
|
||||
}
|
||||
validKey[i][sectorNo] = false;
|
||||
foundKey[i][sectorNo][0] = 0xFF;
|
||||
foundKey[i][sectorNo][1] = 0xFF;
|
||||
foundKey[i][sectorNo][2] = 0xFF;
|
||||
foundKey[i][sectorNo][3] = 0xFF;
|
||||
foundKey[i][sectorNo][4] = 0xFF;
|
||||
foundKey[i][sectorNo][5] = 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Iterates through each sector checking if there is a correct key.
|
||||
*/
|
||||
// Iterates through each sector checking if there is a correct key.
|
||||
bool err = 0;
|
||||
bool allKeysFound = true;
|
||||
uint32_t size = mfKeysCnt;
|
||||
|
@ -324,7 +440,7 @@ void RunMod(void) {
|
|||
int key = saMifareChkKeys(block, type, true, size, &keyBlock[0], &key64);
|
||||
if (key == -1) {
|
||||
LED(LED_RED, 50);
|
||||
Dbprintf("\t✕ Key not found for this sector!");
|
||||
Dbprintf("\t [✕] Key not found for this sector!");
|
||||
allKeysFound = false;
|
||||
// break;
|
||||
} else if (key == -2) {
|
||||
|
@ -334,7 +450,7 @@ void RunMod(void) {
|
|||
num_to_bytes(key64, 6, foundKey[type][sec]);
|
||||
validKey[type][sec] = true;
|
||||
keyFound = true;
|
||||
Dbprintf("\t✓ Found valid key: [%02x%02x%02x%02x%02x%02x]\n",
|
||||
Dbprintf("\t [✓] Found valid key: [%02x%02x%02x%02x%02x%02x]\n",
|
||||
(keyBlock + 6 * key)[0], (keyBlock + 6 * key)[1], (keyBlock + 6 * key)[2],
|
||||
(keyBlock + 6 * key)[3], (keyBlock + 6 * key)[4], (keyBlock + 6 * key)[5]
|
||||
);
|
||||
|
@ -371,8 +487,9 @@ void RunMod(void) {
|
|||
emlClearMem();
|
||||
|
||||
uint8_t mblock[16];
|
||||
for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
|
||||
for (uint8_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
|
||||
if (validKey[0][sectorNo] || validKey[1][sectorNo]) {
|
||||
|
||||
emlGetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1); // data, block num, blocks count (max 4)
|
||||
for (uint16_t t = 0; t < 2; t++) {
|
||||
if (validKey[t][sectorNo]) {
|
||||
|
@ -382,47 +499,40 @@ void RunMod(void) {
|
|||
emlSetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1);
|
||||
}
|
||||
}
|
||||
Dbprintf("\t✓ Found keys have been transferred to the emulator memory.");
|
||||
|
||||
Dbprintf("\t [✓] Found keys have been transferred to the emulator memory.");
|
||||
|
||||
if (ecfill) {
|
||||
int filled;
|
||||
Dbprintf("\tFilling in with key A.");
|
||||
filled = MifareECardLoad(sectorsCnt, 0);
|
||||
if (filled != PM3_SUCCESS) {
|
||||
Dbprintf("\t✕ Failed filling with A.");
|
||||
}
|
||||
|
||||
Dbprintf("\tFilling in with key B.");
|
||||
filled = MifareECardLoad(sectorsCnt, 1);
|
||||
filled = saMifareECardLoad(sectorsCnt, 0);
|
||||
if (filled != PM3_SUCCESS) {
|
||||
Dbprintf("\t✕ Failed filling with B.");
|
||||
|
||||
Dbprintf("\t [✕] Failed filling with A.");
|
||||
Dbprintf("\tFilling in with key B.");
|
||||
filled = saMifareECardLoad(sectorsCnt, 1);
|
||||
if (filled != PM3_SUCCESS) {
|
||||
Dbprintf("\t [✕] Failed filling with B.");
|
||||
}
|
||||
}
|
||||
|
||||
if ((filled == PM3_SUCCESS) && simulation) {
|
||||
Dbprintf("\t✓ Emulator memory filled, simulation started.");
|
||||
Dbprintf("\t [✓] Emulator memory filled, simulation started.");
|
||||
|
||||
// This will tell the fpga to emulate using previous keys and current target tag content.
|
||||
Dbprintf("\t Press button to abort simulation at anytime.");
|
||||
|
||||
LED_B_ON(); // green
|
||||
// assuming arg0==0, use hardcoded uid 0xdeadbeaf
|
||||
uint16_t simflags;
|
||||
switch (p_card.uidlen) {
|
||||
case 10:
|
||||
simflags = FLAG_10B_UID_IN_DATA;
|
||||
break;
|
||||
case 7:
|
||||
simflags = FLAG_7B_UID_IN_DATA;
|
||||
break;
|
||||
default:
|
||||
simflags = FLAG_4B_UID_IN_DATA;
|
||||
break;
|
||||
}
|
||||
Mifare1ksim(simflags | FLAG_MF_1K, 0, uid, 0, 0);
|
||||
LED_B_OFF();
|
||||
|
||||
/*
|
||||
Needs further testing.
|
||||
*/
|
||||
uint16_t simflags = FLAG_UID_IN_EMUL | FLAG_MF_1K;
|
||||
|
||||
SpinOff(1000);
|
||||
Mifare1ksim(simflags, 0, uid, 0, 0);
|
||||
LED_B_OFF();
|
||||
Dbprintf("\t [✓] Simulation ended");
|
||||
|
||||
// Needs further testing.
|
||||
if (fillFromEmulator) {
|
||||
uint8_t retry = 5;
|
||||
Dbprintf("\t Trying to dump into blank card.");
|
||||
|
@ -457,8 +567,10 @@ void RunMod(void) {
|
|||
}
|
||||
|
||||
}
|
||||
} else if (filled != PM3_SUCCESS) {
|
||||
Dbprintf("\t✕ Emulator memory could not be filled due to errors.");
|
||||
}
|
||||
|
||||
if (filled != PM3_SUCCESS) {
|
||||
Dbprintf("\t [✕] Emulator memory could not be filled due to errors.");
|
||||
LED_C_ON();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ void ModInfo(void) {
|
|||
* technologies. Be brave enough to share your knowledge & inspire others. Salvador Mendoza.
|
||||
*/
|
||||
|
||||
uint8_t ppdol [255] = {0x80, 0xA8, 0x00, 0x00, 0x02, 0x83, 0x00}; // Default GET PROCESSING
|
||||
static uint8_t ppdol [255] = {0x80, 0xA8, 0x00, 0x00, 0x02, 0x83, 0x00}; // Default GET PROCESSING
|
||||
|
||||
static uint8_t treatPDOL(uint8_t *apdu) { //Generate GET PROCESSING
|
||||
uint8_t plen = 7;
|
||||
|
@ -119,7 +119,7 @@ static uint8_t treatPDOL(uint8_t *apdu) { //Generate GET PROCES
|
|||
|
||||
void RunMod(void) {
|
||||
StandAloneMode();
|
||||
Dbprintf(_YELLOW_(">>") "Reading Visa cards & Emulating a Visa MSD Transaction a.k.a. MSDSal Started<<");
|
||||
DbpString(_YELLOW_(">>") "Reading Visa cards & Emulating a Visa MSD Transaction a.k.a. MSDSal Started " _YELLOW_("<<"));
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
|
||||
//For reading process
|
||||
|
@ -206,10 +206,10 @@ void RunMod(void) {
|
|||
//Checking if the user wants to go directly to emulation mode using a hardcoded track 2
|
||||
if (chktoken == true && token[0] != 0x00) {
|
||||
state = STATE_EMU;
|
||||
Dbprintf(_YELLOW_("[") "Initialized emulation mode " _YELLOW_("]"));
|
||||
DbpString(_YELLOW_("[ ") "Initialized emulation mode" _YELLOW_(" ]"));
|
||||
DbpString("\n"_YELLOW_("!!") "Waiting for a card reader...");
|
||||
} else {
|
||||
DbpString(_YELLOW_("[") "Initialized reading mode " _YELLOW_("]"));
|
||||
DbpString(_YELLOW_("[ ") "Initialized reading mode" _YELLOW_(" ]"));
|
||||
DbpString("\n"_YELLOW_("!!") "Waiting for a Visa card...");
|
||||
}
|
||||
|
||||
|
@ -228,12 +228,12 @@ void RunMod(void) {
|
|||
if (state == STATE_READ) {
|
||||
if (chktoken == true && token[0] != 0x00) { //Only change to emulation if it saved a track 2 in memory
|
||||
state = STATE_EMU;
|
||||
Dbprintf(_YELLOW_("[") "In emulation mode " _YELLOW_("]"));
|
||||
DbpString(_YELLOW_("[ ") "In emulation mode" _YELLOW_(" ]"));
|
||||
} else
|
||||
Dbprintf(_YELLOW_("!!") "Nothing in memory to emulate");
|
||||
DbpString(_YELLOW_("!!") "Nothing in memory to emulate");
|
||||
} else {
|
||||
state = STATE_READ;
|
||||
Dbprintf(_YELLOW_("[") "In reading mode " _YELLOW_("]"));
|
||||
DbpString(_YELLOW_("[ ") "In reading mode" _YELLOW_(" ]"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -248,7 +248,7 @@ void RunMod(void) {
|
|||
|
||||
if (iso14443a_select_card(NULL, &card_a_info, NULL, true, 0, false)) {
|
||||
|
||||
Dbprintf(_YELLOW_("+") "Found ISO 14443 Type A!");
|
||||
DbpString(_YELLOW_("+") "Found ISO 14443 Type A!");
|
||||
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
chktoken = false;
|
||||
|
@ -257,11 +257,11 @@ void RunMod(void) {
|
|||
uint8_t apdulen = iso14_apdu(apdus[i], (uint16_t) apdusLen[i], false, apdubuffer, NULL);
|
||||
|
||||
if (apdulen > 0) {
|
||||
Dbprintf(_YELLOW_("[") "Proxmark command " _YELLOW_("]"));
|
||||
DbpString(_YELLOW_("[ ") "Proxmark command" _YELLOW_(" ]"));
|
||||
Dbhexdump(apdusLen[i], apdus[i], false);
|
||||
Dbprintf(_GREEN_("[") "Card answer " _GREEN_("]"));
|
||||
DbpString(_GREEN_("[ ") "Card answer" _GREEN_(" ]"));
|
||||
Dbhexdump(apdulen - 2, apdubuffer, false);
|
||||
Dbprintf("----");
|
||||
DbpString("----");
|
||||
|
||||
for (uint8_t u = 0; u < apdulen; u++) {
|
||||
if (i == 1) {
|
||||
|
@ -284,24 +284,24 @@ void RunMod(void) {
|
|||
}
|
||||
|
||||
if (i == 1) {
|
||||
Dbprintf(_GREEN_("[") "Challenge generated " _GREEN_("]"));
|
||||
DbpString(_GREEN_("[ ") "Challenge generated" _GREEN_(" ]"));
|
||||
Dbhexdump(plen, existpdol ? ppdol : processing, false);
|
||||
}
|
||||
} else {
|
||||
Dbprintf(_YELLOW_("!!") "Error reading the card");
|
||||
DbpString(_YELLOW_("!!") "Error reading the card");
|
||||
}
|
||||
LED_B_OFF();
|
||||
}
|
||||
|
||||
if (chktoken) {
|
||||
Dbprintf(_RED_("[") "Track 2 " _RED_("]"));
|
||||
DbpString(_RED_("[ ") "Track 2" _RED_(" ]"));
|
||||
Dbhexdump(19, (uint8_t *)token, false);
|
||||
Dbprintf(_YELLOW_("!!") "Card number");
|
||||
DbpString(_YELLOW_("!!") "Card number");
|
||||
Dbhexdump(8, (uint8_t *)token, false);
|
||||
DbpString("---");
|
||||
LED_C_ON();
|
||||
state = STATE_EMU;
|
||||
Dbprintf(_YELLOW_("[") "Initialized emulation mode " _YELLOW_("]"));
|
||||
DbpString(_YELLOW_("[ ") "Initialized emulation mode" _YELLOW_(" ]"));
|
||||
DbpString("\n"_YELLOW_("!!") "Waiting for a card reader...");
|
||||
}
|
||||
}
|
||||
|
@ -318,7 +318,7 @@ void RunMod(void) {
|
|||
DbpString(_YELLOW_("!!") "Error initializing the emulation process!");
|
||||
SpinDelay(500);
|
||||
state = STATE_READ;
|
||||
DbpString(_YELLOW_("[") "Initialized reading mode " _YELLOW_("]"));
|
||||
DbpString(_YELLOW_("[ ") "Initialized reading mode" _YELLOW_(" ]"));
|
||||
DbpString("\n" _YELLOW_("!!") "Waiting for a Visa card...");
|
||||
break;
|
||||
}
|
||||
|
@ -336,7 +336,7 @@ void RunMod(void) {
|
|||
LED_B_OFF();
|
||||
// Clean receive command buffer
|
||||
if (!GetIso14443aCommandFromReader(receivedCmd, receivedCmdPar, &len)) {
|
||||
Dbprintf(_YELLOW_("!!") "Emulator stopped");
|
||||
DbpString(_YELLOW_("!!") "Emulator stopped");
|
||||
retval = PM3_EOPABORTED;
|
||||
break;
|
||||
}
|
||||
|
@ -367,7 +367,7 @@ void RunMod(void) {
|
|||
DbpString(_YELLOW_("+") "Request for RATS");
|
||||
p_response = &responses[RATS];
|
||||
} else {
|
||||
Dbprintf(_YELLOW_("[") "Card reader command " _YELLOW_("]"));
|
||||
DbpString(_YELLOW_("[ ") "Card reader command" _YELLOW_(" ]"));
|
||||
Dbhexdump(len, receivedCmd, false);
|
||||
|
||||
if (receivedCmd[0] == 0x02 || receivedCmd[0] == 0x03) { //Emulate a Visa MSD(Magnetic stripe data) card
|
||||
|
@ -408,7 +408,7 @@ void RunMod(void) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
Dbprintf(_YELLOW_("!!") "Received unknown command!");
|
||||
DbpString(_YELLOW_("!!") "Received unknown command!");
|
||||
if (prevCmd < 4) {
|
||||
memcpy(dynamic_response_info.response, receivedCmd, len);
|
||||
dynamic_response_info.response_n = len;
|
||||
|
@ -418,9 +418,9 @@ void RunMod(void) {
|
|||
}
|
||||
}
|
||||
if (dynamic_response_info.response_n > 0) {
|
||||
Dbprintf(_GREEN_("[") "Proxmark3 answer " _GREEN_("]"));
|
||||
DbpString(_GREEN_("[ ") "Proxmark3 answer" _GREEN_(" ]"));
|
||||
Dbhexdump(dynamic_response_info.response_n, dynamic_response_info.response, false);
|
||||
Dbprintf("----");
|
||||
DbpString("----");
|
||||
|
||||
// Add CRC bytes, always used in ISO 14443A-4 compliant cards
|
||||
AddCrc14A(dynamic_response_info.response, dynamic_response_info.response_n);
|
||||
|
|
|
@ -151,10 +151,10 @@ void RunMod(void) {
|
|||
SpinDelay(500);
|
||||
// Begin clone function here:
|
||||
/* Example from client/mifarehost.c for commanding a block write for "magic Chinese" cards:
|
||||
SendCommandOLD(CMD_HF_MIFARE_CSETBL, params & (0xFE | (uid == NULL ? 0:1)), blockNo, 0, data, 16);
|
||||
SendCommandMIX(CMD_HF_MIFARE_CSETBL, params & (0xFE | (uid == NULL ? 0:1)), blockNo, 0, data, 16);
|
||||
|
||||
Block read is similar:
|
||||
SendCommandOLD(CMD_HF_MIFARE_CGETBL, params, blockNo, 0,...};
|
||||
SendCommandMIX(CMD_HF_MIFARE_CGETBL, params, blockNo, 0,...};
|
||||
We need to imitate that call with blockNo 0 to set a uid.
|
||||
|
||||
The get and set commands are handled in this file:
|
||||
|
|
|
@ -25,11 +25,9 @@
|
|||
|
||||
// low & high - array for storage IDs. Its length must be equal.
|
||||
// Predefined IDs must be stored in low[].
|
||||
// In high[] must be nulls
|
||||
uint64_t low[] = {0x565A1140BE, 0x365A398149, 0x5555555555, 0xFFFFFFFFFF};
|
||||
uint32_t high[] = {0, 0, 0, 0};
|
||||
uint8_t *bba, slots_count;
|
||||
int buflen;
|
||||
static uint64_t low[] = {0x565A1140BE, 0x365A398149, 0x5555555555, 0xFFFFFFFFFF};
|
||||
static uint8_t *bba, slots_count;
|
||||
static int buflen;
|
||||
|
||||
void ModInfo(void) {
|
||||
DbpString(" LF EM4100 simulator standalone mode");
|
||||
|
|
|
@ -39,10 +39,10 @@
|
|||
// low & high - array for storage IDs. Its length must be equal.
|
||||
// Predefined IDs must be stored in low[].
|
||||
// In high[] must be nulls
|
||||
uint64_t low[] = {0x565AF781C7, 0x540053E4E2, 0x1234567890, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
uint32_t high[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
uint8_t *bba, slots_count;
|
||||
int buflen;
|
||||
static uint64_t low[] = {0x565AF781C7, 0x540053E4E2, 0x1234567890, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
static uint32_t high[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
static uint8_t *bba, slots_count;
|
||||
static int buflen;
|
||||
|
||||
void ModInfo(void) {
|
||||
DbpString(" LF EM4100 read/write/clone mode");
|
||||
|
@ -161,7 +161,7 @@ void RunMod(void) {
|
|||
state = 3;
|
||||
} else if (button_pressed == BUTTON_SINGLE_CLICK) {
|
||||
// Click - exit to select mode
|
||||
CmdEM410xdemod(1, &high[selected], &low[selected], 0);
|
||||
CmdEM410xdemod(1, &high[selected], &low[selected]);
|
||||
FlashLEDs(100, 5);
|
||||
#ifdef WITH_FLASH
|
||||
SaveIDtoFlash(selected, low[selected]);
|
||||
|
|
|
@ -231,7 +231,8 @@ static uint32_t IceHIDDemod(void) {
|
|||
uint32_t hi2 = 0, hi = 0, lo = 0;
|
||||
|
||||
// large enough to catch 2 sequences of largest format
|
||||
size_t size = 50 * 128 * 2; // 12800 bytes
|
||||
// size_t size = 50 * 128 * 2; // 12800 bytes
|
||||
size_t size = MIN(12800, BigBuf_max_traceLen());
|
||||
//uint8_t *dest = BigBuf_malloc(size);
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
|
||||
|
@ -350,30 +351,32 @@ void RunMod(void) {
|
|||
|
||||
uint32_t res;
|
||||
|
||||
// since we steal 12800 from bigbuffer, no need to sample it.
|
||||
DoAcquisition_config(false, 28000);
|
||||
// since we steal 12800 from bigbuffer, no need to sample it.
|
||||
size_t size = MIN(28000, BigBuf_max_traceLen());
|
||||
DoAcquisition_config(false, size);
|
||||
res = IceHIDDemod();
|
||||
if (res == PM3_SUCCESS) {
|
||||
LED_A_OFF();
|
||||
continue;
|
||||
}
|
||||
|
||||
DoAcquisition_config(false, 28000);
|
||||
DoAcquisition_config(false, size);
|
||||
res = IceAWIDdemod();
|
||||
if (res == PM3_SUCCESS) {
|
||||
LED_A_OFF();
|
||||
continue;
|
||||
}
|
||||
|
||||
DoAcquisition_config(false, 20000);
|
||||
res = IceEM410xdemod();
|
||||
DoAcquisition_config(false, size);
|
||||
res = IceIOdemod();
|
||||
if (res == PM3_SUCCESS) {
|
||||
LED_A_OFF();
|
||||
continue;
|
||||
}
|
||||
|
||||
DoAcquisition_config(false, 28000);
|
||||
res = IceIOdemod();
|
||||
size = MIN(20000, BigBuf_max_traceLen());
|
||||
DoAcquisition_config(false, size);
|
||||
res = IceEM410xdemod();
|
||||
if (res == PM3_SUCCESS) {
|
||||
LED_A_OFF();
|
||||
continue;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue