Proxmark developers community

Research, development and trades concerning the powerful Proxmark3 device.

Remember; sharing is caring. Bring something back to the community.


"Learn the tools of the trade the hard way." +Fravia

You are not logged in.

#1 2018-01-12 20:12:19

altamic
Contributor
Registered: 2018-01-12
Posts: 5

Italian city public transportation system (MF0ICU1)

In the city where I live, the local public transport company sells NFC carnets of 5 or 15 rides in the form of 14443-A NFC Forum Type 2 tags.
In the past they were Mifare Ultralight (MF0ICU1) but recently they use Infineon my-move lean (SLE66R01L).

I have collected something like 850 dumps of sequential obliterations and I have gathered most of the carnet structure/semantic [1].

The missing piece is how the last 2 bytes are computed [2]. Despite the relatively abundant data, I still have not found a correlation/mapping between the ticket data and these 16 bits –that I have improperly called "checksum".

Would you like to help me in my research?

P.S.: the corpus contains a Ruby script used to convert a structured YAML file into a sequence of ASCII hex dump files named conveniently[3].


[1]: carnet structure

0KXXYYZZ    0x88 ⊕ 0x0K ⊕ 0xXX ⊕ 0xYY = 0xZZ
GGHHIIJJ    UID: 0x0KXXYYGGHHIIJJ (represented in decimal in the receipt)
LL          0xLL = 0xGG ⊕ 0xHH ⊕ 0xII ⊕ 0xJJ
  KK        internal: 0xKK related to chip vendor identifier
    F2      Lock byte #1:
                         0xF:         1            1               1              1
                       meaning:   Page7locked, Page6locked,   Page5locked, Page4locked

                         0x2:         0            0               1              0
                       meaning:  OTPlocked, Pages10to15locked, Pages4to9locked, OTPlocked

      03    Lock byte #2:
                         0x0:         0            0               0              0
                       meaning:  Page15locked, Page14locked, Page13locked, Page12locked

                         0x3:         0            0               1              1
                       meaning:  Page11locked, Page10locked,  Page9locked,  Page8locked

MMNNOOPP    OTP: remaining rides (zero bits population in OOPP)
01LL0000    Layout -> Carnet rides
QQ01RRRR    Mask, Tariff (commercial info)
TTTTTT00    Purchase date in minutes since epoch (2005-01-01)
00######
##00%%%%    Purchase serial number (found in the receipt, represented as ########-%%%% where %%%% in decimal)
CCCCCCCC    Locked constant (maybe random)
TTTTTT00    First obliteration timestamp in minutes since epoch
04F80000    Zone
TTTTTT00    Last obliteration timestamp within 90' of validity period
PPPPPPPP    Bus line / Metro stop
F8AEHHHH    Zone, Obliterator Id part 1
HH12????    Obliterator Id part 2, constant, "checksum"

Lock bytes are F2:03 then only the last 6 pages are effectively changeable after purchase.

[2] Are they a function of UID, Locked constant, Last timestamp and/or who knows what?
I have also found some collisions: 2869, 4F11, D7EE, E4BB.

[3] dump file name structure:

              +-- rides subtracted from total
              |
              v
c15_03_minus_12M_+44.txt
  ^  ^         ^  ^
  |  |         |  +-- next obliteration within 90' of validity period (44' in this case)
  |  |         + -- M stands for a Metro entrance (it's a Bus line when not present)
  |  +-- sequential hex id for carnet
  +-- total rides

Last edited by altamic (2018-01-14 02:27:44)

Offline

#2 2018-01-13 12:39:48

iceman
Administrator
Registered: 2013-04-25
Posts: 4,275
Website

Re: Italian city public transportation system (MF0ICU1)

Someone has done his homework well. I'll take a look at it later.


modhex(hkhehghthbhudcfcdchkigiehgduiehg)

Offline

#3 2018-01-13 14:30:07

altamic
Contributor
Registered: 2018-01-12
Posts: 5

Re: Italian city public transportation system (MF0ICU1)

iceman wrote:

Someone has done his homework well. I'll take a look at it later.

Wow!! iceman!! I am honoured that you stop and look at my puzzle smile

Offline

#4 2018-01-13 15:56:57

altamic
Contributor
Registered: 2018-01-12
Posts: 5

Re: Italian city public transportation system (MF0ICU1)

I noticed that the YAML source has annoying quotes for some values.
You can remove them with:

$ sed -i "s/'//g" carnets.yaml # Linux

or

$ sed -i '' -e "s/'//g" carnets.yaml # MacOS/BSD

Last edited by altamic (2018-01-13 16:31:48)

Offline

#5 2018-01-13 18:14:25

altamic
Contributor
Registered: 2018-01-12
Posts: 5

Re: Italian city public transportation system (MF0ICU1)

The YAML file contains the carnet structure that I have represented in the first post.

In particular, I have used the following names for various fields:

uid
cb0
cb1
internal
lock
otp
layout
mask
tariff
purchase_date
serial_number
unknown
first_validation
constant_1
zone_1
last_validation
line
zone_2
constant_2
obliterator
constant_3
checksum

Such structure can be manipulated easily with unix commands.

For example, to have a list of distinct sorted UIDs you just fire up:

$ grep uid carnets.yaml | cut -d ' ' -f 4 | sort -u
0416E1CA004980
041CBB32882881
04208E5A753381
042C5002323680
043DA2CA004981
0462015A753384
0468252A3C3C84
...

or to find collisions in "checksum", you can run the longer:

$ grep checksum carnets.yaml | cut -d ' ' -f 4 | sort | uniq -c | grep ' 2 ' | cut -d ' ' -f 5
2869
4F11
BACC
D7EE
E4BB

Suppose you would like to find a conventional date for a given date/timestamp found in a ticket, say 63A3B0.
You can find it as follows:

$ date -d @$((16#63A3B0 * 60 + 1104534000)) # Linux
Thu Jun  1 17:48:00 CEST 2017

or

$ date -r $((16#63A3B0 * 60 + 1104534000)) # MacOs/BSD
Thu Jun  1 17:48:00 CEST 2017

Last edited by altamic (2018-01-14 12:57:28)

Offline

Board footer

Powered by FluxBB