Android 6.0 permissions in protection and attack

Everyday, new vulnerabilities are discovered in mobile devices that can be exploited by intruders. They can send an SMS to a pay-per-call number, they can collect and sell a large database of contact details, and they can also compromise a specific individual. Successful exploitation of a vulnerability requires that a whole range of conditions are met. There is another way, however! Provide the user with a really useful application (a game with birds), whose manifest contains a list of device information that we are interested in. In this article, we will look at ways of obtaining and saving important information from an Android device.

Android OS architecture is built in a way that allows apps to exchange different kinds of information. An app which works with maps requires location, while a voice recorder requires access to the microphone. So, it all seems clear and transparent.

We openly write the required data or features in the application manifest and receive them upon installation. Nobody is being deceives, everything is voluntary. However, the problem is that users are highly illiterate as far as information technology is concerned. Few people wonder why the voice recorder, for example, needs their location or access to SMS. The application clearly declares its intentions in the manifest, and it would be strange to expect it to act differently.

Before the now famous disclosure, I understood that the game with the angry birds on your device is an informant, as, in addition to everything else, it wants to read the device ID and call data. A simple question “Why do you need this data?” reveals the true intentions of its creators.

When installing the application, the user either has to let it do anything it wants, or not have the application at all. Not many people will browse the store for an app with similar functions but fewer requests (there might not even be anything similar), so the users quickly develop the habit of pressing “yes-yes-yes” to all questions. Let’s accept that it is easy to get used to this, as for many years of living offline, users have developed the reflex to automatically sign multipage agreements on the principle “well, everybody signs it, there can’t be anything wrong with it. Anyway, I don’t have a choice, either I sign here or I don’t get what I want.”


After installation, the spying application doesn’t even need to be launched, as it may contain a mechanism for receiving broadband messages (BroadcastReceiver), which, when it receives a message from the system, will launch an information collection service.

If we remove all the application’s permissions, the OS, in order to prevent the app crashing, can simply give it empty values. The application can be deceived by providing it with knowingly false information (position of the North Pole) or simple zeroes. For example, the application may request a list of contacts on the device and the developer presupposes in its architecture that it can be empty (a brand-new device). There is nothing suspicious here; the data is saved and the application has not crashed.

Such tricks were necessary before Android 6.0 Marshmallow. It boasts a new mechanism for working with permissions and allows permissions to be granted and revoked when the application is working. For reverse compatibility of old applications (i.e. the ones whose targetSdkVersion is less than 23), an old mechanism for requesting permissions during installation has remained functional. Updated applications should request permissions when they are working. We can look at the app permissions in the application’s settings and revoke access if we so wish.

Let’s look at how this works on a device running Android 6.0.

Let’s install the birds but revoke all their rights before the first launch.
When the rights are requested during installation from Google Play, we can see that the app’s targetSdkVersion is less than 23.

Request of rights during installation of birds from the market

Request of rights during installation of birds from the market

The settings display tells us that the app creators have slightly more interest.

List of birds' permissions

List of birds’ permissions

How about reducing them a bit?

Revoking permissions

Revoking permissions

That's better

That’s better

Having revoked the permissions, I launched the game and it turned out that it didn’t affect how the application worked at all. It seems that the background service for data collection has no influence on the main gaming interface.

Now let’s look at the work of the updated Skype app.
Here we have part of a manifest of a “similar” app.

The list of permissions and requirements from the manifest is inspiring:





































































If only users had seen this…
If we want to protect at least a small part of our private life, we can only rely on the operating system.

Let’s look at the application installation process.
No dialog windows are shown during installation from the market � the application will ask for all permissions later.
Let’s check the settings.

Skype has no permissions

Skype has no permissions

Let’s check again…

Skype has no permissions at all

Skype has no permissions at all

Let’s launch the app. Seven requests follow in sequence.

Skype's request 1

Skype’s request 1

Let’s deny all requests one by one and Skype turns into an Internet chat :).

Wait, did I say “an Internet chat”? Why didn’t it ask for permission to access the Internet? This is because all permissions are divided into two groups: regular and dangerous. Only the latter ones should request permission now. The list of regular permissions is available here. Here are the dangerous permissions (and their groups).

There are detailed materials for creating permission requests: patterns for using permissions requests, recommendations for accessing permissions, and here is the full list of permissions.

Now we understand the theory more or less, let’s put it into practice.

Accessing the contacts list (in a good way)

With this new knowledge, let’s write a short application, which we will use to read the user’s contacts data through requests in the interface and the service. As it recently turned out, some applications like to read this data very often (which is not surprising � what if something has changed there, and the creators of “good” applications don’t know about it?).

WWW


The project’s source code is available at link.

By pressing the button, we check the OS version and, if it is 23 or higher, we request the rights:

public void setRequestReadContacts(View view) {
   // Check for already provided permissions
   if (hasSelfPermission(this, Manifest.permission.READ_CONTACTS)) {
       // Permission has been granted, let's show contacts
       showContacts();
   } else {
       // There is no permission, let's send a request
       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
           requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, REQUEST_READ_CONTACTS);
       }
   }
}
Dialog for rights request

Dialog for rights request

Following the dialog, the following response must be processed in onRequestPermissionsResult method:

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
   if (requestCode == REQUEST_READ_CONTACTS) {
       if (verifyAllPermissions(grantResults)) {
           // Permission has been received, let's show contacts
           showContacts();
       } else {
           Toast.makeText(this, "REQUEST_READ_CONTACTS permission was not received", Toast.LENGTH_SHORT).show();
       }
   } else {
       super.onRequestPermissionsResult(requestCode, permissions, grantResults);
   }
}

Let’s read the contacts in a string, moving to a new string:

private String readContacts() {
   Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
   String names = "";
   while (phones.moveToNext()) {
       names = names + phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)) + "\n";
   }
   phones.close();
   return names;
}

Let’s show the contacts in a window, it will open when clicked:

public void createWindow(String contacts) {
   LayoutInflater layoutInflater
           = (LayoutInflater) getBaseContext()
           .getSystemService(LAYOUT_INFLATER_SERVICE);
   View popupView = layoutInflater.inflate(R.layout.popup_window, null);
   if (mPopupWindow != null)
       mPopupWindow.dismiss();
   mPopupWindow = new PopupWindow(
           popupView,
           ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
   mPopupWindow.setAnimationStyle(android.R.style.Animation_Dialog);
   LinearLayout ll = (LinearLayout) popupView.findViewById(R.id.PopUp);
   TextView tv_message = (TextView) popupView.findViewById(R.id.tv_message);
   tv_message.setText(contacts);
   ll.setOnClickListener(new View.OnClickListener() {

       @Override
       public void onClick(View v) {
           mPopupWindow.dismiss();
       }
   });
   mPopupWindow.showAtLocation(mMainLayout, Gravity.CENTER, 0, (int) (mSidePopup * 0.3));

}

Here’s the result of our work on reading contacts:

I forgot to take contacts from the owl

I forgot to take contacts from the owl

Accessing the contacts list (in a bad way)

Let’s do the same but in the service, just like the bad app is expected to. The service will not send any requests, but will simply try to read the contacts directly.

We’ll set the service to launch when connected to Wi-Fi.
Service code:

public class ReadContactsService extends Service {
   public ReadContactsService() {
   }

   @Override
   public IBinder onBind(Intent intent) {
       // TODO: Return the communication channel to the service.
       throw new UnsupportedOperationException("Not yet implemented");
   }

   private String readContacts() {
       Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
       String names = "";
       while (phones.moveToNext()) {
           names = names + phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)) + "\n";
       }
       phones.close();
       return names;
   }

   @Override
   public int onStartCommand(Intent intent, int flags, int startId) {
       Toast.makeText(getBaseContext(), readContacts(), Toast.LENGTH_SHORT).show();
       return START_STICKY;
   }

}

Receiver code:

public class WifiReceiver extends BroadcastReceiver {
   public WifiReceiver() {
   }

   @Override
   public void onReceive(Context context, Intent intent) {
       NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
       if (info != null && info.isConnected()) {
           // Doing our job
           Toast.makeText(context, "Connected", Toast.LENGTH_LONG).show();
           Intent myIntent=new Intent(context,ReadContactsService.class);
           context.startService(myIntent);
       }
   }
}

If the application has rights, the service will show a Toast-message with a list of contacts; if there are no rights it will show an error message.

Now let’s investigate the app’s behavior if we set its targetSdkVersion below 23.

The application was given rights by default, and everything works properly without requests. After the rights are turned off in the application settings, the contacts list starts to come up empty. We didn’t get any errors, but we didn’t get any contacts either. This means that without us knowing, the apps will receive irrelevant information.

Conclusion

The new Android version contains more reliable and flexible app rights settings. We could say that the new version protects our data more reliably, but it doesn’t mean that you have to blindly accept all offers which appear in pop-up windows. Be vigilant!


One Response to “Android 6.0 permissions in protection and attack”

  1. Ertugrul Tiryaki

    Thank you man. Thank you for this article. I always try to explain to my friends in this case. But some times its hard to get understanding from their windows. When they share their contact information, actually they share my information. There is no way to secure your information if your friends blindly accept all offers. This is so sad. Hopefully everybody will start to read then think it wisely then choice accept if it safety. We should give the response together to app developers. Stay away from my privacy life!
    Best regards,
    Ertugrul

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>