Accessibilité Android - un loup déguisé en mouton? Conférence Yandex

Il y a un mois, lors du prochain Droid Party, la développeur principale Danila Fetisov a examiné en détail le principe du service, qui est responsable des fonctions d'accessibilité d'Android. Vous apprendrez à l'utiliser pour améliorer l'accessibilité de vos projets, ainsi qu'une dangereuse vulnérabilité appelée clickjacking.


- Je m'appelle Danila Fetisov, je suis du bureau de Moscou de Yandex, plus précisément de Taxi, plus précisément de Taximeter. Aujourd'hui, nous allons parler de ce qu'est l'accessibilité Android et pourquoi j'ai décidé d'appeler une si petite chose sainte pour les personnes handicapées un loup déguisé en mouton.



Donc, les grandes lignes du rapport. Tout d'abord, nous verrons comment cette chose peut être utilisée, créée et personnalisée. Je vais peut-être vous dire quelques astuces de vie, des nishtyaks d'épicerie. Et puis sur le plus intéressant - pourquoi cette chose est dangereuse.

Comment pouvons-nous appliquer cela? En général, qu'est-ce que pour ceux qui ne savent pas? Tous les événements se produisent dans le système, ils entrent dans notre service et nous les traitons.

Une fois que quelque chose nous tombe dessus, nous pouvons prendre le contenu à partir de là et l'exprimer en utilisant le même Yandex SpeechKit, Google Text-to-Speech ou autre chose que vous aimez. Mais ce qui est le plus intéressant, nous pouvons non seulement recevoir, mais aussi lancer un événement système. Vous pouvez toujours dire quelque chose. Il a lancé l'événement, a appuyé sur le bouton, et tout va bien, profitez de la vie.

Si nous parlons de ces deux points, ils sont en fait par défaut. Google a lancé cette fonctionnalité pour que les personnes handicapées puissent utiliser votre application. Mais comme tout le monde le sait, nous, les développeurs, ne voulons pas nous ennuyer: nous nous asseyons, regardons le code et pensons: comment l'appliquer? Et c'est parti.

Automatisation, test en simulant les actions des utilisateurs, publicité contextuelle. Vous comprenez: puisque nous obtenons du contenu de l'écran, nous pouvons comprendre comment frustrer cet utilisateur.

Quoi d'autre est intéressant? Traitement des demandes USSD. Malheureusement, l'API normale n'est apparue qu'à partir du 26e SDK, et les développeurs doivent en quelque sorte survivre. Et vous imaginez, ils analysent sérieusement les demandes USSD, analysant les interfaces utilisateur à l'aide d'AccessibilityService.

Le sixième point est l'ellipse. Pourquoi? Parce qu'après ce rapport, vous comprendrez comment l'appliquer et pour quoi. Et puis vous ouvrez littéralement votre flux d'imagination, prenez une tasse de thé, de café et conduisez pour coder leurs fonctionnalités cool.

Par où commencer? La diapositive suivante sera douloureusement courante.


Nous prenons un service, héritons d'AccessibilityService et profitons de la vie.

Ensuite, nous lançons ce service dans Manifest, et qu'est-ce qui est intéressant ici? Essentiellement un dossier de service régulier. Mais faites attention au champ d'étiquette. Maintenant, je ne dirai pas ce que c'est. N'oubliez pas que ce sera un peu plus tard.



Plus loin dans Manifest, nous avons juste un fichier de configuration, rien d'intéressant non plus.


Et le fichier de configuration lui-même semble un peu plus terrible. D'après ce dont vous aurez besoin, 85 à 90% sont probablement le champ des paramètres de filtre pour les événements entrants.

Disons que cela vaut la peine de vouloir recevoir absolument tous les événements. Vous pouvez mettre un filtre uniquement sur les clics, sur le changement de contenu ou sur autre chose.

Vient ensuite un filtre pour les packages d'application. À quoi ça sert? Vous comprenez parfaitement que recevoir des événements de toutes les applications du système serait trop pour une seule application. Par conséquent, Google a décidé de la limiter en quelque sorte. Ajout d'un filtre.

Plus de description. Il y avait un champ d'étiquette, et maintenant utilisez la description. En fait, ils créent une paire, qui indique ensuite à l'utilisateur pourquoi vous devez activer votre service.

Et le dernier point: le contenu est nécessaire ou pas nécessaire à partir de la fenêtre ouverte actuelle. Si vous voulez simplement comprendre qu'un événement s'est produit, définissez-le sur false et ne tourmentez plus l'utilisateur.


L'inclusion du service. Malheureusement, pour activer cette fonctionnalité, vous devrez torturer l'utilisateur et le forcer à parcourir sept cercles de paramètres infernaux, relativement parlant.

Tout d'abord, nous lui ouvrons des opportunités spéciales. Cool AccessibilityService - c'est exactement la même étiquette du manifeste, dont je vous ai parlé dans les diapositives précédentes.


Plus loin. L'utilisateur doit sélectionner votre service, puis il commence à lire la description, pourquoi voulez-vous activer ce service et obtenir un certain contrôle sur l'appareil.


OK, comprend. Mais ça y était. Une sorte de dialogue effrayant sort, qui dit: "Mec, si vous l'allumez maintenant, nous prendrons le contrôle total de votre demande, relativement parlant, tout sera effrayant." Les utilisateurs ne lisent pas toujours tout cela, il suffit de cliquer sur «OK» pour que nous soyons derrière eux. Nous vivons donc.

Eh bien, où en est le traitement des événements? La diapositive suivante est un peu plus intelligente que la première diapositive sur le service, mais néanmoins.


Voici notre DummyAccessibilityService, et nous y déposons deux méthodes, dans lesquelles nous allons tout écrire. En fait, l'interruption est une telle méthode dans laquelle vous devez nettoyer vos liens, arrêter les abonnements ou autre chose.

Le plus intéressant est la classe AccessibilityEvent, qui nous revient. Que pouvons-nous en retirer?

Pour commencer, nous pouvons comprendre ce qui s'est réellement passé dans votre système. Nous prenons EventType, et qu'obtenons-nous ici?

Et nous obtenons que nous avons une sorte d'activité ouverte, ou Dialogue, ou Popup, ou en général la notification est tombée. Tout tombe juste là sur window_state_changed.

Nous comprenons en outre que le contenu de certaines vues a changé. Ils l'ont déplacé, ont jeté une ligne dans la vue texte ou quelque chose comme ça.

Et puis nous découvrons quand l'utilisateur clique ou sélectionne une vue. À mon avis, 85, et même 98, probablement, le pourcentage des principales tâches du produit que vous couvrez avec ces types d'événements.

Mais si vous n'en avez pas assez, s'il vous plaît, vous pouvez aller dans la documentation, je vous montrerai un lien à la fin du rapport, et, bien sûr, vous allez télécharger le rapport, vous pouvez continuer. C'est juste une lecture pour toute la soirée, il y a une énorme liste. Sérieusement, vous ne le maîtriserez pas à la fois.

Maintenant, nous avons une question: comment trouver une vue? Nous avons découvert ce qui s'est passé. Et maintenant, comprenons avec quelle vue, avec quel composant cela s'est produit.

Prenez notre événement AccessibilityEvent.

Nous lui prenons Source et, voila, nous avons déjà des méta-informations de vue.

Mais que se passe-t-il si vous êtes un développeur hardcore et que vous ne disposez pas de suffisamment d'informations sur une seule vue, vous voulez comprendre ce qui se passe essentiellement à l'écran maintenant? Il existe une limitation sur le SDK, mais elle est petite.

Nous prenons notre AccessibilityService, et nous obtenons, en fait, une référence à l'élément racine dans toute la hiérarchie sur l'écran actuel. Et alors seulement, nous obtenons nos méta-informations sur la vue.

Bien sûr, c'est cool, mais maintenant vous devriez avoir une question dans votre tête: eh bien, nous avons un lien vers l'élément racine. Que faisons-nous ensuite?

Si vous voulez suivre la voie sûre, alors, s'il vous plaît, la première option. Prenez une vue ID et trouvez une seule méthode.

S'il vous semble que c'est ennuyeux, la chasse est quelque chose de plus amusant, alors nous prenons le texte en vue, nous le trouvons dans le texte.

Si ce n'est pas assez intéressant pour vous - eh bien, les gars, prenez Child and Recursion, marchez dessus. Ensuite, vous comprendrez exactement ce qui se passe.

Super. Vous et moi avons trouvé comment trouver une vue. Comment maintenant interagir avec elle?

Encore une fois, nous prenons notre AccessibilityNodeInfo, et maintenant nous y jetons déjà Action. Quelle action pouvons-nous y lancer?

Pour commencer, nous pouvons lancer Click. Pourquoi à la fin ai-je mis ici non seulement après Click, mais aussi Click and Select? Oui, car il y a un tas de cas d'angle, lorsque le clic habituel ne vous sauve pas. Supposons qu'un utilisateur sélectionne un texte et que cliquer sur la vue supprime proprement la sélection de ce texte. Ou, sur certains appareils, en principe, la vue n'est pas cliquable jusqu'à ce que vous appeliez Select dessus. En général, beaucoup de problèmes. Et si vous voulez simplement prendre un bain de vapeur - sélectionnez, cliquez. Deux actions, et c'est tout, il y a du bonheur.

Quelle est la prochaine étape avec nous? Et puis nous avons l'installation de texte. Ici aussi, tout est simple. Prenez Action_set_text, créez un Bundle avec notre ligne et vivez.

Et le troisième point est d'aller à la documentation. Encore une fois, c'est la deuxième soirée que vous aurez. Un tas d'actions directement, à mon avis, encore plus que des événements.

Hourra! La partie la plus ennuyeuse du rapport est terminée. Il est maintenant temps pour toutes sortes de nishtyachkov.

Supposons que vous ayez créé un service, l'avez configuré et lancé une sorte de traitement d'événement. Vous devez maintenant comprendre comment forcer l'utilisateur, comment lui demander de toujours activer ce service. Pour comprendre cela, vous devez savoir, en principe, que le service est maintenant activé ou non.


Tout est simple jusqu'à la banalité. Nous prenons AccessibilityManager et lui demandons tous les services actuellement inclus dans le système, et nous y trouvons les nôtres.

Mais tout serait bien sûr cool si le gestionnaire d'accessibilité était un gars normal, et il n'y en avait pas de tel que vous lui demandiez: "Mec, donnez-moi, s'il vous plaît, tous les services disponibles", et il dit: "Désolé, je ne suis pas aujourd'hui d'humeur. Voici une liste vide pour vous. " Et vous êtes tellement assis et pensez: "Merde, nous avons parlé normalement."


Eh bien, il y a de bons vieux amis - ce sont Settings.Secure.getInt et getString. Nous demandons d'abord si les services sont même inclus dans le système. S'il est inclus, alors tout est jeté sur une seule ligne, et là, nous recherchons déjà le nôtre à travers une sorte de contenu.

Et ici, nous rencontrons le fait que nous avons tout fait correctement. Nous avons créé la configuration, créé la construction de tous les événements, activé le service. Nous voyons avec certitude que nous avons activé le service, et les événements ne nous arrivent pas. Et donc, ils arrivent ou n'arrivent pas. À ce moment-là, j'ai pensé que dans ma vie une sorte de strie noire était venue. Il n'y avait pas d'options.

J'ai pensé, pensé, reserched, reserched, puis, bingo, j'ai réalisé que c'était Xiaomi avec leur MIUI. C'est juste la douleur des gars! C'est sérieux.

D'accord, comprenez quel est le problème. Comment le résoudre maintenant? Malheureusement, sur certains micrologiciels de MIUI, tout est fait pour que si votre application n'est pas en démarrage automatique, le système ne démarrera même pas votre service en principe.


Mais voici une solution - nous demandons à l'utilisateur d'ajouter votre application au démarrage automatique, et nous continuons à vivre, à profiter de la vie.

Et puis vint la cerise sur le gâteau. Pourquoi ce service, si gentil pour les personnes handicapées, est-il un loup déguisé en mouton?

Il me semble que beaucoup d'entre vous ont déjà deviné que si un utilisateur active ce service, nous pouvons facilement voler beaucoup d'informations confidentielles sur son appareil. Non seulement nous pouvons le voler, nous pouvons le déposer quelque part, par exemple, déverrouiller l'écran s'il est verrouillé à l'aide d'un code PIN. Bon, ok, déverrouille l'écran. Et ensuite? Nous faisons de la publicité nous-mêmes, nous gagnerons beaucoup d'argent, nous vivrons tout de suite. Et, en fin de compte, nous pouvons essentiellement imiter absolument toutes les actions de l'utilisateur, et, par exemple, mettre une sorte d'application, lui donner des droits d'administrateur et dire à l'utilisateur: «Au revoir. Dites adieu à votre appareil. "

D'accord, nous pouvons faire tout cela, mais maintenant vous direz: «Vous, bien sûr, bien joué. Il nous a expliqué comment nous pouvons voler quel type de données. Mais comment incitez-vous l'utilisateur à activer votre AccessibilityService et si l'application est pour gaucher? » D'accord, l'utilisateur, il me semble, ouvre simplement les paramètres, comprend qu'il y a une sorte de non-sens écrit, ferme, désinstalle l'application et oublie. Et vous savez, vous aurez raison en ce sens que la première façon d'activer les paramètres système passe à «non», car, vous savez, c'est une sorte de non-sens. Et ici, une vulnérabilité vient à notre aide, qui, en substance, est appelée détournement de clics. Combien d'entre vous connaissent le détournement de clics? Génial, ce sera intéressant.

Donc, sur la base de cette vulnérabilité, certains gars - je mets une petite référence, car toutes les captures d'écran suivantes proviendront des ressources de ces gars - ont proposé une attaque appelée Cloak and Dagger. En fait, avec seulement deux autorisations et une interaction utilisateur minimale, vous avez accès à l'ensemble de l'application directement à partir du mot «complètement».
Mais ok, que devons-nous faire pour pirater l'utilisateur?

Nous lançons notre application sur Google Play. Nous espérons que l'utilisateur de la version Android est inférieur à 8.

Vous comprenez, un peu - 95% pour le moment. Et c'est tout, l'utilisateur télécharge notre application.


En bref, ce malware explique à l'utilisateur comment devenir un bon gars, montre une vidéo à la fin. Maintenant, vous verrez tout par vous-même.


Ok, commençons. Un petit texte. On nous dit: "Si vous commencez le tutoriel maintenant, vous deviendrez un bon gars." D'accord, bien sûr, nous commençons.


Un autre texte. De plus, les gens seront présentés sous la forme d'hommes verts. Bon, ok, cliquons sur Suivant.


Un autre texte. Et bien. Maintenant, je vais finir de le lire et je vais certainement voir une vidéo sur laquelle ils me diront comment devenir un bon gars.



Je clique sur "OK", et là commence la vidéo. Ce n'est pas si important pour nous. Il est important de savoir ce qui s'est réellement passé sur l'appareil à ce moment-là. L'utilisateur lance l'application, et puisque nous l'avons installée à partir de Google Play, nous sommes automatiquement autorisés à superposer. Voila, nous ouvrons la fenêtre d'accessibilité, et en haut juste superposons. L'utilisateur clique sur Démarrer le didacticiel, mais sélectionne en fait notre AccessibilityService. Eh bien, vous comprenez la suite.


Ensuite, nous cliquons sur Suivant, sélectionnez le commutateur à bascule.


À la toute fin, nous activons AccessibilityService, et l'utilisateur ne se rend même pas compte que cela s'est produit.

Savez-vous quel est le problème? La superposition est disposée de manière à ce qu'ils absorbent complètement tous les événements, que tous les contacts soient déjà loin ou qu'ils manquent complètement. Et le point de cette attaque particulière est que nous remplissons la superposition, tout l'écran sauf un espace. Dans ce cas, il s'agit du bouton OK. Ce bouton est vraiment issu du dialogue. Lorsque nous cliquons dessus, nous obtenons un événement qui dit que le contact avec l'extérieur s'est produit, et tout va bien.

Comment Google répond-il à tous ces problèmes? Vous comprenez, c'est une vulnérabilité plutôt brutale.

Tout a commencé de façon assez intéressante - le tout avec huit ans de silence. Google a dévoilé cette petite chose, a déclaré: «Les gars, utilisez-le. C'est sûr. Je dis pour sûr. " Et bien. Lança Google. Les mêmes gars que Cloak et Dagger ont inventé, ont apporté un soutien, des trackers de problèmes et des trackers de bugs.

Ensuite, Google a dit: «D'accord, les gars, calmez-vous. Je vais fermer le détournement de clics à Oreo. " Eh bien, fermez-le. Ils restent assis là, ils pensent: «Eh bien, bon sang, les gars, tout de même, si les attaquants forcent l'utilisateur à activer l'accessibilité, ce sera mauvais. Raillons un peu les développeurs.

Et ils envoient une lettre: "Faites-le, je ne sais pas quoi, sinon votre application sera supprimée de Google Play." En bref, la lettre était la suivante: "Les gars, dites-nous et les utilisateurs pourquoi vous avez besoin d'AccessibiiltyService." Comment dire? Dans quel format? O?? Généralement aucune compréhension. Et dans la lettre, bien sûr, cela n'est pas indiqué.

Et bien. D'énormes discussions sur reddit, un tas de lettres à soutenir. Et puis un développeur met une lettre sur reddit, et il dit: «Oui les gars, rien de compliqué. Mettez-le dans la description que je vous ai montrée, manifestement, mettez-le dans la description sur Google Play, et tout ira bien, je vous laisserai tranquille. "

À ce moment-là, j'ai pensé: bon, d'accord, j'ai trouvé cette lettre en marge de Reddit. Mais que faire si je suis un jeune développeur, je viens de me familiariser avec AccessibilityService et je veux publier l'application avec cela? Comment savoir si je dois effectuer de telles actions, dois-je le déposer dans la description sur Google Play, etc.? J'ai pensé, pensé, fouillé, fouillé, et, vous savez, les gars, je n'ai rien trouvé du tout.

Eh bien, sérieusement, il n'y a rien. Il y a juste une description dans la documentation principale: «Les gars, c'est uniquement pour les personnes handicapées, c'est le point. Vous ne pouvez plus l'utiliser. " Mais en fait, il s'avère que c'est possible.

Eh bien, vous et moi avons pris fin. De quoi pourrions-nous vous parler? Nous avons discuté de la façon de l'utiliser, compris comment tout créer, le configurer et comment gérer les événements d'interface utilisateur. Et, bien sûr, nous avons compris comment cela est possible, mais vous n'avez pas besoin d'interagir avec le service d'accessibilité. Bien sûr, je ne vous recommande pas de le faire, c'était juste pour information. Voici les sources promises:

- 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.org

Les gars, merci beaucoup pour votre attention!

Source: https://habr.com/ru/post/fr417865/


All Articles