Introduction

Security Aspects of Android

Android is a privilege-separated operating system, in which each application runs with a distinct system identity (Linux user ID and group ID). Parts of the system are also separated into distinct identities. Linux isolates applications from each other and from the system. Additional finer- grained security features are provided through a “permission” mechanism that enforces restrictions on the specific operations that a particular process can perform, and per-URI permissions for granting ad-hoc access to specific pieces of data.
A central design point of the Android security architecture is that no application, by default, has permission to perform any operations that would adversely impact other applications, the operating system, or the user. This includes reading or writing the user‘s private data (such as contacts or e- mails), reading or writing another application‘s files, performing network access, keeping the device awake, etc.
Because Android sandboxes applications from each other, applications must explicitly share resources and data. They do this by declaring the permissions they need for additional capabilities not provided by the basic sandbox. Applications statically declare the permissions they require, and the Android system prompts the user for consent at the time the application is installed.
The application sandbox does not depend on the technology used to build an application. In particular the Dalvik VM is not a security boundary, and any app can run native code (see the Android NDK). All types of applicationsJava, native, and hybrid—are sand-boxed in the same way and have the same degree of security from each other.

Executive Summary

This report details a vulnerability submitted to Google about the Tags application (app), shipped with the Android OS that is responsible for reading NFC (Near Field Communication) tags, parsing them, and forwarding the results to the relevant application according to its contents.
This vulnerability, with CVE-2019-9295 assigned, allows for a rogue application to trick the Tags app into thinking a new NFC tag was just read. It then shows the user a list of actions they can perform with the tags, so the user has to always interact with the app, which is not ideal from an attacker perspective. There are some scenarios where user interaction is not a problem, in fact, it is actually expected like it would be, explained in the attack scenarios.
While not a critical vulnerability, this is still something that Android OS users – particularly ones not yet operating on Android 10 yet – should be aware of since the different behaviors for different tags cannot be predicted in the future, which might introduce more serious bugs.
According to Google, “As a moderate-severity issue, this vulnerability was addressed in Android 10 only; the fix was not backported to prior versions of Android.”
This type of research activity is part of the Checkmarx Security Research Team’s ongoing efforts to drive the necessary changes in software security practices among organizations who develop consumer-based products while bringing more security awareness amid the consumers who use them. Protecting privacy of consumers must be a priority for all of us in today’s increasingly-connected world.

Use cases and attack scenarios

In this section, a practical use case is given for the different vulnerabilities found. Sometimes it’s not just about the CVSS score. In some cases, the way a vulnerability can be used or chained augment its real value and usage in the real world.

False Tag

This vulnerability allows a malicious app to simulate the receiving of an NFC tag, as if the victim’s phone has just read a tag. It can simulate any type of tags (more exactly an NDEF Record), for example, a URI with a telephone number – tel:123456789.
The drawback from an attacker’s perspective is that the user has to interact and click on the shown tag in order to take the corresponding action. In the case of the previous URI, the user would have to click on the screen so that the call is placed.

Showing a random “New tag scanned” pop-up window is something very strange that will probably get most users‘ attention. On the right, we see a spoofed tag with a URL. The Android Tag app will ask the user if they want to open it with Chrome (or any other registered browser on the device).

Spoofed Tag

To make things less “phishy”, an application was developed that can spoof tags that have been read. The app registers to listen for specific actions, like android.nfc.action.NDEF_DISCOVERED via an intent filter. When a user actually tries to read an NFC tag, the malicious app reads the tag, changes its contents and then calls the default Android Tag viewer. In this scenario, the user is actually expecting to take action after the card has been read, so they have no reason to suspect foul-play.
Default Behavior:                                                        With malicious app installed:

In the above example, a NFC tag with a phone number was used. The real phone number on the NFC tag is “555-111-12222”. When the malicious app is not installed, the real number appears. But if the malicious app is installed, it grabs the NFC tag contents, changes them, and spoofs a false tag calling the Android tag viewer. The user only sees the new number “666-666-666” and has no reason to suspect that it’s not the number on the NFC tag.
It’s important to note that the malicious application does not need any particular permission, since it is just registering for NFC intents and not using the actual NFC hardware.

Caveats

This spoofing method is not without caveats. There is a reason to show the phone number tag and not, let’s say, a URL tag. In a Samsung S8, for example, if we registered an application to receive URL-containing tags, and the user scanned for a NFC card containing a URL, the following screen would appear:

That’s because Chrome is also registered to handle NFC URL type tags. So the user would have to choose the malicious (rogue) app to complete the action in order for it to access and change its content. It is not an impossible scenario, but again it would require user interaction.
In some circumstances, the rogue app can intercept and change the content of the tag before it is handled by the default OS app. Example: a user scans a tag that is a business card and contains a phone number. The rogue app can change the phone number to another one on the fly and the user has no way to know it was altered.
In other cases, the rogue app cannot directly intercept the tag. The user will be presented with a choice to choose the app to handle the tag. In the previous example, the OS presents a menu to the user to choose the handler for that tag, which would be Chrome and the rogue app. If the user chooses the rogue app, it can then modify the URL to direct the user to a malicious site. It’s a more unlikely scenario, but the rogue app could be a Chrome look-alike to trick the user into choosing it as the handler.
This happens because of the way the tag dispatch system works in Android. The tag dispatch system uses the Type Name Format record and type fields to try to map a MIME type or URI to the NDEF message. When the tag dispatch system is done creating an intent that encapsulates the NFC tag and its identifying information, it sends the intent to an application that filters for the intent. If more than one application can handle the intent, the Activity Chooser is presented so the user can select the Activity.
There are 3 intents:

  • ACTION_NDEF_DISCOVERED
  • ACTION_TECH_DISCOVERED
  • ACTION_TAG_DISCOVERED

If there is an app that filters for the ACTION_NDEF_DISCOVERED, the system tries to start it before any other intent. If not, it searches for apps that filter for ACTION_TECH_DISCOVERED and finally for ACTION_TAG_DISCOVERED.
Our rogue app always filters for ACTION_NDEF_DISCOVERED. Since the default phone app is not filtering for this, which is a high priority, our rogue app can effectively grab the tag, change it, and use the tagviewer to pass it down to the default phone app, invisibly to the user.
Chrome, by comparison, also filters for ACTION_NDEF_DISCOVERED. This means that when a URL tag is scanned, the system sees that two different apps can handle the intent and presents the pop up message. So, depending on the app, the behavior might be different. That being said, there are many types of NFC tags possible and many are not being handled by any specific app or the handler app does not filter for ACTION_NDEF_DISCOVERED. Whenever that happens, the tag spoofing is completely transparent, like in the phone number example.
Different smartphones might also have different handlers for different NFC tag types, which creates an exhaustive list of which NFC Tag type, to which App, in which model, a challenging task to say the least.

The NFC Tools Android app is a good place to start searching for tag types:

These are just some examples, there are more types of NFC tags supported.

Research results

com.android.apps.tag

The default app that handles new NFC tags in the android operating system is the Tag Viewer, in the package com.android.apps.tags.

Information


The android Tag viewer handles NFC tag reading (not all, but many types of tags). The class responsible for handling tags is: …/packages/apps/Tag/src/com/android/apps/tag/TagViewer.java
Analysis of the source allows one to conclude that this activity can be ‘fooled’ to show any tag that a user wants, since this activity is exported and not protected by any permissions and also the actions used are not protected by the OS.

TagViewer.java



In order to exploit this situation, a malicious app just has to build an Intent with action NfcAdapter.ACTION_TAG_DISCOVERED or NfcAdapter.ACTION_TECH_DISCOVERED and provide the proper extra Parcelable NfcAdapter.EXTRA_NDEF_MESSAGES.
This can be done with, for example:

Which starts the TagViewer with an HTTP Tag. Several URI schemes are possible, like tel: or sms:, but user confirmation is needed to call the associated application, limiting this as a practical attack.
An NdefRecord can actually be many different objects, not just URIs. In fact, the message parser checks for the following types:

NdefMessageParser.java

Conclusion

In summary, there are two main attack scenarios:

  1. A popup window that could randomly appear alerting the user that an NFC tag was scanned (generated by a rogue app). The user has to interact with it to choose an application to deal with the
  2. The user scans a real The rogue app can intercept and change the content of the tag before it is handled by the default OS app. Example: A user scans a tag of a business that contains a phone number. The rogue app can change the phone number to another one on the fly, and the user has no way to know it was altered (except by scanning the tag in an ‘uninfected’ phone).

In scenario 1 or 2, users could eventually be tricked to click on a link leading them to a malicious landing page, calling/texting the wrong number, or any other action possible with NFC tags.
Although the flaw in itself allows for the spoofing of any tag, it requires user-interaction to actually start an application. This requirement lowers the severity of the flaw, in our opinion. That being said, and as we’ve shown, there are attack scenarios where the user interaction is actually expected.
Most would agree that no external app should be able to fool the operating system default NFC tag resolver into thinking a new tag was just scanned. The results can be completely unpredictable.
Recommendation: Updating to Android 10, which was initially released on September 3rd, will mitigate this issue. However, please note that the Android 10 update is still being rolled out by many phone manufacturers and carriers. Find out when you can expect the Android 10 update for your phone here.