[![oosmetrics](https://api.oosmetrics.com/api/v1/badge/achievement/775d2dc4-b8fd-4ab4-9621-733b03fea04f.svg)](https://oosmetrics.com/repo/atlas4381/qualcomm_avb_exploit_poc) # qualcomm_avb_exploit_poc PoC for a Qualcomm ABL bootloader unlock via Keymaster TA unauthenticated `READ/WRITE_KM_DEVICE_STATE`. Tested on Redmi 14R (flame, Snapdragon 4 Gen 2). Expected to affect other Qualcomm devices with vulnerable ABL builds. > [!CAUTION] > **Disclaimer**: This PoC is for **educational and technical research purposes only**. Modifying the RPMB device state or partition table carries a high risk of **permanently bricking** your device. **The author** shall not be held responsible for any damage, data loss, or legal consequences resulting from the use of this PoC. **Proceed at your own risk**. ## Background `Is_VERIFIED_BOOT_2()` in `QcommModulePkg/Library/avb/VerifiedBoot.c` determined the verified boot path at **runtime** by checking whether a `vbmeta_a` or `vbmeta` partition exists in the GPT. If neither partition is found, the function returns `FALSE`, and the bootloader takes the `NO_AVB` path. The `NO_AVB` path does not call `KEYMASTER_MILESTONE_CALL`. Once the milestone is set (in the normal AVB2 path), the Keymaster TA refuses to execute `READ_KM_DEVICE_STATE` and `WRITE_KM_DEVICE_STATE`. Without the milestone, these commands execute without restriction. ## Vulnerability By renaming the `vbmeta` partition to any other name (e.g. `xbmeta`), `Is_VERIFIED_BOOT_2()` finds no vbmeta partition and returns `FALSE`. This forces the `NO_AVB` path, the milestone is never set, and the Keymaster TA does not block device state operations. An attacker can then load the Keymaster TA, read the `DeviceInfo` structure from RPMB, set `is_unlocked` and `is_unlock_critical` to `1`, and write it back — effectively unlocking the bootloader without going through `fastboot oem unlock`. ``` vbmeta renamed → Is_VERIFIED_BOOT_2() returns FALSE → NO_AVB → KEYMASTER_MILESTONE_CALL skipped → Keymaster TA READ/WRITE_KM_DEVICE_STATE not blocked → DeviceInfo in RPMB writable → bootloader unlocked ``` ## Fix [edk2: Set VB2 status at compile time](https://git.codelinaro.org/clo/la/abl/tianocore/edk2/-/commit/1b2e5f9c4e95db4c74570b828d047e45f9f426d1) `Is_VERIFIED_BOOT_2()` now returns a compile-time constant based on the `VERIFIED_BOOT_ENABLED` macro, making the result immune to GPT partition table modifications. ## Prerequisites 1. Write access to partition table and partitions (e.g. via EDL or existing exploit) 2. Rename `vbmeta` partition to anything else (e.g. `xbmeta`) via `sgdisk` or similar 3. Flash and Boot to TWRP 4. Start `qseecomd` daemon ## Usage ```sh # Read current DeviceInfo state ./poc # Write unlock flags (triggers confirmation prompt) ./poc -w ``` After successful write, reboot to fastboot and run: ```sh fastboot -w ``` ## Build ```sh $NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android28-clang -fPIE -pie poc.c -ldl -o poc ``` ## Notes - `TA_IMG_LEN` is hardcoded to the keymaster partition size (512 KB). Adjust if your device differs. - This PoC uses `_Static_assert` to ensure the structure size is `0xCA8`. However, even if the size matches, field offsets can vary between SoC models or Android versions.