X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/52eeaef568ac6855f701c51a48d71a393cee3df9..4eabb8ad382f87aaee497d35e88c169da96b8fda:/client/cmdhf14a.c diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 9f40e754..21c97fa2 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -1,5 +1,6 @@ //----------------------------------------------------------------------------- // 2011, Merlok +// 2014, Peter Fillmore // Copyright (C) 2010 iZsh , Hagen Fritsch // // This code is licensed to you under the terms of the GNU GPL, version 2 or, @@ -64,7 +65,7 @@ const manufactureName manufactureMapping[] = { { 0x17, "KSW Microtec GmbH Germany" }, { 0x18, "ZMD AG Germany" }, { 0x19, "XICOR, Inc. USA" }, - { 0x1A, "Sony Corporation Japan Identifier Company Country" }, + { 0x1A, "Sony Corporation Japan" }, { 0x1B, "Malaysia Microelectronic Solutions Sdn. Bhd Malaysia" }, { 0x1C, "Emosyn USA" }, { 0x1D, "Shanghai Fudan Microelectronics Co. Ltd. P.R. China" }, @@ -94,7 +95,7 @@ const manufactureName manufactureMapping[] = { { 0x35, "Fraunhofer Institute for Photonic Microsystems Germany" }, { 0x36, "IDS Microchip AG Switzerland" }, { 0x37, "Kovio USA" }, - { 0x38, "HMT Microelectronic Ltd Switzerland Identifier Company Country" }, + { 0x38, "HMT Microelectronic Ltd Switzerland" }, { 0x39, "Silicon Craft Technology Thailand" }, { 0x3A, "Advanced Film Device Inc. Japan" }, { 0x3B, "Nitecrest Ltd UK" }, @@ -106,7 +107,8 @@ const manufactureName manufactureMapping[] = { { 0x41, "Renesas Electronics Corporation Japan" }, { 0x42, "3Alogics Inc Korea" }, { 0x43, "Top TroniQ Asia Limited Hong Kong" }, - { 0x44, "Gentag Inc (USA) USA" }, + { 0x44, "Gentag Inc. USA" }, + { 0x56, "Sensible Object. UK" }, { 0x00, "no tag-info available" } // must be the last entry }; @@ -130,23 +132,27 @@ char* getTagInfo(uint8_t uid) { int usage_hf_14a_sim(void) { // PrintAndLog("\n Emulating ISO/IEC 14443 type A tag with 4,7 or 10 byte UID\n"); PrintAndLog("\n Emulating ISO/IEC 14443 type A tag with 4,7 byte UID\n"); - PrintAndLog("Usage: hf 14a sim t u x"); - PrintAndLog(" Options : "); - PrintAndLog(" h : this help"); - PrintAndLog(" t : 1 = MIFARE Classic"); + PrintAndLog("usage: hf 14a sim [h] t u [x] [e] [v]"); + PrintAndLog("options: "); + PrintAndLog(" h : This help"); + PrintAndLog(" t : 1 = MIFARE Classic 1k"); PrintAndLog(" 2 = MIFARE Ultralight"); PrintAndLog(" 3 = MIFARE Desfire"); PrintAndLog(" 4 = ISO/IEC 14443-4"); PrintAndLog(" 5 = MIFARE Tnp3xxx"); PrintAndLog(" 6 = MIFARE Mini"); PrintAndLog(" 7 = AMIIBO (NTAG 215), pack 0x8080"); + PrintAndLog(" 8 = MIFARE Classic 4k"); // PrintAndLog(" u : 4, 7 or 10 byte UID"); PrintAndLog(" u : 4, 7 byte UID"); - PrintAndLog(" x : (Optional) performs the 'reader attack', nr/ar attack against a legitimate reader"); - PrintAndLog("\n sample : hf 14a sim t 1 u 11223344 x"); - PrintAndLog(" : hf 14a sim t 1 u 11223344"); - PrintAndLog(" : hf 14a sim t 1 u 11223344556677"); -// PrintAndLog(" : hf 14a sim t 1 u 11223445566778899AA\n"); + PrintAndLog(" x : (Optional) Performs the 'reader attack', nr/ar attack against a reader"); + PrintAndLog(" e : (Optional) Fill simulator keys from found keys"); + PrintAndLog(" v : (Optional) Verbose"); + PrintAndLog("samples:"); + PrintAndLog(" hf 14a sim t 1 u 11223344 x"); + PrintAndLog(" hf 14a sim t 1 u 11223344"); + PrintAndLog(" hf 14a sim t 1 u 11223344556677"); +// PrintAndLog(" hf 14a sim t 1 u 11223445566778899AA\n"); return 0; } int usage_hf_14a_sniff(void){ @@ -179,11 +185,12 @@ int CmdHF14AList(const char *Cmd) { } int CmdHF14AReader(const char *Cmd) { + UsbCommand cDisconnect = {CMD_READER_ISO_14443a, {0,0,0}}; UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}}; clearCommandBuffer(); SendCommand(&c); UsbCommand resp; - WaitForResponse(CMD_ACK,&resp); + WaitForResponse(CMD_ACK, &resp); iso14a_card_select_t card; memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t)); @@ -192,22 +199,14 @@ int CmdHF14AReader(const char *Cmd) { if(select_status == 0) { if (Cmd[0] != 's') PrintAndLog("iso14443a card select failed"); - // disconnect - c.arg[0] = 0; - c.arg[1] = 0; - c.arg[2] = 0; - SendCommand(&c); + SendCommand(&cDisconnect); return 0; } if(select_status == 3) { PrintAndLog("Card doesn't support standard iso14443-3 anticollision"); PrintAndLog("ATQA : %02x %02x", card.atqa[1], card.atqa[0]); - // disconnect - c.arg[0] = 0; - c.arg[1] = 0; - c.arg[2] = 0; - SendCommand(&c); + SendCommand(&cDisconnect); return 0; } @@ -218,22 +217,23 @@ int CmdHF14AReader(const char *Cmd) { switch (card.sak) { case 0x00: - //***************************************test**************** + // ******** is card of the MFU type (UL/ULC/NTAG/ etc etc) ul_switch_off_field(); uint32_t tagT = GetHF14AMfU_Type(); - ul_print_type(tagT, 0); + if (tagT != UL_ERROR) + ul_print_type(tagT, 0); + else + PrintAndLog("TYPE: Possible AZTEK (iso14443a compliant)"); - //reconnect for further tests + // reconnect for further tests c.arg[0] = ISO14A_CONNECT | ISO14A_NO_DISCONNECT; c.arg[1] = 0; c.arg[2] = 0; - clearCommandBuffer(); SendCommand(&c); - UsbCommand resp; - WaitForResponse(CMD_ACK,&resp); + WaitForResponse(CMD_ACK, &resp); memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t)); @@ -243,27 +243,6 @@ int CmdHF14AReader(const char *Cmd) { ul_switch_off_field(); return 0; } - - /* orig - // check if the tag answers to GETVERSION (0x60) - c.arg[0] = ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT; - c.arg[1] = 1; - c.arg[2] = 0; - c.d.asBytes[0] = 0x60; - SendCommand(&c); - WaitForResponse(CMD_ACK,&resp); - - uint8_t version[10] = {0}; - memcpy(version, resp.d.asBytes, resp.arg[0] < sizeof(version) ? resp.arg[0] : sizeof(version)); - uint8_t len = resp.arg[0] & 0xff; - switch ( len){ - // todo, identify "Magic UL-C tags". // they usually have a static nonce response to 0x1A command. - // UL-EV1, size, check version[6] == 0x0b (smaller) 0x0b * 4 == 48 - case 0x0A:PrintAndLog("TYPE : NXP MIFARE Ultralight EV1 %d bytes", (version[6] == 0xB) ? 48 : 128); break; - case 0x01:PrintAndLog("TYPE : NXP MIFARE Ultralight C");break; - case 0x00:PrintAndLog("TYPE : NXP MIFARE Ultralight");break; - } - */ break; case 0x01: PrintAndLog("TYPE : NXP TNP3xxx Activision Game Appliance"); break; case 0x04: PrintAndLog("TYPE : NXP MIFARE (various !DESFire !DESFire EV1)"); break; @@ -379,59 +358,29 @@ int CmdHF14AReader(const char *Cmd) { PrintAndLog(" %02x -> Length is %d bytes", card.ats[pos + 1], card.ats[pos + 1]); switch (card.ats[pos + 2] & 0xf0) { - case 0x10: - PrintAndLog(" 1x -> MIFARE DESFire"); - break; - case 0x20: - PrintAndLog(" 2x -> MIFARE Plus"); - break; + case 0x10: PrintAndLog(" 1x -> MIFARE DESFire"); break; + case 0x20: PrintAndLog(" 2x -> MIFARE Plus"); break; } switch (card.ats[pos + 2] & 0x0f) { - case 0x00: - PrintAndLog(" x0 -> <1 kByte"); - break; - case 0x01: - PrintAndLog(" x1 -> 1 kByte"); - break; - case 0x02: - PrintAndLog(" x2 -> 2 kByte"); - break; - case 0x03: - PrintAndLog(" x3 -> 4 kByte"); - break; - case 0x04: - PrintAndLog(" x4 -> 8 kByte"); - break; + case 0x00: PrintAndLog(" x0 -> <1 kByte"); break; + case 0x01: PrintAndLog(" x1 -> 1 kByte"); break; + case 0x02: PrintAndLog(" x2 -> 2 kByte"); break; + case 0x03: PrintAndLog(" x3 -> 4 kByte"); break; + case 0x04: PrintAndLog(" x4 -> 8 kByte"); break; } switch (card.ats[pos + 3] & 0xf0) { - case 0x00: - PrintAndLog(" 0x -> Engineering sample"); - break; - case 0x20: - PrintAndLog(" 2x -> Released"); - break; + case 0x00: PrintAndLog(" 0x -> Engineering sample"); break; + case 0x20: PrintAndLog(" 2x -> Released"); break; } switch (card.ats[pos + 3] & 0x0f) { - case 0x00: - PrintAndLog(" x0 -> Generation 1"); - break; - case 0x01: - PrintAndLog(" x1 -> Generation 2"); - break; - case 0x02: - PrintAndLog(" x2 -> Generation 3"); - break; + case 0x00: PrintAndLog(" x0 -> Generation 1"); break; + case 0x01: PrintAndLog(" x1 -> Generation 2"); break; + case 0x02: PrintAndLog(" x2 -> Generation 3"); break; } switch (card.ats[pos + 4] & 0x0f) { - case 0x00: - PrintAndLog(" x0 -> Only VCSL supported"); - break; - case 0x01: - PrintAndLog(" x1 -> VCS, VCSL, and SVC supported"); - break; - case 0x0E: - PrintAndLog(" xE -> no VCS command supported"); - break; + case 0x00: PrintAndLog(" x0 -> Only VCSL supported"); break; + case 0x01: PrintAndLog(" x1 -> VCS, VCSL, and SVC supported"); break; + case 0x0E: PrintAndLog(" xE -> no VCS command supported"); break; } } } @@ -441,7 +390,7 @@ int CmdHF14AReader(const char *Cmd) { // try to see if card responses to "chinese magic backdoor" commands. - uint8_t isOK = 0; + uint8_t isGeneration = 0; clearCommandBuffer(); c.cmd = CMD_MIFARE_CIDENT; c.arg[0] = 0; @@ -449,17 +398,17 @@ int CmdHF14AReader(const char *Cmd) { c.arg[2] = 0; SendCommand(&c); if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) - isOK = resp.arg[0] & 0xff; - - PrintAndLog("Answers to magic commands (GEN1): %s", (isOK ? "YES" : "NO") ); + isGeneration = resp.arg[0] & 0xff; - // disconnect - c.cmd = CMD_READER_ISO_14443a; - c.arg[0] = 0; - c.arg[1] = 0; - c.arg[2] = 0; - SendCommand(&c); + switch( isGeneration ){ + case 1: PrintAndLog("Answers to magic commands (GEN 1a): YES"); break; + case 2: PrintAndLog("Answers to magic commands (GEN 1b): YES"); break; + //case 4: PrintAndLog("Answers to magic commands (GEN 2): YES"); break; + default: PrintAndLog("Answers to magic commands: NO"); break; + } + // disconnect + SendCommand(&cDisconnect); return select_status; } @@ -501,7 +450,6 @@ int CmdHF14ACUIDs(const char *Cmd) { // ## simulate iso14443a tag // ## greg - added ability to specify tag UID int CmdHF14ASim(const char *Cmd) { - #define ATTACK_KEY_COUNT 8 bool errors = FALSE; uint8_t flags = 0; uint8_t tagtype = 1; @@ -509,7 +457,10 @@ int CmdHF14ASim(const char *Cmd) { uint8_t uid[10] = {0,0,0,0,0,0,0,0,0,0}; int uidlen = 0; bool useUIDfromEML = TRUE; - + bool setEmulatorMem = FALSE; + bool verbose = FALSE; + nonces_t data[1]; + while(param_getchar(Cmd, cmdp) != 0x00) { switch(param_getchar(Cmd, cmdp)) { case 'h': @@ -520,7 +471,7 @@ int CmdHF14ASim(const char *Cmd) { // Retrieve the tag type tagtype = param_get8ex(Cmd, cmdp+1, 0, 10); if (tagtype == 0) - errors = true; + errors = TRUE; cmdp += 2; break; case 'u': @@ -539,14 +490,24 @@ int CmdHF14ASim(const char *Cmd) { } cmdp += 2; break; + case 'v': + case 'V': + verbose = TRUE; + cmdp++; + break; case 'x': case 'X': flags |= FLAG_NR_AR_ATTACK; cmdp++; break; + case 'e': + case 'E': + setEmulatorMem = TRUE; + cmdp++; + break; default: PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = true; + errors = TRUE; break; } if(errors) break; @@ -558,25 +519,23 @@ int CmdHF14ASim(const char *Cmd) { if ( useUIDfromEML ) flags |= FLAG_UID_IN_EMUL; - PrintAndLog("Press pm3-button to abort simulation"); - UsbCommand c = {CMD_SIMULATE_TAG_ISO_14443a,{ tagtype, flags, 0 }}; memcpy(c.d.asBytes, uid, uidlen>>1); clearCommandBuffer(); SendCommand(&c); - - nonces_t data[ATTACK_KEY_COUNT*2]; UsbCommand resp; - + + PrintAndLog("Press pm3-button to abort simulation"); + while( !ukbhit() ){ if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500) ) continue; - if ( !(flags & FLAG_NR_AR_ATTACK) ) break; if ( (resp.arg[0] & 0xffff) != CMD_SIMULATE_MIFARE_CARD ) break; - memcpy( data, resp.d.asBytes, sizeof(data) ); - readerAttack(data, TRUE); + memcpy(data, resp.d.asBytes, sizeof(data) ); + readerAttack(data[0], setEmulatorMem, verbose); } + showSectorTable(); return 0; } @@ -717,14 +676,17 @@ int CmdHF14ACmdRaw(const char *cmd) { c.arg[2] = 13560000 / 1000 / (8*16) * timeout; // timeout in ETUs (time to transfer 1 bit, approx. 9.4 us) } - if(power) + if(power) { c.arg[0] |= ISO14A_NO_DISCONNECT; - - if(datalen>0) + } + + if(datalen>0) { c.arg[0] |= ISO14A_RAW; - - if(topazmode) + } + + if(topazmode) { c.arg[0] |= ISO14A_TOPAZMODE; + } // Max buffer is USB_CMD_DATA_SIZE datalen = (datalen > USB_CMD_DATA_SIZE) ? USB_CMD_DATA_SIZE : datalen; @@ -744,7 +706,8 @@ int CmdHF14ACmdRaw(const char *cmd) { return 0; } -static void waitCmd(uint8_t iSelect) { +static void waitCmd(uint8_t iSelect) +{ UsbCommand resp; uint16_t len = 0;