Size Matters — CVE-2021–0485 (High)

+Ch0pin🕷️
5 min readAug 7, 2021

Don’t get me wrong but I couldn’t find more appropriate title in order to describe the specific vulnerability.

I don’t know what happens when it comes to your sexual life, but I can assure you that in software development even the smallest neglect matters. Ah… At this point let me assure you that not any kind of age-restricted content is discussed in this article, so no need to keep your children away from the screen.

Restrictions…Restrictions…Restrictions

While many UI based attacks have already been analysed and published in the past, the main motive behind creating this article is to present an innovative way of leveraging a special window type in order to overcome multiple privacy restrictions that were imported in newer Android versions.

More specifically, in 2017 Android Oreo introduced a number of background execution limitations including the frequency of location updates for better overall system health and performance. In 2018, Android Pie went a step further and disabled access to sensors for idle UIDs, thus an application being in the background for more than a certain amount of time shouldn’t be able to use the camera, microphone or other sensors in general. Finally Android Q, imported new restrictions that prevent an application to start an activity from the background. At this point, an alternative of displaying notifications instead of popping windows out of nowhere, was suggested.

Spyware developers and ad-fraudsters were literally knocked down by these changes, as applications are not further able to spy the user without being visible nor can display ads out of the blue, while an activity is not running in the foreground.

In a constantly changing environment, security measures must evolve in order to follow the newest privacy norms and requirements, thus on a frequent basis those measures are being reviewed, redesigned or even written from scratch. Developers know better, that when new restrictions must apply, there are many things that should be taken under consideration. Besides the backward compatibility, which is the first thing that comes to everyone’s mind, features which was not considered to have any security impact in the past, need to be evaluated again when applied in an updated or more strict environment.

Picture in Picture

From the respective Android Developers Page: Picture In Picture or PIP is a special type of multi window mode mostly used for video playback. It lets the user watch a video in a small window pinned to a corner of the screen while navigating between apps or browsing content on the main screen.

Image by https://www.techquila.co.in/youtube-testing-picture-in-picture-ios/

This is a really handy… and not just for video playback, Google Maps use this feature extensively while navigating in real life but also in the mobile screen. The PIP implementation is quite straight forward:

First you have to declare a PIP support in your manifest file:

<activity android:name="VideoActivity"
android:supportsPictureInPicture="true"
android:configChanges=
"screenSize|smallestScreenSize|screenLayout|orientation"
...

And then you just have to perform a simple function call:

enterPictureInPictureMode()

…And as you probably noticed NO SPECIAL PERMISSION IS REQUIRED

CVE-2021–0485

As there is no control of the minimum allowed window size while in PiP mode, it is possible to create an arbitrary small window which won’t be visible to the user. Using this window as a foothold, it is possible for an unprivileged application to maintain its foreground stage and bypass security restrictions which were introduced in Android Oreo and later.

Proof of Concept

Git Repo Here

Let us first start by creating a simple PiP window by following the Android Developers documentation:

  1. Create a new android studio project
  2. Add the following entry in your manifest file
<activity android:name=".MainActivity"
android:supportsPictureInPicture="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

3. Add the following call in your MainActivity’s onCreate:

enterPictureInPictureMode();

By running the app you should get the following (or something similar):

If you play around with it will surely remind you of something …. yes… that:

Image by https://newgia.com/messenger-bubbles-in-android/

By clicking on the created window, the default behaviour is to expand and show UI controls which may be used to close or maximise it.

Customising the UI

My first thought was to create a transparent activity which will be invisible to the user but would still help me to maintain a foreground state for my application. There is a significant issue though…. besides a user’s accidental touch….as you probably didn’t notice, there is a shadow dropped in the window frame which distinguishes the PiP window from the rest of the UI. But what about the size ?

After a small research I found out two ways in order to change the PiP size, one of which is by using the setAspectRatio function of the PictureInPictureParams.Builder and will not work in the particular case. The other is by using the <layout> manifest element which supports several attributes that affect how an activity behaves in multi-window mode [Ref] (don’t forget that PiP is just a special type of multi window mode):

android:defaultWidth

Default width of the activity when launched in freeform mode.

android:defaultHeight

Default height of the activity when launched in freeform mode.

android:gravity

Initial placement of the activity when launched in freeform mode. See the Gravity reference for suitable values.

android:minHeight, android:minWidth

Minimum height and minimum width for the activity in both split-screen and freeform modes. If the user moves the divider in split-screen mode to make an activity smaller than the specified minimum, the system crops the activity to the size the user requests.

For example, the following code shows how to specify an activity’s default size and location, and its minimum size, when the activity is displayed in freeform mode:

<activity android:name=".MyActivity">
<layout android:defaultHeight="500dp"
android:defaultWidth="600dp"
android:gravity="top|end"
android:minHeight="450dp"
android:minWidth="300dp" />
</activity>

Exploitation

Using the method above we can set up an arbitrary small PIP window which is not visible or touchable. The ‘way’ is pretty straightforward as the only thing you have to do is add the following entry:

<activity android:name=".MainActivity"
android:supportsPictureInPicture="true"
android:theme="@style/Theme.AppCompat">
<layout android:defaultHeight="1dp"
android:defaultWidth="1dp"
android:gravity="top|end"
android:minHeight="1dp"
android:minWidth="1dp" />

And here is how it looks like:

This little ‘dot’ will maintain your application in the foreground bypassing the restrictions we described in the beginning of the article.

Summary

Since 2017 Android imported a series of background execution limitations targeting better performance, health and security. An application which maintains its foreground state will be able to bypass these restrictions with consequences that may affect the user’s privacy. By using a very small PiP window it is possible for an application to maintain a foreground state without becoming perceived to the user.

Details about the fix can be found here: https://source.android.com/security/bulletin/2021-05-01

Download the POC here: https://github.com/Ch0pin/CVE20210485

--

--