diff --git a/CHANGELOG.md b/CHANGELOG.md index cae4e650716..eadbffddbfa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fixed the timeout of TCP connections (@wh201906) - Changed the connection timeout configurable (@wh201906) - Add hf_cardhopper standalone mode for long-distance relay attacks (@startrekdude) + - Add rudimentary MFU authentication (@shallax) ## [Seven.4.16717][2023-06-25] - Change `hf 14a info` - now identifes QL88 tags (@iceman1001) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index c3ee6f05000..8ceaf529d4e 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1286,6 +1286,15 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, tag_r rPACK[1] = 0x80; } } + + if (tagType == 2) { + uint8_t pack[4]; + uint16_t start = (*pages - 1) * 4 + MFU_DUMP_PREFIX_LENGTH; + emlGetMemBt(pack, start, sizeof(pack)); + rPACK[0] = pack[0]; + rPACK[1] = pack[1]; + } + AddCrc14A(rPACK, sizeof(rPACK) - 2); static tag_response_info_t responses_init[] = { @@ -1703,34 +1712,27 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_ } else if (receivedCmd[0] == MIFARE_ULC_AUTH_1) { // ULC authentication, or Desfire Authentication LogTrace(receivedCmd, Uart.len, Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); p_response = NULL; - } else if (receivedCmd[0] == MIFARE_ULEV1_AUTH && len == 7 && tagType == 7) { // NTAG / EV-1 authentication - - /* - // PWD stored in dump now + } else if (receivedCmd[0] == MIFARE_ULEV1_AUTH && len == 7 && tagType == 7) { // NTAG / EV-1 + p_response = &responses[RESP_INDEX_PACK]; + } else if (receivedCmd[0] == MIFARE_ULEV1_AUTH && len == 7 && tagType == 2) { // MFU authentication uint8_t pwd[4]; - emlGetMemBt(pwd, (pages - 1) * 4 + MFU_DUMP_PREFIX_LENGTH, sizeof(pwd)); - if (memcmp(pwd, "\x00\x00\x00\x00", 4) == 0) { - Uint4byteToMemLe(pwd, ul_ev1_pwdgenB(data)); - Dbprintf("Calc pwd... %02X %02X %02X %02X", pwd[0], pwd[1], pwd[2], pwd[3]); - } - - if (memcmp(receivedCmd + 1, pwd, 4) == 0) { - - uint8_t pack[4]; - emlGetMemBt(pack, pages * 4 + MFU_DUMP_PREFIX_LENGTH, 2); - if (memcmp(pack, "\x00\x00\x00\x00", 4) == 0) { - pack[0] = 0x80; - pack[1] = 0x80; - } - AddCrc14A(pack, sizeof(pack) - 2); - EmSendCmd(pack, sizeof(pack)); + uint16_t start = (pages - 2) * 4 + MFU_DUMP_PREFIX_LENGTH; + emlGetMemBt(pwd, start, sizeof(pwd)); + Dbprintf("Reader sent password: "); + Dbhexdump(4, receivedCmd + 1, 0); + + Dbprintf("Loaded password from memory: "); + Dbhexdump(4, pwd, 0); + + if (pwd[0] == receivedCmd[1] && + pwd[1] == receivedCmd[2] && + pwd[2] == receivedCmd[3] && + pwd[3] == receivedCmd[4]) { + p_response = &responses[RESP_INDEX_PACK]; } else { - EmSend4bit(CARD_NACK_NA); - if (g_dbglevel >= DBG_DEBUG) Dbprintf("Auth attempt: %08x", bytes_to_num(receivedCmd + 1, 4)); + p_response = NULL; + EmSend4bit(CARD_NACK_IV); } - p_response = NULL; - */ - p_response = &responses[RESP_INDEX_PACK]; } else if (receivedCmd[0] == MIFARE_ULEV1_VCSL && len == 23 && tagType == 7) { uint8_t cmd[3]; emlGetMemBt(cmd, (pages - 2) * 4 + 1 + MFU_DUMP_PREFIX_LENGTH, 1); diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index 13b8c9cb4e1..3dd0a059bc5 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -2657,7 +2657,7 @@ static int CmdHF14AMfUDump(const char *Cmd) { //add *special* blocks to dump // pack and pwd saved into last pages of dump, if was not partial read - dump_file_data.pages = pages - 1; + dump_file_data.pages = pages; memcpy(dump_file_data.version, get_version, sizeof(dump_file_data.version)); memcpy(dump_file_data.signature, get_signature, sizeof(dump_file_data.signature)); memcpy(dump_file_data.counter_tearing, get_counter_tearing, sizeof(dump_file_data.counter_tearing));