mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-05-12 11:18:11 -07:00
Merge pull request #3176 from Antiklesys/master
Added `hf iclass tagsim` command and `--live` `hf iclass lookup`
This commit is contained in:
@@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file.
|
||||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||
|
||||
## [unreleased][unreleased]
|
||||
- Improved SIO parsing for `hf iclass view` based on Iceman's "Dismantling the SEOS Protocol" talk (@antiklesys)
|
||||
- Added live fc/cn update to `hf iclass tagsim` refreshing the csn with each update (@antiklesys)
|
||||
- Added `--live` option to `hf iclass lookup` command to perform a live recovery of the reader's key by simulating a tag and running the lookup command against both standard and elite dictionaries (@antiklesys)
|
||||
- Added `hf iclass tagsim` command to quickly simulate an iclass card based on facility code and card number(@antiklesys)
|
||||
- Added `-f` parameter to `hf iclass sam` command to use the sam to parse a card dump (@antiklesys)
|
||||
- Fixed WTX response behavior in `ExchangeRaw14A()` (@team-orangeBlue)
|
||||
- Added `-t` / `--timeout` option for `hf 15 sim` (@recursivenomad)
|
||||
|
||||
@@ -500,6 +500,27 @@ int do_iclass_simulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||
|
||||
uint32_t reader_eof_time = 0;
|
||||
len = GetIso15693CommandFromReader(receivedCmd, MAX_FRAME_SIZE, &reader_eof_time);
|
||||
if (len == -2) {
|
||||
// USB data arrived while waiting for RF — drain all pending EML_MEMSET
|
||||
// commands inline (without FpgaDownloadAndGo) so live tag updates work.
|
||||
PacketCommandNG rx;
|
||||
while (data_available()) {
|
||||
if (receive_ng(&rx) != PM3_SUCCESS) break;
|
||||
if (rx.cmd == CMD_HF_ICLASS_EML_MEMSET) {
|
||||
struct p {
|
||||
uint16_t offset;
|
||||
uint16_t plen;
|
||||
uint8_t data[];
|
||||
} PACKED;
|
||||
struct p *payload = (struct p *) rx.data.asBytes;
|
||||
emlSet(payload->data, payload->offset, payload->plen);
|
||||
} else {
|
||||
exit_loop = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (len < 0) {
|
||||
button_pressed = true;
|
||||
exit_loop = true;
|
||||
@@ -512,6 +533,45 @@ int do_iclass_simulation(int simulationMode, uint8_t *reader_mac_buf) {
|
||||
block = receivedCmd[1];
|
||||
|
||||
if (cmd == ICLASS_CMD_ACTALL && len == 1) { // 0x0A
|
||||
|
||||
// Check for a live tag-identity reload requested by the client.
|
||||
// The client writes a non-zero byte to emulator offset 32*8 = 256
|
||||
// (one byte past the 32-block tag data) then updates blocks 0, 3, 4, 6-9
|
||||
// in emulator memory. We pick it up at the start of each anti-collision
|
||||
// cycle so the reader sees the new identity from the very first SELECT.
|
||||
if ((simulationMode == ICLASS_SIM_MODE_FULL ||
|
||||
simulationMode == ICLASS_SIM_MODE_FULL_GLITCH ||
|
||||
simulationMode == ICLASS_SIM_MODE_FULL_GLITCH_KEY) &&
|
||||
emulator[32 * 8] != 0) {
|
||||
|
||||
emulator[32 * 8] = 0; // consume the flag
|
||||
|
||||
// Reload CSN (block 0) and rebuild anticollision/CSN responses
|
||||
memcpy(csn_data, emulator, 8);
|
||||
rotateCSN(csn_data, anticoll_data);
|
||||
AddCrc(anticoll_data, 8);
|
||||
AddCrc(csn_data, 8);
|
||||
|
||||
CodeIso15693AsTag(anticoll_data, sizeof(anticoll_data));
|
||||
memcpy(resp_anticoll, ts->buf, ts->max);
|
||||
resp_anticoll_len = ts->max;
|
||||
|
||||
CodeIso15693AsTag(csn_data, sizeof(csn_data));
|
||||
memcpy(resp_csn, ts->buf, ts->max);
|
||||
resp_csn_len = ts->max;
|
||||
|
||||
// Reload KD/KC (blocks 3 & 4) and recompute cipher states
|
||||
memcpy(diversified_kd, emulator + (8 * 3), 8);
|
||||
memcpy(diversified_kc, emulator + (8 * 4), 8);
|
||||
cipher_state_KD[0] = opt_doTagMAC_1(card_challenge_data, diversified_kd);
|
||||
cipher_state_KC[0] = opt_doTagMAC_1(card_challenge_data, diversified_kc);
|
||||
|
||||
// Reset per-transaction auth state
|
||||
kc_attempt = 0;
|
||||
using_kc = false;
|
||||
cipher_state = &cipher_state_KD[0];
|
||||
}
|
||||
|
||||
// Reader in anti collision phase
|
||||
modulated_response = resp_sof;
|
||||
modulated_response_size = resp_sof_len;
|
||||
|
||||
+9
-2
@@ -1500,8 +1500,10 @@ int GetIso15693CommandFromReader(uint8_t *received, size_t max_len, uint32_t *eo
|
||||
int samples = 0;
|
||||
bool gotFrame = false;
|
||||
|
||||
// the decoder data structure
|
||||
DecodeReader_t *dr = (DecodeReader_t *)BigBuf_calloc(sizeof(DecodeReader_t));
|
||||
// the decoder data structure — use stack, not BigBuf, to avoid a per-call
|
||||
// allocation leak when the function is restarted (e.g. on data_available exit)
|
||||
DecodeReader_t dr_buf = {0};
|
||||
DecodeReader_t *dr = &dr_buf;
|
||||
DecodeReaderInit(dr, received, max_len, 0, NULL);
|
||||
|
||||
// wait for last transfer to complete
|
||||
@@ -1569,6 +1571,11 @@ int GetIso15693CommandFromReader(uint8_t *received, size_t max_len, uint32_t *eo
|
||||
break;
|
||||
}
|
||||
|
||||
if (data_available()) {
|
||||
dr->byteCount = -2;
|
||||
break;
|
||||
}
|
||||
|
||||
WDT_HIT();
|
||||
}
|
||||
|
||||
|
||||
+814
-26
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user