]> cvs.zerfleddert.de Git - proxmark3-svn/blobdiff - client/cmdhfmfu.c
REM: Removed the GetVendorStr, and used the getTagInfo() instead.
[proxmark3-svn] / client / cmdhfmfu.c
index 9bccc420a28574eaec6397fefb9f40d92e146d65..85b824cf984c88980adc2b948bde0123383a0eb1 100644 (file)
@@ -11,6 +11,7 @@
 #include "cmdhfmfu.h"
 #include "cmdhfmf.h"
 #include "cmdhf14a.h"
 #include "cmdhfmfu.h"
 #include "cmdhfmf.h"
 #include "cmdhf14a.h"
+#include "mifare.h"
 
 #define MAX_ULTRA_BLOCKS   0x0f
 #define MAX_ULTRAC_BLOCKS  0x2f
 
 #define MAX_ULTRA_BLOCKS   0x0f
 #define MAX_ULTRAC_BLOCKS  0x2f
@@ -22,7 +23,7 @@ int CmdHF14AMfUInfo(const char *Cmd){
 
        uint8_t datatemp[7] = {0x00};
        uint8_t isOK  = 0;
 
        uint8_t datatemp[7] = {0x00};
        uint8_t isOK  = 0;
-       uint8_t *data = NULL;
+       uint8_t data[16] = {0x00};
 
        UsbCommand c = {CMD_MIFAREU_READCARD, {0, 4}};
        SendCommand(&c);
 
        UsbCommand c = {CMD_MIFAREU_READCARD, {0, 4}};
        SendCommand(&c);
@@ -30,7 +31,7 @@ int CmdHF14AMfUInfo(const char *Cmd){
 
        if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
                isOK  = resp.arg[0] & 0xff;
 
        if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
                isOK  = resp.arg[0] & 0xff;
-               data  = resp.d.asBytes;
+               memcpy(data, resp.d.asBytes, sizeof(data));
 
                if (!isOK) {
                        PrintAndLog("Error reading from tag");
 
                if (!isOK) {
                        PrintAndLog("Error reading from tag");
@@ -40,11 +41,35 @@ int CmdHF14AMfUInfo(const char *Cmd){
                PrintAndLog("Command execute timed out");
                return -1;
        }
                PrintAndLog("Command execute timed out");
                return -1;
        }
-       
-       PrintAndLog("");
-       PrintAndLog("-- Mifare Ultralight / Ultralight-C Tag Information ---------");
-       PrintAndLog("-------------------------------------------------------------");
 
 
+       PrintAndLog("\n-- Tag Information ---------");
+       PrintAndLog("-------------------------------------------------------------");
+       
+       UsbCommand cmd = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_RAW | ISO14A_APPEND_CRC , 1, 0}};
+       cmd.d.asBytes[0] = 0x60;
+       SendCommand(&cmd);
+       WaitForResponse(CMD_ACK, &resp);
+       
+       if ( resp.arg[0] ) {
+               if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
+
+                       uint8_t version[8] = {0,0,0,0,0,0,0,0};
+                       memcpy(&version, resp.d.asBytes, 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;
+                       }
+               }
+       }
+       // TODO:
+       // Answers to 0x1A == UL-C
+       // NONCE seems to be fixed for my Magic UL-C.  How to detect a Magic UL?
+       // maybe read Block0, change 1 byte, write back, and see if it failes or not.  If magic,  revert changes made?
+       
        // UID
        memcpy( datatemp, data, 3);
        memcpy( datatemp+3, data+4, 4);
        // UID
        memcpy( datatemp, data, 3);
        memcpy( datatemp+3, data+4, 4);
@@ -71,14 +96,6 @@ int CmdHF14AMfUInfo(const char *Cmd){
        PrintAndLog("        Lock : %s - %s", sprint_hex(datatemp, 2),printBits( 2, &datatemp) );
        PrintAndLog("  OneTimePad : %s ", sprint_hex(data + 3*4, 4));
        PrintAndLog("");
        PrintAndLog("        Lock : %s - %s", sprint_hex(datatemp, 2),printBits( 2, &datatemp) );
        PrintAndLog("  OneTimePad : %s ", sprint_hex(data + 3*4, 4));
        PrintAndLog("");
-
-       int len = CmdHF14AMfucAuth("K 0");
-//     PrintAndLog("CODE: %d",len);
-// Fix reading UL-C 's password higher blocks.
-       
-       PrintAndLog("Seems to be a Ultralight %s", (len==0) ? "-C" :"");
-       
-       
        return 0;
 }
 
        return 0;
 }
 
@@ -797,12 +814,15 @@ int CmdHF14AMfucSetPwd(const char *Cmd){
 //
 int CmdHF14AMfucSetUid(const char *Cmd){
 
 //
 int CmdHF14AMfucSetUid(const char *Cmd){
 
+       UsbCommand c;
+       UsbCommand resp;
        uint8_t uid[7] = {0x00};
        char cmdp = param_getchar(Cmd, 0);
        
        if (strlen(Cmd) == 0  || cmdp == 'h' || cmdp == 'H') {  
                PrintAndLog("Usage:  hf mfu setuid <uid (14 hex symbols)>");
                PrintAndLog("       [uid] - (14 hex symbols)");
        uint8_t uid[7] = {0x00};
        char cmdp = param_getchar(Cmd, 0);
        
        if (strlen(Cmd) == 0  || cmdp == 'h' || cmdp == 'H') {  
                PrintAndLog("Usage:  hf mfu setuid <uid (14 hex symbols)>");
                PrintAndLog("       [uid] - (14 hex symbols)");
+               PrintAndLog("\nThis only works for Magic Ultralight tags.");
                PrintAndLog("");
                PrintAndLog("sample: hf mfu setuid 11223344556677");
                PrintAndLog("");
                PrintAndLog("");
                PrintAndLog("sample: hf mfu setuid 11223344556677");
                PrintAndLog("");
@@ -810,27 +830,60 @@ int CmdHF14AMfucSetUid(const char *Cmd){
        }
        
        if (param_gethex(Cmd, 0, uid, 14)) {
        }
        
        if (param_gethex(Cmd, 0, uid, 14)) {
-               PrintAndLog("Password must include 14 HEX symbols");
+               PrintAndLog("UID must include 14 HEX symbols");
                return 1;
        }
 
                return 1;
        }
 
-       UsbCommand c = {CMD_MIFAREU_SETUID};    
-       memcpy( c.d.asBytes, uid, 14);
+       // read block2. 
+       c.cmd = CMD_MIFAREU_READBL;
+       c.arg[0] = 2;
        SendCommand(&c);
        SendCommand(&c);
-
-       UsbCommand resp;        
-       if (WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
-               if ( (resp.arg[0] & 0xff) == 1)
-                       PrintAndLog("New UID: %s", sprint_hex(uid,14));
-               else{
-                       PrintAndLog("Failed writing new uid");
-                       return 1;
-               }
+       if (!WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
+               PrintAndLog("Command execute timeout");
+               return 2;
        }
        }
-       else {
-               PrintAndLog("command execution time out");
-               return 1;
+       
+       // save old block2.
+       uint8_t oldblock2[4] = {0x00};
+       memcpy(resp.d.asBytes, oldblock2, 4);
+       
+       // block 0.
+       c.cmd = CMD_MIFAREU_WRITEBL;
+       c.arg[0] = 0;
+       c.d.asBytes[0] = uid[0];
+       c.d.asBytes[1] = uid[1];
+       c.d.asBytes[2] = uid[2];
+       c.d.asBytes[3] =  0x88 ^ uid[0] ^ uid[1] ^ uid[2];
+       SendCommand(&c);
+       if (!WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
+               PrintAndLog("Command execute timeout");
+               return 3;
        }
        }
+       
+       // block 1.
+       c.arg[0] = 1;
+       c.d.asBytes[0] = uid[3];
+       c.d.asBytes[1] = uid[4];
+       c.d.asBytes[2] = uid[5];
+       c.d.asBytes[3] = uid[6];
+       SendCommand(&c);
+       if (!WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
+               PrintAndLog("Command execute timeout");
+               return 4;
+       }
+
+       // block 2.
+       c.arg[0] = 2;
+       c.d.asBytes[0] = uid[3] ^ uid[4] ^ uid[5] ^ uid[6];
+       c.d.asBytes[1] = oldblock2[1];
+       c.d.asBytes[2] = oldblock2[2];
+       c.d.asBytes[3] = oldblock2[3];
+       SendCommand(&c);
+       if (!WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
+               PrintAndLog("Command execute timeout");
+               return 5;
+       }
+       
        return 0;
 }
 
        return 0;
 }
 
@@ -839,43 +892,86 @@ int CmdHF14AMfuGenDiverseKeys(const char *Cmd){
        uint8_t iv[8] = { 0x00 };
        uint8_t block = 0x07;
        
        uint8_t iv[8] = { 0x00 };
        uint8_t block = 0x07;
        
+       // UL-EV1
+       //04 57 b6 e2 05 3f 80 UID
+       //4a f8 4b 19   PWD
        uint8_t uid[] = { 0xF4,0xEA, 0x54, 0x8E };
        uint8_t uid[] = { 0xF4,0xEA, 0x54, 0x8E };
-       uint8_t mifarekey[] = { 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5 };
+       uint8_t mifarekeyA[] = { 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5 };
+       uint8_t mifarekeyB[] = { 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5 };
+       uint8_t dkeyA[8] = { 0x00 };
+       uint8_t dkeyB[8] = { 0x00 };
+       
        uint8_t masterkey[] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff };
        
        uint8_t mix[8] = { 0x00 };
        uint8_t divkey[8] = { 0x00 };
        
        uint8_t masterkey[] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff };
        
        uint8_t mix[8] = { 0x00 };
        uint8_t divkey[8] = { 0x00 };
        
-       memcpy(mix, mifarekey, 4);
+       memcpy(mix, mifarekeyA, 4);
        
        
-       mix[4] = mifarekey[4] ^ uid[0];
-       mix[5] = mifarekey[5] ^ uid[1];
+       mix[4] = mifarekeyA[4] ^ uid[0];
+       mix[5] = mifarekeyA[5] ^ uid[1];
        mix[6] = block ^ uid[2];
        mix[7] = uid[3];
        
        des3_context ctx = { 0x00 };
        des3_set2key_enc(&ctx, masterkey);
 
        mix[6] = block ^ uid[2];
        mix[7] = uid[3];
        
        des3_context ctx = { 0x00 };
        des3_set2key_enc(&ctx, masterkey);
 
-       des3_crypt_cbc(&ctx     // des3_context *ctx
-               , DES_ENCRYPT       // int mode
-               , sizeof(mix)    // size_t length
-               , iv                // unsigned char iv[8]
-               , mix            // const unsigned char *input
-               , divkey           // unsigned char *output
+       des3_crypt_cbc(&ctx  // des3_context
+               , DES_ENCRYPT    // int mode
+               , sizeof(mix)    // length
+               , iv             // iv[8]
+               , mix            // input
+               , divkey         // output
                );
 
        PrintAndLog("3DES version");
        PrintAndLog("Masterkey    :\t %s", sprint_hex(masterkey,sizeof(masterkey)));
        PrintAndLog("UID          :\t %s", sprint_hex(uid, sizeof(uid)));
        PrintAndLog("Sector       :\t %0d", block);
                );
 
        PrintAndLog("3DES version");
        PrintAndLog("Masterkey    :\t %s", sprint_hex(masterkey,sizeof(masterkey)));
        PrintAndLog("UID          :\t %s", sprint_hex(uid, sizeof(uid)));
        PrintAndLog("Sector       :\t %0d", block);
-       PrintAndLog("Mifare key   :\t %s", sprint_hex(mifarekey, sizeof(mifarekey)));
+       PrintAndLog("Mifare key   :\t %s", sprint_hex(mifarekeyA, sizeof(mifarekeyA)));
        PrintAndLog("Message      :\t %s", sprint_hex(mix, sizeof(mix)));
        PrintAndLog("Diversified key: %s", sprint_hex(divkey+1, 6));
                
        PrintAndLog("Message      :\t %s", sprint_hex(mix, sizeof(mix)));
        PrintAndLog("Diversified key: %s", sprint_hex(divkey+1, 6));
                
+       PrintAndLog("\n DES version");
+       
+       for (int i=0; i < sizeof(mifarekeyA); ++i){
+               dkeyA[i] = (mifarekeyA[i] << 1) & 0xff;
+               dkeyA[6] |=  ((mifarekeyA[i] >> 7) & 1) << (i+1);
+       }
+       
+       for (int i=0; i < sizeof(mifarekeyB); ++i){
+               dkeyB[1] |=  ((mifarekeyB[i] >> 7) & 1) << (i+1);
+               dkeyB[2+i] = (mifarekeyB[i] << 1) & 0xff;
+       }
+       
+       uint8_t zeros[8] = {0x00};
+       uint8_t newpwd[8] = {0x00};
+       uint8_t dmkey[24] = {0x00};
+       memcpy(dmkey, dkeyA, 8);
+       memcpy(dmkey+8, dkeyB, 8);
+       memcpy(dmkey+16, dkeyA, 8);
+       memset(iv, 0x00, 8);
+       
+       des3_set3key_enc(&ctx, dmkey);
+
+       des3_crypt_cbc(&ctx  // des3_context
+               , DES_ENCRYPT    // int mode
+               , sizeof(newpwd) // length
+               , iv             // iv[8]
+               , zeros         // input
+               , newpwd         // output
+               );
+       
+       PrintAndLog("Mifare dkeyA :\t %s", sprint_hex(dkeyA, sizeof(dkeyA)));
+       PrintAndLog("Mifare dkeyB :\t %s", sprint_hex(dkeyB, sizeof(dkeyB)));
+       PrintAndLog("Mifare ABA   :\t %s", sprint_hex(dmkey, sizeof(dmkey)));
+       PrintAndLog("Mifare Pwd   :\t %s", sprint_hex(newpwd, sizeof(newpwd)));
+       
        return 0;
 }
 
        return 0;
 }
 
-// uint8_t * diversify_key(uint8_t * key){
+// static uint8_t * diversify_key(uint8_t * key){
+       
  // for(int i=0; i<16; i++){
    // if(i<=6) key[i]^=cuid[i];
    // if(i>6) key[i]^=cuid[i%7];
  // for(int i=0; i<16; i++){
    // if(i<=6) key[i]^=cuid[i];
    // if(i>6) key[i]^=cuid[i%7];
Impressum, Datenschutz