Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
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.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
ReparcelBug2 — Writeup and exploit for installed app to system privilege escalation on Android 12 Beta through CVE-2021-0928, a `writeToParcel`/`createFromParcel` serialization mismatch in `OutputConfiguration` | Kitploit
Tools/GitHubGitHub/michalbednarski/reparcelbug2
Android SecurityPrivilege EscalationVulnerability AnalysisExploitationMobile SecurityBinary Analysis
GitHubmichalbednarski/reparcelbug2

ReparcelBug2

Writeup and exploit for installed app to system privilege escalation on Android 12 Beta through CVE-2021-0928, a `writeToParcel`/`createFromParcel` serialization mismatch in `OutputConfiguration`

View Repository
12524684 years agoReviewed by Kitploit

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-2021-0928, writeToParcel/createFromParcel serialization mismatch in android.hardware.camera2.params.OutputConfiguration

This is exploit using that vulnerability for privilege escalation from installed Android app into Android Settings app (or any other app installed app could send to <receiver> declared in AndroidManifest.xml, privilege escalation by sending to <activity> was possible too, although not presented here)

I've found issue originally on Android 12 Developer Preview 3

Exploit version present in this repo works on Android 12 Beta 2 and 3

Vulnerability was fixed in first official Android 12 release

Writeup below was originally written for Google for consideration of this report as complete exploit chain

At time of writing Android 12 was not available in AOSP (Android Developer Preview/Beta releases are not open source)

Screenshot of Android notification from Settings app: 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

Introduction to Parcel

Most of IPC on Android is done through class called Parcel

Basic usage of Parcel is as following:

Parcel p = Parcel.obtain();
p.writeInt(1);
p.writeString("Hello");

Then Parcel is sent to another process through Binder. Alternatively for testing one can call p.setDataPosition(0) to rewind parcel to beginning position and start reading:

int a = p.readInt(); // a = 1
String b = p.readString(); // b = "Hello"

It should be noted that parcel internally holds position from which reads are performed. It it responsibility of Parcel class user to ensure that read* methods match previously used write* methods, otherwise subsequent reads will be from wrong positions in buffer

Parcel also provides ability to write custom objects, preferred way to do so is by implementing Parcelable interface

Here is example implementation of Parcelable interface (irrelevant code removed, WindowContainerTransaction class is used in exploit as part of gadget chain, however there isn't anything wrong with it)

package android.window;
public final class WindowContainerTransaction implements Parcelable {
    private final ArrayMap<IBinder, Change> mChanges = new ArrayMap<>();
    private final ArrayList<HierarchyOp> 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);
                }
            };
}

As can be seen above, writeToParcel() method is used during writing. Then while reading CREATOR.createFromParcel() factory method is called. It is responsibility of Parcelable implementation to ensure that createFromParcel reads same amount of data as was written by writeToParcel, otherwise all subsequent reads from that Parcel will read data from wrong offset

Such class can be written to/read from Parcel through:

  • Directly calling obj.writeToParcel(parcel, 0) / obj = WindowContainerTransaction.CREATOR.createFromParcel(), this is often used when type of class is known, for example when Parcelable has field with different Parcelable or in code generated by AIDL when defined RPC method has Parcelable as argument
  • Through Parcel.writeParcelable/readParcelable. writeParcelable first writes name of class and then calls writeToParcel method from Parcelable interface. readParcelable reads written class name, finds class with that name in provided ClassLoader or BOOTCLASSPATH if null was provided. Once class is found it's static field CREATOR is used to obtain Parcelable.Creator instance which is factory used to read that class. It is important to note that when readParcelable method is used it can read any Parcelable available in class path as name of object to be created is read from same Parcel
  • readParcelable is used by many other Parcel methods, for example readList seen in example above reads elements through readValue, which is most generic method of transferring objects in Parcel and one of ways it uses is through readParcelable. Also in above example due to Java's Type Erasure ArrayList<HierarchyOp> mHierarchyOps field can actually contain any objects supported by Parcel, not only those compatible with type specified in generic type declaration

writeToParcel/createFromParcel mismatches

As noted above it is responsibility of Parcelable interface implementation to ensure that createFromParcel reads same amount of data from Parcel as matching writeToParcel has previously written. Whenever there is in BOOTCLASSPATH a Parcelable which can violate that contract it creates a vulnerability as it allows for following scenario:

  1. An evil application sends to system_server a Bundle OR Parcelable containing faulty Parcelable instance along with specifically constructed data that will be actually read in step 3 but passed verbatim during step 2
  2. system_server verifies Bundle is safe and then forwards it OR system_server passes provided Parcelable to AIDL method that also has critical data passed in next parameter (if data received in that parameter could be modified that would cause security issue)
  3. Another app receives data from system_server and trusts it, however due to faulty serialization data that it actually sees differs from data system_server intended to send

I've used "OR" in above steps as these steps describe both an old exploit variant which leads to starting arbitrary Activity which I've published in 2017 (on the left side of "OR") and a new variant which I'll describe here in next section

How BroadcastReceiver is executed in app

Download Tool