20 minutes 13 seconds
Speaker 1
00:00:00 - 00:00:30
On this channel I haven't covered mobile app security much. For me the app sandbox restrictions are so good, that finding good security issues seems rare. But then Google approached me and asked if I want to make a video about a bug hunter who is looking for bugs in Google android apps. Meet Sergei Toshin, also known as Oversecured. From him I learned that there are very interesting bug classes that I wasn't really aware of.
Speaker 1
00:00:30 - 00:00:47
And in this video he will show us how he found a vulnerability in the Google snapseed android app. And this was not a super simple bug, but also not a crazy bug. It's a bug that you can also find. But his process is what is really interesting. And I think we can learn a lot from him.
Speaker 1
00:00:47 - 00:01:29
And maybe it's a good starting point for you as well. Sergei or Oversecured is an interesting bug hunter for various reasons. First of all, he is 1 of the most successful Google bug hunters targeting android apps. But to be fair, most hunters focus on web security, so there is definitely enough room for you to join the top as well. Second, a lot of successful and full-time bug hunters do not share their exact methodology, or the kind of bugs they report, because revealing the tricks could lead to less income.
Speaker 1
00:01:29 - 00:01:57
Which is totally understandable. But Sergey shares so much. His blog over at oversecured is probably 1 of the best android app security blogs. There are of course a lot of android security resources out there, including the official developer android security documentation, but a lot of them are rather basic. Sergey on the other hand has a lot of practical examples from his bug bounty work.
Speaker 1
00:01:57 - 00:02:32
And lastly his methodology is interesting, because he is automating a lot. I assume most successful bug hunters heavily rely on automation, but not many share their setup. But Oversecured is showing us how he does it. And not only that, he is sharing his automation tool as a paid service over at oversecured.com. Just a little disclaimer, Google is not endorsing that tool, I'm just here to share with you Sergei's work and it just happens to involve his own scanner.
Speaker 1
00:02:32 - 00:02:50
It should go without saying that this is not a magic tool that makes you rich without skill. And it's not the only tool out there either. This tool is like a pen. In the hands of a skilled artist they can draw something amazing. In my hands you get this.
Speaker 1
00:02:51 - 00:02:55
Anyway, let's hear from Oversecured how he got where
Speaker 2
00:02:55 - 00:03:21
he is today. I think it was 2018 when I developed multiple scripts to search different security issues on Android. And I also participated in Google Play security rewards program. And I also started developing like a single big tool that searches for different security issues."
Speaker 1
00:03:22 - 00:03:51
But then in 2019 Google announced that they would expand their bug bounty program to any app in the play store with more than 100 million downloads. This means Google pays for vulnerabilities in apps not from Google. Crazy right? It's all in the effort to secure the wider android ecosystem. Anyway, when this was announced, Sergey was at a bar and heard the news.
Speaker 2
00:03:51 - 00:04:16
And then they told that we are allowing you to report bugs in any apps that have 100 million of installations. And at that moment I was in the bar and I thought, wow, like there are hundreds of such apps. I'm going to become a millionaire. And really after the bar, I came to home, scanned like
Speaker 1
00:04:18 - 00:04:18
20
Speaker 2
00:04:18 - 00:04:48
apps and found like 40 potential issues. Next day I woke up with alarm because I never wake up with alarm and I woke up with alarm and started reporting the bugs like every day and I reported them I think within 6 months like every day a few bugs. I think my best day is 15 issues reported and in total Google paid me out I think almost
Speaker 1
00:04:49 - 00:04:50
900 000
Speaker 2
00:04:51 - 00:04:51
of dollars.
Speaker 1
00:04:53 - 00:05:17
And pay close attention to what he says here. His scanner found potential issues, not confirmed issues. His automation does not automatically submit any bugs the scanner finds. They are just potential bugs that he has to manually review to determine if they are actually vulnerabilities or not. And that of course requires experience and skills.
Speaker 1
00:05:17 - 00:05:35
I have seen bug hunters just blindly report anything they see. And that is really bad. When you do that, you won't become a valued bug hunter like Sergey. So please never trust any automatic scanners and always verify the output. Google also has an article and video about blindly reporting scanner results.
Speaker 1
00:05:35 - 00:06:05
Of course the manual confirmation is still labor intensive, but at least his tooling provides a list of potential issues, which significantly reduces the overall time needed to find valid vulnerabilities. Anyway, let's go through his process. Here is the scan report for the Snapseed app. And as you can see, it found a lot of potential issues. But to understand those numbers you need to understand how the tool works.
Speaker 1
00:06:05 - 00:06:42
It basically tries to identify all sources, so places in the code where attacker data could enter into the application, and sinks, so places that are critical if attacker data gets there. I made a video about the terms before, you can find it here. So if there are multiple sources leading to the same sink, or a single input source leading to multiple sinks, then the tool will track each option, inflating the numbers a bit. And so while he scrolled over the long list, I asked him, did you go over all of them now?
Speaker 3
00:06:42 - 00:07:03
I think I checked them, but It uses a lot of code. I think those vulnerabilities could be valid too. But the dataflow is long and I need to realize what's going on in this code. Yeah it could be valid too, but the verification would take a lot of time.
Speaker 1
00:07:03 - 00:07:17
Yeah, some of these potential findings were too annoying for him to actually verify. But still, he knows he has to verify them, and cannot simply copy the scan results. So he started looking at the potential findings with very little code.
Speaker 3
00:07:18 - 00:07:28
But then I thought, what's in other categories? Maybe there are easier bugs? And I checked this. And this is super easy. Just look at this.
Speaker 3
00:07:28 - 00:07:36
Like only 2 blocks of code. Only activity and set result for this. Yeah that's super easy.
Speaker 1
00:07:37 - 00:07:55
Alright. Now let's confirm the bug. His go-to choice for looking at the android app code is the java decompiler JADX. Loading the APK in it and then going to the function that his tool flagged for being a potential issue So what are the actual conditions for triggering it?
Speaker 3
00:07:55 - 00:08:36
You see like main activity vulnerable line of code and you need to find where it's used. And yeah, we can see it's invoked in main activity in the catch block. So when some error happens, it displays alert dialogue. And when user clicks on the positive button, this code is triggered and returns attacker controlled content back to the attacker, leading to gaining access to arbitrary content provider vulnerability. So all we need to do is triggering class castException.
Speaker 3
00:08:37 - 00:08:40
And we need to realize how can we trigger it.
Speaker 1
00:08:40 - 00:09:06
So we have the 2 pieces of the code. Here we have the onClickButton handler for an alert dialog, which attempts to return a result back to the sender of an intent. This is vulnerable code. But this dialog is only triggered if we have a class cast exception. So now Sergi has to figure out, is there a way to trigger that?
Speaker 1
00:09:06 - 00:09:37
If this code is maybe never reached, it would not be exploitable. And this is really important to understand. You always need to verify if you can even reach the vulnerable code. Another example where you might not be able to find an attack, is for example when you have an if case that checks if the app is in debug mode, but the debug mode is never enabled in the production app, So you could never reach it. I cannot stress it enough how important it is to verify the bug in the code.
Speaker 1
00:09:37 - 00:10:04
To do that, Sergey pulls up the android studio and starts developing a malicious app. Yes, for Android bugs you probably need a basic understanding of how android apps are developed. In web bug hunting you often don't need to know programming, but here you often have to write a bit of code to exploit a bug you found. Anyway. You probably asked yourself, I don't understand what is this vulnerability here.
Speaker 1
00:10:04 - 00:10:15
And I'm glad you asked. So let me explain what he actually found here. We need to explain 3 concepts. Android Intents, Content Providers and Android Permissions. First.
Speaker 1
00:10:15 - 00:10:29
Android Intents. In the android ecosystem you have the concept of intents. Intent is a weird word to you maybe? So try to not get confused by new terminology. It's very basic when I replace the word intent with the word data.
Speaker 1
00:10:30 - 00:10:57
Android apps can send and receive data. So 1 app can send data to another. For example when you want to share a website, you open up the share view and you can click on another app, for example message. This then opens the message app and it has the link I want to share. Under the hood, the browser app sent this data, so an intent, to the message app with the data, the URL.
Speaker 1
00:10:57 - 00:11:19
This is a very basic example and of course you can send a lot more than just text. Intents have tons of features, you will see in just a moment. But for now, intents are simply used to pass data to other apps. As you can see, intents are a very typical attack surface for android apps. A malicious app could send any kind of intent to other apps.
Speaker 1
00:11:19 - 00:11:41
And if the app handles the intent badly, it could lead to all kinds of security issues. Second, content providers. Another important android feature and threat surface to understand here, is the concept of content providers. Apps can define content providers and it does what the name says. Provide content.
Speaker 1
00:11:42 - 00:12:11
They try to abstract the way how data is really stored. Content providers work through URIs. So if you have your nodes stored in an SQL database, you could create a content provider to access the nodes instead. Then no SQL queries are needed, and you can just use a URI like this. So now that your app stores notes and has a content provider for them, your app could expose this content provider to allow other apps to access those notes.
Speaker 1
00:12:12 - 00:12:47
But of course it's a bad idea to just have the content provider publicly accessible. It would be much better if another app has to request access, and then the user has to confirm this first. An external app could ask your app, can I get access to the nodes? You display a dialogue to the user, and if the user hits OK, you send back an intent with the flag, flag grant read uri permission. Adding this flag to the intent you sent back to the requesting app, grants the other app to access the content via the notes URL.
Speaker 1
00:12:47 - 00:13:03
So you shared the content provider with another app. Third, Android permissions. The last concept we need to understand. Android permissions. In this case the Snapseed app has read and write permissions to external storage.
Speaker 1
00:13:03 - 00:13:26
And by requesting these permissions, the app will actually get access to the hidden, or rather internal content provider for files on the external storage. The URL for that looks for example like this. Content colon media external. That's it. Snapseed can now use this content provider to access files on the external storage.
Speaker 1
00:13:26 - 00:13:51
And it's important to note that our attacker app does not have these permissions. It cannot access the file storage. Ok, now that we have all the 3 concepts we need, we can now come back to the vulnerability Sergey found. In the meantime he has written up his malicious attack app, so let's check out his code. When the malicious app starts, he creates a new intent object, and sets various values.
Speaker 1
00:13:52 - 00:14:17
But ignore these for now. Important is only the set class name and this put extra. With set class name you can specify exactly the receiver of the intent. In this case it's the SnapseedAppBundle as well as the VulnerableActivity class. When he now starts this activity, he sends this intent, it will launch the main activity from Snapseed with this extra streamdata.
Speaker 1
00:14:18 - 00:14:45
And now let's go to the receiving side. Here the main activity now tries to access this streamdata and cast it to an android.net URI. But the intent did not contain a URI, It's this wow string. So this triggers the required class cast exception, which causes this alert dialog to be created. So now the app has the dialog, there is the ok button to confirm you read the error.
Speaker 1
00:14:46 - 00:15:01
And now we know what this button does from the onclick handler. It returns a result back to the app with setResult. It sets the result value to 0, probably to tell the other app that it didn't work. 0. False.
Speaker 1
00:15:01 - 00:15:16
Fail. But additionally it also adds the original intent that was sent to the app from Sergey. Probably to give the receiving app a bit of context. What was the intent that didn't work. But This is dangerous.
Speaker 1
00:15:17 - 00:15:43
We know how android passes data between apps, so of course this result is sent back as an intent to the malicious app. And now think about how the intent looks like that it sends here. It's reflecting the intent that Sergey created. And now the other fields become important. The intent contains the external content URI, as well as the flag grant read URI permission.
Speaker 1
00:15:43 - 00:16:18
Do you see where this is going? By Snapseed sending such an intent to the malicious app, it tells the android operating system, Snapseed would like to give the attacker app the permissions to access my internal file content provider. Which means the malicious app has now the permission to use the Snapseed's content provider for external files. Here in the result handler, so where the attacker app receives the response intent, in there Sergey can now access the media storage. Let's run the full exploit.
Speaker 1
00:16:19 - 00:16:26
Sergey used Android Studio to develop his malicious app, then installs it on his phone and launches the malicious app.
Speaker 3
00:16:30 - 00:16:42
Here and we click on ok, we see that 2 files are here. So it's working. And I think we can report it right now to Google.
Speaker 1
00:16:42 - 00:17:13
So this attack showed that Snapseed was vulnerable to hijacking a content provider. It essentially allowed a malicious app, without permissions, to access external storage. And that is a valid bug. As you can see, Sergey then went on the bughunters.google.com website to create a writeup of the issue. Always make sure to clearly state the issue, copy the important code snippets and add your proof of concept attack code as well, submit the report and there we go.
Speaker 1
00:17:13 - 00:17:39
That was it. Now how much reward does a report like this get? Here you have to differentiate if it's an app covered by the Google Play Security Reward Program, which means you found a bug in a very very popular third party app, or if you found a bug directly in a Google app. If we look into the reward policy for third party android apps, we can see here that we have 3. User must install a malicious app.
Speaker 1
00:17:39 - 00:18:10
And then we have theft of sensitive data due to the access to the app's content providers. So this issue should be a $1000 bounty if the bug is in a popular third party app. But in this case Sergey found the issue in a Google app. So the regular bug bounty rewards apply. And in the table we can find here unrestricted file system or database access, or logic floor bugs, leaking or bypassing significant security controls, both could apply here.
Speaker 1
00:18:10 - 00:18:31
Also the app probably falls under the lower priority applications. A photo editing app is probably not a critical Google app like gmail. So either it's 500 dollars or 1337 dollars. And he later told me he got the 1337 dollars. Good job Sergey.
Speaker 1
00:18:32 - 00:18:52
As you can see, Sergey used his tool to find a valid bug in a Google app. So Google came up with a cool idea. Google actually scanned multiple apps of theirs and made the results available to you. You can find the links in the description. Just please don't copy and paste the scan results and report it.
Speaker 1
00:18:52 - 00:19:10
That makes no sense. Google has the scans as well. What is important is, like Sergey showed you in this video, you have to actually verify the bugs. For example by implementing a proof of concept attack. This is of course maybe not easy, but that's why you also have a good chance to find something.
Speaker 1
00:19:11 - 00:19:35
In Android bug bounty you don't have a lot of competition. So why don't you give it a try? Also if you find a valid bug, send me a message via email or twitter, so I can make sure to add notes in the description about what has already been reported. I'm actually quite excited about the results of this little experiment. Maybe I will make a follow up video sometime about the results of all of this.
Speaker 1
00:19:36 - 00:19:47
I wonder how much bounty falls out of this. Cool. I hope you enjoyed this introduction into the world of android app security and Android app bug bounty hunting. And hopefully
Speaker 2
00:20:00 - 00:19:47
you
Omnivision Solutions Ltd