Presentation on theme: "Eagle1753@onenetbeyond.org - firstname.lastname@example.org How to build a safe NFC validating system Matteo Collura (Eagle1753) & Matteo Beccaro (bughardy)"— Presentation transcript:
email@example.com - firstname.lastname@example.org How to build a safe NFC validating system Matteo Collura (Eagle1753) & Matteo Beccaro (bughardy)-
2Who we are Matteo Collura Matteo Beccaro Nickname: Eagle1753 Mail:Student at Politecnico of Turin: Electronic EngineeringMatteo BeccaroNickname: bughardyMail:Student at Politecnico of Turin: Computer EngineeringEmployee at Secure NetworkBoth speakers at DefCon 21 («OTP it won’t save you from free rides»)
3What we are dealing with MIFARE ULTRALIGHT tags, as ticketsDesigned to MHzManufactured by NXP SemiconductorsArduino Uno with NFC shield, as stamping machineShield NFC by Adafruit
5Structure 512 bits (64 bytes) arranged in 16 pages Page Address Byte # DECHEX1230x00UID0x010x02InternalLock Bytes0x03OTPFrom 4 to 150x04 to 0x0FData
6UID + Internal 7 Bytes «Serial Number» + 1 Byte «Internal» 2 «Check Bytes», as a result of XOR operationsProgrammed by the manifacturer, read onlyByte 0Byte 1Byte 2Byte 3Page 00hSN0SN1SN2CB0Page 01hSN3SN4SN5SN6Page 02hCB1InternalLock bytesPage AddressByte #DECHEX1230x00UID0x010x02InternalLock Bytes0x03OTPFrom 4 to 150x04 to 0x0FData
7Lock Bytes2 BytesPossibility of making a whole page (4 bytes) read-onlyPossibility of making the Lock Bytesthemselves read-onlyL - 7L - 6L - 5L - 4L - OTPBL – 10 to 15BL – 4 to 9BL - OTPL -15L -14L - 13L - 12L - 11L - 10L - 9L - 8Page AddressByte #DECHEX1230x00UID0x010x02InternalLock Bytes0x03OTPFrom 4 to 150x04 to 0x0FData
8Lock Bytes They can’t be edited as you want OR 1 What you are about to write is simply bitwise OredOne bit in state «1» cannot be turned into «0»anymoreOR1Page AddressByte #DECHEX1230x00UID0x010x02InternalLock Bytes0x03OTPFrom 4 to 150x04 to 0x0FData
9OTP The only security function in MIFARE ULTRALIGHT tags 4 bytes, 0x00 by defaultAs the Lock Bytes, what you are about to write is ORed with the previousIt stands for «One-Time Programmable»,not «One Time Password»Page AddressByte #DECHEX1230x00UID0x010x02InternalLock Bytes0x03OTPFrom 4 to 150x04 to 0x0FData
10Data previously written OTPUsed for storing the number of rides left in a multiple-ride ticketExample of writing on OTP sectorData to be writtenData previously writtenFinal resultPage AddressByte #DECHEX1230x00UID0x010x02InternalLock Bytes0x03OTPFrom 4 to 150x04 to 0x0FData
11Data Widest sector Read/Write mode 48 Bytes, arranged in 12 pagesRead/Write modeAs regards transportation system applications you find here:Time of last stampValidator Machine IDBus line or underground stopPage AddressByte #DECHEX1230x00UID0x010x02InternalLock Bytes0x03OTPFrom 4 to 150x04 to 0x0FData
13Pros Cons Cheap Possibility of creating limited tickets They expire after a finite number of timesGood for public transportation systemNo hardware encryptionUsually not well implemented on public transportation systems:Reset AttackLock AttackTime AttackReplay Attack
15Reset Attack It works if the rides are stored in the data sectorJust dump a fresh ticketOnce it is expired write the previous dump on the ticketHave fun with your restored ticket !Hardly appliable as it is a well known exploit (theoretically speaking)
16Lock Attack It works fine if the stamp machine does not check the lock bit of the OTPJust turn it from state «0» to «1»Have fun with your ticket for life !L - 7L - 6L - 5L - 4L - OTPBL – 10 to 15BL – 4 to 9BL - OTPL -15L -14L - 13L - 12L - 11L - 10L - 9L - 8Page AddressByte #DECHEX1230x00UID0x010x02InternalLock Bytes0x03OTPFrom 4 to 150x04 to 0x0FData
17Lock Attack  Whoops Quick summary: No feedback WIN Check last time stamp more than X min ago:No the ticket is still validYes let’s stamp the the ticketCheck if there are rides left:No your ticket is uselessYes let’s stamp it!Write timestamp OKWrite other stuff OKWrite the new number of rides left FailNo feedback WINDo Not forget to take one ride off !Type of multiple ride ticket = 5 rides ticketTicket is valid, Rides left = 5Whoops
18Time Attack  Assume you know: Stamp the ticket by yourself: Where the time of last stamp is storedIt is not encryptedStamp the ticket by yourself:Just write the actual time in the same way & locationFully Undetectable:Just doing the stamp machine workNumber of rides left doesn’t change
19Replay Attack [Never applied] Assume that data regarding timestamp is encrypted:Non-univocal parameters are usedI.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
21How to build a safe ticketing system Fix the previous vulnerabilities:Reset Attack:Rides left must not be stored in DATA sectorLock Attack:Possibility of writing on the OTP sectorCheck if the lock bit state is 1 or 0If 1 Do not stamp the ticketIf 0 Do the usual operations
22How to build a safe ticketing system Fix the previous vulnerabilities:Time Attack:Encrypt those kind of dataReplay Attack:Use univocal ticket detail (as UID) while generating encrypted string
24The Sample LibArduino + 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 sucksrides_check()remove_rides()Just an example to point out the functions which are necessary to get a «secure» ticketing system.
25Why «secure»? Unfortunately it is not 100% safe, but it could well be enough secureWe are going to see this later.
26encrypt_aes(int result) The Sample Libencrypt_aes(int result)It requires an array of size 64 on the ticket where to write the encrypted actual timestampUnix timestamp divided by 60 to get minutes, more useful to be checkedThe encryption algorithm used is AES128(NSA didn’t pay us, or better, not so much)By default, we used a strong keyUse of the UID to prevent replay attacksThe final result is:aes(timestamp()/60 + UID, key)
27The Sample Lib valid_or_not() It does exactly the opposite job of encrypt_aes()It reads and decrypt all the encrypted data and check ifActual timestamp() – stored timestamp() < 100We chose 100 minutes for our sample
28otp_check(char* lock_page) The Sample Libotp_check(char* lock_page)Fundamental function to avoid the lock attack.It takes as input the lock_page of the ticketIt checks if the OTP lock bit is set to 1 or 0,replying 0 or 1 respectivelyYou can easily refuse to stamp the ticketif OTP is read-only.
29otp_check(char* lock_page) The Sample Libotp_check(char* lock_page)It takes as input the OTP page:Checks how many zeroes are thereOne zero = one ride leftIt 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.
30remove_rides(char* otp) The Sample Libremove_rides(char* otp)It takes the OTP page as inputIt writes on the ticket the new OTP page, taking one ride offIt just turns one bit from «0» into «1»It returns 1 if the operation goes throughNote:This function does not check whether the OTP is writable or not. It is already done by otp_ckeck(char* lock_page)
31otp_check(char* lock_page) What if you don’t useotp_check(char* lock_page)Something like this may occurType of multiple ride ticket = 5 rides ticketTicket is valid, Rides left = 5WTF???
33Issues regarding the Sample Lib Everything is very nice, but...It is not 100% secure... Why?Security features are all in the ticketRFID frequencies could be jammedThere aren’t any live statistics about what is happening to your networkBy using this lib you can create a system that is enough secure for a little transport networkAs regards the bigger ones...
34Issues 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 ticketsRides left for each ticketBlacklist of UID ticketsUpdate key for stamping machinesCompany statsNumber of tickets used per dayLines used most
35A little contribute We love bitcoins BTC address: 1nfciKph3dfCgHAwUiCA4Qq9KTkn872PjIf 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.