The AutoRepro Gradle plugin is built on top of the Android Trade Federation test harness to test all Android devices for security patch tests against vulnerabilities in the Android Security Bulletin. These tests are exclusively for fixes that are associated or will be associated with a Common Vulnerabilities and Exposures (CVE).
The plugin allows development of Tradefed tests outside of the Android source tree using Android Studio or the standard Android SDK. It includes all utilities that are needed to build and run a Tradefed test.
It is primarily used to submit automatically reproducible proof-of-concepts for the Android Vulnerability Rewards Program.
Prerequisites
Instructions are provided for a 64-bit Linux PC.
- Android Studio Ladybug or newer - Can also be installed from your distro's package manager.
- Android SDK platform tools
(
adb
,fastboot
) - Need to be installed and be in your$PATH
(That is, you should be able to runadb
from the command line). The easiest way to install the platform tools is using your distro's package manager.- If using Android Studio's SDK manager instead of standalone platform
tools, remember to add the SDK's
platform-tools
directory to your$PATH
for command-line development.
- If using Android Studio's SDK manager instead of standalone platform
tools, remember to add the SDK's
- AAPT2. - Can also be installed using your distro's package manager.
- Java JDK 21 or newer - compatible with the Android SDK and Gradle.
Get started using Android Studio
After extracting the example or template, open the directory in Android Studio as an existing project and wait for Gradle sync to complete. There are several preconfigured Android Studio run configurations.
Gradle tasks:
assembleSubmissionSources
- Assemble the source files for the submission zip.assembleSubmissionZip
- Assemble the submission zip for upload.copyInvocationResultsToSubmission
- Copy the results from previous Tradefed invocations into the AutoRepro submission sources directory to assist with the review process. Note that this contains logs from both the host and device; review the contents before or after running this.
AutoRepro invocation Android Studio run configurations:
autorepro_nonroot_arm64
autorepro_nonroot_x86_64
autorepro_root_arm64
autorepro_root_x86_64
The launcher configurations are in the form
autorepro_{device_root}_{device_arch}
. It's generally preferable to use
nonroot because vulnerabilities requiring root are less severe. However, using
root to perform setup or cleanup can be acceptable so long as it is clearly
documented and is generally accepted as a valid nonroot state. For example, it's
acceptable to use root to fake send text messages to the device to avoid
requiring a second device and multiple SIM cards.
These will launch Tradefed for your test. Tradefed waits for a valid device to be connected so ensure one is connected and ADB debugging authorized.
Write an AutoRepro test
There are three parts to an AutoRepro test and three corresponding Gradle plugins:
- Gradle plugin
id("com.android.security.autorepro.javahosttest")
The single host-side Tradefed test that interacts with the device through ADB. The example uses it in thesubmission/hostTest/
directory. - Gradle plugin
id("com.android.security.autorepro.apptest")
An app or service APK that is installed onto the device throughadb install
and launched by the host-side test. The app or service can also contain its own set of JUnit assertions that is reported to the host-side runner. The example uses it in thesubmission/appTest/
and directory. - Gradle plugin
id("com.android.security.autorepro.ndktest")
An optional NDK-based proof-of-concept attack that is pushed onto the device throughadb push
and executed by the host-side test. The example uses it in thesubmission/ndkTest/
directory.
A typical AutoRepro test flow usually follows one of two patterns:
Instrumented test app:
- The host-side test pushes an APK consisting of an instrumented app or service onto the device.
- The host-side test starts the device-side JUnit tests that is bundled
with the APK through
runDeviceTest()
. - The device-side JUnit tests taps buttons and watches the app using UIAutomator, or otherwise accesses the Android APIs in ways that reveal security vulnerabilities.
- The success or failure of the device-side JUnit tests is returned to the host-side test, which can be used to determine if the test passed or not. The failure message should contain detailed information on why the assertion failed and any specific objects, values, exceptions, stacktraces, or other artifacts as proof of vulnerability.
NDK proof-of-concept:
- The host-side test pushes and launches a Linux executable on the device.
- The native program crashes or returns a specific exit code.
- The host-side test checks for crashes, looks at the logcat backtrace, or looks for the specific exit code to determine whether the attack succeeded. The failure message should contain detailed information on why the assertion failed and any specific structs, values, stacktraces, or other artifacts as proof of vulnerability.
A combination of the two patterns (for example, running of a native program in
conjunction with device-side tests) is also possible. Some other instrumentation
frameworks, such as frida-inject
, are also available. For details, see the
Security Test Suite reference docs and the
Tradefed reference docs.
My proof-of-concept attack doesn't need a test app or native executable
Most tests will not need both a device-side app and a native executable.
If your test does not involve the use a feature, delete the unnecessary gradle subproject directories.
My proof-of-concept attack involves a second app/service
Add as many Gradle subprojects with AutoRepro plugins as you like.
Submit the AutoRepro test
To include test results from your device as part of the submission:
- Optionally run the Gradle
clean
task to delete any old test runs. - Run the appropriate AutoRepro run configuration to invoke Tradefed for your test and collect logs and results.
- Run the
copyInvocationResultsToSubmission
task to copy the logs and results into the submission sources directory.
Run the assembleSubmissionZip
to create the
submission/build/autorepro-submission.zip
file. Upload that file along with
your submission to the Android Vulnerability Reward Program. Ensure that the
attachment matches the pattern *autorepro-submission*.zip
and that it is
uploaded with the initial report. Uploading submissions late will impact our
ability to properly review your report.