Android Security AutoRepro

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.

Download AutoRepro Example

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 run adb 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.
  • 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:

  1. 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 the submission/hostTest/ directory.
  2. Gradle plugin id("com.android.security.autorepro.apptest") An app or service APK that is installed onto the device through adb 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 the submission/appTest/ and directory.
  3. Gradle plugin id("com.android.security.autorepro.ndktest") An optional NDK-based proof-of-concept attack that is pushed onto the device through adb push and executed by the host-side test. The example uses it in the submission/ndkTest/ directory.

A typical AutoRepro test flow usually follows one of two patterns:

  • Instrumented test app:

    1. The host-side test pushes an APK consisting of an instrumented app or service onto the device.
    2. The host-side test starts the device-side JUnit tests that is bundled with the APK through runDeviceTest().
    3. 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.
    4. 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:

    1. The host-side test pushes and launches a Linux executable on the device.
    2. The native program crashes or returns a specific exit code.
    3. 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.