Há um mês, na próxima
Droid Party, a desenvolvedora sênior Danila Fetisov examinou em detalhes o princípio do serviço, responsável pelas funções de acessibilidade do Android. Você aprenderá como usá-lo para melhorar a acessibilidade de seus projetos, bem como uma vulnerabilidade perigosa chamada clickjacking.
- Meu nome é Danila Fetisov, sou do escritório de Yandex em Moscou, mais especificamente de táxi, mais especificamente de taxímetro. Hoje falaremos sobre o que é a acessibilidade do Android e por que decidi chamar uma coisa tão sagrada para pessoas com deficiência de lobo em pele de cordeiro.

Então, o esboço do relatório. Primeiro, veremos como essa coisa pode ser usada, criada e personalizada. Talvez eu lhe conte alguns truques da vida, nishtyaks de supermercado. E então o mais interessante - sobre por que essa coisa é perigosa.

Como podemos aplicar isso? Em geral, o que é isso para quem não sabe? Quaisquer eventos ocorrem no sistema, eles caem em nosso serviço e nós os processamos.
Quando algo cai para nós, podemos pegar o conteúdo de lá e dublá-lo usando o mesmo Yandex SpeechKit, Google Text-to-Speech do Google ou qualquer outra coisa que você gosta. Mas o mais interessante, não podemos apenas receber, mas também lançar um evento do sistema. Você ainda pode dizer alguma coisa. Ele jogou o evento, apertou o botão, e está tudo bem, aproveite a vida.
Se falamos sobre esses dois pontos, eles, na verdade, são inadimplentes. O Google lançou esse recurso para que pessoas com deficiência possam usar seu aplicativo. Mas como todos sabem, nós desenvolvedores não queremos ficar entediados: sentamos, olhamos o código e pensamos: como podemos aplicá-lo? E lá vamos nós.
Automação, teste simulando ações do usuário, publicidade contextual. Você entende: como obtemos conteúdo da tela, podemos entender como frustrar esse usuário.
O que mais é interessante? Processando solicitações USSD. Infelizmente, a API normal apareceu apenas no 26º SDK, e os desenvolvedores de alguma forma precisam sobreviver. E você imagina que eles estão analisando seriamente solicitações USSD, analisando UIs usando o AccessibilityService.
O sexto ponto é a elipse. Porque Porque, após este relatório, você entenderá como aplicá-lo e para quê. E então você literalmente abre seu fluxo de imaginação, toma uma xícara de chá, café e dirige para codificar seus recursos interessantes.
Por onde começar? O próximo slide será dolorosamente comum.

Tomamos um serviço, herdamos do AccessibilityService e desfrutamos a vida.
Em seguida, lançamos esse serviço no Manifest, e o que é interessante aqui? Essencialmente, um registro de serviço regular. Mas preste atenção ao campo do rótulo. Agora não vou contar o que é. Lembre-se, isso será um pouco mais tarde.


Mais adiante, no Manifest, temos apenas um arquivo de configuração, nada interessante.

E o próprio arquivo configs parece um pouco mais terrível. Do que você precisará, provavelmente, 85 a 90% é o campo de configurações de filtro para eventos recebidos.
Digamos que vale a pena aqui que queremos receber absolutamente todos os eventos. Você pode colocar um filtro apenas nos cliques, na alteração de conteúdo ou em outra coisa.
A seguir, um filtro para pacotes de aplicativos. Para que é isso? Você mesmo entende perfeitamente que receber eventos de absolutamente todos os aplicativos no sistema seria demais para um aplicativo. Portanto, o Google decidiu limitá-lo de alguma forma. Adicionado um filtro.
Descrição adicional. Havia um campo de etiqueta e agora use a descrição. De fato, eles criam um par, que diz ao usuário por que você precisa habilitar seu serviço.
E o último ponto: o conteúdo é necessário ou não na janela aberta atual. Se você quiser apenas entender que ocorreu um evento, defina-o como false e não atormente o usuário novamente.

A inclusão do serviço. Infelizmente, para ativar esse recurso, você terá que torturar o usuário e forçá-lo a passar por sete círculos de configurações infernais, relativamente falando.
Primeiro, abrimos oportunidades especiais para ele. Cool AccessibilityService - esse é exatamente o mesmo rótulo do manifesto, que eu mencionei nos slides anteriores.

Mais longe. O usuário precisa selecionar seu serviço e, em seguida, ele começa a ler a descrição. Por que você deseja habilitar esse serviço e obter algum controle sobre o dispositivo.

OK, inclui. Mas lá estava. Sai algum tipo de diálogo assustador, que diz: "Cara, se você ativá-lo agora, assumiremos o controle total do seu aplicativo, relativamente falando, tudo será assustador". Os usuários nem sempre leem tudo isso, basta clicar em "OK" para estarmos atrás deles. Então nós vivemos.
Bem, onde está o processamento do evento? O próximo slide é um pouco mais inteligente do que o primeiro slide sobre o serviço, mas mesmo assim.

Aqui está nosso DummyAccessibilityService, e deixamos cair dois métodos lá, nos quais escreveremos tudo. De fato, interrupção é um método no qual você precisa limpar seus links, interromper assinaturas ou algo mais.
O mais interessante é a classe AccessibilityEvent, que é nossa. O que podemos tirar disso?

Para começar, podemos entender o que realmente aconteceu no seu sistema. Tomamos EventType, e o que chegamos aqui?
E percebemos que temos algum tipo de atividade aberta, ou Diálogo, ou Pop-up, ou, em geral, a notificação caiu. Tudo cai ali em window_state_changed.
Compreendemos ainda que o conteúdo de algumas visualizações mudou. Eles o moveram, jogaram alguma linha na exibição de texto ou algo assim.
E então descobrimos quando o usuário clica ou seleciona uma visualização. Na minha opinião, 85 e até 98, provavelmente, por cento das principais tarefas do produto que você cobre com esses tipos de eventos.
Mas se você não tiver um número suficiente deles, por favor, vá para a documentação, mostrarei um link no final do relatório e, é claro, você fará o download do relatório, poderá prosseguir. É apenas uma leitura para toda a noite, há uma lista enorme. Sério, você não vai dominá-lo de cada vez.

Agora temos uma pergunta: como encontrar uma vista? Nós descobrimos o que aconteceu. E agora vamos entender com qual visão, com qual componente isso aconteceu.
Participe do nosso AccessibilityEvent.
Pegamos o Source dele e, voila, já temos meta-informações.
Mas e se você for um desenvolvedor hardcore e não tiver informações suficientes sobre uma visualização, deseja entender o que está acontecendo basicamente na tela agora? Há uma limitação no SDK, mas é pequeno.

Tomamos nosso AccessibilityService e obtemos, de fato, uma referência ao elemento raiz em toda a hierarquia na tela atual. E só então temos nossa meta-informação em exibição.

É claro que isso é legal, mas agora você deve ter uma pergunta em mente: bem, temos um link para o elemento raiz. O que faremos a seguir?
Se você deseja seguir o caminho seguro, então, por favor, a primeira opção. Faça uma visualização de ID e encontre apenas um método.
Se você acha que é algo entediante, a caça é algo mais divertido, então tiramos o texto da vista, o encontramos.
Se isso não for interessante o suficiente para você - bem, pessoal, tomem Criança e Recursão, andem nela. Então você entenderá exatamente o que está acontecendo.
Ótimo. Você e eu descobrimos como encontrar uma vista. Como agora para interagir com ela?
Mais uma vez, pegamos nosso AccessibilityNodeInfo e agora já estamos lançando Ação nele. Que ação podemos lançar lá?

Para começar, podemos jogar Click. Por que no final eu coloquei aqui não apenas depois do Click, mas também do Click and Select? Sim, porque há várias caixas de canto, quando o clique usual não o salva. Suponha que um usuário selecione um texto e clique na visualização para remover de maneira limpa a seleção desse texto. Ou, em alguns dispositivos, em princípio, a visualização não é clicável até você chamar Selecionar nela. Em geral, muitos problemas. E se você quiser tomar um banho de vapor - selecione, clique. Duas ações, e isso é tudo, há felicidade.
O que vem a seguir conosco? E então temos a instalação de texto. Aqui também tudo é simples. Tome Action_set_text, crie um Bundle com nossa linha e viva.
E o terceiro ponto é ir para a documentação. Novamente, esta é a segunda noite que você terá. Um monte de ações diretamente, na minha opinião, mais do que eventos.
Viva! A parte mais chata do relatório acabou. Agora é hora de todos os tipos de nishtyachkov.
Suponha que você criou um serviço, o configurou e lançou algum tipo de processamento de eventos. Agora você precisa entender como forçar o usuário, como pedir para ele ainda habilitar este serviço. Para entender isso, você precisa descobrir, em princípio, o serviço agora está ativado ou não.

Tudo é simples ao ponto da banalidade. Tomamos o AccessibilityManager e solicitamos todos os serviços atualmente incluídos no sistema e lá encontramos os nossos.
Mas tudo seria legal, é claro, se o AccessibilityManager fosse um cara normal, e não havia como você perguntar: "Cara, me dê, por favor, todos os serviços disponíveis" e ele diz: "Desculpe, eu não estou hoje de bom humor. Aqui está uma lista vazia para você. E você está tão sentado e pensando: "Porra, nós conversamos normalmente."

Bem, existem bons velhos amigos - esses são Settings.Secure.getInt e getString. Primeiro, perguntamos se os serviços estão inclusos no sistema. Se incluído, tudo será lançado em uma linha, e já estamos procurando o nosso por meio de algum tipo de conteúdo.
E aqui nos reunimos com o fato de que fizemos tudo certo. Criamos a configuração, criamos a construção de qualquer evento, ativamos o serviço. Temos certeza de que ativamos o serviço e os eventos não chegam até nós. E assim, eles chegam ou não chegam. Naquele momento, pensei que na minha vida algum tipo de faixa preta havia chegado. Bem, não havia opções.
Eu pensei, pensei, reserched, reserched e, em seguida, bingo, percebi que essa é a Xiaomi com o MIUI deles. Isso é só dor! Isso é serio.
Ok, entenda qual é o problema. Como resolvê-lo agora? Infelizmente, em alguns firmware no MIUI, tudo é feito para que, se seu aplicativo não estiver na inicialização automática, o sistema nem iniciará o serviço em princípio.

Mas aqui está uma solução: pedimos ao usuário para adicionar seu aplicativo ao início automático e continuamos a viver, aproveitar a vida.

E então veio a cereja no bolo. Por que esse serviço, tão gentil para as pessoas com deficiência, é um lobo em pele de cordeiro?
Parece-me que muitos de vocês já imaginaram que, se um usuário ativar esse serviço, poderemos facilmente roubar muitas informações confidenciais do dispositivo. Não apenas podemos roubá-lo, podemos deixá-lo em algum lugar, por exemplo, desbloquear a tela se ela estiver bloqueada usando um código PIN. Bem, ok, desbloqueie a tela. O que vem a seguir? Estamos nos anunciando, ganharemos muito dinheiro, viveremos imediatamente. E, no final, podemos basicamente imitar absolutamente qualquer ação do usuário e, digamos, colocar algum tipo de aplicativo, conceder direitos de administrador e dizer ao usuário: “Adeus. Diga adeus ao seu dispositivo.

Tudo bem, podemos fazer tudo isso, mas agora você dirá: “Você, é claro, muito bem. Ele nos disse como podemos roubar que tipo de dados. Mas como você faz o usuário ativar o AccessibilityService e se o aplicativo é canhoto? ” Tudo bem, o usuário, ao que me parece, apenas abre as configurações, entende que há algum tipo de bobagem escrita lá, fecha, desinstala o aplicativo e esquece. E você sabe, você estará certo de que a primeira maneira de ativar as configurações do sistema é "não", porque, você sabe, isso é algum tipo de absurdo. E aqui vem uma vulnerabilidade em nosso auxílio, que, em essência, é chamada de clickjacking. Quantos de vocês estão familiarizados com o clickjacking? Ótimo, será interessante.
Portanto, com base nessa vulnerabilidade, alguns caras - coloquei uma pequena referência, porque todas as capturas de tela a seguir serão dos recursos desses caras - criaram um ataque chamado Cloak and Dagger. De fato, com apenas duas permissões e interação mínima do usuário, você obtém acesso a todo o aplicativo diretamente da palavra "completamente".
Mas ok, o que precisamos fazer para hackear o usuário?
Estamos lançando nosso aplicativo no Google Play. Esperamos que o usuário da versão Android seja menor que 8.
Você entende, um pouco - 95% no momento. E é tudo, o usuário baixa nosso aplicativo.

Em suma, esse malware diz ao usuário como se tornar um cara legal, mostra um vídeo no final. Agora você verá tudo por si mesmo.

Ok, vamos começar. Um pequeno texto. É-nos dito: "Se você iniciar o tutorial agora, se tornará um cara legal". Ok, claro, estamos começando.

Algum outro texto. Além disso, as pessoas serão apresentadas na forma de homens verdes. Bem, ok, vamos clicar em Avançar.

Outro texto. Bem, tudo bem. Agora vou terminar de ler e definitivamente verei um vídeo no qual eles me dirão como me tornar um cara legal.


Clico em "OK" e o vídeo começa. Isso não é tão importante para nós. É importante o que realmente aconteceu no dispositivo naquele momento. O usuário inicia o aplicativo e, como o instalamos no Google Play, recebemos automaticamente permissão para sobrepor. Voila, abrimos a janela de acessibilidade e, em cima, apenas sobrepomos. O usuário clica no Tutorial Iniciar, mas na verdade seleciona o nosso AccessibilityService. Bem, você entende o que vem a seguir.

Em seguida, clique em Avançar, selecione a opção de alternância.

No final, ativamos o AccessibilityService e o usuário nem percebe que isso aconteceu.
Você sabe qual é o problema? A sobreposição é organizada de tal maneira que eles absorvem completamente todos os eventos, todos os toques já estão distantes ou perdem completamente. E o objetivo desse ataque em particular é preencher a sobreposição, a tela inteira, exceto um espaço. Nesse caso, este é o botão OK. Este botão é realmente do diálogo. Quando clicamos nele, obtemos um evento que diz que o toque externo aconteceu e está tudo bem.
Como o Google responde a todos esses problemas? Você entende, essa é uma vulnerabilidade bastante brutal.

Tudo começou de maneira interessante - tudo com oito anos de silêncio. O Google revelou essa coisinha, disse: “Gente, use-a. Está seguro. Eu digo com certeza. Bem, tudo bem. Google jogou. Os mesmos caras que Cloak e Dagger inventaram, deram apoio, emitiram rastreadores e rastreadores de bugs.
Então o Google disse: “Ok, pessoal, acalme-se. Fecharei o clickjacking no Oreo. " Bem, desligue. Eles ainda estão lá, pensam: “Bem, droga, pessoal, mesmo assim, se os atacantes forçarem o usuário a permitir acessibilidade, será ruim. Vamos zombar dos desenvolvedores um pouco.
E eles enviam uma carta: "Faça, não sei o quê, caso contrário, seu aplicativo será excluído do Google Play". Em resumo, a carta era a seguinte: "Pessoal, conte-nos e usuários por que você precisa do AccessibiiltyService". Como saber? Em que formato? Onde Geralmente sem entendimento. E na carta, é claro, isso não é indicado.
Bem, tudo bem. Tópicos enormes no reddit, um monte de cartas para apoiar. E então algum desenvolvedor coloca uma carta no reddit e diz: “Sim, pessoal, nada complicado. Coloque na descrição que eu mostrei, no manifesto, coloque na descrição no Google Play, e tudo ficará bem, eu vou deixar você em paz. "
Naquele momento, pensei: bem, tudo bem, encontrei esta carta à margem do Reddit. Mas e se eu sou um desenvolvedor jovem, acabei de conhecer o AccessibilityService e quero liberar o aplicativo com isso? Como devo descobrir que preciso executar essas ações? Preciso incluí-lo na descrição no Google Play etc.? Eu pensei, pensei, procurei, procurei e, sabe, pessoal, não encontrei nada, a partir da palavra.
Bem, sério, não há nada. Há apenas uma descrição na documentação principal: "Pessoal, isso é apenas para pessoas com deficiência, esse é o ponto. Você não pode mais usá-lo. " Mas, de fato, é possível.

Bem, você e eu chegamos ao fim. O que poderíamos falar com você? Falamos sobre como usá-lo, entendemos como criar tudo, configurá-lo e como lidar com eventos da interface do usuário. E, é claro, entendemos como isso é possível, mas você não precisa interagir com o AccessibilityService. Claro, eu não recomendo que você faça isso, foi apenas para obter informações. Aqui estão as fontes prometidas:
-
developer.android.com/guide/topics/ui/accessibility/services-
developer.android.com/reference/android/view/accessibility/AccessibilityEvent-
developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo-
cloak-and-dagger.orgGente, muito obrigado pela atenção!