Skip to content
KitploitKITPLOIT
HerramientasBlog
Log in
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

FeedsContactoPrivacidad© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
ReparcelBug2 — Writeup y exploit para escalada de privilegios de una app instalada a nivel de sistema en Android 12 Beta mediante CVE-2021-0928, una discrepancia de serialización `writeToParcel`/`createFromParcel` en `OutputConfiguration` | Kitploit
Herramientas/GitHubGitHub/michalbednarski/reparcelbug2
Seguridad AndroidEscalada de PrivilegiosAnálisis de VulnerabilidadesExplotaciónSeguridad MóvilAnálisis de Binarios
GitHubmichalbednarski/reparcelbug2

ReparcelBug2

Writeup y exploit para escalada de privilegios de una app instalada a nivel de sistema en Android 12 Beta mediante CVE-2021-0928, una discrepancia de serialización `writeToParcel`/`createFromParcel` en `OutputConfiguration`

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir
Ver Repositorio
1252468hace 4 añosRevisado por Kitploit

CVE-2021-0928, discrepancia de serialización writeToParcel/createFromParcel en android.hardware.camera2.params.OutputConfiguration

Este es un exploit que utiliza esa vulnerabilidad para escalar privilegios desde una app de Android instalada hacia la app de Configuración de Android (o cualquier otra app instalada a la que se pudiera enviar un <receiver> declarado en AndroidManifest.xml; la escalada de privilegios enviando a un <activity> también era posible, aunque no se presenta aquí)

Encontré el problema originalmente en Android 12 Developer Preview 3

La versión del exploit presente en este repositorio funciona en Android 12 Beta 2 y 3

La vulnerabilidad se corrigió en la primera versión oficial de Android 12

El informe que aparece a continuación fue escrito originalmente para Google para que este informe se considerara como una cadena de exploit completa

En el momento de redactar este informe, Android 12 no estaba disponible en AOSP (las versiones Developer Preview/Beta de Android no son de código abierto)

Captura de pantalla de la notificación de Android de la app de Configuración: 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

Introducción a Parcel

La mayor parte de la IPC en Android se realiza a través de la clase llamada Parcel

El uso básico de Parcel es el siguiente:```java Parcel p = Parcel.obtain(); p.writeInt(1); p.writeString("Hello");

Entonces `Parcel` se envía a otro proceso [a través de `Binder`](https://developer.android.com/reference/android/os/IBinder#transact(int,%20android.os.Parcel,%20android.os.Parcel,%20int)). Alternativamente, para pruebas se puede llamar a [`p.setDataPosition(0)`](https://developer.android.com/reference/android/os/Parcel#setDataPosition(int)) para rebobinar el parcel a la posición inicial y comenzar a leer:```java
int a = p.readInt(); // a = 1
String b = p.readString(); // b = "Hello"

Debe tenerse en cuenta que Parcel internamente mantiene la posición desde la cual se realizan las lecturas. Es responsabilidad del usuario de la clase Parcel asegurarse de que los métodos read* coincidan con los métodos write* utilizados previamente; de lo contrario, las lecturas posteriores se realizarán desde posiciones incorrectas en el búfer.

Parcel también proporciona la capacidad de escribir objetos personalizados; la forma preferida de hacerlo es implementando la interfaz Parcelable.

Aquí hay un ejemplo de implementación de la interfaz Parcelable (se eliminó código irrelevante; la clase WindowContainerTransaction se usa en el exploit como parte de la cadena de gadgets, sin embargo, no hay nada incorrecto en ella).```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 se puede ver arriba, el método `writeToParcel()` se utiliza durante la escritura. Luego, al leer, se llama al método de fábrica `CREATOR.createFromParcel()`. Es responsabilidad de la implementación de `Parcelable` asegurarse de que `createFromParcel` lea la misma cantidad de datos que fue escrita por `writeToParcel`; de lo contrario, todas las lecturas posteriores de ese `Parcel` leerán datos desde un offset incorrecto.

Dicha clase se puede escribir/leer desde/hacia `Parcel` mediante:

* Llamando directamente a `obj.writeToParcel(parcel, 0)` / `obj = WindowContainerTransaction.CREATOR.createFromParcel()`, esto se usa a menudo cuando se conoce el tipo de la clase, por ejemplo cuando `Parcelable` tiene un campo con otro `Parcelable` o en código generado por AIDL cuando el método RPC definido tiene un `Parcelable` como argumento
* A travé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) primero escribe el nombre de la clase y luego llama al método `writeToParcel` de la interfaz `Parcelable`. [`readParcelable`](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/Parcel.java;l=3282;drc=58787794eb5c879f6e39ee58c0071b36e337f8e3) lee el nombre de clase escrito, encuentra la clase con ese nombre en el `ClassLoader` proporcionado o en `BOOTCLASSPATH` si se proporcionó null. Una vez que se encuentra la clase, se usa su campo estático `CREATOR` para obtener una instancia de [`Parcelable.Creator`](https://developer.android.com/reference/android/os/Parcelable.Creator), que es la fábrica utilizada para leer esa clase. Es importante notar que cuando se usa el método `readParcelable`, puede leer cualquier `Parcelable` disponible en el classpath, ya que el nombre del objeto a crear se lee del mismo `Parcel`
* `readParcelable` es utilizado por muchos otros métodos de `Parcel`, por ejemplo `readList` visto en el ejemplo anterior lee elementos a través de `readValue`, que es el método más genérico para transferir objetos en `Parcel` y una de las formas que usa es a través de `readParcelable`. Además, en el ejemplo anterior, debido al Type Erasure de Java, el campo `ArrayList<HierarchyOp> mHierarchyOps` puede contener en realidad cualquier objeto soportado por Parcel, no solo aquellos compatibles con el tipo especificado en la declaración del tipo genérico

# Desajustes de `writeToParcel`/`createFromParcel`

Como se señaló anteriormente, es responsabilidad de la implementación de la interfaz `Parcelable` asegurarse de que `createFromParcel` lea la misma cantidad de datos del `Parcel` que el `writeToParcel` correspondiente escribió previamente. Siempre que haya en `BOOTCLASSPATH` un `Parcelable` que pueda violar ese contrato, se crea una vulnerabilidad, ya que permite el siguiente escenario:

1. Una aplicación maliciosa envía a `system_server` un `Bundle` O un `Parcelable` que contiene una instancia `Parcelable` defectuosa junto con datos específicamente construidos que se leerán realmente en el paso 3 pero se pasarán textualmente durante el paso 2
2. `system_server` verifica que el `Bundle` es seguro y luego lo reenvía O `system_server` pasa el `Parcelable` proporcionado a un método AIDL que también tiene datos críticos pasados en el siguiente parámetro (si los datos recibidos en ese parámetro pudieran modificarse, eso causaría un problema de seguridad)
3. Otra aplicación recibe datos de `system_server` y confía en ellos; sin embargo, debido a la serialización defectuosa, los datos que realmente ve difieren de los datos que `system_server` pretendía enviar
Descargar herramienta