Can we agree that NFC is here to stay? Just about every mobile platform supports it, (I’m looking at you Apple) including simple feature phones from way back when . Let me just get to the good part: NFC input vectors for pen-testing. The scenario here is a mobile application that supports some kind of NFC exchange. Maybe it’s a Windows Phone 8 tag reader or something using Android Beam — whatever. The point is that the mobile app is receiving input from an outside source (the NFC tag), and we want to make sure it’s properly validating that input. Specifically, when an application reads in the NDEF (or proprietary) content from the NFC tag, how is it used by the application? What happens when we change this value to something unexpected? In an ideal world, it will catch the exception and stop trying to read the tag, but what about in the case of “less than ideal” programming.
To get started we need something that can read and write NFC tags. Sorry, iPhone users, but the easiest way to do this as I see it is to use an Android device and a few choice apps:
Does exactly what its name implies. It gives you info on an NFC tag. This includes any kind of ASCII characters inside of the NDEF storage container or a hex representation of the values if that’s your thing. This is step 1 when it comes to learning about the content that’s on an NFC tag. Play store link.
NXP’s tag writer will read, write, and copy tags. When I say copy, I mean it will copy the NDEF format. That’s the content that’s normally on an NFC tag. Hard coded values like the UID can’t be changed (unless you know where to get sketchy NFC tags and even then you need a libNFC-based tool to interface with it). Play store link.
This is where the fun happens. This app allows you to design just about any NDEF formatted NFC tag you want. The nice part of this is if there is an application implementing a weird custom format, you can create it. It’s made by Thomas Skjolberg who apparently has a whole workshop on the subject that gets you started with NFC on Android.
Used in partnership with the ndefeditor.com site, the app lets you generate just about any NFC tag you can think of and then record it to a tag. Or you can use the Eclipse Plugin that does the same thing inside of Eclipse. Very useful.
Create a new tag in Eclipse by going to New>Other>NDEF File
Fill the file with whatever contents you want or whatever the application can handle. This may be a specific MIME type like below or a Android Application Resource (AAR)… or many other things for that matter.
Once you’re done, it’ll create a QR code for you that you can scan with the NFC Developer application installed on your device.
You’ll now be able to load your custom NDEF message onto an NFC tag of your choice.
If you’re using Android, you don’t necessarily need to write your content to physical tags. It’s possible to manually create intents that look like the device is receiving an NFC tag. But since we’re talking about testing any NFC function on *any* platform, you’ll need to pick up some NFC tags. The NFC protocol itself supports a “card emulation” mode where you could theoretically turn your Android phone into a simple NFC tag, but from what I understand, it’s either extremely hard to do or impossible right now because it’s based on the NFC secure element that is manufacturer specific. If someone wants to enlighten me on that, please feel free.
You’ll want a variety of tag types. The main difference you’ll be concerned about here is just the amount of storage. The Mifare 4K have a reasonably large storage capacity and can still deliver the data in the same way that a Mifare Classic (1K). Maybe there’s a situation where you’ll need a special tag type but I haven’t run into that yet. Either way, here’s a random link to some tags.
Lets take a look at some example code for Android that we’re trying to exploit. This is a portion of code that is reading an NFC tag, and saving to a file name based on that input. You can see that the value of “strfile1” is whatever the first NDEF record is. What happens if that payload was something like “../databases/superimportantcontent.db”. Even worse, the app looks at the second value of the NDEF record for the content to write to.
Parcelable rawMsgs = intent.getParcelableArrayExtra( NfcAdapter.EXTRA_NDEF_MESSAGES); NdefMessage msg = (NdefMessage) rawMsgs; String payload = new String(msg.getRecords().getPayload()); String strfile1 = getApplicationContext().getFilesDir().getAbsolutePath() + payload ; //is this bad? :) File f1 = new File(strfile1); FileWriter filewriter = new FileWriter(f1); BufferedWriter out = new BufferedWriter(filewriter); out.write(msg.getRecords().getPayload()); out.close();
Lets imagine that this app stores a textfile of SSH hosts to connect to. In this case, we could create a custom NFC tag that would have a first record of the path we want to access (“SSH.txt”) and the second record would be the values to put inside of this file (your malicious SSH MiTM proxy). Having a user read your custom tag would redirect their connections to you.