From 5cca8616cb4c3ed3d5bbbbb0a27755561ac6bd4b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 8 Nov 2019 10:28:29 +0100 Subject: [PATCH] Add: 'hf mfu otptear' - draft of @fukmar implementation for a tear-off attack against OTP block on Mifare Ultralight based card. --- armsrc/appmain.c | 32 ++++++++++++---------- armsrc/mifarecmd.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++ armsrc/mifarecmd.h | 3 +++ client/cmdhfmfu.c | 43 +++++++++++++++++++++++++++++ include/pm3_cmd.h | 3 +++ 5 files changed, 134 insertions(+), 14 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 5011c1979..ef96d9fef 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -696,10 +696,23 @@ static void PacketReceived(PacketCommandNG *packet) { */ switch (packet->cmd) { - case CMD_QUIT_SESSION: + case CMD_QUIT_SESSION: { reply_via_fpc = false; reply_via_usb = false; break; + } + // emulator + case CMD_SET_DBGMODE: { + DBGLEVEL = packet->data.asBytes[0]; + Dbprintf("Debug level: %d", DBGLEVEL); + reply_ng(CMD_SET_DBGMODE, PM3_SUCCESS, NULL, 0); + break; + } + // always available + case CMD_HF_DROPFIELD: { + hf_field_off(); + break; + } #ifdef WITH_LF case CMD_LF_T55XX_SET_CONFIG: { setT55xxConfig(packet->oldarg[0], (t55xx_configurations_t *) packet->data.asBytes); @@ -1034,12 +1047,6 @@ static void PacketReceived(PacketCommandNG *packet) { } #endif -// always available - case CMD_HF_DROPFIELD: { - hf_field_off(); - break; - } - #ifdef WITH_ISO14443a case CMD_HF_ISO14443A_SNIFF: { SniffIso14443a(packet->data.asBytes[0]); @@ -1155,13 +1162,6 @@ static void PacketReceived(PacketCommandNG *packet) { Mifare1ksim(payload->flags, payload->exitAfter, payload->uid, payload->atqa, payload->sak); break; } - // emulator - case CMD_SET_DBGMODE: { - DBGLEVEL = packet->data.asBytes[0]; - Dbprintf("Debug level: %d", DBGLEVEL); - reply_ng(CMD_SET_DBGMODE, PM3_SUCCESS, NULL, 0); - break; - } case CMD_HF_MIFARE_EML_MEMCLR: { MifareEMemClr(); reply_ng(CMD_HF_MIFARE_EML_MEMCLR, PM3_SUCCESS, NULL, 0); @@ -1245,6 +1245,10 @@ static void PacketReceived(PacketCommandNG *packet) { DetectNACKbug(); break; } + case CMD_HF_MFU_OTP_TEAROFF: { + MifareU_Otp_Tearoff(); + break; + } #endif #ifdef WITH_NFCBARCODE diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index f5e3fe961..0b840e2fb 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -2173,3 +2173,70 @@ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain) { LEDsoff(); set_tracing(false); } + +// +// Tear-off attack against MFU. +// - Mobius et al +void MifareU_Otp_Tearoff() { + +// should the +// optional time be configurable via client side? +// optional authentication before? +// optional data to be written? + + if (DBGLEVEL >= DBG_ERROR) DbpString("Preparing OTP tear-off"); + + LEDsoff(); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + clear_trace(); + set_tracing(true); + + StartTicks(); + +#define OTP_TEAR_OFF_TIME 1000 +#define OTP_BLK_NO 3 + + // write cmd to send, include CRC + // 1b write, 1b block, 4b data, 2 crc + uint8_t cmd[] = {MIFARE_ULC_WRITE, OTP_BLK_NO, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0}; + +// User specific data to write? +// memcpy(block + 2, blockData, 4); + + AddCrc14A(cmd, sizeof(cmd) - 2); + + if (DBGLEVEL >= DBG_ERROR) DbpString("Transmitting"); + + // anticollision / select card + if (!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) { + if (DBGLEVEL >= DBG_ERROR) Dbprintf("Can't select card"); + OnError(1); + return; + }; + + /* + // UL-EV1 / NTAG authentication + if (usePwd) { + uint8_t pwd[4] = {0x00}; + memcpy(pwd, datain + 4, 4); + uint8_t pack[4] = {0, 0, 0, 0}; + if (!mifare_ul_ev1_auth(pwd, pack)) { + OnError(1); + return; + } + } + */ + + // send + ReaderTransmit(cmd, sizeof(cmd), NULL); + + // Wait before cutting power. aka tear-off + LED_D_ON(); + WaitUS(OTP_TEAR_OFF_TIME); + switch_off(); + + reply_ng(CMD_HF_MFU_OTP_TEAROFF, PM3_SUCCESS, NULL, 0); + StopTicks(); + + if (DBGLEVEL >= DBG_ERROR) DbpString("Done"); +} diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index 0b8e2acd3..6b730fb58 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -52,4 +52,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype); void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain); void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain); +// Tear-off test for MFU +void MifareU_Otp_Tearoff(); + #endif diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 06f44e35d..3107dd585 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -221,6 +221,16 @@ static int usage_hf_mfu_pwdgen(void) { return PM3_SUCCESS; } +static int usage_hf_mfu_otp_tearoff(void) { + PrintAndLogEx(NORMAL, "Tear-off test against OTP block on MFU tags - More help sooner or later\n"); + PrintAndLogEx(NORMAL, "Usage: hf mfu otptear [h]"); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h : this help"); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, " hf mfu otptear"); + return PM3_SUCCESS; +} + uint8_t default_3des_keys[][16] = { { 0x42, 0x52, 0x45, 0x41, 0x4b, 0x4d, 0x45, 0x49, 0x46, 0x59, 0x4f, 0x55, 0x43, 0x41, 0x4e, 0x21 }, // 3des std key @@ -2740,6 +2750,38 @@ static int CmdHF14AMfUPwdGen(const char *Cmd) { PrintAndLogEx(NORMAL, "--------------------"); return PM3_SUCCESS; } + +// +// MFU TearOff against OTP +// Mobeius et al +// +static int CmdHF14AMfuOtpTearoff(const char *Cmd){ + uint8_t cmdp = 0; + bool errors = 0; + uint32_t len = strtol(Cmd, NULL, 0); + uint8_t data[PM3_CMD_DATA_SIZE] = {0}; + + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_hf_mfu_otp_tearoff(); + default: + break; + } + } + + if (errors) return usage_hf_mfu_otp_tearoff(); + + clearCommandBuffer(); + SendCommandNG(CMD_HF_MFU_OTP_TEAROFF, data, len); + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_HF_MFU_OTP_TEAROFF, &resp, 4000)) { + PrintAndLogEx(WARNING, "Failed"); + return PM3_ESOFT; + } + return PM3_SUCCESS; +} + //------------------------------------ // Menu Stuff //------------------------------------ @@ -2757,6 +2799,7 @@ static command_t CommandTable[] = { {"sim", CmdHF14AMfUSim, IfPm3Iso14443a, "Simulate Ultralight from emulator memory"}, {"gen", CmdHF14AMfUGenDiverseKeys, AlwaysAvailable, "Generate 3des mifare diversified keys"}, {"pwdgen", CmdHF14AMfUPwdGen, AlwaysAvailable, "Generate pwd from known algos"}, + {"otptear", CmdHF14AMfuOtpTearoff, IfPm3Iso14443a, "Tear-off test on OTP bits"}, {NULL, NULL, NULL, NULL} }; diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 544d5e5c2..0f7212600 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -507,6 +507,9 @@ typedef struct { #define CMD_HF_MIFARE_NACK_DETECT 0x0730 +// MFU OTP TearOff +#define CMD_HF_MFU_OTP_TEAROFF 0x0740 + #define CMD_HF_SNIFF 0x0800 // For ThinFilm Kovio