Seeed-Studio / PN532

NFC library using PN532 to read/write card and communicate with android
436 stars 180 forks source link

How to write blocks of Chinese Clone Mifare card by the libs on Arduino? #31

Closed AxisRay closed 5 years ago

AxisRay commented 9 years ago

There is a program nfc-mfclassic based on libnfc with chip PN532.It's can unlock special Mifare 1K cards (Chinese clones) which can be read or write all the blocks without authentication. How can I read or write the special Mifare Card on Arduino? Thanks! In the source code of nfc-mfclassic,it send a special command 0x40 0x43.

// special unlock command
uint8_t  abtUnlock1[1] = { 0x40 };
uint8_t  abtUnlock2[1] = { 0x43 };

Here is the code of unlock in the source code of nfc-mfclassic

static bool
unlock_card(void)
{
  if (magic2) {
    printf("Don't use R/W with this card, this is not required!\n");
    return false;
  }

  // Configure the CRC
  if (nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, false) < 0) {
    nfc_perror(pnd, "nfc_configure");
    return false;
  }
  // Use raw send/receive methods
  if (nfc_device_set_property_bool(pnd, NP_EASY_FRAMING, false) < 0) {
    nfc_perror(pnd, "nfc_configure");
    return false;
  }

  iso14443a_crc_append(abtHalt, 2);
  transmit_bytes(abtHalt, 4);
  // now send unlock
  if (!transmit_bits(abtUnlock1, 7)) {
    printf("unlock failure!\n");
    return false;
  }
  if (!transmit_bytes(abtUnlock2, 1)) {
    printf("unlock failure!\n");
    return false;
  }

  // reset reader
  // Configure the CRC
  if (nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, true) < 0) {
    nfc_perror(pnd, "nfc_device_set_property_bool");
    return false;
  }
  // Switch off raw send/receive methods
  if (nfc_device_set_property_bool(pnd, NP_EASY_FRAMING, true) < 0) {
    nfc_perror(pnd, "nfc_device_set_property_bool");
    return false;
  }
  return true;
}

full source code https://github.com/nfc-tools/libnfc/blob/master/utils/nfc-mfclassic.c

xiongyihui commented 9 years ago

Not sure how it works, but you can add an unlock function in [https://github.com/Seeed-Studio/PN532/blob/master/PN532/PN532.cpp]()

AxisRay commented 9 years ago

I'm trying…… Well……Unfortunately,I'm a begainner of Arduino. I'm reading the user manual of PN532 and the source code of nfc-mfclassic.... It's seems hard for me……

aalistarh commented 8 years ago

Hi AxisRay, are you still working on this problem? I see two solutions to the problem: either with libnfclibrary as mentioned by you or by trying to adapt the code from MRC522 module from Miguel Balboa's library. Are you still working on this?

aalistarh commented 8 years ago

I am trying to see if I can configure the library to do what you said, but I admit it needs some attention.

AxisRay commented 8 years ago

@aalistarh I have solved the problem you can see my repositories mifarecloner there is a method called Unlock()

AxisRay commented 8 years ago

@aalistarh I have solved the problem you can see my repositories mifarecloner there is a method called Unlock()

aalistarh commented 8 years ago

Awsome, I will try it. Thank you very much.

aalistarh commented 8 years ago

Hi AxisRay,

Although I have managed to use your code, I did not manage to write a new UID to the chinese card. Basically, this is what I have in the loop function:


void loop(void) {
   uint32_t id;

 uint8_t block_0[16] = {0xCC, 0xDD, 0xAA, 0xBB, 0x00, 0x00, 0x0A, 0xCB, 0xC8, 0x5D, 
 0x55, 0x81, 0x01, 0x33, 0x03, 0x03};

   if(!Unlock){
    Serial.println("Failed to activate backdoor technique...");

    }else{
        nfc.authenticateBlock(1,id,0,KEY_A,keyList[0]);
        if (nfc.writeMemoryBlock(1, 1, block_0)){
            Serial.println("\nSuccess");
        }else
        {
           Serial.println("\nWriting uid failed....try again");
          }

       id = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A);
      nfc.authenticateBlock(1,id,0,KEY_A,keyList[0]);
       uint8_t block[16];
      if(nfc.readMemoryBlock(1, 0, block)){
           Serial.print("UID:");
           Serial.print(id, HEX); 
           Serial.println("\nNow write a new one...");

   } else{
     Serial.println("Read failed...");
     }
   }
    delay(50);
}

An this is the ouput which I am getting when trying a chinese card:

Hello!
Found chip PN53
Firmware ver. 50.1
Supports 6

Writing uid failed....try again
UID:CCA11178
Now write a new one...

Writing uid failed....try again
UID:CCA11178
Now write a new one...

Any thoughts on what might I have done wrong? The key from the card is the first one in the array you have.

Many thanks.

aalistarh commented 8 years ago

I have tried to write my data to address 2 and this worked but it did not work for byte 0. I think there is a problem with the unlock method, or I am not using the library properly. Thank you.

AxisRay commented 8 years ago

@aalistarh I have reviewed your code Be careful if the Unlock() function was called successfully there is no need to call authenticateBlock() to auth the block you can read or write immediately see the following code in my repositories

  lcd.print("Unlocking...    ");
  if(!Unlock()){
    ErrorReport(-1,"Unlock Failed!  ");
    return;
  }
  lcd.setCursor(0,0);
  lcd.print("Force Writing...");
  int addr=0;
  for(int blockn=0; blockn<64; blockn++){
    lcd.setCursor(blockn/4, 1);
    lcd.print("*");
    uint8_t block[16];
    for (int j = 0; j < 16; j++) {
      block[j] = EEPROM.read(addr);
      addr++;
    }
    if (!nfc.writeMemoryBlock(1, blockn, block)){
      ErrorReport(blockn,"Write Fail! R?");
      return;
    }
  }
ReturnToMenu();
aalistarh commented 8 years ago

Hi AxisRay,

Thanks for your understanding with this. Don't worry, your English is perfect. I am still having difficulty with this. I do not have a lcd so I use the system monitor to view the faults. So I have removed the LCD code. Further, I have installed a fresh copy of your library to make sure nothing wrong was happening. I am also sure that the cards I use have changeable uids since I use libnfc and works very well.

This is what I managed to do. I do not know why unlocking fails. Should I check the sequence?

void loop(void) {
uint32_t id;
  bool success;

 uint8_t block_0[64] = {0xCC, 0xDD, 0xAA, 0xBB, 0x00, 0x00, 0x0A, 0xCB, 0xC8, 0x5D, 
 0x55, 0x81, 0x01, 0x33, 0x03, 0x03,0xCC, 0xDD, 0xAA, 0xBB, 0x00, 0x00, 0x0A, 0xCB, 0xC8, 0x5D, 
 0x55, 0x81, 0x01, 0x33, 0x03, 0x03,0xCC, 0xDD, 0xAA, 0xBB, 0x00, 0x00, 0x0A, 0xCB, 0xC8, 0x5D, 
 0x55, 0x81, 0x01, 0x33, 0x03, 0x03,0xCC, 0xDD, 0xAA, 0xBB, 0x00, 0x00, 0x0A, 0xCB, 0xC8, 0x5D, 
 0x55, 0x81, 0x01, 0x33, 0x03, 0x03};

 Serial.println("\nUnlocking...    ");
  if(!Unlock()){
    Serial.println("\nUnlock Failed!");
  }
  Serial.println("\nForce Writing...");
  int addr=0;
  for(int blockn=0; blockn<64; blockn++){
    uint8_t block[16];
    for (int j = 0; j < 16; j++) {
      block[j] = block_0[addr];
      addr++;
    }
    if (!nfc.writeMemoryBlock(1, blockn, block)){
      Serial.println("Write Fail! R? at index:  ");
      Serial.println(blockn);
      return;
    }
  }

       id = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A);
      nfc.authenticateBlock(1,id,0,KEY_A,keyList[0]);
       uint8_t block[16];
      if(nfc.readMemoryBlock(1, 0, block)){
           Serial.print("UID:");
           Serial.print(id, HEX); 
           Serial.println("\nNow write a new one...");

   } else{
     Serial.println("Read failed...");
     }

    delay(50);

}

The output on the system monitor:

Hello!
Found chip PN53
Firmware ver. 50.1
Supports 6

Unlocking...    

Unlock Failed!

Force Writing...
Write Fail! R? at index:  
0

Unlocking...    

Unlock Failed!

Force Writing...
Write Fail! R? at index:  
0

I am sure there must be something I am missing, but I can't figure it out. I am using an Elechouse V3 board which has a pn532. I should work the same as the Seed PN532 board because I ran several examples before and they worked with Elechouse v3.

My pin connections are SS - 10 SCK-13 MOSI-11 MISO-12

Could it be the baud rate?

Thank you very much.

Best wishes, Cristian

AxisRay commented 8 years ago

@aalistarh It has been a long time since I write these code I will test it again as soon as possible

aalistarh commented 8 years ago

Thank you for your help.

aalistarh commented 8 years ago

Hi AxisRay, I have not managed to unlock it yet, but I noticed that you append the 0X43 for every unlock command buffer. Why is that? Also, I am not sure what WriteRegister is about. Could you explain? I know that to get it in special mode, one has to send a 7bit command. Does InCommunicateThru send 7 bits? Thank you.

AxisRay commented 8 years ago

you can see UNLOCK.txt in my repository it record some DEBUG information of nfc-mfclassic maybe you should read pn532 user manual to figure it out i combined the user manual and DEBUG info to write these code It has a long time passed since i writed these. i need time to review unfortunately i am really busy recently :(

AxisRay commented 8 years ago

in aadition, i have borrowed a Arduino Uno board yesterday . i plan to test it in this weekend

AxisRay commented 8 years ago

addition

aalistarh commented 8 years ago

Thank you very much.

AxisRay commented 8 years ago

@aalistarh Are you sure your Mifare Card can be “unlocked” ? The function Unlock only works with special Mifare 1K cards (Chinese clones) you can try to use nfc-mfclassic to test your Mifare card first ··· nfc-mfclassic R a dumpfile.mfd ···

aalistarh commented 8 years ago

Hi Axis Ray,

Thank you for your message.

Yes, this is the code I get when enter the command you said:


NFC reader: pn532_uart:/dev/tty.SLAB_USBtoUART opened
Found MIFARE Classic card:
ISO/IEC 14443A (106 kbps) target:
    ATQA (SENS_RES): 00  04  
       UID (NFCID1): 24  2d  31  00  
      SAK (SEL_RES): 08  
Guessing size: seems to be a 1024-byte card
Sent bits:     50  00  57  cd  
Sent bits:     40 (7 bits)
Received bits: a (4 bits)
Sent bits:     43  
Received bits: 0a  
Reading out 64 blocks |................................................................|
Done, 64 of 64 blocks read.
Writing data to file: dumpfile.mfd ...Done.
I:examples Alex$ 

They also work great with nfc-mfsetuid AABBCCDD.

I:examples Alex$ nfc-mfsetuid AABBCCDD
NFC reader: pn532_uart:/dev/tty.SLAB_USBtoUART opened
Sent bits:     26 (7 bits)
Received bits: 04  00  
Sent bits:     93  20  
Received bits: 24  2d  31  00  38  
Sent bits:     93  70  24  2d  31  00  38  78  f1  
Received bits: 08  b6  dd  

Found tag with
 UID: 242d3100
ATQA: 0004
 SAK: 08

Sent bits:     50  00  57  cd  
Sent bits:     40 (7 bits)
Received bits: a (4 bits)
Sent bits:     43  
Received bits: 0a  
Sent bits:     a0  00  5f  b1  
Received bits: 0a  
Sent bits:     aa  bb  cc  dd  00  08  04  00  46  59  25  58  49  10  23  02  86  9a  
Received bits: 0a  
I:examples Alex$ nfc-poll
nfc-poll uses libnfc 1.7.1
NFC reader: pn532_uart:/dev/tty.SLAB_USBtoUART opened
NFC device will poll during 30000 ms (20 pollings of 300 ms for 5 modulations)
ISO/IEC 14443A (106 kbps) target:
    ATQA (SENS_RES): 00  04  
       UID (NFCID1): aa  bb  cc  dd  
      SAK (SEL_RES): 08  
nfc_initiator_target_is_present: Target Released
Waiting for card removing...done.
I:examples Alex$ 
aalistarh commented 8 years ago

But, unfortunately, they do not work with the Unlock() function. It seemed to me you have the same sequence as nfc-mfsetuid starting with 50 00 57 cd but I do not know why it does not work in Arduino IDE

AxisRay commented 8 years ago

@aalistarh not strange Unlocking divided into three steps Halt Unlock1 Unlock2

AxisRay commented 8 years ago

50 00 57 Halt command

AxisRay commented 8 years ago

00 00 ff 06 fa d4 42 50 00 57 cd 76 00 00 00 ff Header 06 Length fa Length check sum d4 Host to PN532 42 InCommunicateThru 50 00 57 command ……

AxisRay commented 8 years ago

there seems nothing wrong it should work :( which lib do you use? PN532_SPI.h in my repo?

aalistarh commented 8 years ago

Hi Axis Ray. Yes, I used yours. Sorry, I am at work today, so I will look at it as soon as I get home.

aalistarh commented 8 years ago

I am thinking maybe you can put your most recent library or files unless you have just got a fresh copy from the repo.

Pillar1989 commented 5 years ago

I'll close the issues and open it again if you need to discuss it later.

mac3d0 commented 5 years ago

I have the same problem. But I use an ACR122U, I can not write in block 0 of the Chinese card, I do this feat of a Kali Linux. Is it if I edit the nfc-mfclassic source code and uncomment the unlock function works?