mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-01-30 20:07:55 +08:00
Add: 'hf mfu otptear' - draft of @fukmar implementation for a tear-off attack against OTP block on Mifare Ultralight based card.
This commit is contained in:
parent
33fe2b890b
commit
5cca8616cb
5 changed files with 134 additions and 14 deletions
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue