Fazemos tudo para manter a plataforma Android segura para todos os usuários em todos os dispositivos. As atualizações de segurança são lançadas todos os meses com correções para vulnerabilidades encontradas por membros do Vulnerability Rewards Program (VRP) . No entanto, também tentamos proteger a plataforma de outras vulnerabilidades potenciais, por exemplo, usando um compilador e melhorando o ambiente de teste. O ecossistema Android inclui dispositivos com uma ampla variedade de recursos, portanto, todas as decisões devem ser equilibradas e devem levar em conta os dados disponíveis.
Este artigo explica como selecionamos os controles de segurança para circunstâncias específicas e como eles são implementados.
Manter o Android seguro tem uma abordagem holística. Para dificultar a exploração de vulnerabilidades em potencial, tomamos decisões baseadas em dados usando vários princípios e técnicas. Quando se trata de fortalecer a plataforma, as seguintes questões precisam ser respondidas:
- Que dados temos e como eles podem nos ajudar a tomar decisões?
- Quais ferramentas de prevenção de ataques estão disponíveis? Como eles podem ser melhorados? Em que situações eles devem ser aplicados?
- Que problemas podem surgir ao usar certas ferramentas de segurança? Que layouts possíveis devem ser levados em consideração?
Os princípios que usamos em nossas escolhas de segurança refletem nossa abordagem geral para proteger os usuários da plataforma Android.
Tome decisões de segurança baseadas em dados
Para descobrir para quais componentes da plataforma certas soluções serão eficazes, recorremos a várias fontes. O Android Vulnerability Rewards Program (VRP) é talvez o mais informativo de todos eles. Nossos engenheiros de segurança analisam todas as vulnerabilidades descobertas pelos participantes do programa, determinando sua causa raiz e nível de gravidade (com base nessas recomendações ). Além disso, existem relatórios de bugs internos e externos. Eles ajudam a identificar componentes vulneráveis, bem como trechos de código que costumam causar falhas. Conhecendo a aparência desses fragmentos e entendendo a gravidade e a frequência dos erros que resultam deles, podemos tomar decisões informadas sobre quais medidas de segurança serão mais eficazes.
Vulnerabilidades de gravidade alta e crítica corrigidas nos boletins de segurança do Android 2019.
No entanto, não dependa apenas dos relatórios de vulnerabilidade. Eles inicialmente fornecem uma imagem distorcida, pois os profissionais de segurança frequentemente prestam atenção às zonas "quentes", ou seja, aquelas áreas onde as vulnerabilidades já foram encontradas (por exemplo, Stagefright ). Ou podem procurar vulnerabilidades onde são mais fáceis de detectar usando soluções prontas para usar. Por exemplo, se uma ferramenta de análise de segurança for publicada na plataforma GitHub, muitos profissionais a usarão.
Tentamos distribuir nossos esforços para melhorar a segurança de maneira uniforme. Nossas equipes prestam atenção aos componentes menos explorados e mais complexos da plataforma. Além disso, o teste de difusão automatizado é executado continuamente em máquinas virtuais e dispositivos Android físicos, o que permite encontrar e corrigir bugs nos primeiros estágios de desenvolvimento. Ao decidir quais ferramentas usar, também analisamos as causas raízes e a gravidade dos problemas que encontramos.
Como parte do programa Android VRP, encorajamos os desenvolvedores a adicionar cadeias de vulnerabilidade completaspermitindo que você rastreie todo o processo de ataque do início ao fim. Como regra, os cibercriminosos exploram várias vulnerabilidades ao mesmo tempo e, nessas cadeias, esses "pacotes" são claramente visíveis, portanto, são muito informativos. Nossos engenheiros de segurança analisam cadeias inteiras e seus links individuais e tentam descobrir novas estratégias de ataque neles. Esta análise ajuda a determinar estratégias para ajudar a prevenir a exploração sequencial de vulnerabilidades (por exemplo, alocação de espaço de endereço aleatório e métodos de Integridade de Fluxo de Controle ) e também entende se o ataque pode ser mitigado se o processo obtiver acesso indesejado aos recursos.
Obviamente, algumas vulnerabilidades podem ser incluídas em várias cadeias de uma vez e estão localizadas em uma ordem diferente. Portanto, é melhor usar "defesa em profundidade", reduzindo a eficácia das vulnerabilidades individuais e alongando as cadeias de explorações. Nesse caso, será mais difícil para um invasor construir uma cadeia eficaz e conduzir um ataque.
Para entender as ameaças de segurança atuais e prever tendências futuras, você precisa manter constantemente o controle da comunidade de segurança, em particular:
- trabalhar em estreita colaboração com especialistas em segurança de terceiros;
- leia publicações temáticas e participe de conferências;
- estudar as tecnologias usadas pelo malware;
- acompanhar os últimos desenvolvimentos no campo da segurança;
- participar de projetos paralelos como KSPP , syzbot, LLVM, Rust, etc.
Como resultado, você terá um melhor entendimento de sua estratégia geral de segurança, da eficácia das soluções existentes e das oportunidades de melhoria.
Por que uma proteção mais forte é necessária
Fortalecimento da proteção e prevenção de ataques
A análise dos dados ajuda a identificar áreas onde a mitigação de ataques eficaz pode abordar classes inteiras de vulnerabilidades. Por exemplo, se alguns componentes da plataforma desenvolverem muitas vulnerabilidades devido a erros de estouro de número inteiro, você deve usar um sanitizer de comportamento não especificado ( UBSan ), como Integer Overflow Sanitizer. Se as vulnerabilidades de acesso à memória forem comuns, você deve usar alocadores de memória protegidos ( habilitados por padrão no Android 11 ) e ferramentas de prevenção de ataques (como Control Flow Integrity ) que são resistentes a estouro de memória e vulnerabilidades Use-After.
Antes de falarmos sobre o uso de dados, propomos uma classificação de ferramentas para fortalecer a segurança da plataforma. Aqui estão os principais segmentos nos quais todas essas ferramentas podem ser divididas (embora algumas ferramentas e métodos possam se aplicar a várias delas ao mesmo tempo):
- Explorar ferramentas de eliminação
- Ferramentas de remediação de tempo de execução determinísticas detectam comportamento indefinido ou indesejado e interrompem a execução do programa. Isso elimina a corrupção de dados na memória, mantendo a probabilidade de apenas pequenas falhas. Freqüentemente, essas ferramentas podem ser aplicadas pontualmente e ainda assim serão eficazes, uma vez que foram projetadas para erros individuais. Exemplos: sanitizer de estouro de inteiro e BoundsSanitizer .
- . . . . , . : , Control Flow Integrity (CFI), , .
- , . , . : .
-
- . , . , .
Dependendo do problema específico, decidimos quais das ferramentas descritas devem ser usadas e como. Por exemplo, cada um deles é adequado se estivermos lidando com um grande processo envolvendo o processamento de dados não confiáveis e análise complexa. As plataformas multimídia têm sido uma grande demonstração de como a decomposição da arquitetura pode ser usada para mitigar explorações de maneira mais eficaz e evitar o aumento de privilégios.
Decomposição da arquitetura e isolamento de estruturas de mídia em um contexto histórico
Os alvos de ataques remotos (NFC, Bluetooth, Wi-Fi e conteúdo de mídia) são tradicionalmente associados às vulnerabilidades mais sérias, portanto, fortalecer sua segurança deve ser uma prioridade. Normalmente, essas vulnerabilidades são causadas pelas causas raiz mais comuns encontradas no programa VRP, e recentemente adicionamos desinfetantes para todas elas.
As ferramentas de prevenção de ataques são úteis para bibliotecas e processos que definem ou residem dentro dos limites de segurança (por exemplo, libbinder , bem como as bibliotecas padrão libui , libcore e libcutils), uma vez que não estão vinculados a processos específicos. No entanto, essas bibliotecas são responsáveis pela operação eficiente e estável dos sistemas, portanto, antes de usar um método específico, você precisa de uma garantia séria de que ele aumentará a segurança.
Finalmente, é importante proteger o kernel, dado seu alto nível de privilégios. Todas as bases de código têm características e funcionalidades diferentes, portanto, a probabilidade de vulnerabilidades nelas é diferente. Os principais critérios aqui são estabilidade e desempenho. Use apenas medidas de segurança eficazes que não interfiram no trabalho dos usuários. Portanto, antes de escolher a estratégia ideal para proteção reforçada, analisamos cuidadosamente todos os dados disponíveis relacionados ao kernel.
A abordagem baseada em dados produziu resultados tangíveis. Depois que a vulnerabilidade Stagefright foi descoberta em 2015, começamos a receber relatórios de um grande número de outras vulnerabilidades críticas na plataforma de mídia Android. Para complicar as coisas, muitos deles eram acessíveis remotamente. Realizamos uma decomposição massiva do sistema Android Nougat e aceleramos a correção de vulnerabilidades em componentes multimídia . Graças a essas mudanças, em 2020 não houve relatos de vulnerabilidades críticas em plataformas multimídia que podem ser acessadas pela Internet.
Como a decisão de implantação é feita
Naturalmente, faz sentido se concentrar nas ferramentas de prevenção de ataques que funcionam melhor. Para identificá-los, observamos como cada ferramenta afeta o desempenho, quanto trabalho é necessário para implantá-la e suportá-la e se afetará negativamente a estabilidade do sistema.
Desempenho
Ao escolher uma ferramenta de prevenção de ataques, você precisa entender como ela afeta o desempenho do dispositivo. Se alguns componentes ou o sistema como um todo não puderem suportar a carga, a vida útil da bateria e o desempenho geral podem ser reduzidos. Isso é especialmente verdadeiro para dispositivos básicos que também precisam de maior segurança. Assim, damos preferência às soluções mais eficazes que não afetem o desempenho dos dispositivos.
Ao avaliar o desempenho, prestamos atenção não apenas ao tempo do processador, mas também ao uso da memória, comprimento do código, duração da bateria e casos de congelamento da interface.... Para garantir que uma ferramenta tenha um bom desempenho em todo o ecossistema Android, é especialmente importante testar os parâmetros listados em dispositivos básicos.
É muito importante para qual componente as medidas de proteção são aplicadas. Por exemplo, a vinculação é mais comumente usada para comunicação entre processos. Portanto, qualquer carga excessiva afetará instantaneamente a operação do dispositivo. No caso de um reprodutor de mídia que processa apenas frames na taxa original, a situação é diferente. Se a velocidade do vídeo for muito maior do que a velocidade da tela, a carga adicional não será tão crítica.
Usamos benchmarks para determinar o impacto no desempenho de uma solução específica. Se não houver resultados de benchmark para um componente, você precisará obtê-los, por exemplo, chamando o codec afetado para decodificar o arquivo de mídia. Se o teste indicar uma carga inaceitável, existem várias opções:
- Desative seletivamente a prevenção de ataques para recursos que têm um impacto significativo no desempenho. Normalmente, apenas algumas funções consomem recursos em tempo de execução. Ao não aplicar a mitigação de ataques a eles, você pode manter o desempenho e maximizar o impacto na segurança. Aqui está um exemplo dessa abordagem para um dos codecs de mídia. Para eliminar os riscos, as funções mencionadas devem ser verificadas previamente quanto a erros.
- Otimize o uso da prevenção de ataques. Freqüentemente, isso requer mudanças no compilador. Por exemplo, nossa equipe passou a usar Integer Overflow Sanitizer e Bounds Sanitizer.
- Algumas opções de mitigação de ataque, como a resiliência de heap embutida do Scudo, podem ser ajustadas para melhorar o desempenho.
Muitas dessas melhorias requerem mudanças no design do LLVM. Como resultado, não apenas a plataforma Android ganha, mas também outros membros da comunidade LLVM.
Implantação e suporte
Ao escolher uma ferramenta de prevenção de ataques, você precisa considerar não apenas as considerações de segurança e desempenho, mas também os custos de implantação e suporte de longo prazo.
Impacto das medidas de segurança na operação estável do sistema
É importante entender se é possível acionar falsamente uma determinada ferramenta de prevenção de ataques. Por exemplo, se o sanitizer Bounds lançar um erro, é definitivamente um acesso negado (embora possa não ter sido usado). No caso do sanitizer de estouro de número inteiro, falsos positivos são possíveis, já que um estouro de número inteiro costuma ser um processo absolutamente normal e inofensivo.
Portanto, é importante considerar o impacto das ferramentas de prevenção de ataques na estabilidade do sistema. Não importa se houve um falso positivo ou se houve uma ameaça real à segurança - em qualquer caso, o usuário é incomodado. Aqui, novamente, notamos que é necessário entender claramente para quais componentes uma ou outra medida de segurança deve ser usada. Porque as falhas em alguns componentes têm um impacto maior na estabilidade do sistema. Se o Attack Prevention travar o codec de mídia, a reprodução do vídeo simplesmente será interrompida. No entanto, em caso de erro no processo
netd
ao instalar a atualização, o dispositivo pode não ligar mais. Mesmo que os falsos positivos não causem problemas para algumas ferramentas anti-ataque (por exemplo, como é o caso com o desinfetante Bounds), ainda conduzimos testes extensivos para garantir que o dispositivo esteja estável. Por exemplo, erros de polarização por um podem não travar normalmente e o desinfetante Bounds interrompe o processo e interrompe a estabilidade do sistema.
Também é importante entender se é possível identificar com antecedência todos os componentes que a ferramenta de prevenção de ataques pode desabilitar. Por exemplo, no caso do sanitizador de estouro de inteiro, é muito difícil prever os riscos sem fazer testes extensivos, porque é difícil determinar quais estouros de inteiro são intencionais (permitidos) e quais podem causar vulnerabilidades.
Apoio, suporte
É necessário considerar não apenas os possíveis problemas na implantação de ferramentas de prevenção de ataques, mas também as especificidades de seu suporte a longo prazo. Estimamos o tempo que leva para integrar a ferramenta com os sistemas existentes, ativá-la e depurá-la, implantá-la nos dispositivos e, em seguida, fazer o serviço após o lançamento. A tecnologia SELinux é um bom exemplo. É preciso muito tempo e esforço para criar um conjunto de regras. E esse conjunto precisa ser mantido por anos, independentemente das alterações de código, bem como da adição ou remoção de recursos individuais.
Nós nos esforçamos para garantir que as ferramentas de prevenção de ataques tenham um impacto mínimo na estabilidade e que os desenvolvedores tenham todas as informações de que precisam. Para atingir esses objetivos, estamos aprimorando nossos algoritmos atuais para reduzir o número de falsos positivos e publicamos a documentação em source.android.com . Ao facilitar a depuração em caso de falhas, você pode reduzir a carga de manutenção dos desenvolvedores. Por exemplo, para facilitar a localização de bugs no sanitizer UBSan, adicionamos suporte de tempo de execução mínimo UBSan ao sistema de compilação do Android por padrão. Inicialmente, o tempo mínimo de execução foi adicionado outros desenvolvedores do Google especificamente para essa finalidade. Se o programa travar devido ao sanitizador Integer Overflow, o seguinte snippet é adicionado à mensagem de erro SIGABRT:
Abort message: 'ubsan: sub-overflow'
Depois de ver esta mensagem, os desenvolvedores entenderão que é necessário habilitar o modo de diagnóstico para imprimir as informações sobre a falha:
frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp:2188:32: runtime error: unsigned integer overflow: 0 - 1 cannot be represented in type 'size_t' (aka 'unsigned long')
Ao mesmo tempo, o SELinux possui uma ferramenta audit2allow que permite propor regras que permitem certas operações bloqueadas:
adb logcat -d | audit2allow -p policy
#============= rmt ==============
allow rmt kmem_device:chr_file { read write };
Embora audit2allow nem sempre sugira as opções certas, é de grande ajuda para os desenvolvedores novos no SELinux.
Conclusão
A cada versão do Android, trazemos novas ferramentas que protegem todo o ecossistema, garantindo o desempenho e a estabilidade de que você precisa. A análise de dados desempenha um papel importante nisso. Esperamos que este artigo tenha ajudado você a entender melhor os desafios da implementação de novas ferramentas de prevenção de ataques e como lidamos com eles.
Obrigado aos nossos colegas e autores: Kevin Deus, Joel Galenson, Billy Lau, Ivan Lozano - especialistas em segurança e privacidade do Android. Agradecimentos especiais a Zviad Kardava e Jeff Van Der Stup por sua ajuda na preparação deste artigo.