Transferencia segura de datos entre dos aplicaciones.

Hola a todos, hoy me gustaría contarles algunas opciones para transferir datos entre dos aplicaciones de Android y considerarlas desde un punto de vista de seguridad. Decidí escribir este artículo por dos razones. Primero, a menudo comencé a encontrar una falta de comprensión de los desarrolladores de los mecanismos para trabajar con los componentes de una aplicación de Android. El segundo: dejé de entender en qué se basa la elección de este o aquel mecanismo al implementar las características y quería transmitir cómo debería verse al mínimo.

Desafío

Tenemos 2 aplicaciones que acceden a la misma API. Los clientes pueden acceder a la API mediante token de acceso (sessionId). Debe implementar una transición perfecta de una aplicación a otra. Para hacer esto, debe buscar entre ellos, por ejemplo, dejar que sea sessionId.

Opción n. ° 1: CONSULTA DE REFERENCIA

La opción más obvia es transferir el token a Query DeepLink. Se verá más o menos así:
slave://main?sessionId=686A885A4FB644053C584B9BE2A70C7D
En este caso, el destinatario podrá extraer sessionId y usarlo sin solicitar autorización del usuario. Desde el lado del desarrollador, parece que la tarea se ha completado, pero profundicemos un poco más.

Secuestro de Deeplink


Como cualquier aplicación puede registrar el esquema tinkoff: //, el sistema operativo puede abrir la aplicación incorrecta. Esto es posible debido al hecho de que no hay registro y restricciones en el uso de esquemas. Una aplicación maliciosa puede registrar el esquema tinkoff: // e interceptar la solicitud a la aplicación Tinkoff e iniciarse. En este caso, sessionId caerá en las manos equivocadas y su cuenta se verá comprometida. Además, DeepLink Hijacking le permite realizar phishing, por ejemplo, mostrar campos para ingresar un nombre de usuario y contraseña.

Conceptualmente, el proceso se ve así:

imagen

Hay 2 soluciones a este problema. Primero, la tecnología AppLinks ya no permite a los desarrolladores personalizar el esquema; en su lugar, se usa http / https. En este caso, el sistema operativo toma el enlace slave.com/profile y se pone en contacto con el host slave.com para su verificación. El segundo, URL de intención, en lugar de llamar a slave: //, se llama a intent: //, donde se pasa el identificador único de la aplicación que se iniciará. Se ve así:

 intent://main/#Intent;scheme=slave;package=com.example.slave.client.android;end" 

En este caso, no será posible interceptar el lanzamiento de la aplicación, ya que se especifica un paquete específico. Aún así, el problema sigue siendo que el usuario puede instalar la aplicación desde una fuente de terceros con el mismo Id. De paquete que su esclavo. En este caso, si no tenía una aplicación esclava legítima, la aplicación maliciosa instalará y recibirá su token.

Fijación de la sesión


Este es un ataque en el que un atacante obliga al cliente a establecer una sesión con el software de destino utilizando el Id. De sesión proporcionado por el atacante. Tan pronto como el usuario se autentique, el atacante podrá usar este identificador ya privilegiado para sus propios fines. El ataque explota el hecho de que el software de destino utiliza el mismo Id. De sesión después de la escalada de privilegios.


Cómo se ve en nuestro caso:

  1. el atacante obtiene sesión anónima de la aplicación
  2. lanza bellamente una carta a la víctima en nombre del banco, en la que se le invita a ir a su cuenta personal
  3. Al hacer clic en el enlace, llegamos a DeepLink con un esclavo de sesión de atacante: // main? sessionId = 686A885A4FB644053C584B9BE2A70C7D
  4. la aplicación móvil toma una sesión, entiende que no tiene suficientes derechos y le pide al usuario que se autentique
  5. el usuario lo pasa, la sesión tiene mayores derechos
  6. usuario en la aplicación, un atacante con una sesión privilegiada, ganancia

Sería correcto corregir esto en la API, emitiendo otro sessionId después de la escalada de privilegios, pero estamos escribiendo una aplicación móvil. Y nuestra forma es negarnos a transferir la ficha de maestro a esclavo. Además, esto nos dará una protección profunda y, si algo se rompe en la API y los tokens no cambian cuando se aumentan los privilegios, entonces un ataque seguirá siendo imposible.

Fuga de terceros


Otra desventaja de esta opción. Muchas personas usan servicios de terceros para DeepLink debido a la conveniencia de generar enlaces, análisis y otras cosas interesantes. En este caso, simplemente le da su token a una empresa de terceros.

Opción # 2: PROVEEDOR DE CONTENIDO

¿Cómo lo haremos? Definimos el proveedor de contenido maestro y hacemos que el esclavo vaya a este proveedor de contenido para el token.



Por lo tanto, nos deshacemos del riesgo de transferir el token a la aplicación incorrecta en el caso de DeepLink Hijacking y hacemos imposible el ataque de Sesión Fija. Pero tenemos otros problemas: en la versión actual, en general, cualquier aplicación puede solicitar un token en cualquier momento, incluso si no iniciamos su lanzamiento.

Nivel de protección


En la mayoría de los casos, debe verificar que el esclavo esté firmado con la misma clave que el maestro, es decir, que pertenecen al mismo autor. Para este caso, el administrador de paquetes tiene un método checkSignatures que verifica las firmas de la aplicación. Para usar esta función, debe agregar permiso con protectionLevel = "signature" en Content-Provider en el manifiesto de la aplicación:

 <permission android:name="com.example.contentprovider.access" android:protectionLevel="signature"/> <application> <provider ... android:readPermission="com.example.contentprovider.access"> </application> 

El esquema apenas cambiará de la figura anterior, solo aparecerá una garantía de que solo las aplicaciones con una firma del mismo autor tendrán acceso al token.

Permiso Condición de carrera


Hay una característica muy desagradable que los nombres de permisos no son únicos, que pueden ser utilizados por una aplicación maliciosa y registrar permisos con nuestro nombre y nivel de protección = "normal" delante de nosotros. En este caso, al instalar nuestra aplicación, el permiso ya existirá en el sistema operativo y no se sobrescribirá. En consecuencia, nuestro proveedor de contenido permanecerá desprotegido y con acceso autorizado desde cualquier aplicación.

Diferentes firmas


Desafortunadamente, las aplicaciones no siempre se firman con la misma clave, por ejemplo, algunas de las aplicaciones se compran, o "históricamente", pero aún se necesita una transición sin problemas. En este caso, tomamos la verificación de firma de nosotros mismos.
¿Cómo se puede implementar esto?
Content-Provider tiene un método getCallingPackage (), mediante el cual podemos obtener el packageId de la aplicación que ha solicitado datos, y por packageId podemos obtener una lista de firmas y verificarlas con las incorporadas.

 String pkg = this.getCallingPackage(); PackageInfo pkgInfo = pkgmgr.getPackageInfo(pkg, GET_SIGNATURES); Signatures[] signatures = pkgInfo.signatures; for (Signature sig: signatures) { if (sig.equals(TRUSTED_SIGNATURE)) { // trusted signature found, trust the application } } 



Parece que hicimos todo perfectamente, pero no.

Vulnerabilidad de identificación falsa


El problema es que cuando Android crea una cadena de confianza, el proceso de verificación solo compara el tema y no verifica la firma en el campo del firmante del certificado. Como resultado, un atacante puede construir una cadena de confianza sin una firma real.

Debido a este error, se genera una cadena de certificados incorrecta, que puede incluir certificados legítimos integrados en el APK, pero que en realidad no se utilizan para firmar la solicitud. Al final, dejaré un enlace al commit que corrige esta vulnerabilidad. El problema se solucionó en Android 4.4, por lo que solo podemos elevar el nivel de API a 19.

Conclusiones

Hoy examinamos cómo se deben analizar las características durante el desarrollo.
También examinamos las opciones para transferir el secreto entre dos aplicaciones, durante las cuales analizamos los problemas de cada opción y encontramos formas de evitarlos.

Todas las aplicaciones seguras!

Referencias

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


All Articles