This commit is contained in:
Antiklesys
2026-03-25 18:22:35 +08:00
6 changed files with 54 additions and 17 deletions
+1
View File
@@ -4,6 +4,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
## [unreleased][unreleased]
- 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)
- Added `--aid` parameter to `hf seos` commands (@kormax)
- Added `hf iclass blacktears` command to perform an automated tearoff of block 1 to set non-secure page mode(@antiklesys)
+11 -6
View File
@@ -301,9 +301,14 @@ void RunMod(void) {
if (iso14443a_select_card(NULL, &card_a_info, NULL, true, 0, false)) {
DbpString(_YELLOW_("+") "Found ISO 14443 Type A!");
chktoken = false;
for (uint8_t i = 0; i < 4; i++) {
chktoken = false;
if (i == 3 && chktoken) {
break; // Tag 57 was already found in GPO, no need to issue READ RECORD
}
LED_C_OFF();
LED_B_ON();
uint8_t apdulen = iso14_apdu(apdus[i], (uint16_t) apduslen[i], false, apdubuffer, sizeof(apdubuffer), NULL);
@@ -331,13 +336,13 @@ void RunMod(void) {
}
} else if (i == 3) {
} else if (i == 2 || i == 3) {
// find track 2
if (apdubuffer[u] == 0x57 && apdubuffer[u + 1] == 0x13 && !chktoken) {
// find track 2 in GPO or READ RECORD
if (u + 20 < apdulen && apdubuffer[u] == 0x57 && apdubuffer[u + 1] == 0x13 && !chktoken) {
chktoken = true;
memcpy(&token, &apdubuffer[u + 2], 19);
memcpy(token, &apdubuffer[u + 2], 19);
break;
}
}
+2 -2
View File
@@ -286,7 +286,7 @@ static void hitag2_handle_reader_command(uint8_t *rx, const size_t rxlen, uint8_
// Received RWD authentication challenge and response
case 64: {
// Store the authentication attempt
if (auth_table_len < (AUTH_TABLE_LENGTH - 8)) {
if (auth_table_len + 8 <= AUTH_TABLE_LENGTH) {
memcpy(auth_table + auth_table_len, rx, 8);
auth_table_len += 8;
}
@@ -1371,7 +1371,7 @@ void SniffHitag2(bool ledcontrol) {
// Check if we recognize a valid authentication attempt
if (rxlen == 64) {
// Store the authentication attempt
if (auth_table_len < (AUTH_TABLE_LENGTH - 8)) {
if (auth_table_len + 8 <= AUTH_TABLE_LENGTH) {
memcpy(auth_table + auth_table_len, rx, 8);
auth_table_len += 8;
}
+18 -8
View File
@@ -4492,16 +4492,21 @@ void DetectNACKbug(void) {
set_tracing(false);
}
/* ///
Based upon the SimulateIso14443aTag, this aims to instead take an AID Value you've supplied, and return your selected response.
It can also continue after the AID has been selected, and respond to other request types.
This was forked from the original function to allow for more flexibility in the future, and to increase the processing speed of the original function.
/// */
// Increased the buffer size to allow for more complex responses
#define DYNAMIC_RESPONSE_BUFFER2_SIZE ( 512 )
#define DYNAMIC_MODULATION_BUFFER2_SIZE ( 1536 )
// EvilDaemond
// Based upon the SimulateIso14443aTag, this aims to instead take an AID Value you've supplied, and return your selected response.
// It can also continue after the AID has been selected, and respond to other request types.
// This was forked from the original function to allow for more flexibility in the future, and to increase the processing speed of the original function.
//
void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *uid,
uint8_t *ats, size_t ats_len, uint8_t *aid, size_t aid_len,
uint8_t *selectaid_response, size_t selectaid_response_len,
uint8_t *getdata_response, size_t getdata_response_len) {
tag_response_info_t *responses;
uint32_t cuid = 0;
uint8_t pages = 0;
@@ -4514,14 +4519,19 @@ void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *uid,
// Copy the AID, AID Response, and the GetData APDU response into our variables
if ((aid == NULL) || (selectaid_response == NULL) || (getdata_response == NULL)) {
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINVARG, NULL, 0);
return;
}
// free eventually allocated BigBuf memory but keep Emulator Memory
BigBuf_free_keep_EM();
// Increased the buffer size to allow for more complex responses
#define DYNAMIC_RESPONSE_BUFFER2_SIZE 512
#define DYNAMIC_MODULATION_BUFFER2_SIZE 1536
// Response payloads must fit within the dynamic response buffer,
// accounting for 1-byte IBlock header + 1-byte optional CID (offset 0 or 1)
if (selectaid_response_len + 2 > DYNAMIC_RESPONSE_BUFFER2_SIZE ||
getdata_response_len + 2 > DYNAMIC_RESPONSE_BUFFER2_SIZE) {
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINVARG, NULL, 0);
return;
}
uint8_t *dynamic_response_buffer2 = BigBuf_calloc(DYNAMIC_RESPONSE_BUFFER2_SIZE);
if (dynamic_response_buffer2 == NULL) {
+4
View File
@@ -323,6 +323,10 @@ void MifareDES_Auth1(uint8_t *datain) {
memcpy(keybytes, PICC_MASTER_KEY24, 24);
}
} else {
if (payload->keylen > sizeof(keybytes)) {
OnErrorNG(CMD_HF_DESFIRE_AUTH1, PM3_EINVARG);
return;
}
memcpy(keybytes, payload->key, payload->keylen);
}
+18 -1
View File
@@ -1162,6 +1162,7 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav
uint8_t *recv;
PacketResponseNG resp;
resend:
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
recv = resp.data.asBytes;
int iLen = resp.oldarg[0];
@@ -1184,7 +1185,23 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav
}
return PM3_ELENGTH;
}
if (recv[0] & 0xf0) {
uint8_t dbg_curr = DBG_NONE;
if (getDeviceDebugLevel(&dbg_curr) != PM3_SUCCESS) {
return PM3_EFAILED;
}
if (dbg_curr >= DBG_DEBUG) {
PrintAndLogEx(WARNING, "Card requested WTX");
}
// WARNING for users of this function:
// This NO_DISCONNECT flag will NOT save you. If you run your commands with LeaveSignalOn set to false, they will still fail if a card asks for WTX.
// Better keep the flag on and do a DropField(); at the end.
SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_RAW | ISO14A_NO_DISCONNECT | cmdc, 5, 0, recv, min); // 2b frame +1b "data" + 2b crc. Hardcode length to 5 and reply to response
goto resend;
}
// OBS
// This if check below breaks command flow if the card for whatever reason decides to request a WTX.
// Because WTX will do a |= 0xF0 to the framing, this check triggers and everything that was happening will stop.
if (recv[0] != data[0]) {
if (silentMode == false) {
PrintAndLogEx(ERR, "iso14443-4 framing error. Card send %2x must be %2x", recv[0], data[0]);