mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 05:43:48 -07:00
chg: icehid now records HID/AWID/IO/EM4100..
This commit is contained in:
parent
8696b521ef
commit
9bf26c080d
1 changed files with 314 additions and 37 deletions
|
@ -11,13 +11,15 @@
|
|||
#include "proxmark3_arm.h"
|
||||
#include "appmain.h"
|
||||
#include "lfops.h"
|
||||
#include "lfsampling.h"
|
||||
#include "BigBuf.h"
|
||||
#include "fpgaloader.h"
|
||||
#include "util.h"
|
||||
#include "dbprint.h"
|
||||
#include "printf.h"
|
||||
#include "spiffs.h"
|
||||
#include "ticks.h"
|
||||
|
||||
#include "lfdemod.h"
|
||||
/*
|
||||
* `lf_hidcollect` sniffs after LF HID credentials, and stores them in internal
|
||||
* flash. It requires RDV4 hardware (for flash and battery).
|
||||
|
@ -50,6 +52,7 @@
|
|||
|
||||
#define LF_HIDCOLLECT_LOGFILE "lf_hidcollect.log"
|
||||
|
||||
|
||||
void DownloadLogInstructions() {
|
||||
Dbprintf("");
|
||||
Dbprintf("[=] To get the logfile from flash and display it:");
|
||||
|
@ -58,19 +61,291 @@ void DownloadLogInstructions() {
|
|||
Dbprintf("[=] " _YELLOW_("3.") "cat "LF_HIDCOLLECT_LOGFILE);
|
||||
}
|
||||
|
||||
bool log_exists;
|
||||
|
||||
void append(uint8_t* entry, size_t entry_len) {
|
||||
|
||||
LED_B_ON();
|
||||
if (log_exists == false) {
|
||||
rdv40_spiffs_write(LF_HIDCOLLECT_LOGFILE, entry, entry_len, RDV40_SPIFFS_SAFETY_SAFE);
|
||||
log_exists = true;
|
||||
} else {
|
||||
rdv40_spiffs_append(LF_HIDCOLLECT_LOGFILE, entry, entry_len, RDV40_SPIFFS_SAFETY_SAFE);
|
||||
}
|
||||
LED_B_OFF();
|
||||
}
|
||||
|
||||
uint32_t IceEM410xdemod() {
|
||||
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
size_t idx = 0;
|
||||
int clk = 0, invert = 0, maxErr = 20;
|
||||
uint32_t hi = 0;
|
||||
uint64_t lo = 0;
|
||||
|
||||
size_t size = MIN(16385, BigBuf_max_traceLen());
|
||||
|
||||
//askdemod and manchester decode
|
||||
int errCnt = askdemod(dest, &size, &clk, &invert, maxErr, 0, 1);
|
||||
|
||||
WDT_HIT();
|
||||
|
||||
if (errCnt > 50) {
|
||||
BigBuf_free();
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
errCnt = Em410xDecode(dest, &size, &idx, &hi, &lo);
|
||||
if (errCnt != 1) {
|
||||
BigBuf_free();
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
uint8_t entry[60];
|
||||
memset(entry, 0, sizeof(entry));
|
||||
|
||||
if (size == 128) {
|
||||
sprintf((char *)entry, "EM XL TAG ID: %06lx%08lx%08lx - (%05ld_%03ld_%08ld)",
|
||||
hi,
|
||||
(uint32_t)(lo >> 32),
|
||||
(uint32_t)lo,
|
||||
(uint32_t)(lo & 0xFFFF),
|
||||
(uint32_t)((lo >> 16LL) & 0xFF),
|
||||
(uint32_t)(lo & 0xFFFFFF));
|
||||
} else {
|
||||
sprintf((char *)entry, "EM TAG ID: %02lx%08lx - (%05ld_%03ld_%08ld)",
|
||||
(uint32_t)(lo >> 32),
|
||||
(uint32_t)lo,
|
||||
(uint32_t)(lo & 0xFFFF),
|
||||
(uint32_t)((lo >> 16LL) & 0xFF),
|
||||
(uint32_t)(lo & 0xFFFFFF));
|
||||
}
|
||||
|
||||
append(entry, strlen((char*)entry));
|
||||
Dbprintf("strlen %d", strlen((char*)entry));
|
||||
|
||||
Dbprintf("%s", entry);
|
||||
BigBuf_free();
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t IceAWIDdemod() {
|
||||
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
size_t size = MIN(12800, BigBuf_max_traceLen());
|
||||
int dummyIdx = 0;
|
||||
|
||||
//askdemod and manchester decode
|
||||
int idx = detectAWID(dest, &size, &dummyIdx);
|
||||
|
||||
if (idx <= 0 || size != 96) {
|
||||
BigBuf_free();
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
//get raw ID before removing parities
|
||||
uint32_t rawLo = bytebits_to_byte(dest + idx + 64, 32);
|
||||
uint32_t rawHi = bytebits_to_byte(dest + idx + 32, 32);
|
||||
uint32_t rawHi2 = bytebits_to_byte(dest + idx, 32);
|
||||
|
||||
size = removeParity(dest, idx + 8, 4, 1, 88);
|
||||
if (size != 66) {
|
||||
BigBuf_free();
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
uint8_t entry[110];
|
||||
memset(entry, 0, sizeof(entry));
|
||||
|
||||
uint8_t fmtLen = bytebits_to_byte(dest, 8);
|
||||
if (fmtLen == 26) {
|
||||
uint8_t fac = bytebits_to_byte(dest + 9, 8);
|
||||
uint32_t cardnum = bytebits_to_byte(dest + 17, 16);
|
||||
uint32_t code1 = bytebits_to_byte(dest + 8, fmtLen);
|
||||
sprintf((char *)entry, "AWID bit len: %d, FC: %d, Card: %ld - Wiegand: %lx, Raw: %08lx%08lx%08lx \n", fmtLen, fac, cardnum, code1, rawHi2, rawHi, rawLo);
|
||||
} else {
|
||||
uint32_t cardnum = bytebits_to_byte(dest + 8 + (fmtLen - 17), 16);
|
||||
if (fmtLen > 32) {
|
||||
uint32_t code1 = bytebits_to_byte(dest + 8, fmtLen - 32);
|
||||
uint32_t code2 = bytebits_to_byte(dest + 8 + (fmtLen - 32), 32);
|
||||
sprintf((char *)entry, "AWID bit len: %d -unk bit len - Card: %ld - Wiegand: %lx%08lx, Raw: %08lx%08lx%08lx \n", fmtLen, cardnum, code1, code2, rawHi2, rawHi, rawLo);
|
||||
} else {
|
||||
uint32_t code1 = bytebits_to_byte(dest + 8, fmtLen);
|
||||
sprintf((char *)entry, "AWID bit len: %d -unk bit len - Card: %ld - Wiegand: %lx, Raw: %08lx%08lx%08lx \n", fmtLen, cardnum, code1, rawHi2, rawHi, rawLo);
|
||||
}
|
||||
}
|
||||
|
||||
append(entry, strlen((char*)entry));
|
||||
Dbprintf("%s", entry);
|
||||
BigBuf_free();
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t IceIOdemod() {
|
||||
|
||||
int dummyIdx = 0;
|
||||
uint8_t version = 0, facilitycode = 0, crc = 0;
|
||||
uint16_t number = 0, calccrc = 0;
|
||||
uint32_t hi = 0, lo = 0;
|
||||
|
||||
size_t size = MIN(12000, BigBuf_max_traceLen());
|
||||
|
||||
// uint8_t *dest = BigBuf_malloc(size);
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
|
||||
//fskdemod and get start index
|
||||
int idx = detectIOProx(dest, &size, &dummyIdx);
|
||||
|
||||
if (idx < 0) {
|
||||
BigBuf_free();
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
hi = bytebits_to_byte(dest + idx, 32);
|
||||
lo = bytebits_to_byte(dest + idx + 32, 32);
|
||||
|
||||
version = bytebits_to_byte(dest + idx + 27, 8); //14,4
|
||||
facilitycode = bytebits_to_byte(dest + idx + 18, 8);
|
||||
number = (bytebits_to_byte(dest + idx + 36, 8) << 8) | (bytebits_to_byte(dest + idx + 45, 8)); //36,9
|
||||
|
||||
crc = bytebits_to_byte(dest + idx + 54, 8);
|
||||
for (uint8_t i = 1; i < 6; ++i)
|
||||
calccrc += bytebits_to_byte(dest + idx + 9 * i, 8);
|
||||
|
||||
calccrc &= 0xff;
|
||||
calccrc = 0xff - calccrc;
|
||||
|
||||
char *crcStr = (crc == calccrc) ? "ok" : "!crc";
|
||||
|
||||
uint8_t entry[64];
|
||||
memset(entry, 0, sizeof(entry));
|
||||
|
||||
sprintf((char *)entry, "IO Prox XSF(%02d)%02x:%05d (%08lx%08lx) [%02x %s] \n"
|
||||
, version
|
||||
, facilitycode
|
||||
, number
|
||||
, hi
|
||||
, lo
|
||||
, crc
|
||||
, crcStr
|
||||
);
|
||||
|
||||
append(entry, strlen((char*)entry));
|
||||
Dbprintf("%s", entry);
|
||||
|
||||
BigBuf_free();
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t IceHIDDemod() {
|
||||
|
||||
int dummyIdx = 0;
|
||||
|
||||
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
|
||||
//uint8_t *dest = BigBuf_malloc(size);
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
|
||||
// FSK demodulator
|
||||
int idx = HIDdemodFSK(dest, &size, &hi2, &hi, &lo, &dummyIdx);
|
||||
if (idx < 0) {
|
||||
BigBuf_free();
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
if ((size == 96 || size == 192)) {
|
||||
|
||||
uint8_t entry[80];
|
||||
memset(entry, 0, sizeof(entry));
|
||||
|
||||
// go over previously decoded manchester data and decode into usable tag ID
|
||||
if (hi2 != 0) { //extra large HID tags 88/192 bits
|
||||
|
||||
sprintf((char *)entry, "HID large: %lx%08lx%08lx (%ld) \n",
|
||||
hi2,
|
||||
hi,
|
||||
lo,
|
||||
(lo >> 1) & 0xFFFF
|
||||
);
|
||||
|
||||
append(entry, strlen((char*)entry));
|
||||
|
||||
} else { //standard HID tags 44/96 bits
|
||||
uint8_t bitlen = 0;
|
||||
uint32_t fac = 0;
|
||||
uint32_t cardnum = 0;
|
||||
|
||||
if (((hi >> 5) & 1) == 1) { //if bit 38 is set then < 37 bit format is used
|
||||
uint32_t lo2 = 0;
|
||||
lo2 = (((hi & 31) << 12) | (lo >> 20)); //get bits 21-37 to check for format len bit
|
||||
uint8_t idx3 = 1;
|
||||
while (lo2 > 1) { //find last bit set to 1 (format len bit)
|
||||
lo2 >>= 1;
|
||||
idx3++;
|
||||
}
|
||||
bitlen = idx3 + 19;
|
||||
fac = 0;
|
||||
cardnum = 0;
|
||||
if (bitlen == 26) {
|
||||
cardnum = (lo >> 1) & 0xFFFF;
|
||||
fac = (lo >> 17) & 0xFF;
|
||||
}
|
||||
if (bitlen == 37) {
|
||||
cardnum = (lo >> 1) & 0x7FFFF;
|
||||
fac = ((hi & 0xF) << 12) | (lo >> 20);
|
||||
}
|
||||
if (bitlen == 34) {
|
||||
cardnum = (lo >> 1) & 0xFFFF;
|
||||
fac = ((hi & 1) << 15) | (lo >> 17);
|
||||
}
|
||||
if (bitlen == 35) {
|
||||
cardnum = (lo >> 1) & 0xFFFFF;
|
||||
fac = ((hi & 1) << 11) | (lo >> 21);
|
||||
}
|
||||
} else { //if bit 38 is not set then 37 bit format is used
|
||||
bitlen = 37;
|
||||
cardnum = (lo >> 1) & 0x7FFFF;
|
||||
fac = ((hi & 0xF) << 12) | (lo >> 20);
|
||||
}
|
||||
|
||||
sprintf((char *)entry, "HID: %lx%08lx (%ld) Format: %d bit FC: %ld Card: %ld \n",
|
||||
hi,
|
||||
lo,
|
||||
(lo >> 1) & 0xFFFF,
|
||||
bitlen,
|
||||
fac,
|
||||
cardnum
|
||||
);
|
||||
|
||||
append(entry, strlen((char*)entry));
|
||||
}
|
||||
|
||||
Dbprintf("%s", entry);
|
||||
}
|
||||
|
||||
BigBuf_free();
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
void ModInfo(void) {
|
||||
DbpString(" LF HID collector mode - a.k.a IceHID (Iceman)");
|
||||
DbpString(" LF HID / IOprox / AWID / EM4100 collector mode - a.k.a IceHID (Iceman)");
|
||||
}
|
||||
|
||||
void RunMod() {
|
||||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
LFSetupFPGAForADC(LF_DIVISOR_125, true);
|
||||
BigBuf_Clear();
|
||||
|
||||
StandAloneMode();
|
||||
|
||||
Dbprintf("[=] LF HID collector a.k.a IceHID started");
|
||||
|
||||
rdv40_spiffs_lazy_mount();
|
||||
|
||||
bool log_exists = exists_in_spiffs(LF_HIDCOLLECT_LOGFILE);
|
||||
log_exists = exists_in_spiffs(LF_HIDCOLLECT_LOGFILE);
|
||||
|
||||
// the main loop for your standalone mode
|
||||
for (;;) {
|
||||
|
@ -85,42 +360,44 @@ void RunMod() {
|
|||
break;
|
||||
|
||||
LED_A_ON();
|
||||
// findone, high, low,
|
||||
uint32_t hi = 0, lo = 0;
|
||||
CmdHIDdemodFSK(1, &hi, &lo, 0);
|
||||
|
||||
uint32_t res;
|
||||
|
||||
// since we steal 12800 from bigbuffer, no need to sample it.
|
||||
DoAcquisition_config(false, 28000);
|
||||
res = IceHIDDemod();
|
||||
if (res == PM3_SUCCESS) {
|
||||
LED_A_OFF();
|
||||
|
||||
//didn't collect any, loop
|
||||
if (hi == 0 && lo == 0)
|
||||
continue;
|
||||
|
||||
uint8_t entry[20];
|
||||
memset(entry, 0, sizeof(entry));
|
||||
sprintf((char *)entry, "%lx%08lx\n", hi, lo);
|
||||
|
||||
LED_B_ON();
|
||||
if (!log_exists) {
|
||||
rdv40_spiffs_write(LF_HIDCOLLECT_LOGFILE, entry, sizeof(entry), RDV40_SPIFFS_SAFETY_SAFE);
|
||||
log_exists = true;
|
||||
} else {
|
||||
rdv40_spiffs_append(LF_HIDCOLLECT_LOGFILE, entry, sizeof(entry), RDV40_SPIFFS_SAFETY_SAFE);
|
||||
}
|
||||
LED_B_OFF();
|
||||
|
||||
SpinErr(LED_A, 250, 2);
|
||||
DoAcquisition_config(false, 28000);
|
||||
res = IceAWIDdemod();
|
||||
if (res == PM3_SUCCESS) {
|
||||
LED_A_OFF();
|
||||
continue;
|
||||
}
|
||||
|
||||
DoAcquisition_config(false, 20000);
|
||||
res = IceEM410xdemod();
|
||||
if (res == PM3_SUCCESS) {
|
||||
LED_A_OFF();
|
||||
continue;
|
||||
}
|
||||
|
||||
DoAcquisition_config(false, 28000);
|
||||
res = IceIOdemod();
|
||||
if (res == PM3_SUCCESS) {
|
||||
LED_A_OFF();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
LED_C_ON();
|
||||
rdv40_spiffs_lazy_unmount();
|
||||
LED_C_OFF();
|
||||
|
||||
SpinErr(LED_A, 200, 5);
|
||||
SpinDelay(100);
|
||||
|
||||
LEDsoff();
|
||||
SpinDelay(300);
|
||||
DownloadLogInstructions();
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue