Android Security AutoRepro

Wtyczka Gradle AutoRepro jest oparta na platformie testowej Android Trade Federation i służy do testowania wszystkich urządzeń z Androidem pod kątem poprawek zabezpieczeń w odniesieniu do luk w zabezpieczeniach opisanych w Biuletynie bezpieczeństwa w Androidzie. Te testy dotyczą wyłącznie poprawek, które są lub będą powiązane z typem luki w zabezpieczeniach (CVE).

Wtyczka umożliwia tworzenie testów Tradefed poza drzewem źródłowym Androida za pomocą Android Studio lub standardowego pakietu Android SDK. Zawiera wszystkie narzędzia potrzebne do tworzenia i uruchamiania testu Tradefed.

Służy on głównie do przesyłania automatycznie odtwarzalnych dowodów koncepcji w ramach Programu nagród za wykrywanie luk w zabezpieczeniach Androida.

Przykład automatycznego odtwarzania pobranego bezpośrednio pliku

Przeglądanie przykładów i szablonów AutoRepro

Wymagania wstępne

Instrukcje dotyczą 64-bitowego komputera z systemem Linux.

  • Android Studio Ladybug lub nowsze – można też zainstalować za pomocą menedżera pakietów dystrybucji.
  • Narzędzia platformy Android SDK (adb, fastboot) – muszą być zainstalowane i znajdować się w $PATH (czyli powinna być możliwość uruchomienia adb z wiersza poleceń). Najprostszym sposobem zainstalowania narzędzi platformy jest użycie menedżera pakietów dystrybucji.
    • Jeśli zamiast samodzielnych narzędzi platformy używasz menedżera SDK w Android Studio, pamiętaj, aby dodać katalog platform-tools pakietu SDK do $PATH na potrzeby programowania w wierszu poleceń.
  • AAPT2 – Można ją też zainstalować za pomocą menedżera pakietów dystrybucji.
  • Java JDK 21 lub nowsza – zgodna z pakietem Android SDK i Gradle.

Pierwsze kroki z Androidem Studio

Po wyodrębnieniu przykładu lub szablonu otwórz katalog w Android Studio jako istniejący projekt i poczekaj na zakończenie synchronizacji Gradle. Istnieje kilka wstępnie skonfigurowanych konfiguracji uruchamiania Androida Studio.

Zadania Gradle:

  • assembleSubmissionSources – przygotuj pliki źródłowe do przesłania w formacie ZIP.
  • assembleSubmissionZip – przygotuj plik ZIP do przesłania.
  • copyInvocationResultsToSubmission – skopiuj wyniki z poprzednich wywołań Tradefed do katalogu źródeł przesyłania AutoRepro, aby ułatwić proces weryfikacji. Pamiętaj, że zawiera on logi zarówno z hosta, jak i z urządzenia. Sprawdź zawartość przed uruchomieniem lub po uruchomieniu tego polecenia.

Wywołanie AutoRepro w konfiguracjach uruchamiania Androida Studio:

  • autorepro_nonroot_arm64
  • autorepro_nonroot_x86_64
  • autorepro_root_arm64
  • autorepro_root_x86_64

Konfiguracje programu uruchamiającego mają postać autorepro_{device_root}_{device_arch}. Zwykle lepiej jest używać konta bez uprawnień roota, ponieważ luki w zabezpieczeniach wymagające uprawnień roota są mniej poważne. Używanie uprawnień roota do konfigurowania lub czyszczenia może być jednak dopuszczalne, o ile jest to wyraźnie udokumentowane i ogólnie akceptowane jako prawidłowy stan bez uprawnień roota. Na przykład dopuszczalne jest użycie roota do fałszywego wysyłania wiadomości tekstowych na urządzenie, aby uniknąć konieczności używania drugiego urządzenia i wielu kart SIM.

Spowoduje to uruchomienie Tradefed na potrzeby testu. Tradefed czeka na podłączenie prawidłowego urządzenia, więc upewnij się, że jest ono podłączone, a debugowanie ADB jest autoryzowane.

Integracja z agentami do kodowania

Przykład i szablony zawierają AGENTS.mdplik kontekstowy zgodny z Gemini w Android Studio, interfejsem wiersza poleceń Gemini i innymi agentami do kodowania. Zawiera treści z opiniami na temat struktury zgłoszeń i instrukcje korzystania z narzędzia AutoRepro. Możesz go użyć do:

  • Automatyczne uruchamianie AutoRepro na urządzeniu
  • Sprawdź istniejące zgłoszenie pod kątem zmian, które mogą przyspieszyć akceptację raportu.
  • Pomoc w opracowaniu nowego dowodu koncepcji na podstawie informacji o luke w zabezpieczeniach

Pisanie testu AutoRepro

Test AutoRepro składa się z 3 części i ma 3 odpowiednie wtyczki Gradle:

  1. Wtyczka Gradle id("com.android.security.autorepro.javahosttest") Pojedynczy test Tradefed po stronie hosta, który wchodzi w interakcję z urządzeniem za pomocą ADB. W przykładzie użyto go w katalogu submission/hostTest/.
  2. Wtyczka Gradle id("com.android.security.autorepro.apptest") Aplikacja lub plik APK usługi, który jest instalowany na urządzeniu za pomocą adb install i uruchamiany przez test po stronie hosta. Aplikacja lub usługa może też zawierać własny zestaw asercji JUnit, które są zgłaszane do narzędzia uruchamiającego po stronie hosta. W przykładzie użyto go w parametrze submission/appTest/ i katalogu.
  3. Wtyczka Gradle id("com.android.security.autorepro.ndktest") Opcjonalny atak oparty na NDK, który jest przesyłany na urządzenie za pomocą adb push i wykonywany przez test po stronie hosta. W tym przykładzie użyto go w katalogu submission/ndkTest/.

Typowy przepływ testu AutoRepro zwykle przebiega według jednego z 2 wzorców:

  • Aplikacja testowa z instrumentacją:

    1. Test po stronie hosta przesyła na urządzenie plik APK zawierający aplikację lub usługę z instrumentacją.
    2. Test po stronie hosta uruchamia testy JUnit po stronie urządzenia, które są dołączone do pliku APK za pomocą runDeviceTest().
    3. Testy JUnit po stronie urządzenia klikają przyciski i obserwują aplikację za pomocą UIAutomatora lub w inny sposób uzyskują dostęp do interfejsów API Androida, co ujawnia luki w zabezpieczeniach.
    4. Informacja o powodzeniu lub niepowodzeniu testów JUnit po stronie urządzenia jest zwracana do testu po stronie hosta, co pozwala określić, czy test został zaliczony. Komunikat o błędzie powinien zawierać szczegółowe informacje o tym, dlaczego testowanie się nie powiodło, oraz wszelkie konkretne obiekty, wartości, wyjątki, ślady stosu lub inne artefakty jako dowód podatności na zagrożenia.
  • Model koncepcyjny NDK:

    1. Test po stronie hosta przesyła i uruchamia na urządzeniu plik wykonywalny Linuksa.
    2. Program natywny ulegnie awarii lub zwróci określony kod zakończenia.
    3. Test po stronie hosta sprawdza awarie, analizuje ślad wsteczny logcat lub szuka określonego kodu zakończenia, aby ustalić, czy atak się powiódł. Komunikat o błędzie powinien zawierać szczegółowe informacje o tym, dlaczego test się nie powiódł, oraz konkretne struktury, wartości, ślady stosu lub inne artefakty jako dowód na istnienie luki w zabezpieczeniach.

Możliwe jest też połączenie tych 2 wzorców (np. uruchomienie programu natywnego w połączeniu z testami na urządzeniu). Dostępne są też inne platformy do instrumentacji, np. frida-inject. Szczegółowe informacje znajdziesz w dokumentacji referencyjnej pakietu testów bezpieczeństwadokumentacji referencyjnej Tradefed.

Strukturyzacja dowodów w modelu koncepcyjnym

Wysokiej jakości dowód koncepcji musi robić więcej niż tylko wywoływać błąd. Powinien dostarczać weryfikowalny dowód na to, że przekroczono granicę bezpieczeństwa. Aby to osiągnąć, PoC mogą postępować zgodnie z określonym 3-etapowym wzorcem „najpierw porażka, potem sukces”:

  1. Konfiguracja: przygotuj urządzenie, instalując niezbędne aplikacje, przesyłając pliki i upewniając się, że urządzenie jest w określonym stanie wymaganym bezpośrednio przed wykorzystaniem luki w zabezpieczeniach. (Użycie roota jest dozwolone w przypadku konfiguracji, jeśli jest uzasadnione i odzwierciedla realistyczny stan użytkownika).
  2. Udowodnij istnienie granicy: przed wywołaniem luki w zabezpieczeniach spróbuj wykonać działanie docelowe i potwierdź, że się nie powiodło. Jeśli na przykład luka w zabezpieczeniach umożliwia odczytanie chronionego pliku, musisz najpierw spróbować go odczytać i potwierdzić, że otrzymujesz błąd „Odmowa dostępu”.
  3. Wywołaj i sprawdź: wywołaj lukę w zabezpieczeniach, a następnie natychmiast powtórz czynność z kroku 2. Na urządzeniu podatnym na ataki ta czynność powinna się teraz udać. Aby to sprawdzić, musisz użyć asercji, która nie działa na podatnym na ataki urządzeniu, i wyświetlić komunikat zaczynający się od dokładnego prefiksu AUTOREPRO_VULNERABILITY_PROVEN:. Wiadomość musi zawierać zwięzły opis luki w zabezpieczeniach i wszystkie przechwycone artefakty (np. wyciek danych lub nieoczekiwane stany), aby jednoznacznie udowodnić, że wykorzystanie luki w zabezpieczeniach zakończyło się powodzeniem.

Przykład:

@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);
    }
}

Mój dowód koncepcji ataku nie wymaga aplikacji testowej ani natywnego pliku wykonywalnego

Większość testów nie będzie wymagać aplikacji po stronie urządzenia i natywnego pliku wykonywalnego.

Jeśli test nie obejmuje korzystania z funkcji, usuń niepotrzebne katalogi podprojektów Gradle.

Mój atak typu proof-of-concept obejmuje drugą aplikację lub usługę

Dodaj dowolną liczbę podprojektów Gradle z wtyczkami AutoRepro.

Przesyłanie testu AutoRepro

Aby dołączyć wyniki testu z urządzenia do zgłoszenia:

  • Opcjonalnie uruchom zadanie Gradle clean, aby usunąć stare przebiegi testów.
  • Uruchom odpowiednią konfigurację AutoRepro, aby wywołać Tradefed dla testu i zebrać logi oraz wyniki.
  • Uruchom zadanie copyInvocationResultsToSubmission, aby skopiować logi i wyniki do katalogu źródeł zgłoszeń.

Uruchom polecenie assembleSubmissionZip, aby utworzyć plik submission/build/autorepro-submission.zip. Prześlij ten plik wraz ze zgłoszeniem w ramach programu wykrywania luk w zabezpieczeniach Androida. Upewnij się, że załącznik pasuje do wzorca *autorepro-submission*.zip i że został przesłany wraz z raportem początkowym. Przesłanie zgłoszenia z opóźnieniem wpłynie na naszą możliwość prawidłowego sprawdzenia raportu.