The Toast Overlay Attack

Hi, I recently came across this DEFCON talk from Nikita Kurtin about different tricks he found to bypass the Android permission system. One technique that I particularly liked was the Toast Overlay Attack. So, I wanted to study it in a bit more detail, and implement my own proof of concept for it.

On android, Toasts are little messages that are used to display information to the user :

They are displayed by the system, and can appear even if our application is not in the foreground. Moreover, on older versions of Android, the appearance of these messages could be modified at will, and even be made intangible. This two facts combined could enable a malicious application to trick the user into giving it permissions without the user realizing it. The app could trick the user into, for example :

  • Giving it accessibility permission, to enable further overlay attacks over any application
  • Giving it device admin permission, and possibly use it to create a ransomware
  • Allowing the application to access and steal user data

Interested ? Let’s take a look at the PoC I developed before I explain in more details how it works (I could not resist giving the video an Unregistered HyperCam 2 vibe (•‿•) ):

Explanations

What exactly happened here ? After launching the attack, the user is presented with a text to make them want to click on a button, in this case to disable ads in the application. This button takes them to another page, with a switch to activate said function. Once the user clicks on the switch, they are taken back to the main page, but the application has gained the permission it was seeking. How did that happen ?

Well, the user was tricked into, in fact, going into the device settings and enabling the permission from there. But at no point in time did we see the user in the settings menu, so how is that possible ? Well, we used a few Toasts to display fake screens to the user, guiding him to click where we wanted him to click to give us that permission. Since the Toasts are displayed over any application, including the system Settings, the user was actually seeing one thing, while actually interacting with another.

Let’s see the same attack, but this time with transparent Toasts to better see what was happening :

As you could see, the user indeed gave the location permission by themselves, although inadvertently. But you might have noticed a few things :

First, why did we not cover the final slider on the permissions page ? Android 6.0 already had some protection mechanisms to protect the users from this kind of attack. If we cover the final switch with an overlay, the user gets this message when clicking on it :

If we wanted to to this, we would need the “Draw over other applications” permission beforehand, and if we can obtain this permission without using an overlay, we probably don’t need this attack anyway. Leaving the slider uncovered allows us to remain undetected and to get the permission we wanted.

Secondly, why are there two different kinds of overlay (blue/red) ?

Basically, the blue overlays are blocking the user’s clicks, and the red ones are letting them pass through. This is done for the following reasons :

For the red ones, If we make the red view listen to clicks on itself, it is going to catch those clicks, and prevent the covered application from reacting to them. Basically we need to make them transparent to clicks, so that the user clicks on the hidden menu instead of our overlay. This works well, but creates a problem : since the view is transparent to clicks, it does not know when the user has interacted with the menu, and we can’t know when to change our overlays to make the user click on the final slider. The solution for this takes the form of the blue views.

The blue views have a dual purpose. First, they listen to clicks outside of themselves, which allows us to know when the user has interacted with the settings. Secondly, they block clicks on themselves, preventing the user from going elsewhere than where we want them to go. On the second video, you can see clicks on the blue overlays which do not take the user to the related menus, showing that the user can only interact with what we want them to interact with.

Now that you understand what happened, let’s take a look at the code to make it work.

A bit of code

The code for this PoC is available on GitHub, and is inspired by this article from Palo Alto Networks. For this part, I am going to assume some familiarity with Android programming in Java.

I mostly wanted to take a look at two things :

First, on versions of android before API 30 (Android R), any views could be made with the properties of a Toast message. For that, the Toast type simply has to be passed when creating the view :

int type = WindowManager.LayoutParams.TYPE_TOAST;
WindowManager.LayoutParams layoutParams2 = new WindowManager.LayoutParams(main_layout.getLayoutParams().width,
                250,
                0, 1225,
                type,
                flags | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                      | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
                PixelFormat.TRANSLUCENT
        );

After that, the two most important part are the flags passed when creating the views. For a red view, clickable, we pass these two flags :

WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE

The first one prevents the view from getting the input focus, meaning that no input will be directed towards it. It also implicitly sets the FLAG_NOT_TOUCH_MODAL flag, which we will discuss later. The second flag prevents the view from receiving any touch event, and allows them to pass to the view behind it.

For a blue view, the following flags are set :

WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL

The FLAG_NOT_TOUCH_MODAL, will “allow any pointer events outside of the window to be sent to the windows behind it. Otherwise it will consume all pointer events itself, regardless of whether they are inside of the window. (from the Android Documentation)”. While redundant, its goal is to allow the touches on the red view to get sent to the window behind.

Another flag is set on the blue view responsible for detecting user clicks :

WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH

This flag allows the view to receive touch event from all windows, even ones from other applications. By first checking if the event happened inside or outside of the unclickable view, we can know if the user clicked where we wanted it to.

Other than that, the code is pretty normal, and is mostly responsible for organizing the views and the order in which they appear.

I strongly encourage you to take a look at the full code and play around with it to better understand the flow and the capabilities of this attack. Speaking of our capabilities, let’s look at a few limitations of this attack.

Limitations

In the previous part, you may have noticed some magic numbers in the code. These numbers are here to set the size and position of the different overlays. They are constants, since it is not easy to support many different displays with this attack. Here, we targeted a Nexus 6 phone, with the following display characteristics :

If trying to use the application with a different phone, things may look out of place and the overlays wont cover the right parts of the screen. This attack is best against targeted individuals when their phone model are known.

Moreover, at least in this PoC, physical buttons are not taken into account. This means that the user could press the back button in the middle of the attack, which would break its flow and create a weird state where the overlays don’t match the window underneath, and the user makes unrelated actions. For example, here, the application was taken out of focus, but the overlay remained :

And, finally, this vulnerability is quite old, and was patched by Google in September 2017. This means that any phone running Android 7.1 or above, or even Android 7.0 with the latest security patches will prevent this attack by deleting all Toasts when the user is in the permissions menu or shown a permission request.

Conclusion

I really enjoyed making this app. It allowed me to better understand what was really happening in the many overlay attacks, and to learn what were the limitations and different countermeasures implemented to try and prevent these attacks. I hope you liked this little presentation of it, and maybe learned a thing or two while there.


Posted

in

by

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *