Vor einem Monat hat Senior-Entwickler Danila Fetisov auf der nächsten
Droid Party das Prinzip des Dienstes, der für die Barrierefreiheitsfunktionen von Android verantwortlich ist, eingehend untersucht. Sie erfahren, wie Sie damit die Zugänglichkeit Ihrer Projekte verbessern sowie eine gefährliche Sicherheitsanfälligkeit namens Clickjacking verbessern können.
- Mein Name ist Danila Fetisov, ich komme aus dem Moskauer Büro von Yandex, genauer gesagt von Taxi, genauer gesagt von Taximeter. Heute werden wir darüber sprechen, was Android-Barrierefreiheit ist und warum ich beschlossen habe, ein so heiliges kleines Ding für Menschen mit Behinderungen einen Wolf im Schafspelz zu nennen.

Also die Gliederung des Berichts. Zuerst werden wir sehen, wie dieses Ding verwendet, erstellt und angepasst werden kann. Vielleicht erzähle ich Ihnen ein paar Life-Hacks, Lebensmittel-Nishtyaks. Und dann über das Interessanteste - darüber, warum dieses Ding gefährlich ist.

Wie können wir das überhaupt anwenden? Was ist es im Allgemeinen für diejenigen, die es nicht wissen? Alle Ereignisse, die im System auftreten, fallen in unseren Dienst und wir verarbeiten sie.
Sobald etwas auf uns hereinfällt, können wir den Inhalt von dort übernehmen und ihn mit demselben Yandex SpeechKit, Google Text-to-Speech oder etwas anderem, das Ihnen gefällt, aussprechen. Aber was am interessantesten ist, wir können nicht nur ein Systemereignis empfangen, sondern auch auslösen. Du kannst immer noch etwas sagen. Er warf die Veranstaltung, drückte den Knopf, und richtig, alles ist in Ordnung, genießen Sie das Leben.
Wenn wir über diese beiden Punkte sprechen, sind sie tatsächlich voreingestellt. Google hat diese Funktion gestartet, damit Menschen mit Behinderungen Ihre Anwendung verwenden können. Aber wie jeder weiß, wollen wir Entwickler uns nicht langweilen: Wir setzen uns, schauen uns den Code an und überlegen: Wie können wir ihn anwenden? Und los geht's.
Automatisierung, Testen durch Simulation von Benutzeraktionen, kontextbezogene Werbung. Sie verstehen: Da wir Inhalte vom Bildschirm erhalten, können wir verstehen, wie wir diesen Benutzer frustrieren können.
Was ist sonst noch interessant? Verarbeitung von USSD-Anfragen. Leider erschien die normale API erst ab dem 26. SDK und Entwickler müssen irgendwie überleben. Und Sie stellen sich vor, sie analysieren ernsthaft USSD-Anforderungen und analysieren Benutzeroberflächen mithilfe des AccessibilityService.
Der sechste Punkt ist die Ellipse. Warum? Denn nach diesem Bericht haben Sie Verständnis dafür, wie und wofür Sie ihn anwenden müssen. Und dann öffnen Sie buchstäblich Ihren Fantasiefluss, nehmen eine Tasse Tee, Kaffee und fahren, um ihre coolen Funktionen zu codieren.
Wo soll ich anfangen? Die nächste Folie wird schmerzhaft alltäglich sein.

Wir nehmen einen Service in Anspruch, erben von AccessibilityService und genießen das Leben.
Dann werfen wir diesen Dienst in Manifest, und was ist hier interessant? Im Wesentlichen eine regelmäßige Serviceaufzeichnung. Achten Sie jedoch auf das Beschriftungsfeld. Jetzt werde ich nicht sagen, was es ist. Denken Sie daran, dies wird etwas später sein.


Weiter unten im Manifest haben wir nur eine Konfigurationsdatei, auch nichts Interessantes.

Und die Konfigurationsdatei selbst sieht etwas schrecklicher aus. Von dem, was Sie benötigen, sind höchstwahrscheinlich 85 bis 90 Prozent das Feld für die Filtereinstellungen für eingehende Ereignisse.
Nehmen wir an, es lohnt sich hier, dass wir absolut alle Veranstaltungen erhalten möchten. Sie können einen Filter nur für Klicks, für das Ändern von Inhalten oder für etwas anderes verwenden.
Als nächstes folgt ein Filter für Anwendungspakete. Wofür ist das? Sie selbst verstehen vollkommen, dass das Empfangen von Ereignissen von absolut allen Anwendungen im System für eine Anwendung zu viel wäre. Aus diesem Grund hat Google beschlossen, dies irgendwie einzuschränken. Filter hinzugefügt.
Weitere Beschreibung. Es gab ein Beschriftungsfeld und verwenden Sie jetzt die Beschreibung. Tatsächlich erstellen sie ein Paar, das dem Benutzer dann mitteilt, warum Sie Ihren Dienst aktivieren müssen.
Und der letzte Punkt: Inhalt wird vom aktuell geöffneten Fenster benötigt oder nicht benötigt. Wenn Sie nur verstehen möchten, dass ein Ereignis aufgetreten ist, setzen Sie es auf false und quälen Sie den Benutzer nicht erneut.

Die Aufnahme des Dienstes. Um diese Funktion zu aktivieren, müssen Sie den Benutzer leider quälen und ihn zwingen, relativ gesehen sieben Kreise der Einstellungshölle zu durchlaufen.
Erstens eröffnen wir ihm besondere Möglichkeiten. Cool AccessibilityService - Dies ist genau das gleiche Label aus dem Manifest, von dem ich Ihnen in den vorherigen Folien erzählt habe.

Weiter. Der Benutzer muss Ihren Dienst auswählen und beginnt dann, die Beschreibung zu lesen. Warum möchten Sie diesen Dienst aktivieren und die Kontrolle über das Gerät erlangen?

OK, beinhaltet. Aber da war es. Es kommt eine Art beängstigender Dialog heraus, der besagt: "Alter, wenn Sie ihn jetzt einschalten, übernehmen wir die volle Kontrolle über Ihre Anwendung. Relativ gesehen wird alles beängstigend sein." Benutzer lesen dies nicht immer, klicken Sie einfach auf "OK", damit wir hinter ihnen stehen. Also leben wir.
Woher kommt eigentlich die Ereignisverarbeitung? Die nächste Folie ist etwas schlauer als die erste Folie über den Service, aber dennoch.

Hier ist unser DummyAccessibilityService, und wir legen dort zwei Methoden ab, in die wir alles schreiben werden. In der Tat ist Interrupt eine solche Methode, bei der Sie Ihre Links bereinigen, Abonnements beenden oder etwas anderes.
Am interessantesten ist die AccessibilityEvent-Klasse, die uns zukommt. Was können wir daraus machen?

Zunächst können wir verstehen, was wirklich in Ihrem System passiert ist. Wir nehmen EventType und was bekommen wir hier?
Und wir bekommen, dass wir dort eine Art Aktivität geöffnet haben, oder Dialog oder Popup, oder im Allgemeinen ist die Benachrichtigung gefallen. Alles fällt genau dort auf window_state_changed.
Wir verstehen weiter, dass sich der Inhalt einiger Ansichten geändert hat. Sie haben es verschoben, eine Zeile in die Textansicht geworfen oder so ähnlich.
Und dann finden wir heraus, wann der Benutzer auf eine Ansicht klickt oder diese auswählt. Meiner Meinung nach sind 85 und sogar 98 Prozent der Hauptproduktaufgaben, die Sie mit diesen Ereignistypen abdecken.
Aber wenn Sie nicht genug davon haben, können Sie bitte zur Dokumentation gehen, ich werde Ihnen am Ende des Berichts einen Link zeigen, und natürlich werden Sie den Bericht herunterladen, Sie können fortfahren. Es ist nur eine Lesung für den ganzen Abend, es gibt eine riesige Liste. Im Ernst, Sie werden es nicht auf einmal beherrschen.

Jetzt haben wir eine Frage: Wie finde ich eine Ansicht? Wir haben herausgefunden, was passiert ist. Und jetzt wollen wir verstehen, mit welcher Ansicht, mit welcher Komponente dies passiert ist.
Nehmen Sie an unserem AccessibilityEvent teil.
Wir nehmen Source von ihm und, voila, wir haben bereits Metainformationen angezeigt.
Aber was ist, wenn Sie ein Hardcore-Entwickler sind und nicht genügend Informationen zu einer Ansicht haben, möchten Sie verstehen, was jetzt im Grunde auf dem Bildschirm passiert? Das SDK ist begrenzt, aber klein.

Wir nehmen unseren AccessibilityService und erhalten tatsächlich einen Verweis auf das Stammelement in der gesamten Hierarchie auf dem aktuellen Bildschirm. Und erst dann bekommen wir unsere Metainformationen zu sehen.

Das ist natürlich cool, aber jetzt sollten Sie eine Frage im Kopf haben: Nun, wir haben einen Link zum Root-Element. Was machen wir als nächstes?
Wenn Sie den sicheren Weg gehen wollen, dann bitte die erste Option. Nehmen Sie eine ID-Ansicht und finden Sie nur eine Methode.
Wenn es Ihnen irgendwie langweilig vorkommt, dass die Jagd etwas mehr Spaß macht, dann nehmen wir den Text aus der Ansicht, wir finden ihn aus dem Text.
Wenn das für dich nicht interessant genug ist - Leute, nimm Kind und Rekursion, geh drauf. Dann werden Sie genau verstehen, was passiert.
Großartig. Sie und ich haben herausgefunden, wie Sie eine Ansicht finden. Wie soll ich jetzt mit ihr interagieren?
Wieder nehmen wir unsere AccessibilityNodeInfo und werfen jetzt bereits Action hinein. Welche Aktion können wir dort werfen?

Zunächst können wir Click werfen. Warum habe ich hier nicht nur nach Klick, sondern auch Klick und Auswahl hier gesetzt? Ja, weil es eine Reihe von Eckfällen gibt, wenn der übliche Klick Sie nicht rettet. Angenommen, ein Benutzer wählt einen Text aus und durch Klicken auf die Ansicht wird die Auswahl sauber aus diesem Text entfernt. Auf einigen Geräten kann die Ansicht im Prinzip erst angeklickt werden, wenn Sie Select darauf aufrufen. Im Allgemeinen viele Probleme. Und wenn Sie nur ein Dampfbad nehmen möchten - wählen Sie, klicken Sie. Zwei Aktionen, und das ist alles, es gibt Glück.
Was kommt als nächstes bei uns? Und dann haben wir die Textinstallation. Auch hier ist alles einfach. Nehmen Sie Action_set_text, erstellen Sie ein Bundle mit unserer Linie und leben Sie.
Und der dritte Punkt ist die Dokumentation. Dies ist wieder der zweite Abend, den Sie haben werden. Eine Reihe von Aktionen direkt, meiner Meinung nach sogar mehr als Ereignisse.
Hurra! Der langweiligste Teil des Berichts ist vorbei. Jetzt ist es Zeit für alle Arten von Nishtyachkov.
Angenommen, Sie haben einen Dienst erstellt, konfiguriert und eine Art Ereignisverarbeitung ausgeführt. Jetzt müssen Sie verstehen, wie Sie den Benutzer zwingen und ihn bitten, diesen Dienst weiterhin zu aktivieren. Um dies zu verstehen, müssen Sie im Prinzip herausfinden, ob der Dienst jetzt aktiviert ist oder nicht.

Alles ist einfach bis zur Banalität. Wir nehmen den AccessibilityManager und fragen ihn nach allen derzeit im System enthaltenen Diensten. Dort finden wir unsere.
Aber natürlich wäre alles cool, wenn der AccessibilityManager ein normaler Typ wäre, und es gab keinen, bei dem Sie ihn fragen: "Alter, geben Sie mir bitte alle verfügbaren Dienste", und er sagt: "Entschuldigung, ich bin nicht heute in der Stimmung. Hier ist eine leere Liste für dich. “ Und du sitzt so und denkst: "Verdammt, wir haben normal geredet."

Nun, es gibt gute alte Freunde - das sind Settings.Secure.getInt und getString. Zuerst fragen wir, ob Dienste überhaupt im System enthalten sind. Wenn enthalten, wird alles in eine Zeile geworfen, und dort suchen wir bereits nach unseren Inhalten.
Und hier begegnen wir der Tatsache, dass wir alles richtig gemacht haben. Wir haben die Konfiguration erstellt, die Erstellung von Ereignissen erstellt und den Dienst aktiviert. Wir sehen mit Sicherheit, dass wir den Service eingeschaltet haben und keine Ereignisse zu uns kommen. Und so kommen sie entweder an oder kommen nicht an. In diesem Moment dachte ich, dass in meinem Leben eine Art schwarzer Streifen gekommen war. Richtig, es gab keine Optionen.
Ich dachte, dachte, reserched, reserched und dann, Bingo, wurde mir klar, dass dies Xiaomi mit ihrem MIUI ist. Das ist nur Jungs Schmerz! Das ist ernst.
Okay, verstehe, was das Problem ist. Wie kann ich es jetzt lösen? Leider wird bei einigen Firmware-Versionen in MIUI alles so ausgeführt, dass das System Ihren Dienst im Prinzip nicht einmal startet, wenn sich Ihre Anwendung nicht im automatischen Start befindet.

Aber hier ist eine Lösung: Wir bitten den Benutzer, Ihre Anwendung zum automatischen Start hinzuzufügen, und wir leben weiter und genießen das Leben.

Und dann kam die Kirsche auf den Kuchen. Warum ist dieser Dienst für Menschen mit Behinderungen so freundlich, ein Wolf im Schafspelz?
Es scheint mir, dass viele von Ihnen bereits vermutet haben, dass wir, wenn ein Benutzer diesen Dienst aktiviert, leicht viele vertrauliche Informationen von seinem Gerät stehlen können. Wir können es nicht nur stehlen, sondern auch irgendwo ablegen, z. B. den Bildschirm entsperren, wenn er mit einem PIN-Code gesperrt ist. Nun, ok, schalte den Bildschirm frei. Was weiter? Wir werben für uns selbst, wir werden viel Geld verdienen, wir werden sofort leben. Und am Ende können wir grundsätzlich alle Aktionen des Benutzers imitieren und beispielsweise eine Art Anwendung einfügen, ihr Administratorrechte erteilen und dem Benutzer sagen: „Auf Wiedersehen. Verabschieden Sie sich von Ihrem Gerät. “

Okay, wir können das alles machen, aber jetzt wirst du sagen: „Du bist natürlich gut gemacht. Er sagte uns, wie wir welche Art von Daten stehlen können. Aber wie bringt man den Benutzer dazu, Ihren AccessibilityService einzuschalten, und ob die Anwendung Linkshänder ist? “ Okay, der Benutzer, so scheint es mir, öffnet einfach die Einstellungen, versteht, dass dort eine Art Unsinn geschrieben ist, schließt, deinstalliert die Anwendung und vergisst. Und Sie wissen, Sie werden Recht haben, wenn der erste Weg, um die Systemeinstellungen einzuschalten, auf "Nein" geht, weil dies eine Art Unsinn ist. Und hier kommt uns eine Schwachstelle zu Hilfe, die im Wesentlichen als Clickjacking bezeichnet wird. Wie viele von euch kennen sich mit Clickjacking aus? Großartig, es wird interessant sein.
Aufgrund dieser Sicherheitsanfälligkeit haben einige Leute - ich habe eine kleine Referenz angegeben, da alle folgenden Screenshots aus den Ressourcen dieser Leute stammen - einen Angriff namens Cloak and Dagger entwickelt. Mit nur zwei Berechtigungen und minimaler Benutzerinteraktion erhalten Sie direkt über das Wort „vollständig“ Zugriff auf die gesamte Anwendung.
Aber ok, was müssen wir tun, um den Benutzer zu hacken?
Wir werfen unsere Anwendung auf Google Play. Wir hoffen, dass der Benutzer der Android-Version weniger als 8 ist.
Sie verstehen, ein bisschen - 95% im Moment. Und das ist alles, der Benutzer lädt unsere Anwendung herunter.

Kurz gesagt, diese Malware sagt dem Benutzer, wie man ein guter Kerl wird, und zeigt ganz am Ende ein Video. Jetzt sehen Sie alles selbst.

Ok, lass uns anfangen. Ein kleiner Text. Uns wird gesagt: "Wenn Sie jetzt mit dem Tutorial beginnen, werden Sie ein guter Kerl." Okay, natürlich fangen wir an.

Ein anderer Text. Außerdem werden Menschen in Form von grünen Männern präsentiert. Nun, ok, klicken wir auf Weiter.

Ein anderer Text. Okay. Jetzt werde ich es zu Ende lesen und auf jeden Fall ein Video sehen, in dem sie mir sagen, wie ich ein guter Kerl werden kann.


Ich klicke auf "OK" und dort startet das Video. Das ist uns nicht so wichtig. Es ist wichtig, was in diesem Moment wirklich auf dem Gerät passiert ist. Der Nutzer startet die Anwendung und da wir sie über Google Play installiert haben, wird uns automatisch die Berechtigung zum Überlagern erteilt. Voila, wir öffnen das Eingabehilfenfenster und überlagern es einfach. Der Benutzer klickt auf das Start-Tutorial, wählt jedoch tatsächlich unseren AccessibilityService aus. Nun, Sie verstehen, was als nächstes kommt.

Als nächstes klicken wir auf Weiter und wählen den Kippschalter.

Ganz am Ende schalten wir den AccessibilityService ein, und der Benutzer merkt nicht einmal, dass dies passiert ist.
Wissen Sie, wo das Problem liegt? Die Überlagerung ist so angeordnet, dass sie entweder alle Ereignisse vollständig absorbiert, alle Berührungen bereits weit entfernt sind oder vollständig fehlen. Und der Punkt dieses speziellen Angriffs ist, dass wir das Overlay füllen, den gesamten Bildschirm mit Ausnahme eines Leerzeichens. In diesem Fall ist dies die Schaltfläche OK. Diese Schaltfläche ist wirklich aus dem Dialog. Wenn wir darauf klicken, erhalten wir ein Ereignis, das besagt, dass eine Berührung draußen stattgefunden hat und alles in Ordnung ist.
Wie reagiert Google auf all diese Probleme? Sie verstehen, dies ist eine ziemlich brutale Sicherheitslücke.

Alles begann sehr interessant - alles mit acht Jahren Schweigen. Google enthüllte dieses kleine Ding und sagte: „Leute, benutzt es. Es ist sicher. Ich sage sicher. " Na gut. Google warf. Die gleichen Leute, die Cloak und Dagger erfunden haben, haben Unterstützung geleistet, Tracker und Bug-Tracker ausgegeben.
Dann sagte Google: „Okay, okay Leute, beruhigt euch. Ich werde Clickjacking in Oreo schließen. " Nun, mach es aus. Sie sitzen immer noch da und denken: „Verdammt, Leute, egal, wenn Angreifer den Benutzer zwingen, die Zugänglichkeit zu aktivieren, wird es schlecht. Lassen Sie uns die Entwickler ein wenig verspotten.
Und sie senden einen Brief: "Tun Sie es, ich weiß nicht was, sonst wird Ihre Bewerbung aus Google Play gelöscht." Kurz gesagt lautete der Brief wie folgt: „Leute, sagt uns und den Benutzern, warum ihr AccessibiiltyService brauchst.“ Wie kann man das sagen? In welchem Format? Wo? Im Allgemeinen kein Verständnis. Und in dem Brief ist dies natürlich nicht angegeben.
Na gut. Riesige Fäden auf reddit, ein paar Briefe zur Unterstützung. Und dann schreibt ein Entwickler einen Brief auf reddit und sagt: „Ja, Leute, nichts Kompliziertes. Fügen Sie es in die Beschreibung ein, die ich Ihnen gezeigt habe, und geben Sie es in die Beschreibung von Google Play ein. Alles wird gut, ich werde Sie in Ruhe lassen. "
In diesem Moment dachte ich: Okay, ich habe diesen Brief an einer Seitenlinie von Reddit gefunden. Aber was ist, wenn ich ein junger Entwickler bin, ich habe gerade AccessibilityService kennengelernt und möchte die Anwendung damit freigeben? Wie soll ich herausfinden, dass ich solche Aktionen ausführen muss, muss ich sie in der Beschreibung bei Google Play usw. ablegen? Ich dachte, dachte, suchte, suchte und, weißt du, Leute, ich habe überhaupt nichts gefunden.
Im Ernst, es gibt nichts. In der Hauptdokumentation gibt es nur eine Beschreibung: "Leute, das ist nur für Menschen mit Behinderungen, das ist der Punkt. Du kannst es nicht mehr benutzen. " Aber tatsächlich stellt sich heraus, dass es möglich ist.

Nun, du und ich sind zu Ende gegangen. Was könnten wir mit dir reden? Wir haben darüber gesprochen, wie man es verwendet, wie man alles erstellt, konfiguriert und wie man mit UI-Ereignissen umgeht. Natürlich haben wir verstanden, wie dies möglich ist, aber Sie müssen nicht mit dem AccessibilityService interagieren. Natürlich empfehle ich Ihnen nicht, dies zu tun, es war nur zur Information. Hier sind die versprochenen Quellen:
-
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.orgLeute, vielen Dank für eure Aufmerksamkeit!