Android Security AutoRepro

Das AutoRepro-Gradle-Plug-in basiert auf dem Android Trade Federation-Test-Harness, um alle Android-Geräte auf Sicherheitspatch-Tests gegen Sicherheitslücken im Android-Sicherheitsbulletin zu testen. Diese Tests sind ausschließlich für Korrekturen vorgesehen, die mit einer CVE (Common Vulnerabilities and Exposures) verknüpft sind oder verknüpft werden.

Mit dem Plug-in können Tradefed-Tests außerhalb des Android-Quellbaums mit Android Studio oder dem Standard-Android-SDK entwickelt werden. Sie enthält alle Dienstprogramme, die zum Erstellen und Ausführen eines Tradefed-Tests erforderlich sind.

Es wird hauptsächlich verwendet, um automatisch reproduzierbare Proof-of-Concepts für das Vulnerability Reward Program für Android einzureichen.

Beispiel für die automatische Reproduktion beim direkten Download 

AutoRepro-Beispiele und -Vorlagen ansehen 

Voraussetzungen

Die Anleitung bezieht sich auf einen 64-Bit-Linux-PC.

  • Android Studio Ladybug oder höher – kann auch über den Paketmanager Ihrer Distribution installiert werden.
  • Android SDK-Plattformtools (adb, fastboot): Müssen installiert sein und sich in Ihrem $PATH befinden. Das bedeutet, dass Sie adb über die Befehlszeile ausführen können. Am einfachsten installieren Sie die Plattformtools mit dem Paketmanager Ihrer Distribution.
    • Wenn Sie den SDK Manager von Android Studio anstelle von eigenständigen Plattformtools verwenden, müssen Sie das platform-tools-Verzeichnis des SDK in Ihren $PATH für die Befehlszeilenentwicklung einfügen.
  • AAPT2 – Kann auch mit dem Paketmanager Ihrer Distribution installiert werden.
  • Java JDK 21 oder höher – kompatibel mit dem Android SDK und Gradle.

Erste Schritte mit Android Studio

Nachdem Sie das Beispiel oder die Vorlage extrahiert haben, öffnen Sie das Verzeichnis in Android Studio als vorhandenes Projekt und warten Sie, bis die Gradle-Synchronisierung abgeschlossen ist. Es gibt mehrere vorkonfigurierte Android Studio-Ausführungskonfigurationen.

Gradle-Aufgaben:

  • assembleSubmissionSources – Quelldateien für die ZIP-Datei der Einreichung zusammenstellen
  • assembleSubmissionZip: Die ZIP-Datei für die Einreichung wird für den Upload zusammengestellt.
  • copyInvocationResultsToSubmission – Kopieren Sie die Ergebnisse aus vorherigen Tradefed-Aufrufen in das Quellverzeichnis der AutoRepro-Einreichung, um den Überprüfungsprozess zu unterstützen. Diese Datei enthält Protokolle vom Host und vom Gerät. Sehen Sie sich die Inhalte vor oder nach dem Ausführen des Befehls an.

AutoRepro-Aufruf in Android Studio-Ausführungskonfigurationen:

  • autorepro_nonroot_arm64
  • autorepro_nonroot_x86_64
  • autorepro_root_arm64
  • autorepro_root_x86_64

Die Launcher-Konfigurationen haben das Format autorepro_{device_root}_{device_arch}. Im Allgemeinen ist es besser, „nonroot“ zu verwenden, da Sicherheitslücken, die Root-Zugriff erfordern, weniger schwerwiegend sind. Die Verwendung von Root zum Einrichten oder Bereinigen kann jedoch akzeptabel sein, sofern sie klar dokumentiert ist und allgemein als gültiger Nicht-Root-Status akzeptiert wird. Es ist beispielsweise zulässig, das Rooting zu verwenden, um das Senden von SMS an das Gerät zu simulieren, damit kein zweites Gerät und mehrere SIM-Karten erforderlich sind.

Dadurch wird Tradefed für Ihren Test gestartet. Tradefed wartet auf ein gültiges Gerät, das verbunden wird. Achten Sie also darauf, dass ein Gerät verbunden und das ADB-Debugging autorisiert ist.

Einbindung in Coding-Agents

Das Beispiel und die Vorlagen enthalten eine AGENTS.md-Kontextdatei, die mit Gemini in Android Studio, der Gemini CLI und anderen Coding-Agents kompatibel ist. Es enthält Inhalte mit Meinungen zur Strukturierung von Einsendungen und Anleitungen zur Verwendung von AutoRepro. Sie können damit:

  • AutoRepro automatisch auf Ihrem Gerät ausführen
  • Vorhandene Einsendung auf Änderungen überprüfen, die dazu beitragen können, dass Ihr Bericht schneller akzeptiert wird
  • Hilfe bei der Strukturierung eines neuen PoC anhand von Informationen zur Sicherheitslücke

AutoRepro-Test schreiben

Ein AutoRepro-Test besteht aus drei Teilen und es gibt drei entsprechende Gradle-Plug-ins:

  1. Gradle-Plug-in id("com.android.security.autorepro.javahosttest") Der einzelne hostseitige Tradefed-Test, der über ADB mit dem Gerät interagiert. Im Beispiel wird sie im Verzeichnis submission/hostTest/ verwendet.
  2. Gradle-Plug-in id("com.android.security.autorepro.apptest"): Ein App- oder Dienst-APK, das über adb install auf dem Gerät installiert und vom Host-seitigen Test gestartet wird. Die App oder der Dienst kann auch eigene JUnit-Assertions enthalten, die an den Host-seitigen Runner gemeldet werden. Im Beispiel wird es im Verzeichnis submission/appTest/ verwendet.
  3. Gradle-Plug-in id("com.android.security.autorepro.ndktest") Ein optionaler NDK-basierter Proof-of-Concept-Angriff, der über adb push auf das Gerät übertragen und vom hostseitigen Test ausgeführt wird. Im Beispiel wird es im Verzeichnis submission/ndkTest/ verwendet.

Ein typischer AutoRepro-Testablauf folgt in der Regel einem von zwei Mustern:

  • Instrumentierte Test-App:

    1. Beim Host-seitigen Test wird ein APK, das aus einer instrumentierten App oder einem instrumentierten Dienst besteht, auf das Gerät übertragen.
    2. Der Hostseitentest startet die geräteseitigen JUnit-Tests, die über runDeviceTest() mit dem APK gebündelt werden.
    3. Die JUnit-Tests auf dem Gerät tippen auf Schaltflächen und beobachten die App mit UIAutomator oder greifen auf andere Weise auf die Android-APIs zu, die Sicherheitslücken aufdecken.
    4. Der Erfolg oder Misserfolg der JUnit-Tests auf dem Gerät wird an den Host-seitigen Test zurückgegeben, mit dem ermittelt werden kann, ob der Test bestanden wurde oder nicht. Die Fehlermeldung sollte detaillierte Informationen dazu enthalten, warum die Assertion fehlgeschlagen ist, sowie alle spezifischen Objekte, Werte, Ausnahmen, Stacktraces oder andere Artefakte als Beweis für die Sicherheitslücke.
  • NDK-Proof of Concept:

    1. Beim Hostseitentest wird eine ausführbare Linux-Datei auf das Gerät übertragen und gestartet.
    2. Das native Programm stürzt ab oder gibt einen bestimmten Exit-Code zurück.
    3. Der hostseitige Test prüft auf Abstürze, sieht sich den Logcat-Backtrace an oder sucht nach dem spezifischen Exit-Code, um festzustellen, ob der Angriff erfolgreich war. Die Fehlermeldung sollte detaillierte Informationen dazu enthalten, warum die Assertion fehlgeschlagen ist, sowie alle spezifischen Strukturen, Werte, Stacktraces oder anderen Artefakte als Beweis für die Sicherheitslücke.

Eine Kombination der beiden Muster (z. B. die Ausführung eines nativen Programms in Verbindung mit geräteseitigen Tests) ist ebenfalls möglich. Es sind auch andere Instrumentierungs-Frameworks wie frida-inject verfügbar. Weitere Informationen finden Sie in der Referenzdokumentation zur Security Test Suite und in der Tradefed-Referenzdokumentation.

Strukturierung der Nachweisbarkeit von Proofs of Concept

Ein hochwertiger PoC muss mehr als nur einen Fehler auslösen. Er sollte einen überprüfbaren Beweis dafür liefern, dass eine Sicherheitsgrenze überschritten wurde. Dazu können PoCs einem bestimmten dreistufigen Muster folgen:

  1. Einrichtung:Bereiten Sie das Gerät vor, indem Sie die erforderlichen Apps installieren, Dateien übertragen und dafür sorgen, dass sich das Gerät unmittelbar vor dem Exploit im erforderlichen Zustand befindet. Die Verwendung von Root ist für die Konfiguration zulässig, wenn sie gerechtfertigt ist und einen realistischen Endnutzerstatus darstellt.
  2. Grenze nachweisen:Bevor Sie die Sicherheitslücke auslösen, versuchen Sie, die Zielaktion auszuführen, und bestätigen Sie, dass sie fehlschlägt. Wenn der Exploit beispielsweise das Lesen einer geschützten Datei ermöglicht, müssen Sie zuerst versuchen, sie zu lesen, und bestätigen, dass Sie die Fehlermeldung „Zugriff verweigert“ erhalten.
  3. Auslösen und bestätigen:Lösen Sie die Sicherheitslücke aus und wiederholen Sie dann sofort die Aktion aus Schritt 2. Auf einem anfälligen Gerät sollte diese Aktion jetzt erfolgreich sein. Um dies zu überprüfen, müssen Sie eine Assertion verwenden, die auf einem anfälligen Gerät fehlschlägt und deren Meldung mit dem genauen Präfix AUTOREPRO_VULNERABILITY_PROVEN: beginnt. Diese Nachricht muss eine kurze Beschreibung der Sicherheitslücke und aller erfassten Artefakte (z. B. geleakte Daten oder unerwartete Zustände) enthalten, um den erfolgreichen Exploit eindeutig nachzuweisen.

Beispiel:

@Test
public void testPoc() throws Exception {
    // 1. Setup: Prepare the device.
    setup();

    // 2. Prove the Boundary: Assert the resource is protected BEFORE the exploit.
    // This passes on all devices (safe or vulnerable) before the trigger runs.
    assertDeviceIsSecure();

    // 3. Trigger & Verify: Execute the exploit logic, then immediately repeat
    // the action from Step 2. On a vulnerable device, this action should now
    // succeed, causing assertDeviceIsSecure() to fail with an
    // AUTOREPRO_VULNERABILITY_PROVEN message.
    triggerExploit();
    assertDeviceIsSecure();
}

private void assertDeviceIsSecure() {
    try {
        String content = readProtectedFile();

        // Where possible, put the content in the assertion message.
        // Start the assertion message with "AUTOREPRO_VULNERABILITY_PROVEN:".
        Assert.fail("AUTOREPRO_VULNERABILITY_PROVEN: Successfully read protected file. Content: '" + content + "'");
    } catch (ThisVulnSpecificException e) {
        Log.i(TAG, "protected against reading protected file", e);
    }
}

Für meinen Proof-of-Concept-Angriff ist keine Test-App oder native ausführbare Datei erforderlich.

Für die meisten Tests sind weder eine geräteseitige App noch eine native ausführbare Datei erforderlich.

Wenn in Ihrem Test keine Funktion verwendet wird, löschen Sie die unnötigen Gradle-Unterprojektverzeichnisse.

Mein Proof-of-Concept-Angriff umfasst eine zweite App oder einen zweiten Dienst

Sie können beliebig viele Gradle-Unterprojekte mit AutoRepro-Plug-ins hinzufügen.

AutoRepro-Test einreichen

So fügen Sie Testergebnisse von Ihrem Gerät in den Antrag ein:

  • Optional können Sie die Gradle-Aufgabe clean ausführen, um alte Testläufe zu löschen.
  • Führen Sie die entsprechende AutoRepro-Laufzeitkonfiguration aus, um Tradefed für Ihren Test aufzurufen und Logs und Ergebnisse zu erfassen.
  • Führen Sie die Aufgabe copyInvocationResultsToSubmission aus, um die Logs und Ergebnisse in das Quellverzeichnis für die Einreichung zu kopieren.

Führen Sie assembleSubmissionZip aus, um die Datei submission/build/autorepro-submission.zip zu erstellen. Laden Sie diese Datei zusammen mit Ihrem Beitrag zum Vulnerability Reward Program für Android hoch. Achten Sie darauf, dass der Anhang dem Muster *autorepro-submission*.zip entspricht und mit dem ursprünglichen Bericht hochgeladen wird. Wenn Sie Einsendungen zu spät hochladen, können wir Ihren Bericht nicht richtig prüfen.