This is the final part of Georgia Weidman’s HITBSecConf2012 talk where she explains why open interfaces in Android may pose a security threat, and provides mitigations for the risks emanating from Android interfaces.
Twitter app, that’s an example of it, you take a picture and then it says: “Do you want to send this to Facebook? Do you want to send it to Twitter?” And then it just sends it off nicely for you. So, as a developer – that’s awesome. As a security professional – that sucks, because all of these open interfaces may allow you to actually steal permissions. So, naturally, I wrote an app to do this.
So, we have our two phones again: our Android and our iPhone, and I believe at the beginning of this I expostulate about what’s going on, but no one ever picked up the phone. So I go to Settings again and I’m going to look at the permissions on these apps. I go to Apps; I have an app called SMSbroadcastr, which, if you’re familiar with the Android, means broadcast receiver which listens for intents, which are messages between applications. It says it wants services that cost you money, it wants to send SMS – that’s its only permission.
Then, I have an app called SMSintent, which has absolutely no permissions whatsoever: it should not be able to send SMS or do really anything else. So I call SMSintent, and what I see up here is it called SMS broadcast receiver, which, naturally, is an activity instead of the broadcast receiver, if you’re familiar with this. A broadcast receiver has no UI, but I made it an activity so you could see what actually happened: it called the other application and made it perform functionality.
It put up a UI, it need not; in a malicious scenario it would not, there would be no UI, no indication that this actually happened. But what happened is it called the other application.
Come over to my iPhone, I see that it sent me a text message. The app that I actually clicked on was SMSintent – no permissions. I never clicked on SMS broadcast receiver, I never called it, so I just sent an SMS without the permission to do so by using another application. And I see I’m about to turn red over here, so I’d better continue.So, basically, our good application, when it’s called, sends an SMS. Why this would happen is, for instance, if it’s a game and it wants to check in your scores, this would be one activity, your broadcast receiver service. So, one component of an application that sends an SMS, for instance, with your scores in it.
We would naturally assume that only its own application would ever call this. I don’t export it, so the only way to call it would be to know its name, know its package name and know its actual interface name. So, SMSbroadcastr – it would have to know that. And there is no way we could know that, right? Because we can’t get the source code of the app, so there is no way we could know the name of it, not at all.So, basically, the caller tells it to send an SMS, and we assume that it’s only going to come from the same app, so this is normal, nothing bad here, it’s going to send your scores off when it gets the correct intent or message from another component telling it to send it.
And comes our evil app with the horns, and it calls broadcast receiver and tells it the number to send the message to and the message to send, and thus has the ability to send an SMS message without the actual permission.Code examples, real quick. SMS broadcast receiver, basically, when it’s called, has default values, but it gets the intent, which is the message and you can store additional data on the message. So it looks for 2 specific keys: message and number; pretty easy here, the message you want to send, the number you want to send it to (see image). It looks for those; if the intent it gets doesn’t have those, if it gets a weird intent, it just sends a default, so it won’t crash, but it looks for those if they are there.
Naturally, because we can reverse this, we can see this code, we know we need to send an intent with 2 keys: message and number, and the data we actually wanted to send and where we wanted to send it in message and number. So we can then formulate the intent, we know where to send it to. We need the package, we need the name, so the class name and the package it’s in, and then how to make the intent. And then we’ve got everything we need to make this do our bidding.In SMSintent we do just that; we create an intent, so a message to send to another component on the Android, we tell it the package, we tell it the name of the actual activity, or broadcast receiver, or service, or any interface we want – as long as we can call it by name, it doesn’t matter if it’s exported to us; we can actually just call it (see image).
We give it the strings we want it to send; we want it to send a message that says: “test test”, which could be anything, and the number we want to send it to. We put those extras into the intent, giving them the keys that we found in the previous source code, number and message. And then we send the intent off and it will call the other one, so it will call SMS broadcast receiver, which, when it’s called, sends out a text message; no user interaction required, it just does it if it gets the correct intent, which, due to the source code, we are able to see how to do that.So, mitigations for this: basically, don’t have your dangerous functionality, anything you have to ask for a permission for is considered dangerous functionality on Android. So don’t have it just directly available. For instance, an easy way to deal with this is to just have users have to click OK before it sends off their scores; have it put up a little message box that says: “Can I send your scores to the server?” And you have to click “OK” or “Cancel”.
And so then, when SMSintent called SMS broadcast receiver it would put up that message, and users would be like: “I didn’t just play the game”. They’d probably click OK anyway, admit it, they probably would, but at least we could give them some hope.
Another thing you can do is there’s actually a little-known tag in Android called ‘require-permission’, which you can put in your .xml, and you have to declare all your interfaces, so all your activities and services and such – you have to declare them in your manifest.
And when you do that you can just use the ‘require-permission’, so we could say here: “Require-permission send SMS”, and then when any other application or any other interface even inside that same app has asked for calling this interface, it will check to make sure they have this permission to send SMS; and when they don’t, in the case with SMSintent which had no permissions, they don’t have the ability to send it, it will just say: “No”, and it won’t work.
But hardly anybody uses that. And the reason for that, I think, is mainly because, first of all, developers obviously don’t think about secure development, they just want cool fireworks and stuff to make people download their apps.
And also the problem is Google itself: if you’ve ever looked up how to do Android programming, you’ll see it shows you lots of nice demonstrations and tutorials. It starts out with “Hello world”, just like everybody else does. And you do “Hello world”, and then you make something called Notepad application, but in none of those tutorials does it ever actually ask you to look at the security page, which is all out there, a nice security page that talks about all of this that we’ve talked about. But new developers – they don’t ever see that.