Georgia Weidman, the Founder and CEO of Bulb Security, takes the floor at HITBSecConf2012 Amsterdam to present her research on security details and flaws of the Android permission model.
Cheers everyone to my European debut!
There will be no 0-days in this talk, except one – the 0-day that I came up with last night. I was walking around Amsterdam with some other speakers, and we saw this weird device on the side of the building that kept moving around, and we couldn’t figure out what it was. Of course we googled it to find out what it was, and it actually works with subway, it talks to these little mirrors on the ground to tell whether the subway has sunk or not because there used to be a lake here or something, like all of the Netherlands used to be water and they reclaimed it, so, theoretically, at any time the subway could just, like, sink into the sand and it would all be over. So there’s this device that checks to see if it’s sunk a little bit.
So, my 0-day about how you can shut down the subway is, you know, take a little chisel and drag up the mirror and move it up an inch, and it will make the subway completely freak out, I think, and it’ll stop. So you can stop public transportation in Amsterdam with this 0-day that I just dropped. The rest of it we’re just going to talk about is boring old Android stuff.
Alright, I’m Georgia, we’re going to talk about Android, and I have a little company called Bulb Security that does some security things.
So, first off, the first thing I have to do when I do any research is completely discredit everything I do and say it’s completely not worth it, because we’re going to be talking about bypassing the Android permission model, and I’m going to show you that you don’t have to bypass it at all, that the permission model is just so completely flawed, there’s not even any point in bypassing it.
I’m going to show you an app, I’m not going to tell you what it is, but I’m going to read its permissions and you get to guess what it is, and its permissions are kind of scary. So I’m just going to read it right off my phone, actually.
Alright, the permissions that this app asks before its install are the following: it wants access to my personal information, it wants to read my contact data so it can see everyone I have stored in there, including my work contacts, and this doesn’t just include the phonebook, it’ll include all of my email settings as well. So, if you have this synced with your work contacts, it can see all of them, see their email addresses, phone numbers, names, company affiliation, any data that’s actually stored on the phone.
It can also write this information: for instance, it can overwrite your boss’ contact with its own email address so that then all your emails to your boss with, for instance, your reports in them, like a new version of your pen test report for company ABC, is now going to someone else. That’s not a problem, no…
It also wants this thing called ‘Services that cost you money’. Generally, that tips me off: it might be a little bit scary if it’s going to cost me money. It wants to be able to send SMS messages under that heading, so it wants to be able to send text messages; it can still send them if I’m in Amsterdam, and it’s going to cost me 10 cents a text message. I got a very ‘nice’ text message from my phone provider that said: “You’ve already spent 50 dollars”, and I’ve only been here for a couple of hours, so, yeah, I should stop playing with my data so much when I’m roaming. But it can send text messages on my behalf; it can also send them when I’m in Amsterdam; it can send them to 900 numbers that cost more money; it can send them wherever it wants and they won’t show up in my Sent folder, so I have no idea they were sent at all.
It also wants access to my GPS location, so when I got lost the other day and I turned on my GPS, the app on my phone that asked for this could now see that I am, in fact, in Amsterdam and not at home, so good time to rob my house, right? I’m not there and my phone knows it.
It wants access to my messages, it wants to edit SMS – so, read my text messages, change them. It also wants to be able to receive them. Oddly enough, with Android, if you have the permission to receive SMS, you can receive them before the actual text message app does. So you can keep users from ever seeing their text messages at all, which is a good way to run a botnet, I think; if you’re at all familiar with my work, that’s my big thing – the SMS botnets. So it’s a good way to run a botnet, just intercept people’s text messages, and they give you exclusive permission to do so, so you’re not even doing anything wrong.
It also wants access to my accounts. It can access an account authenticator, so it can log into any other account I have on here. Since it’s an Android, it has my Gmail, of course, and anything else I have on here, like, for instance, Twitter – I love Twitter, so it can log on to Twitter for me.
It can also manage those accounts, so theoretically it can actually log me out of my account, it can change my password and make it so that only the phone can get on my Twitter ever again, and that would make me really sad: I don’t know how about you, but I think I would just die if I lost access to my Twitter.
It wants to be able to modify and delete USB storage contents, so it can read anything from the SD card and it can delete it for me. That might be a good thing. I don’t know if you guys over here so much as we in America like to take pictures of ourselves being drunk and stupid on our phones and then post them online. There is actually a start-up in California right now that the whole idea of the app is they’re going to delete your pictures for you, like, after an hour, so there are none of these incriminating pictures on your phone, so that might actually be a good thing, the one permission right there that will delete incriminating pictures of you doing stupid things in Amsterdam, like drinking onstage, hey!
Let’s see, it wants to make phone calls, it wants to read the phone state and identity. The phone state and identity – that’s when the users go: “What does that even mean?” But that actually is the personal identification number, it wants to read your IMEI, so it’s a unique number to your phone, and a lot of developers use that as a way to uniquely identify you with the server, which you could think of as uniquely identifying you based on your credit card number. That sounds like such a great idea, doesn’t it? We don’t want that going back and forth to the server, but that’s a cool thing to do with Android, so a lot of apps ask for that and theoretically none of them should.
It wants to prevent my phone from sleeping. If any of you have Androids, you would see why keeping the phone from sleeping might be a bad thing; it runs down your battery; and battery is god in Android.
It wants to write my sync settings, so next time I plug it into the computer, I might have a little surprise coming.
And then the final one: it wants network communication; it wants to be able to talk to the Internet.
Anybody want to guess what app this is? (See image) May I introduce you to the absolutely most popular Android download of all times? Facebook for Android. (Page 3) That’s a lot of permissions. See, I’ve had Facebook forever; I was in college when Facebook first came out. You had to have a college, like, .edu email address. I love Facebook, but my Facebook on my computer has one of those permissions: ability to talk to the Internet, none of the other ones. It works great and people love it, and they just made billions of dollars, so why do they have all these?
I figured out why Android apps have so many permissions. Since I’ve done so much Android development lately, and I’ve watched my apps just fall over and die randomly, and I can’t figure out why, and nothing comes up in the debugging settings – why is it falling over? Go to Stack Overflow, they give me their source code that looks just like mine, so it must work, right? It’s Stack Overflow, no problems there. And it just falls over. I figured it out: it’s because I didn’t have the permission, it just dies, because if you don’t have the permission, you can’t use the functionality.
So developers are just asking for all the permissions so that they don’t forget later, and then they forget to take them out, because Facebook doesn’t actually use half of these. I write the source code, I would know.
So, naturally, having seen this I thought: if I put out an application that asks for a lot of permissions (I can assume that users will accept them), how hard would it be for me as not necessarily a very good developer (certainly haven’t had much experience in Android yet) to code ways to abuse this, given that users are willing to accept these permissions – they accept them on Facebook, they accept them on any other app? So, naturally, I wrote an app to see. So we’re going to look at a little demo.
Alright, I’ve got my Android and I’ve got my iPhone here; I wrote an app called ‘Hello Android’, not a very sophisticated name. I’m just going to install it off the SD card and replace what’s already on there.
So, it wants 3 permissions, a lot less than Facebook. It wanted the ability to read your contacts, read that IMEI, and it wants to be able to send SMS. It puts up a screen that says something like: “Hi, I’ve basically just exploited the hell out of you;” but of course a bad developer wouldn’t have to put up this screen at all, they would just put up a game or something, and this would happen in the background.
I go to my Sent folder and I see that I’ve sent no SMS’es, I have no indication that anything has happened here. But if I go to my iPhone, I see that I have sent the IMEI number, my personal identification number, worth about as much to an attacker as a credit card to about 10 cents – so, basically, nothing, but if you have millions of them, you see how this adds up. How malware writers actually make money is a mystery to me; they make a lot more money than I do. It’s probably best that I don’t find out so I don’t turn to the dark side.
But, anyhow, we have just exploited all these permissions: the ability to send SMS – we did it in the background where the user couldn’t see it, it wasn’t in the Sent folder, no indication it happened. The only indication was that screen that I put up that says: “I did it,” which, of course, the user will not see if that was the real evil application, this will just go on in the background.
It stole your IMEI, sent it to someone else, and it also put up the last person you talked to based on your contacts, so it could tell who the last person you talked to was. It can also read all of them and send them off. If I had asked for network communication, I could send this up to a server.
So the moral of the story is that it’s really, really easy to write Android malware without exploiting it at all. Just given the amount of permissions that users are willing to accept, you’re able to completely exploit them in any way you want.
I’ve basically just undermined the whole rest of the presentation; this research never needed to be done because you can just ask for the permissions and exploit them that way. So there is no reason you have to steal permissions, there are no reasons you have to root their phone, you can just do this. But now we’re going to talk about it anyways.
Alright, so basically what happened here, as a run-down, is I asked for 3 permissions. First, read the IMEI, which comes up a lot – a lot of apps ask for this, they should not; no apps should ever ask for this because the only reason to ask for it is to uniquely identify you on their server based on your IMEI, which is like uniquely identifying you based on your credit card number. We don’t stand for that in secure coding, that’s bad, but we allow it on Android. Other permissions – read you contacts and send SMS. And we exploited every single one of these: we stole your IMEI, we saw the last person you talked to, and we SMS’ed the IMEI to ourselves, all in the background, which brings us to the next topic.
A lot of the malware in the world roots your Android. A lot of the not-malware in the world roots your Android too. We wanted to root it, we want complete control over our phones. We buy the device, we get control over it – not so much necessary with Android as it is with iPhone. Basically, if you want to do anything with your iPhone, you have to root it, but you’ll probably be over there, in the other room, if you were interested in that, because they’re showing Absinthe1 right now at the same time as my talk, so thank you all for coming.
Here are the two of the prevalent rooting programs (see image). SuperOneClick still goes on, they update regularly, it does, like, the most recent versions of Android. Well, back in the day and still for a lot of phones, because you’re not getting updates, because Google doesn’t update you or your carriers do not, Z4Mod was the rooting solution for up to, like, Android 2.2, which, sadly, still works for a lot of Android users.
I’ve looked at the source code of both of these, I’m going to talk about evil exploitation for rooting. Neither one of these exploit you evilly; they give you your super user permissions and then they’re done and they go away. So do not come out of this thinking that these 2 apps are evil; they’re not, and I use them regularly.
We are going to look at some evil ideas for rooting Android. Anybody remember this guy? (See image) DroidDream made a huge media splash because researchers like me and you had been saying for a long time, you know: “Anybody can put anything they want in the official Google Marketplace, so it’s really only a matter of time before something evil shows up there.” And of course everyone was like: “No, that will never happen, you’ll never get malware into the Google Marketplace.”
And then DroidDream showed up, the first known outbreak in the Google Marketplace. It rooted your phone, stole your information and did all sorts of crazy evil, and it was just sitting there in the Google Marketplace waiting for you to download, whereas every previous outbreak had been in some third-party market that had a lot of Chinese characters in it; and really, if you downloaded it you kind of deserved it, right? I mean, you couldn’t even read what it said.
But this looks normal. This was inside of the official Store that all end users were basically paying to use by buying an Android device, so they had some reason to believe this would be a safe place for them to find applications.
But because there is absolutely no oversight of all these applications – there’s millions of them, this would take time, this would take effort. iPhone users always complain that it takes so long to get updates into the store or get your apps, in the first place, into the Store, so the idea that things going to Google Store automatically was awesome and people loved it.
But then stuff like this started to happen. But now, of course, if you get DroidDream, since it’s old, Lookout or any other antivirus program will flag it and say something like: “This is DroidDream; you do not want to install this.” But of course at the time when this first came to light, this was not the case; it just looked like a normal application.
What should have tipped some people off is how few permissions DroidDream actually asked for, comparatively to normal applications. We just looked at the normal non-malicious application Facebook that wanted this long, long list of permissions. Droid Dream actually only asked for 4, which might have tipped some people off that something was up here, because you’ll never find an app that only asks for 4 permissions, never. They always have, like, 10 or 12 scary-looking things.
So, it wanted access to the Internet – normal one there, apps want access to the Internet, that doesn’t scare me. It wanted to read the phone state, so it wanted the IMEI – that’s bad, but it’s prevalent, a lot of apps ask for it, so it wouldn’t tip anybody off that anything was wrong here. Basically, it’s probably checking in to the server using the IMEI to uniquely identify you. A lot of the DroidDream variants were games, so that would be how you’re checking your scores, this is normal for Android; definitely not a good idea, but it happens.
And then, the other 2 it wanted: it wanted to be able to change the Wi-Fi state and access the Wi-Fi state. So, theoretically, it just wanted to be able to make sure that you’re on the Wi-Fi before it sent things. So, wow, this app’s really looking out for me, it doesn’t want to run up data charges for me, it’s only going to check in when it’s on the Wi-Fi.
No, that’s actually not what it was doing at all. One of the roots it uses actually requires you to change the Wi-Fi state, like, basically, toggle it on and off before the shell hits, so that was actually malicious. But looking at those, it doesn’t look that scary compared to most apps.
I as an Android researcher, just looking at this list of permissions, would think: “That’s a really small amount of permission coverage; that’s not really that scary at all compared to most apps.” But this was actually one of the scariest apps of all.
So, how does this actually work? Basically, when you downloaded DroidDream you saw something like this (see image). There were many variants of it, some of them were, for instance, adult dating sites, adult videos, which some people say: “I should use that as the demo,” but we’re actually looking at one called ‘Bowling Time’, which is just you play bowling on your phone and try knocking down all the pins. Pretty boring, comparatively to the adult sites, of course.
But then in the background, behind all of this, was where all the evil happened. Basically, when DroidDream would start, it would copy a bunch of normal apps like this that even had nice ads: you see, there’s ads up there, you know. Apps with ads – those are never scary, because they are paying their dues to advertisers.
But it would start the regular app in the foreground, so it would call it to start – just, basically, steal the straight-up source code from the original app, send it off to make it appear on your phone, and then do evil things in the background. So users would be none the wiser that this was any different than the original app.
And then it would root you in the background. You hadn’t downloaded anything and told it to root you – it just did. Upon install, when it started, it automatically tried to root exploits, which at the time were unpatched on all the phones. By the time DroidDream hit the news area, this had been updated on official Google phones, but most phones had not had it pushed out to them yet, so this was basically 0-day for the entire time of DroidDream.
So, if you installed the DroidDream app, you were going to get hit by one of these, because it not only tried one, but it tried two, and these were the same ones that the rooting applications were also trying. Oddly enough, I looked at the source code of DroidDream, I looked at the source code of Z4Mod, and I’m pretty sure DroidDream basically just copied their source code, because it’s even got the same variable names. So the source code was out there and the DroidDream writers copied it, put it in their app and went on their merry way with it. That’s how it happens, I guess.
So, what did DroidDream do after it rooted you if one of those two roots actually worked? And, again, they worked basically 0-days for most phones even up until the end, because people hadn’t been updated, they hadn’t had patches pushed to them by the time it hit the media, unless you were at that point a Nexus One, because it was the only one out then. So, unless you were a Nexus One, you were in trouble through the entirety of the DroidDream’s time on the marketplace.
It rooted your phone against super user permissions; it could write to the entire disk, including the system partition, which is where apps that are installed at, like, the base installs by your carriers are; and, theoretically, no one else should be able to write there. But of course, if you root, you can write wherever you want.
It also installed packages as system, and at that point the permission model completely broke down. There are permissions that you can ask for as system that you would not even dream of as a developer: you can do anything you want there, you have complete control of the phone. And now DroidDream has that as well. So it has access to everything at once: it stole your personal information, it ran up your phone bill, sent it out to the C&C server. It suddenly had access to every permission available. That’s rooting your phone: permission model – gone.
This brings us back to these guys (see image). Again, I’ve read the source code of both of these, non-evil, they give you your super user, and then they go away. But, for instance, you’re looking for Z4Mod and you spell it with 2 O’s, and you end up on a website that has something that looks a lot like this; I mean, it can get the source code so it can pretend to be this, but it isn’t. It actually does root your phone; you come out of it with super user permissions, so you as a user are happy, you got what you wanted. But what happened in the background? You have no idea because it’s all going to go on behind the scenes.
Now I’m going to show a demo of something you might want to do after you root somebody’s phone if you’re a malicious attacker. This is one of my old stories of evil things you can do to phones.
So, I have 3 G1 phones. Phone 1 is the attacker, Phone 2 is the victim who has been maliciously rooted, and Phone 3 is just a friend of that person who’s in their contacts list.
What I as the evil person want to do is I’m going to send an SMS message to Phone 2, to the one that has been maliciously rooted; it says “BOT”, and then it says, “SPAM”, it has a number and then it has a message that doesn’t really mean much to anyone, but it means something to the program on the other end that is now going to be able to intercept your messages and act on them, so this is actually just code of the talk to Phone 2.
So, I sent a text message to Phone 2; we know how text messages work: it shows up, they see this nonsense about bots, and they go on with their life. But what we actually saw happen is the Phone 3 being the one that actually got the message, and the message it got does not say “BOT”, “SPAM”, and blah-blah, it just says “hellohello”, and it says it came from someone named Slave Bot, which obviously is a fake name, no one would have anyone in their phone as Slave Bot. But that’s actually Phone 2, which proves that I’m not making this up.
I just sent the message “Hello”, a normal message, to Phone 2 again, and this time it shows up normally on it. So basically, what you’ve done here is Phone 2 has sent a text message that they don’t know about to Phone 3. They also received the message they don’t know about, this “BOT:SPAM” message, and because we’ve rooted their phone and gained access to system level, we were able to do that without requiring any permissions whatsoever. So, now we’ve basically made them a member of a botnet.
What would be interesting is we grab all their contacts, send them a message that does not say “hellohello”, it says something like “Look at these cool pictures from last night” with a link in it. The link pops their browser, exploits it with a known exploit and then makes them part of the botnet as well. That’s why rooting can sometimes be evil.
How this actually worked in this case is once I gained root access I had access to the entire file system, not just the application layer. This is basically what it looks like when you’re talking to the modem from the application layer (see image). You have userspace on top, which is where apps are, at the base – the kernel level; modem drivers; and then the modem itself, the hardware.
So, when you receive a message it comes up here through the modem, through the drivers, and finally hits the application. When you send one – likewise, it starts at application layer, goes to the drivers, finally hits the modem.
After I rooted their phone, I basically installed the BOT level scheme there at the kernel level because I have access to that now. When you get root access on somebody’s phone, you have access to everything including kernel level. So I would basically just intercept messages coming in and out.
And this would be platform dependent; you’d have to be actually able to talk to specific hardware, which at the time, as you saw it, were G1s as these were the only Android phones at the time. Now there’s a zillion of them, this is a lot harder to do. Doing stuff with the application layer is probably better for malware writers. But if you can write this for a specific platform, this sort of thing will never be detected by any antivirus because it’s too low level, it’s in the kernel. And everybody who ever roots your phone, every piece of software you ever go to that says: “Please give me your root privileges” – could do something like this.
So, basically the other caveat is that SMS and basically all of your traffic over the GSM or CDMA modem is completely unencrypted except it’s encrypted with the session key and transit based on whether you’re 2G, 3G or 4G. By the time it hits your phone, it’s not encrypted anymore, nobody whose malware on your phone has to gain access to your private keys or anything, it’s all just going to be encoded.
This is what your text messages look like (see image). You can break it down into what it actually says. You have the sender number, which is just the 2 digits flipped, like if you can very quickly flip those 2 digits back out, you can get my phone number and you can call me. Obviously, I don’t have an F at the end. And then the message here is just 7-bit GSM-encoded; there are tutorials on how to do this on the Internet, and there’s code to get it back out. I wrote one, there’s one on my website.
If you actually teach beginning programming, this would be a really cool exercise to, like, get SMS messages. You know, everybody gets the packets and they break down what the packets say. But doing GSM packets, I think, would get more computer science students, because kids today are obsessed with their phones – really, admit it, it’s true. So this would be a cool exercise. But you can tell whatever thing in this is, with no keys whatsoever; you don’t have to do any encryption, so if you’re on the phone somewhere you’ve got access to everything without encryption at all.
How SMS botnet works
But if it does indeed have the bot key, it will perform functionality for you. For instance, I told it to spam, which it knew, based on this programming, means send an SMS message to someone else with this data. It’s straight up C code, I mean, it’s down there at the bottom of the Android, you don’t have to know anything about content providers or intents, it’s just straight up C kernel. So, if you as a malware writer have written anything for Linux, you can write for this quite easily – easy transition to working on cell phones.
Mitigations for these root level attacks: users need to update their phones. We always tell the users they need to update. I never thought I would say something nice about Microsoft. First Tuesday of every month, I know that my Windows-based machines are going to update and they get the latest patches, and it’s good, and it’s restarted in the morning and I’ve lost all my data that I forgot to save, but at least I have my updates.
Not so much with my Android phone. I used to complain that Android was the best for updating, because it used to be: you had to plug your iPhone into your computer in order to get your updates; same with the BlackBerry. Now both of those push over the air as well, so they’ve caught up with Android there. But all the iPhones get the updates pretty much at the same time. You get your updates, you get your updates for BlackBerry; you don’t get your updates for Android.
Google phones get their updates, so if you have a Nexus One, Nexus S or Galaxy Nexus, when Google puts those out you’ll get them pretty fast, they’ll come over the air to you: “Will you install those updates and lose your root?” And you’ll say: “No”, because you don’t want to lose your root until somebody’s rooted the newest one. Admit it, it’s true. Nobody wants to admit it? Ok. You guys should drink more, then you’d admit it.
However, everyone else who is not a Google platform, it takes a while for you to get your updates. You might have noticed this, you see, it happened with DroidDream, it happens every time there’s an attack. We don’t have our updates yet, why don’t we have our updates? Well, they have to take the Google firmware and they have to port it to their specific platform, make sure all their default install apps still work, and finally push it out to you. This can take six months, this can take a year. In some cases this may never happen.
My Mom’s friends get this idea: “Oh, your daughter is an Android hacker, can she root my phone for, like, 50 bucks?” I just started a company, why not? Apparently, there are these websites that charge hundreds and hundreds of dollars to root your phone. Seriously, these people are making bank on this. But, you know, I get somebody’s phone, and I’m like: “Oh, it’s going to be the most up-to-date version, this is going to be hard”, and I get in and it’s like Android 2.1. Five minutes later – ok, done.
People never get their updates at all. Like the G1 never went past 1.6; any exploit after that, anybody who has a G1 – vulnerable. All their platforms, you get people who never got past 2.0, 2.1. Nobody updates to the latest version. And they’re vulnerable to everything after that, and that sucks, because we can’t really fix that.
If the updates are not available to them, we cannot shake our fingers at them and say: “You must update your phones; you are vulnerable because you didn’t update”, if the updates are not even available to these people. They have to buy another 500-dollar phone and pay a 2-year contract; I’m not sure how it is here in the EU, but in America you buy a 2-year contract and then you get the phone, so you have to be with the carrier for 2 years or else pay a fine, and you still have to pay a lot of money. So buying a new phone is a really big deal in America. And you can’t really blame people for staying with the old one, but they can’t update it. So, this needs to be fixed.
So far we have talked about evil Android guy with horns, evil application that wants to hurt you, and it’s malicious. When you download it, it’s going to exploit you in some way. But now we’re going to switch gears and talk about this green little guy – normal Android, not scary at all. Android is awesome. I pick on Android a lot in this talk, but Android is my favorite platform by far. I often say I want to throw the iPhone across the room, and as a developer I do, it’s hard to develop for the iPhone. It’s easy to develop for Android; they make it very simple for programmers to do lots of cool functionality.
So, a lot of people are developing for Android. And with that comes the caveat, because Android’s got some new things in it. If you’re a secure developer, you’ve thought a lot about how to stop buffer overflows, SQL injections, things you’re used to. Now you’ve got content providers, and activities, and services, and intents. You’re not used to these, these are new. These are things that might have some security caveats we’re just not used to as secure developers, as a security community, that are just open and we’re not sure how to deal with it yet, which is a lot of what you run into – people who just don’t know, because it’s the new stuff.
So, first off the simple stuff, the stuff that we should be thinking about – Android Storage.
Android apps are cool because every application has its own user ID; this is a Linux model and it’s read-only by default. The only person who can see your data is you because you’re the only one with this unique user ID. Other applications on the phone cannot see it.
The problem comes in when you want to share it, of course. A good place to store things is the SD card; we store all our pictures, and our music, and other things there; and when people switch phones they can still have that with them.
There is a problem with the SD card though. It’s VFAT. If anyone is familiar with VFAT, it’s read-only…no, it’s not read-only, not anymore. It’s world readable, so anyone can see anything you put there, any app. And if you still store it on the internal storage and you want to share it with someone else, naturally the idea goes to: “Let’s just make it world readable, no one will know the filename, who cares?” Not so much.
World Readable SD Cards – the Demo
So, naturally, seeing this stuff I thought: “How hard would it actually be to steal data from another application?” So I wrote one. We’ve got more up-to-date Android platform, and iPhone. And we’re going to look at 2 applications; we’re going to look at one that stores data in an insecure manner, and we’re going to look at another application that steals that data.
You may not be aware of this, but after you install applications, you can still see all the permissions they ask for if you go to settings. You think that you just see it upon install and you say: ‘Yes’, and that’s it, and you’re stuck with it, but you can actually see it all.
I’m going to look at an app called BadFileSave, which no one would ever install of course. They want to modify and delete USB storage contents, so they can write to the SD card, and they want to read the phone state and identity, so they want that IMEI number. You might be able to see where this is going: they want to read it and they want to write it somewhere as world readable all the time. That sounds like a recipe for disaster.
Then I have another application BadSendFile. It does not ask for access to the IMEI number, so it should in no way ever be able to access it, and certainly not be able to send it to another phone, but it asks for the ability to send SMS messages. So, again, you might see where this is going. This should not be able to access the IMEI, but it does have the ability to send SMS. So, I wonder what’s going to happen when I call it.
Let’s see what happens. I call BadSendFile, it says: “Hello Android, I am an evil app;” it can have any app it wants here or no GUI at all, it could be just a service in the background, and I see that my IMEI has been sent to the iPhone. So, data it should not have had access to, it was able to access. Rather straightforward example here.
So, basically our green guy is our good application. It stored its sensitive data on the SD card; this need not be the IMEI, this could be usernames and passwords, encryption keys, anything else that we might want to keep others from seeing not just on the SD card storing as world readable, inside of the actual Android storage it would work the same way. As long as you have the filename, you can then access it. SD card is world readable, so since we stored it there, we’re able to see it.
Here comes the bad guy with the evil horns. He discovers how the data is stored, finds out that it’s stored on the SD card; anybody can read the SD card, we don’t have to ask for permission. We saw in the demo that it only asks for SMS, it didn’t ask for information, it asked permission to read SD card, whereas the other one asked for write to SD card, anyone can by default read from the SD card. So anyone can see your pictures from last night in the app on your phone, just saying…Maybe you want that app that deletes them, who knows.
And then it sends it to the attacker via SMS, which it asked for that permission, so it has that ability to do so, not doing anything evil there. It has the ability to read anything from the SD card, it has the ability to send SMS, so technically this didn’t actually exploit you.
Vulnerable and Malicious Code
Everybody hates it when you show code examples in your talk, but these are really short ones, just to illustrate how easy this is. So, this is everything in BadFileSave (see image): it basically just reads the IMEI, which only takes a couple of lines, and you can look up on Stack Overflow how to do it.
Something interesting about Android is that if you want to exploit the Android, really, just google online: “How do you send someone’s IMEI to yourself via text message?” And there are code examples that will show you exactly how to do that. It’s not exploitation, you asked for the permissions – this isn’t evil. It’s hilarious, really. The stuff you can find on the Internet, even if you don’t know how to code in Java, will show you how to do this. And then, it stores it to the SD card in a file called IMEI string filename. That’s not a very good filename, because that pretty much says exactly what’s in there.
And then, BadSendFile, knowing that it’s called IMEI, reads from the SD card, which is a default permission because it’s not considered scary, and then reads what’s in that file and sends it via SMS – since it has that permission, it can do so (see image). So it sends an SMS, and as a former baseband programmer who wrote kernel codes to send SMS, being able to do it in 3 lines here is really awesome.
But wait. We relied on one little caveat here: we knew what the filename was. How did we know that? How did we know what they were storing there and what it was called? It’s actually quite simple, using open source tools, to basically get the source code out of an Android app. There’s talks on reversing Android apps that do a lot better job than this, but it is for the basics to get the source code out and review it. You can do it just with these 3 tools here: you unzip the APK and you use a free tool that is on Google code called dex2jar that will reverse it back to source code from the compiled Java code; and then open it up in the tool called jd-gui which will show you the source code.
These slides are online at my slideshare.net/GeorgiaWeidman, and there’s a link to the white paper that describes all this. It takes a malware sample and shows all this, reversing the malware and looking at what it’s doing. So, if you’re interested in malware reversing, this would be a good place to start with this paper.
For instance, this is Facebook, I said that I have read the source code for Facebook – this is how (see upper part of the image). Very big app there, it does a lot of things. And then, this is DroidDream (bottom part); you don’t see this very well, but there’s some nonsense here, so the caveat here is this isn’t 100% perfect; sometimes it gets it wrong, there are more sophisticated ways of reversing Android; but just to get the basics you can do this in, like, a minute and a half and get basically the entire source code. If you can’t see, it basically says ‘rage against the cage’ up there, which generally gives me an idea of exactly what this is doing; and then it wants to go to /system/bin/sh and run that.
Even though this is not 100% correct, just looking at this, like, a minute and a half after I download it I can generally get the idea it wants to use the ‘rage against the cage’ exploit and then run it.
And then we get something wrong: it says: while (true) if (i<0), while (true) again and then return, and then do some other stuff, but of course after we’ve returned, we won’t ever do any other stuff.
So I sat there and thought: “What is this? This is really weird code; I’ve never seen anything like this before.” And then my Mom walks by and she’s like: “Wow, your decompiler sucks!” And this solves my problem of what this means: my decompiler was not completely 100% correct. But it did give me the gist of it, and I’ve never come into a time where it wouldn’t give me filenames and such. So this will definitely get you what you need for this sort of attack.
Mitigation for storing things incorrectly – just store things correctly. You have a really good model here: you can store things securely because you only have your user ID and no one else can see it but you.
So don’t store things on the SD card, that’s VFAT, we don’t like that. Don’t store them in the source code, because that’s what we saw: we might get those strings back again. And don’t store them world readable. If you want to share them with others, you can share user ID or you can store them in the SQLite database and share it. But don’t share them these ways, this is bad.
Android Interfaces with Dangerous Functionality
If anyone’s ever done Android programming, one of the reasons Android is so awesome is, for instance, if you want to talk to the camera and take a picture, you don’t have to do all the underlined programming to talk to the camera; you don’t have to talk to the camera at all. All you have to do is call the open interface for the camera app and tell it: “Please, take a picture for me and please return it to me.” And it nicely does and gives it back to your application, and you can go on with your life. So you don’t have to do any camera programming whatsoever.
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.