Skip to content
KitploitKITPLOIT
FerramentasExploitsBlog
Log in
Enviar
FerramentasExploitsBlog
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.

FeedsContatoPrivacidade© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
ReparcelBug2 — Writeup e exploit para escalonamento de privilégios de aplicativo instalado para sistema no Android 12 Beta através do CVE-2021-0928, uma incompatibilidade de serialização `writeToParcel`/`createFromParcel` em `OutputConfiguration` | Kitploit
Ferramentas/GitHubGitHub/michalbednarski/reparcelbug2
Segurança AndroidEscalada de PrivilégiosAnálise de VulnerabilidadesExploraçãoSegurança MóvelAnálise de Binários
GitHubmichalbednarski/reparcelbug2

ReparcelBug2

Writeup e exploit para escalonamento de privilégios de aplicativo instalado para sistema no Android 12 Beta através do CVE-2021-0928, uma incompatibilidade de serialização `writeToParcel`/`createFromParcel` em `OutputConfiguration`

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
Ver Repositório
1252468há 4 anosRevisado pelo Kitploit

CVE-2021-0928, incompatibilidade de serialização writeToParcel/createFromParcel em android.hardware.camera2.params.OutputConfiguration

Este é um exploit que usa essa vulnerabilidade para escalonamento de privilégios de um app Android instalado para o app de Configurações do Android (ou qualquer outro app instalado para o qual o app pudesse enviar para <receiver> declarado em AndroidManifest.xml; o escalonamento de privilégios enviando para <activity> também era possível, embora não apresentado aqui)

Encontrei o problema originalmente no Android 12 Developer Preview 3

A versão do exploit presente neste repositório funciona no Android 12 Beta 2 e 3

A vulnerabilidade foi corrigida no primeiro lançamento oficial do Android 12

O writeup abaixo foi originalmente escrito para o Google para consideração deste relatório como cadeia de exploit completa

No momento da escrita, o Android 12 não estava disponível no AOSP (as versões Android Developer Preview/Beta não são open source)

Captura de tela da notificação do Android do app de Configurações: Hello from uid=1000(system) gid=1000(system) groups=1000(system),1007(log),1065(reserved_disk),1077(external_storage),3001(net_bt_admin),3002(net_bt),3003(inet),3007(net_bw_acct),9997(everybody) context=u:r:system_app:s0

Introdução ao Parcel

A maior parte da IPC no Android é feita através da classe chamada Parcel

O uso básico do Parcel é o seguinte:```java Parcel p = Parcel.obtain(); p.writeInt(1); p.writeString("Hello");

Então, o `Parcel` é enviado para outro processo [através do `Binder`](https://developer.android.com/reference/android/os/IBinder#transact(int,%20android.os.Parcel,%20android.os.Parcel,%20int)). Alternativamente, para fins de teste, pode-se chamar [`p.setDataPosition(0)`](https://developer.android.com/reference/android/os/Parcel#setDataPosition(int)) para rebobinar o parcel até a posição inicial e começar a leitura:```java
int a = p.readInt(); // a = 1
String b = p.readString(); // b = "Hello"

Deve-se notar que o Parcel mantém internamente a posição a partir da qual as leituras são realizadas. É responsabilidade do usuário da classe Parcel garantir que os métodos read* correspondam aos métodos write* usados anteriormente; caso contrário, as leituras subsequentes serão feitas a partir de posições erradas no buffer.

O Parcel também oferece a capacidade de escrever objetos personalizados; a forma preferida de fazer isso é implementando a interface Parcelable.

Aqui está um exemplo de implementação da interface Parcelable (código irrelevante removido; a classe WindowContainerTransaction é usada no exploit como parte da cadeia de gadgets, no entanto não há nada de errado com ela):```java package android.window; public final class WindowContainerTransaction implements Parcelable { private final ArrayMap<IBinder, Change> mChanges = new ArrayMap<>(); private final ArrayList mHierarchyOps = new ArrayList<>();

private WindowContainerTransaction(Parcel in) {
    in.readMap(mChanges, null /* loader */);
    in.readList(mHierarchyOps, null /* loader */);
}

@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
    dest.writeMap(mChanges);
    dest.writeList(mHierarchyOps);
}

@NonNull
public static final Creator<WindowContainerTransaction> CREATOR =
        new Creator<WindowContainerTransaction>() {
            @Override
            public WindowContainerTransaction createFromParcel(Parcel in) {
                return new WindowContainerTransaction(in);
            }
        };

}

Como pode ser visto acima, o método `writeToParcel()` é usado durante a escrita. Em seguida, durante a leitura, o método de fábrica `CREATOR.createFromParcel()` é chamado. É responsabilidade da implementação de `Parcelable` garantir que `createFromParcel` leia a mesma quantidade de dados que foi escrita por `writeToParcel`; caso contrário, todas as leituras subsequentes desse `Parcel` lerão dados de um deslocamento incorreto

Essa classe pode ser gravada/lida de/para `Parcel` através de:

* Chamando diretamente `obj.writeToParcel(parcel, 0)` / `obj = WindowContainerTransaction.CREATOR.createFromParcel()`, isso é frequentemente usado quando o tipo da classe é conhecido, por exemplo, quando `Parcelable` tem um campo com um `Parcelable` diferente ou em código gerado por AIDL quando o método RPC definido tem `Parcelable` como argumento
* Através de `Parcel.writeParcelable`/`readParcelable`. [`writeParcelable`](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/Parcel.java;l=1909;drc=58787794eb5c879f6e39ee58c0071b36e337f8e3) primeiro grava o nome da classe e depois chama o método `writeToParcel` da interface `Parcelable`. [`readParcelable`](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/Parcel.java;l=3282;drc=58787794eb5c879f6e39ee58c0071b36e337f8e3) lê o nome da classe gravado, encontra a classe com esse nome no `ClassLoader` fornecido ou no `BOOTCLASSPATH` se null for fornecido. Uma vez que a classe é encontrada, seu campo estático `CREATOR` é usado para obter uma instância de [`Parcelable.Creator`](https://developer.android.com/reference/android/os/Parcelable.Creator), que é a fábrica usada para ler essa classe. É importante notar que quando o método `readParcelable` é usado, ele pode ler qualquer `Parcelable` disponível no classpath, pois o nome do objeto a ser criado é lido do mesmo `Parcel`
* `readParcelable` é usado por muitos outros métodos de `Parcel`, por exemplo, `readList` visto no exemplo acima lê elementos através de `readValue`, que é o método mais genérico de transferir objetos em `Parcel` e uma das formas que ele usa é através de `readParcelable`. Além disso, no exemplo acima, devido ao Type Erasure do Java, o campo `ArrayList<HierarchyOp> mHierarchyOps` pode na verdade conter quaisquer objetos suportados por Parcel, não apenas aqueles compatíveis com o tipo especificado na declaração do tipo genérico

# Incompatibilidades de `writeToParcel`/`createFromParcel`

Como observado acima, é responsabilidade da implementação da interface `Parcelable` garantir que `createFromParcel` leia a mesma quantidade de dados do `Parcel` que o `writeToParcel` correspondente gravou anteriormente. Sempre que houver no `BOOTCLASSPATH` um `Parcelable` que possa violar esse contrato, isso cria uma vulnerabilidade, pois permite o seguinte cenário:

1. Um aplicativo malicioso envia ao `system_server` um `Bundle` OU `Parcelable` contendo uma instância defeituosa de `Parcelable` juntamente com dados especificamente construídos que serão realmente lidos no passo 3, mas passados verbatim durante o passo 2
2. O `system_server` verifica que o `Bundle` é seguro e o encaminha OU o `system_server` passa o `Parcelable` fornecido para um método AIDL que também tem dados críticos passados no próximo parâmetro (se os dados recebidos nesse parâmetro pudessem ser modificados, isso causaria um problema de segurança)
3. Outro aplicativo recebe dados do `system_server` e confia neles, porém, devido à serialização defeituosa, os dados que ele realmente vê diferem dos dados que o `system_server` pretendia enviar
Baixar ferramenta