Daniel Burov
My online land

My Latest Project:

Reverse Engineering Squid Loyalty NFC tags

Squid Loyalty is a digital loyalty card platform. It works by the vendor having a Squid NFC tag that when a customer purchases a qualifying product can scan the tag with the Squid loyalty app. That then adds a “digital stamp” to their “digital loyalty card”. When the customers have enough “digital stamps” can exchange them for goods at the vendor such as free coffee.

With my flipper zero I have managed to get the contents/data of one of the Squid NFC tags. And reverse engineer how the tags work.

From reading the contents of the tag it is found that: The NFC tag used is an NTAG213 that which each tag has its own specific UID which is a 7-byte number written in hex.

The tag contains 45 pages of data. Each page holds 4 bytes of data. Each byte is stored as a hexadecimal value. meaning the tag stores 180 bytes of information which is specified by the manufacturer.

From reading the data sheet of the NTAG213 by the manufacturer NXP it was figured that:

In pages 0,1,2 the UID of the tag is stored along with 2 check bytes and lock bytes that are used to lock the card to read-only (this could be an attack, to rewrite the Squid tags). How the bytes are stored can be seen below.

pages012

Check byte 0 is defined as CT (cascade byte = 0x88) xor UID0 xor UID 1 XOR UID2. Check byte 1 is defined as UID3 xor UID4 xor UID5 xor UID6. where UID0 is the 1st byte in the UID number.

Pages 3, 4, 5 are preprogrammed constants that are specified in the datasheet.

pages345

Pages 6 to 39 are for user memory. This is where the user decides what data to write to the tag.

Pages 40 to 45 are for other details but are not important to the contents of the Squid tag. But they are kept constant.

A summary of what the data structure is like for the NTAG 213.

datasummary

This was the same as what was found in the data of the Squid NFC tag.

Analyzing the data in the User memory pages. It is seen that the Squid tag only contains 35 bytes of User data. and the rest of the data is blank.

The 35 bytes of user data are encoded in hexadecimal. Using a hex to ASCII decoder the information read TenSquidQTen04XXXXXXXXXXXX. Ignoring the markers it can be seen that this is 2 pieces of information:

  • SquidQ , I think this is for identifying the tag as a Squid tag.
  • 04XXXXXXXXXXXX , This is the UID of the tag.

After finding this information. I speculated that the loyalty program for each vendor depends on the UID of its specific tag. I was able to create tags for different UIDs and using the flipper zero I emulated each tag along with its UID and its specific data.

After trying a few different UID I was able to get a tag that was not the original tag to be scanned by the app. This tag was for a different vendor. My speculation was correct that the loyalty program depends on the UID of each tag.

I created a bash script to mass-create NFC tags for different UIDs and have managed to collect over 100 different tags for different vendors that can be scanned and redeemed for a free item. =]

This info along with the bash script can be found on my GitHub. =]