Accesibilidad de Android: ¿un lobo con piel de cordero? Conferencia de Yandex

Hace un mes, en la próxima Fiesta Droid, el desarrollador senior Danila Fetisov examinó en detalle el principio del servicio, que es responsable de las funciones de accesibilidad de Android. Aprenderá cómo usarlo para mejorar la accesibilidad de sus proyectos, así como una vulnerabilidad peligrosa llamada clickjacking.


- Mi nombre es Danila Fetisov, soy de la oficina de Moscú de Yandex, más específicamente de Taxi, más específicamente de Taxímetro. Hoy hablaremos sobre qué es la accesibilidad de Android y por qué decidí llamar a una cosa tan sagrada para las personas con discapacidad un lobo con piel de cordero.



Entonces, el resumen del informe. Primero, veremos cómo se puede usar, crear y personalizar esta cosa. Tal vez te cuente un par de trucos para la vida, nishtyaks de supermercado. Y luego sobre lo más interesante: sobre por qué esto es peligroso.

¿Cómo podemos aplicar esto? En general, ¿qué es para aquellos que no saben? Cualquier evento ocurre en el sistema, cae en nuestro servicio y los procesamos.

Una vez que algo se enamora de nosotros, podemos tomar el contenido desde allí y expresarlo usando el mismo Yandex SpeechKit, Google Text-to-Speech o algo más que le guste. Pero lo que es más interesante, no solo podemos recibir, sino también lanzar un evento del sistema. Aún puedes decir algo. Lanzó el evento, presionó el botón, y todo está bien, disfruta de la vida.

Si hablamos de estos dos puntos, de hecho, están predeterminados. Google lanzó esta función para que las personas con discapacidad puedan usar su aplicación. Pero como todos saben, los desarrolladores no queremos aburrirnos: nos sentamos, miramos el código y pensamos: ¿cómo podemos aplicarlo? Y nos vamos.

Automatización, pruebas simulando acciones del usuario, publicidad contextual. Usted comprende: dado que obtenemos contenido de la pantalla, podemos entender cómo frustrar a este usuario.

¿Qué más es interesante? Procesamiento de solicitudes USSD. Desafortunadamente, la API normal apareció solo desde el 26 SDK, y los desarrolladores de alguna manera necesitan sobrevivir. Y te imaginas, están analizando seriamente las solicitudes de USSD, analizando las IU utilizando el servicio de accesibilidad.

El sexto punto es la elipsis. Por qué Porque después de este informe, comprenderá cómo aplicarlo y para qué. Y luego, literalmente, abre su flujo de imaginación, toma una taza de té, café y conduce para codificar sus características geniales.

Por donde empezar La próxima diapositiva será dolorosamente común.


Tomamos un servicio, heredamos de AccessibilityService y disfrutamos de la vida.

Luego lanzamos este servicio en Manifiesto, y ¿qué es lo interesante aquí? Esencialmente un registro de servicio regular. Pero preste atención al campo de la etiqueta. Ahora no diré de qué se trata. Recuerde, esto será un poco más tarde.



Más adelante, en Manifiesto, solo tenemos un archivo de configuración, nada interesante tampoco.


Y el archivo de configuración en sí parece un poco más terrible. De lo que necesitará, lo más probable es que el 85–90 por ciento sea el campo de configuración de filtro para los eventos entrantes.

Digamos que vale la pena que queramos recibir absolutamente todos los eventos. Puede colocar un filtro solo en los clics, en el cambio de contenido o en otra cosa.

El siguiente es un filtro para paquetes de aplicaciones. ¿Para qué es esto? Usted mismo comprende perfectamente que recibir eventos de absolutamente todas las aplicaciones en el sistema sería demasiado para una sola aplicación. Por lo tanto, Google decidió limitarlo de alguna manera. Se agregó un filtro.

Descripción adicional Había un campo de etiqueta, y ahora usa la descripción. De hecho, crean un par, que luego le dice al usuario por qué necesita habilitar su servicio.

Y el último punto: el contenido es necesario o no desde la ventana abierta actual. Si solo desea comprender que se ha producido un evento, configúrelo como falso y no vuelva a atormentar al usuario.


La inclusión del servicio. Desafortunadamente, para habilitar esta función, tendrás que torturar al usuario y obligarlo a pasar por siete círculos de infierno, relativamente hablando.

Primero, abrimos oportunidades especiales para él. Cool AccessibilityService: esta es exactamente la misma etiqueta del manifiesto, de la que te hablé en las diapositivas anteriores.


Más lejos. El usuario debe seleccionar su servicio, y luego comienza a leer la descripción, ¿por qué desea habilitar este servicio y obtener cierto control sobre el dispositivo?


OK, incluye. Pero ahí estaba. Aparece algún tipo de diálogo aterrador que dice: "Amigo, si lo enciendes ahora, tomaremos el control total de tu aplicación, en términos relativos, todo será aterrador". Los usuarios no siempre leen todo esto, simplemente haga clic en "Aceptar" para que estemos detrás de ellos. Entonces vivimos.

Bueno, ¿dónde está el procesamiento del evento de hecho? La siguiente diapositiva es un poco más inteligente que la primera diapositiva sobre el servicio, pero no obstante.


Aquí está nuestro DummyAccessibilityService, y colocamos dos métodos allí, en los que escribiremos todo. De hecho, la interrupción es un método en el que tienes que limpiar tus enlaces, detener las suscripciones u otra cosa.

Lo más interesante es la clase AccessibilityEvent, que nos corresponde. ¿Qué podemos sacar de eso?

Para empezar, podemos entender lo que realmente sucedió en su sistema. Tomamos EventType, y ¿qué obtenemos aquí?

Y entendemos que tenemos algún tipo de Actividad abierta, o Diálogo, o Ventana emergente, o en general, la notificación ha caído. Todo cae justo allí en window_state_changed.

Además, entendemos que el contenido de algunas vistas ha cambiado. Lo movieron, arrojaron una línea en la vista de texto o algo así.

Y luego descubrimos cuándo el usuario hace clic o selecciona una vista. En mi opinión, 85, e incluso 98, probablemente, el porcentaje de las principales tareas del producto que cubre con estos tipos de eventos.

Pero si no tiene suficientes, por favor, puede ir a la documentación, le mostraré un enlace al final del informe y, por supuesto, descargará el informe, puede continuar. Es solo una lectura para toda la noche, hay una lista enorme. En serio, no lo dominarás a la vez.

Ahora tenemos una pregunta: ¿cómo encontrar una vista? Descubrimos lo que pasó. Y ahora comprendamos con qué vista, con qué componente sucedió esto.

Tome nuestro Evento de Accesibilidad.

Tomamos Source de él y, voila, ya tenemos meta-información visual.

Pero, ¿qué pasa si eres un desarrollador incondicional y no tienes suficiente información sobre una vista, quieres entender qué está sucediendo básicamente en la pantalla ahora? Hay una limitación en el SDK, pero es pequeño.

Tomamos nuestro AccessibilityService y, de hecho, obtenemos una referencia al elemento raíz en toda la jerarquía en la pantalla actual. Y solo entonces tenemos nuestra metainformación a la vista.

Esto, por supuesto, es genial, pero ahora deberías tener una pregunta en tu cabeza: bueno, tenemos un enlace al elemento raíz. ¿Qué hacemos a continuación?

Si quieres ir por el camino seguro, entonces, por favor, la primera opción. Tome una vista de ID y solo encuentre un método.

Si le parece que de alguna manera es aburrido, cazar es algo más divertido, entonces tomamos el texto de la vista, lo encontramos en el texto.

Si esto no es lo suficientemente interesante para ustedes, bueno, muchachos, tomen Child and Recursion, párense sobre él. Entonces entenderás exactamente lo que está sucediendo.

Genial Tú y yo descubrimos cómo encontrar una vista. ¿Cómo ahora interactuar con ella?

Una vez más, tomamos nuestro AccessibilityNodeInfo, y ahora ya estamos lanzando Action en él. ¿Qué acción podemos lanzar allí?

Para empezar, podemos lanzar Click. ¿Por qué al final puse aquí no solo después de Click, sino también Click and Select? Sí, porque hay un montón de casos de esquina, cuando el clic habitual no te salva. Supongamos que un usuario selecciona un texto y al hacer clic en la vista eliminará limpiamente la selección de ese texto. O, en algunos dispositivos, en principio, no se puede hacer clic en la vista hasta que llame a Seleccionar en ella. En general, muchos problemas. Y si solo desea tomar un baño de vapor, seleccione Seleccionar, haga clic. Dos acciones, y eso es todo, hay felicidad.

¿Qué sigue con nosotros? Y luego tenemos la instalación de texto. Aquí, también, todo es simple. Tome Action_set_text, cree un paquete con nuestra línea y viva.

Y el tercer punto es ir a la documentación. Nuevamente, esta es la segunda noche que tendrá. Un montón de acciones directamente, en mi opinión, incluso más que eventos.

¡Hurra! La parte más aburrida del informe ha terminado. Ahora es el momento para todo tipo de nishtyachkov.

Suponga que creó un servicio, lo configuró y lanzó algún tipo de procesamiento de eventos. Ahora debe comprender cómo forzar al usuario, cómo pedirle que todavía habilite este servicio. Para comprender esto, debe averiguar, en principio, que el servicio está activado o no.


Todo es simple hasta el punto de banalidad. Tomamos el AccessibilityManager y le pedimos todos los servicios incluidos actualmente en el sistema, y ​​allí encontramos el nuestro.

Pero, por supuesto, todo sería genial si el AccessibilityManager fuera un chico normal, y no hubiera tal cosa que le preguntes: "Amigo, dame, por favor, todos los servicios disponibles", y él dice: "Lo siento, no estoy hoy en el estado de animo Aquí hay una lista vacía para ti. Y estás tan sentado y pensando: "Maldición, hemos hablado normalmente".


Bueno, hay buenos viejos amigos: estos son Settings.Secure.getInt y getString. Primero preguntamos si los servicios están incluso incluidos en el sistema. Si se incluye, todo se lanza en una línea, y allí ya estamos buscando el nuestro a través de algún tipo de contenido.

Y aquí nos encontramos con el hecho de que hicimos todo bien. Creamos la configuración, creamos la construcción de cualquier evento, activamos el servicio. Vemos con certeza que activamos el servicio, y los eventos no nos llegan. Y entonces, o llegan o no llegan. En ese momento, pensé que en mi vida había aparecido una especie de raya negra. Justo no había opciones.

Pensé, pensé, investigé, investigué, y luego, bingo, me di cuenta de que esto es Xiaomi con su MIUI. Eso es solo muchachos dolor! Eso es serio

De acuerdo, entiende cuál es el problema. ¿Cómo resolverlo ahora? Desafortunadamente, en algunos firmware en MIUI todo se hace de modo que si su aplicación no está en el inicio automático, el sistema ni siquiera iniciará su servicio en principio.


Pero aquí hay una solución: le pedimos al usuario que agregue su aplicación al inicio automático, y seguimos viviendo, disfrutando la vida.

Y luego vino la guinda del pastel. ¿Por qué este servicio, tan amable para las personas con discapacidad, es un lobo con piel de cordero?

Me parece que muchos de ustedes ya han adivinado que si un usuario activa este servicio, podemos robar fácilmente mucha información confidencial de su dispositivo. No solo podemos robarlo, sino que también podemos soltarlo en algún lugar, por ejemplo, desbloquear la pantalla si está bloqueado con un código PIN. Bueno, ok, desbloquea la pantalla. Que sigue Nos publicitamos a nosotros mismos, ganaremos mucho dinero, viviremos de inmediato. Y, al final, básicamente podemos imitar absolutamente cualquier acción del usuario y, por ejemplo, poner algún tipo de aplicación, otorgarle derechos de administrador y decirle al usuario: “Adiós. Diga adiós a su dispositivo ".

Bien, podemos hacer todo esto, pero ahora dirás: “Tú, por supuesto, bien hecho. Nos dijo cómo podemos robar qué tipo de datos. ¿Pero cómo hace que el usuario encienda su AccessibilityService y si la aplicación es zurda? Bien, el usuario, me parece, simplemente abre la configuración, entiende que hay algún tipo de tontería escrita allí, cierra, desinstala la aplicación y se olvida. Y sabes, tendrás razón en que la primera forma de activar la configuración del sistema es "no", porque, ya sabes, esto es una especie de tontería. Y aquí viene una vulnerabilidad en nuestra ayuda, que, en esencia, se llama clickjacking. ¿Cuántos de ustedes están familiarizados con el clickjacking? Genial, será interesante.

Entonces, en base a esta vulnerabilidad, algunos tipos, pongo una pequeña referencia, porque todas las siguientes capturas de pantalla serán de los recursos de estos tipos, se les ocurrió un ataque llamado Cloak and Dagger. De hecho, con solo dos permisos y una mínima interacción del usuario, obtienes acceso a toda la aplicación directamente desde la palabra "completamente".
Pero bueno, ¿qué debemos hacer para hackear al usuario?

Estamos lanzando nuestra aplicación en Google Play. Esperamos que el usuario de la versión de Android tenga menos de 8.

Entiendes, un poco - 95% en este momento. Y eso es todo, el usuario descarga nuestra aplicación.


En resumen, este malware le dice al usuario cómo convertirse en un buen tipo, muestra un video al final. Ahora verás todo por ti mismo.


Ok, empecemos. Un pequeño texto Se nos dice: "Si comienzas el tutorial ahora, te convertirás en un buen tipo". Bien, por supuesto, estamos empezando.


Algún otro texto. Además, las personas se presentarán en forma de hombres verdes. Bueno, ok, hagamos clic en Siguiente.


Otro texto Bien Ahora terminaré de leerlo y definitivamente veré un video en el que me dirán cómo convertirme en un buen tipo.



Hago clic en "Aceptar" y ahí comienza el video. Esto no es tan importante para nosotros. Es importante lo que realmente sucedió en el dispositivo en ese momento. El usuario inicia la aplicación, y desde que la instalamos desde Google Play, automáticamente se nos otorga permiso para superponer. Voila, abrimos la ventana de accesibilidad, y en la parte superior solo se superpone. El usuario hace clic en el Tutorial de inicio, pero en realidad selecciona nuestro Servicio de accesibilidad. Bueno, entiendes lo que sigue.


A continuación, hacemos clic en Siguiente, seleccionamos el interruptor de palanca.


Al final, activamos el AccessibilityService, y el usuario ni siquiera se da cuenta de que esto sucedió.

¿Sabes cuál es el problema? La superposición se organiza de tal manera que absorben completamente todos los eventos, todos los toques ya están muy lejos o se pierden por completo. Y el objetivo de este ataque en particular es que llenamos la superposición, toda la pantalla, excepto un espacio. En este caso, este es el botón Aceptar. Este botón es realmente del diálogo. Cuando hacemos clic en él, tenemos un evento que dice que ha ocurrido un toque externo y que todo está bien.

¿Cómo responde Google a todos estos problemas? Entiendes, esta es una vulnerabilidad bastante brutal.

Todo comenzó de manera bastante interesante, todo con ocho años de silencio. Google dio a conocer esta pequeña cosa, dijo: "Chicos, úsela. Es seguro Lo digo con seguridad. Bien Google lanzó. Los mismos tipos que Cloak y Dagger inventaron, brindaron apoyo, rastreadores de problemas y rastreadores de errores.

Entonces Google dijo: "Está bien, está bien chicos, cálmense. Cerraré clickjacking en Oreo ". Bueno, apágalo. Todavía se sientan allí, piensan: “Bueno, maldición, muchachos, de todos modos, si los atacantes obligan al usuario a habilitar la accesibilidad, será malo. Vamos a burlarnos un poco de los desarrolladores.

Y envían una carta: "Hazlo, no sé qué, de lo contrario tu aplicación se eliminará de Google Play". En resumen, la carta era la siguiente: "Chicos, díganos a nosotros y a los usuarios por qué necesita AccessibiiltyService". ¿Cómo saberlo? ¿En que formato? Donde En general no hay comprensión. Y en la carta, por supuesto, esto no está indicado.

Bien Enormes hilos en reddit, un montón de cartas para apoyar. Y luego, un desarrollador pone una carta en reddit y dice: “Sí, muchachos, nada complicado. Póngalo en la descripción que le mostré, en manifiesto, póngalo en la descripción en Google Play, y todo estará bien, lo dejaré solo ".

En ese momento pensé: bueno, está bien, encontré esta carta al margen de Reddit. Pero, ¿qué sucede si soy un desarrollador joven y me acabo de familiarizar con AccessibilityService y quiero lanzar la aplicación con esto? ¿Cómo debo saber que necesito realizar tales acciones? ¿Tengo que incluirlo en la descripción de Google Play, etc.? Pensé, pensé, busqué, busqué y, ya saben, muchachos, no encontré nada, de la palabra en absoluto.

Bueno, en serio, no hay nada. Solo hay una descripción en la documentación principal: "Chicos, esto es solo para personas con discapacidades, ese es el punto. Ya no puedes usarlo ". Pero de hecho, resulta que es posible.

Bueno, tú y yo hemos llegado a su fin. ¿Qué podríamos hablar contigo? Hablamos sobre cómo usarlo, entendimos cómo crearlo todo, configurarlo y cómo manejar eventos de IU. Y, por supuesto, entendimos cómo es posible, pero no necesita interactuar con el AccessibilityService. Por supuesto, no te recomiendo que hagas esto, fue solo para información. Aquí están las fuentes 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.org

Chicos, muchas gracias por su atención!

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


All Articles