Secure Network S.r.l.

advertisement
How to build a safe NFC validating
system
Matteo Collura (Eagle1753) & Matteo Beccaro (bughardy)
eagle1753@onenetbeyond.org - bughardy@cryptolab.net
Who we are
•
•
•
•
•
Matteo Collura
Nickname: Eagle1753
Twitter: @Eagle1753
Mail: eagle1753@onenetbeyond.org
Student at Politecnico of Turin:
Electronic Engineering
• Matteo Beccaro
• Nickname: bughardy
• Twitter: @_bughardy_
• Mail: bughardy@cryptolab.net
• Student at Politecnico of Turin:
Computer Engineering
• Employee at Secure Network
• Both speakers at DefCon 21 («OTP it won’t save you from free rides»)
What we are dealing with
• MIFARE ULTRALIGHT tags, as tickets
– Designed to work @ 13.56 MHz
– Manufactured by NXP Semiconductors
• Arduino Uno with NFC shield, as stamping machine
– Shield NFC by Adafruit
MIFARE ULTRALIGHT, Facts&Figures
Structure
• 512 bits (64 bytes) arranged in 16 pages
Page Address
DEC
Byte #
HEX
0
1
2
0
0x00
UID
1
0x01
UID
2
0x02
3
0x03
OTP
From 4 to 15
0x04 to 0x0F
Data
UID
Internal
Lock Bytes
3
Lock Bytes
UID + Internal
• 7 Bytes «Serial Number» + 1 Byte «Internal»
• 2 «Check Bytes», as a result of XOR operations
Byte 0
Byte 1
Byte 2
Byte 3
Page 00h
SN0
SN1
SN2
CB0
Page 01h
SN3
SN4
SN5
SN6
Page 02h
CB1
Internal
Lock bytes
Page Address
• Programmed by the manifacturer, read only
DEC
HEX
Byte #
0
1
2
3
Lock
Bytes
Lock
Bytes
0
0x00
UID
1
0x01
UID
2
0x02
3
0x03
OTP
From 4
to 15
0x04 to
0x0F
Data
UID
Internal
Lock Bytes
• 2 Bytes
L- 7
L- 6
L- 5
L- 4
L - OTP
BL – 10
to 15
BL – 4
to 9
BL OTP
L -15
L -14
L - 13
L - 12
L - 11
L - 10
L- 9
L- 8
• Possibility of making a whole page (4 bytes) read-only
• Possibility of making the Lock Bytes
themselves read-only
Page Address
DEC
HEX
Byte #
0
1
2
3
Lock
Bytes
Lock
Bytes
0
0x00
UID
1
0x01
UID
2
0x02
3
0x03
OTP
From 4
to 15
0x04 to
0x0F
Data
UID
Internal
Lock Bytes
• They can’t be edited as you want
– What you are about to write is simply bitwise Ored
OR
0
1
0
0
1
1
1
1
Page Address
– One bit in state «1» cannot be turned into «0»
anymore
DEC
HEX
Byte #
0
1
2
3
Lock
Bytes
Lock
Bytes
0
0x00
UID
1
0x01
UID
2
0x02
3
0x03
OTP
From 4
to 15
0x04 to
0x0F
Data
UID
Internal
OTP
• The only security function in MIFARE ULTRALIGHT tags
• 4 bytes, 0x00 by default
• As the Lock Bytes, what you are about to write is ORed with the previous
• It stands for «One-Time Programmable»,
not «One Time Password»
Page Address
DEC
HEX
Byte #
0
1
2
3
Lock
Bytes
Lock
Bytes
0
0x00
UID
1
0x01
UID
2
0x02
3
0x03
OTP
From 4
to 15
0x04 to
0x0F
Data
UID
Internal
OTP
• Used for storing the number of rides left in a multiple-ride ticket
• Example of writing on OTP sector
Data to be written
00110101
00001101
11000110
11110010
Data previously written
11100100
00100001
00110110
00111010
Final result
11110101
00101101
11110110
11111010
Page Address
DEC
HEX
Byte #
0
1
2
3
Lock
Bytes
Lock
Bytes
0
0x00
UID
1
0x01
UID
2
0x02
3
0x03
OTP
From 4
to 15
0x04 to
0x0F
Data
UID
Internal
Data
• Widest sector
– 48 Bytes, arranged in 12 pages
• Read/Write mode
• As regards transportation system applications you find here:
– Time of last stamp
– Validator Machine ID
– Bus line or underground stop
Page Address
DEC
HEX
Byte #
0
1
2
3
Lock
Bytes
Lock
Bytes
0
0x00
UID
1
0x01
UID
2
0x02
3
0x03
OTP
From 4
to 15
0x04 to
0x0F
Data
UID
Internal
Pro & Cons of MIFARE ULTRALIGHT tags
Cons
Pros
• Cheap
• No hardware encryption
• Possibility of creating limited
tickets
– They expire after a finite
number of times
– Good for public
transportation system
• Usually not well implemented
on public transportation
systems:
– Reset Attack
– Lock Attack
– Time Attack
– Replay Attack
Known Vulnerabilities
Reset Attack [2011]
• It works if the rides are stored in the data sector
– Just dump a fresh ticket
– Once it is expired write the previous dump on the ticket
– Have fun with your restored ticket !
• Hardly appliable as it is a well known exploit (theoretically speaking)
Lock Attack [2013]
• It works fine if the stamp machine does not check the lock bit of the OTP
L- 7
L- 6
L- 5
L- 4
L - OTP
BL – 10
to 15
BL – 4
to 9
BL OTP
L -15
L -14
L - 13
L - 12
L - 11
L - 10
L- 9
L- 8
• Just turn it from state «0» to «1»
• Have fun with your ticket for life !
Page Address
DEC
HEX
Byte #
0
1
2
3
Lock
Bytes
Lock
Bytes
0
0x00
UID
1
0x01
UID
2
0x02
3
0x03
OTP
From 4
to 15
0x04 to
0x0F
Data
UID
Internal
Lock Attack [2013]
• Quick summary:
– Check last time stamp more than X min ago:
• No  the ticket is still valid
• Yes  let’s stamp the the ticket
Typeleft:
of multiple ride ticket = 5 rides ticket
– Check if there are rides
» No  your ticket is useless
Ticket is valid, Rides left = 5
» Yes  let’s stamp it!
• Write timestamp  OK
• Write other stuff  OK
• Write the new number of rides left Fail
Whoops
• No feedback  WIN
• Do Not forget to take one ride off !
Time Attack [2013]
• Assume you know:
– Where the time of last stamp is stored
– It is not encrypted
• Stamp the ticket by yourself:
– Just write the actual time in the same way & location
• Fully Undetectable:
– Just doing the stamp machine work
– Number of rides left doesn’t change
Replay Attack [Never applied]
• Assume that data regarding timestamp is encrypted:
– Non-univocal parameters are used
• I.e. Everything that is not unique for the ticket (UID)
• A possible encryption could be:
– AES (timestamp,key)
• Replay the encrypted timestamp on several tickets
How to build a safe ticketing system
How to build a safe ticketing system
• Fix the previous vulnerabilities:
– Reset Attack:
Rides left must not be stored in DATA sector
– Lock Attack:
Possibility of writing on the OTP sector
• Check if the lock bit state is 1 or 0
– If 1  Do not stamp the ticket
– If 0  Do the usual operations
How to build a safe ticketing system
• Fix the previous vulnerabilities:
– Time Attack:
Encrypt those kind of data
– Replay Attack:
Use univocal ticket detail (as UID) while generating encrypted string
The Sample Lib
The Sample Lib
• Arduino + NFC Shield by Adafruit + hours in coding = a little sample lib.
– encrypt_aes()
– valid_or_not()
– otp_check()
– power() // just power function, the one in Math.h sucks
– rides_check()
– remove_rides()
• Just an example to point out the functions which are necessary to get a
«secure» ticketing system.
Why «secure»?
• Unfortunately it is not 100% safe,
but it could well be enough secure
– We are going to see this later.
The Sample Lib
encrypt_aes(int result[64])
• It requires an array of size 64 on the ticket where to write the encrypted
actual timestamp
– Unix timestamp divided by 60 to get minutes, more useful to be checked
• The encryption algorithm used is AES128
(NSA didn’t pay us, or better, not so much)
• By default, we used a strong key
• Use of the UID to prevent replay attacks
• The final result is:
aes(timestamp()/60 + UID, key)
The Sample Lib
valid_or_not()
• It does exactly the opposite job of encrypt_aes()
– It reads and decrypt all the encrypted data and check if
• Actual timestamp() – stored timestamp() < 100
– We chose 100 minutes for our sample
The Sample Lib
otp_check(char* lock_page)
• Fundamental function to avoid the lock attack.
• It takes as input the lock_page of the ticket
– It checks if the OTP lock bit is set to 1 or 0,
replying 0 or 1 respectively
• You can easily refuse to stamp the ticket
if OTP is read-only.
The Sample Lib
otp_check(char* lock_page)
• It takes as input the OTP page:
– Checks how many zeroes are there
– One zero = one ride left
• It gives the number of zeroes left as output.
• Note:
In this sample lib we used only half size of OTP sector. So, you can have just
16 rides per ticket. You can easily edit it to get up to 16 rides more.
The Sample Lib
remove_rides(char* otp)
• It takes the OTP page as input
• It writes on the ticket the new OTP page, taking one ride off
– It just turns one bit from «0» into «1»
• It returns 1 if the operation goes through
• Note:
This function does not check whether the OTP is writable or not. It is
already done by otp_ckeck(char* lock_page)
What if you don’t use
otp_check(char* lock_page)
• Something like this may occur
Type of multiple ride ticket = 5 rides ticket
Ticket is valid, Rides left = 5
WTF???
Issues regarding the Sample Lib
Issues regarding the Sample Lib
• Everything is very nice, but...
It is not 100% secure... Why?
– Security features are all in the ticket
– RFID frequencies could be jammed
– There aren’t any live statistics about what is happening to your network
• By using this lib you can create a system that is enough secure for a little
transport network
• As regards the bigger ones...
Issues regarding the Sample Lib
• ... Use an online database.
• If it is possible to connect the stamping machines to the network, you can
share a db with the following data:
– UID of stamped tickets
– Rides left for each ticket
– Blacklist of UID tickets
– Update key for stamping machines
– Company stats
• Number of tickets used per day
• Lines used most
A little contribute
• We love bitcoins
• BTC address:
1nfciKph3dfCgHAwUiCA4Qq9KTkn872Pj
• If you appreciated our job, please send us a little
help.
• If you want to implement our lib on your system
please let us know that.
• We are glad to receive suggestions and also
criticisms.
Thank you!!
Download