AutoRepro da Segurança do Android

O plug-in AutoRepro do Gradle é criado com base no arcabouço de testes da Android Trade Federation para testar todos os dispositivos Android em busca de testes de patch de segurança contra vulnerabilidades no Boletim de segurança do Android. Esses testes são exclusivamente para correções associadas ou que serão associadas a uma Vulnerabilidade e Exposição Comum (CVE).

O plug-in permite o desenvolvimento de testes do Tradefed fora da árvore de origem do Android usando o Android Studio ou o SDK padrão do Android. Ele inclui todas as utilidades necessárias para criar e executar um teste do Tradefed.

Ele é usado principalmente para enviar provas de conceito automaticamente reproduzíveis para o Programa de recompensas por vulnerabilidades do Android.

Exemplo de AutoRepro de download direto

Navegar por exemplos e modelos do AutoRepro

Pré-requisitos

As instruções são fornecidas para um PC Linux de 64 bits.

  • Android Studio Ladybug ou mais recente: também pode ser instalado pelo gerenciador de pacotes da sua distribuição.
  • Ferramentas da plataforma do SDK do Android (adb, fastboot): precisam ser instaladas e estar no seu $PATH. Ou seja, você precisa conseguir executar adb na linha de comando. A maneira mais fácil de instalar as ferramentas da plataforma é usando o gerenciador de pacotes da sua distribuição.
    • Se você estiver usando o SDK Manager do Android Studio em vez de ferramentas autônomas da plataforma, adicione o diretório platform-tools do SDK ao seu $PATH para desenvolvimento de linha de comando.
  • AAPT2. - Também pode ser instalado usando o gerenciador de pacotes da sua distribuição.
  • Java JDK 21 ou mais recente: compatível com o SDK do Android e o Gradle.

Começar a usar o Android Studio

Depois de extrair o exemplo ou modelo, abra o diretório no Android Studio como um projeto atual e aguarde a conclusão da sincronização do Gradle. Há várias configurações de execução predefinidas do Android Studio.

Tarefas do Gradle:

  • assembleSubmissionSources: monte os arquivos de origem para o envio zip.
  • assembleSubmissionZip: monte o ZIP de envio para upload.
  • copyInvocationResultsToSubmission: copie os resultados de invocações anteriores do Tradefed no diretório de fontes de envio do AutoRepro para ajudar no processo de revisão. Isso contém registros do host e do dispositivo. Revise o conteúdo antes ou depois de executar o comando.

Invocações do AutoRepro em configurações de execução do Android Studio:

  • autorepro_nonroot_arm64
  • autorepro_nonroot_x86_64
  • autorepro_root_arm64
  • autorepro_root_x86_64

As configurações do iniciador estão no formato autorepro_{device_root}_{device_arch}. Em geral, é preferível usar não root porque as vulnerabilidades que exigem root são menos graves. No entanto, usar root para realizar configuração ou limpeza pode ser aceitável, desde que esteja claramente documentado e seja geralmente aceito como um estado não root válido. Por exemplo, é aceitável usar o root para simular o envio de mensagens de texto ao dispositivo e evitar a necessidade de um segundo dispositivo e vários chips.

Isso vai iniciar o Tradefed para seu teste. O Tradefed aguarda um dispositivo válido ser conectado. Portanto, verifique se um dispositivo está conectado e se a depuração do ADB está autorizada.

Integração com agentes de programação

O exemplo e os modelos fornecem um arquivo de contexto AGENTS.md compatível com o Gemini no Android Studio, a CLI do Gemini e outros agentes de programação. Ele tem conteúdo com opiniões sobre a estruturação de envios e instruções sobre como usar o AutoRepro. Você pode usar isso para:

  • Executar o AutoRepro automaticamente no seu dispositivo
  • Faça uma revisão de código de um envio atual para encontrar mudanças que possam ajudar seu relatório a ser aceito mais rápido.
  • Ajudar a estruturar uma nova prova de conceito com base nas informações sobre a vulnerabilidade

Criar um teste do AutoRepro

Um teste do AutoRepro tem três partes e três plug-ins correspondentes do Gradle:

  1. Plug-in do Gradle id("com.android.security.autorepro.javahosttest") O único teste do Tradefed do lado do host que interage com o dispositivo usando o ADB. O exemplo usa esse diretório em submission/hostTest/.
  2. Plug-in do Gradle id("com.android.security.autorepro.apptest"): um app ou APK de serviço instalado no dispositivo usando adb install e iniciado pelo teste do lado do host. O app ou serviço também pode conter um conjunto próprio de asserções JUnit que são informadas ao executor do lado do host. O exemplo usa isso no diretório submission/appTest/.
  3. Plug-in do Gradle id("com.android.security.autorepro.ndktest"): um ataque opcional de prova de conceito baseado no NDK que é enviado ao dispositivo por adb push e executado pelo teste do lado do host. O exemplo usa esse diretório em submission/ndkTest/.

Um fluxo de teste AutoRepro típico geralmente segue um destes dois padrões:

  • App de teste instrumentado:

    1. O teste do lado do host envia um APK que consiste em um app ou serviço instrumentado para o dispositivo.
    2. O teste do lado do host inicia os testes JUnit do lado do dispositivo agrupados com o APK usando runDeviceTest().
    3. Os testes JUnit do lado do dispositivo tocam em botões e assistem o app usando UIAutomator ou acessam as APIs Android de maneiras que revelam vulnerabilidades de segurança.
    4. O sucesso ou a falha dos testes JUnit do lado do dispositivo é retornado ao teste do lado do host, que pode ser usado para determinar se o teste foi aprovado ou não. A mensagem de falha precisa conter informações detalhadas sobre o motivo da falha da asserção e objetos, valores, exceções, rastreamentos de pilha ou outros artefatos específicos como prova de vulnerabilidade.
  • Prova de conceito do NDK:

    1. O teste do lado do host envia e inicia um executável do Linux no dispositivo.
    2. O programa nativo falha ou retorna um código de saída específico.
    3. O teste do lado do host verifica falhas, analisa o rastreamento de pilha do logcat ou procura o código de saída específico para determinar se o ataque foi bem-sucedido. A mensagem de falha deve conter informações detalhadas sobre o motivo da falha na declaração e quaisquer structs, valores, stacktraces ou outros artefatos específicos como prova de vulnerabilidade.

Também é possível combinar os dois padrões (por exemplo, executar um programa nativo em conjunto com testes do lado do dispositivo). Outros frameworks de instrumentação, como frida-inject, também estão disponíveis. Para mais detalhes, consulte os documentos de referência do conjunto de testes de segurança e os documentos de referência do Tradefed.

Estruturação de probabilidade de prova de conceito

Uma PoC de alta qualidade precisa fazer mais do que acionar um bug. Ela precisa fornecer uma prova verificável de que um limite de segurança foi ultrapassado. Para isso, as PoCs podem seguir um padrão específico de três etapas "falhar e depois ter sucesso":

  1. Configuração:prepare o dispositivo instalando os apps necessários, enviando arquivos e garantindo que ele esteja no estado específico exigido imediatamente antes do exploit. O uso de root é permitido para configuração se justificado e representativo de um estado realista do usuário final.
  2. Prove the Boundary:antes de acionar a vulnerabilidade, tente a ação de destino e afirme que ela falha. Por exemplo, se o exploit permitir a leitura de um arquivo protegido, primeiro tente ler e confirme se você recebe um erro "Permissão negada".
  3. Acionar e verificar:acione a vulnerabilidade e repita imediatamente a ação da etapa 2. Em um dispositivo vulnerável, essa ação vai funcionar. Para verificar isso, use uma asserção que falhe em um dispositivo vulnerável com uma mensagem que comece com o prefixo exato AUTOREPRO_VULNERABILITY_PROVEN:. Essa mensagem precisa incluir uma descrição concisa da vulnerabilidade e de todos os artefatos capturados (como dados vazados ou estados inesperados) para provar definitivamente que o exploit foi bem-sucedido.

Exemplo:

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

Meu ataque de prova de conceito não precisa de um app de teste ou executável nativo

A maioria dos testes não precisa de um app do lado do dispositivo e um executável nativo.

Se o teste não envolver o uso de um recurso, exclua os diretórios de subprojeto do Gradle desnecessários.

Meu ataque de prova de conceito envolve um segundo app ou serviço

Adicione quantos subprojetos do Gradle com plug-ins do AutoRepro quiser.

Enviar o teste AutoRepro

Para incluir os resultados do teste do seu dispositivo como parte do envio:

  • Opcionalmente, execute a tarefa clean do Gradle para excluir execuções de teste antigas.
  • Execute a configuração de execução do AutoRepro apropriada para invocar o Tradefed no seu teste e colete registros e resultados.
  • Execute a tarefa copyInvocationResultsToSubmission para copiar os registros e resultados no diretório de fontes de envio.

Execute assembleSubmissionZip para criar o arquivo submission/build/autorepro-submission.zip. Faça upload desse arquivo junto com sua inscrição no Programa de recompensa para descobertas de vulnerabilidades do Android. Verifique se o anexo corresponde ao padrão *autorepro-submission*.zip e se ele foi enviado com o relatório inicial. O envio tardio de denúncias afeta nossa capacidade de analisar seu relatório corretamente.