Topic: Read/Write a MIFARE 1/4k tag, again

Hi, i want to read/write a MIFARE 1k tag with libnfc.

I've downloaded the ".mfd" dump file from the site and I've replaced the UID with the correct one, then i've launched the mftool program:

./nfc-mftool r a keys.mfd dump.mfd

But the result is:

...
Connected to NFC reader: ARYGON - PN532 v1.6 (0x07)

TX: 32  00  00  ff  04  fc  d4  4a  01  00  e1  00  
RX: 00  00  ff  00  ff  00  00  00  ff  0c  f4  d5  4b  01  01  00  04  08  04  1c  2b  6a  2b  f2  00  

Found MIFARE Classic 1K card with uid: 1c2b6a2b
Reading out 64 blocks |

TX: 32  00  00  ff  0f  f1  d4  40  01  60  3f  ff  07  80  bc  ff  ff  1c  2b  6a  2b  30  00  
RX: 00  00  ff  00  ff  00  

Error: authentication failed for block 3f

Please, help me smile

Re: Read/Write a MIFARE 1/4k tag, again

First of all, the UID don't need to be fixed, it just gives a warning, that's all.

You are sending the following bytes

.. 60  3f  ff  07  80  bc  ff  ff  1c  2b  6a  2b ..

Which means:
60 = Authenticate use key A
3f = block 0x3f
key = ff  07  80  bc  ff  ff
uid = 1c  2b  6a  2b

Is the key for your MIFARE Classic tag correct for block 0x3f ?

Re: Read/Write a MIFARE 1/4k tag, again

Honestly, I don't know.

How can I read the key A (and B) from a generic MIFARE Classic tag (if I can)?

Re: Read/Write a MIFARE 1/4k tag, again

if you have an empty MIFARE Classic tag usually they come with the default transport keys FF FF FF FF FF FF or A0 B0 C0 D0 E0 F0 or A1 B1 C1 D1 E1 F1...

The key inside the dump is ff  07  80  bc  ff  ff for sector 3. However this might not be the case for your tag so you have to change this to a key that corresponds to sector 3 of your tag. You either know that or you can try to "retrieve" it, but thats a different story wink

Re: Read/Write a MIFARE 1/4k tag, again

Ok...but: I've sent a vCard from a Nokia 6212 to a MIFARE Classic 1k tag. After that I can't read the tag with the default key.

Last edited by zuck (2009-09-21 13:04:16)

Re: Read/Write a MIFARE 1/4k tag, again

Hey Zuck,

zuck wrote:

I've sent a vCard from a Nokia 6212 to a MIFARE Classic 1k tag. After that I can't read the tag with the default key.

I'm not sure about that but i think that Nokia devices put Nokia's keys on MIFARE Classic card when it send some datas.

Hope it helps.

Romuald Conty

Re: Read/Write a MIFARE 1/4k tag, again

Ok. This is my supposition too, and now I can say that...I hate Nokia tongue

If I try to read the tag written by the mobile phone, the authentication fails at block 0x17.

Re: Read/Write a MIFARE 1/4k tag, again

zuck wrote:

Ok. This is my supposition too, and now I can say that...I hate Nokia tongue

Hmm, not sure that's a good reason to hate Nokia: if NFC mobile device see a blank MIFARE Classic card and user ask for putting some Nokia's data on it, why don't put Nokia's keys...

zuck wrote:

If I try to read the tag written by the mobile phone, the authentication fails at block 0x17.

Like MIFARE Classic is NOT secured at all, keys can be recovered... So with some work, you will be able te read Nokia data smile
I hope a Free (Libre) tool based on libnfc will be released to recover MIFARE Classic keys but no one have been reported in "External Projects that use libnfc" section for now.

Romuald Conty

Re: Read/Write a MIFARE 1/4k tag, again

rconty wrote:

I hope a Free (Libre) tool based on libnfc will be released to recover MIFARE Classic keys but no one have been reported in "External Projects that use libnfc" section for now.

--
Romuald

Working on my free time on it as it is interesting, however i believe alot of people already have managed to code such tools. I dont know however about the legal implications of circulating such a tool. But with all those academic papers and attacks outhere dont think there would be any. It's time somebody puts the last nail to MIFARE Classic! big_smile

Re: Read/Write a MIFARE 1/4k tag, again

I just wrote a VCARD to a MIFARE Classic tag and recovered the keys:

block 00...keyA: a0a1a2a3a4a5
block 00.....keyB: d3f7d3f7d3f7
block 04...keyA: d3f7d3f7d3f7
block 04...keyB: d3f7d3f7d3f7
block 08...keyA: d3f7d3f7d3f7
block 08...keyB: d3f7d3f7d3f7
block 0c...keyA: d3f7d3f7d3f7
block 0c...keyB: d3f7d3f7d3f7
block 10...keyA: d3f7d3f7d3f7
block 10...keyB: d3f7d3f7d3f7
block 14......keyA: ffffffffffff
block 14...keyB: ffffffffffff
block 18...keyA: ffffffffffff
block 18...keyB: ffffffffffff
.... etc...

Only the keys from block 0x00 t/m 0x10 seems to be changed.
Can anyone check if these are the default keys (always used) for transmitting a VCARD?

More default keys I have seen floating around are:

  ffffffffffff
  a0a1a2a3a4a5 
  b0b1b2b3b4b5
  4d3a99c351dd 
  1a982c7e459a
  000000000000 
  d3f7d3f7d3f7
  aabbccddeeff

Taken from my lecture

Re: Read/Write a MIFARE 1/4k tag, again

This is my read function:

dev_info* m_nfcAdaptor;
tag_info m_info;

bool pkNfcTagHandle::readMifareClassic()
{
    mifare_param mp;
    int size = (this->type() == pkNfcMifareClassic1k) ? 0x3f : 0xff;
    
    if (m_nfcAdaptor)
    {
        // Read the card from begin to end.
        for (int block = 0; block <= size; block++)
        {
            // Authenticate everytime we reach a trailer block.
            if (is_trailer_block(block))
            {
                // Set the authentication information (uid).
                memcpy(mp.mpa.abtUid, m_info.tia.abtUid, 4);
        
                // Try to authenticate for the current sector, first with the B key
                // then with the A one.
                if (!mifare_classic_autenthicate(m_nfcAdaptor, mp, block))
                    this->setErrorString(tr("Failed to authenticate for block %1 of a MIFARE Classic tag.").arg(block));
                
                continue;
            }
            
            // Try to read out the data block.
            if (!nfc_initiator_mifare_cmd(m_nfcAdaptor, MC_READ, block, &mp))
            {
                if (!nfc_initiator_select_tag(m_nfcAdaptor, IM_ISO14443A_106, NULL, 0, &m_info))
                {
                    this->setErrorString(tr("MIFARE Classic tag (UID %1) removed.").arg((char*)m_info.tia.abtUid));
                    return false;
                }
                
                if (!nfc_initiator_mifare_cmd(m_nfcAdaptor, MC_READ, block, &mp))
                {
                    this->setErrorString(tr("Failed to read the block %1 from the MIFARE Classic tag.").arg(block));
                    return false;
                }
            }
    
            m_buffer.append((const char*)mp.mpd.abtData, 16);
        }

        return true;
    }
    
    return false;
}

Which uses this authentication function:

bool mifare_classic_autenthicate(dev_info* device, mifare_param mp, uint32_t block)
{
    byte_t keys[] = {
        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,
        0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,
        0x4d,0x3a,0x99,0xc3,0x51,0xdd,
        0x1a,0x98,0x2c,0x7e,0x45,0x9a,
        0x00,0x00,0x00,0x00,0x00,0x00,
        0xd3,0xf7,0xd3,0xf7,0xd3,0xf7,
        0xaa,0xbb,0xcc,0xdd,0xee,0xff
    };
    
    int num_keys = sizeof(keys) / 6;
    
    for (int i = 0; i < num_keys; i++)
    {
        memcpy(mp.mpa.abtKey, keys + (i * 6), 6);
                        
        if (nfc_initiator_mifare_cmd(device, MC_AUTH_A, block, &mp))
            return true;
                
        if (nfc_initiator_mifare_cmd(device, MC_AUTH_B, block, &mp))
            return true;
    }
    
    return false;
}

The authentication returns true but the next read command fails and I don't know why.

Last edited by zuck (2009-09-26 13:31:21)

Re: Read/Write a MIFARE 1/4k tag, again

Small update: with your key pattern I can read the MIFARE tag written by the Nokia mobile phone (many thanks roel! smile), but I don't know why my read procedure doesn't work.

Re: Read/Write a MIFARE 1/4k tag, again

Hey Zuck,

After a failed auth() the tag deactivates (HALT). You have to activate it again by sending a WUPA.
You can do this by re-using the nfc_initiator_select_tag() function.

Be aware though that you have to supply the UID as "initiator data", if you leave those empty it will send a REQA, which will get no response.

bool mifare_classic_autenthicate(dev_info* device, tag_info* pti, uint32_t block)
{
  mifare_param mp;
  byte_t keys[] = {
    0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
    0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,
    0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,
    0x4d,0x3a,0x99,0xc3,0x51,0xdd,
    0x1a,0x98,0x2c,0x7e,0x45,0x9a,
    0x00,0x00,0x00,0x00,0x00,0x00,
    0xd3,0xf7,0xd3,0xf7,0xd3,0xf7,
    0xaa,0xbb,0xcc,0xdd,0xee,0xff
  };
  
  int num_keys = sizeof(keys) / 6;
  int i;
  
  memcpy(mp.mpa.abtUid, pti->tia.abtUid, 4);
  for (i = 0; i < num_keys; i++)
  {
    nfc_initiator_select_tag(pdi,IM_ISO14443A_106,pti->tia.abtUid,4,NULL);
    memcpy(mp.mpa.abtKey, keys + (i*6), 6);
    if (nfc_initiator_mifare_cmd(device, MC_AUTH_A, block, &mp))
      return true;
    
    nfc_initiator_select_tag(pdi,IM_ISO14443A_106,pti->tia.abtUid,4,NULL);
    if (nfc_initiator_mifare_cmd(device, MC_AUTH_B, block, &mp))
      return true;
  }
  return false;
}

Re: Read/Write a MIFARE 1/4k tag, again

Thanks, but I think the real problem is here:

// Try to read out the data block.
if (!nfc_initiator_mifare_cmd(m_nfcAdaptor, MC_READ, block, &mp))
{
    if (!nfc_initiator_select_tag(m_nfcAdaptor, IM_ISO14443A_106, NULL, 0, &m_info))
    {
        this->setErrorString(tr("MIFARE Classic tag (UID %1) removed.").arg((char*)m_info.tia.abtUid));
        return false;
    }
                
    if (!nfc_initiator_mifare_cmd(m_nfcAdaptor, MC_READ, block, &mp))
    {
        this->setErrorString(tr("Failed to read the block %1 from the MIFARE Classic tag.").arg(block));
        return false;
    }
}

In some blocks, after a correct authentication, the read command fails. I don't see particular conceptual differences between my code and the mftool one...Any ideas?

Last edited by zuck (2009-09-28 10:39:39)

Re: Read/Write a MIFARE 1/4k tag, again

Are you sure the access conditions of the blocks are not making them "unreadable" using a certain key (A or B)?

Re: Read/Write a MIFARE 1/4k tag, again

If I start to read from the begin of the memory (block 0), the function fails at block 25. If I start from the end of the memory, it fails at block 63.

The tag content is a vcard written by a Nokia 6212 phone.