Paulatinamente, las empresas empezaron a adoptar ciclos de desarrollo seguro y programas de recompensa ―también conocidos como programas de bugbounty―, por el descubrimiento de vulnerabilidades como la mejor manera de prevenir y mitigar los riesgos asociados a la liberación de software. No obstante, mientras algunos fallos reciben nombres propios y permanecen en las portadas de sitios de tecnología durante días y hasta semanas, otras fallas de seguridad suelen ser desestimadas por los fabricantes.

En el mundo del desarrollo, la corrección de una falla depende del riesgo que esta conlleve, es decir, de qué tan crítico es su impacto y qué tan probable es que sea explotada in the wild. Los desarrolladores de apps móviles han entendido hace tiempo lo desastroso que puede ser un error de seguridad que habilite ataques desde canales externos y –mayormente– invierten mucho esfuerzo en diseñar mecanismos seguros para la transferencia de datos y el manejo de interacciones vía Internet. Pero ¿qué ocurre con la comunicación intranet, con las redes PAN, con el almacenamiento interno, con el equipo donde se ejecuta ese aplicativo, con los puertos expuestos que ese hardware pueda tener?

A continuación, analizaremos algunos errores que parecen repetirse entre apps móviles, asociados a la presunción de que el entorno de producción es seguro.

#1. Descuidar el almacenamiento interno

El Open Web Application Security Project (OWASP) es uno de los estándares que suele tenerse en cuenta para realizar procesos de pentesting. OWASP mantiene un documento que detalla los diez tipos de vulnerabilidades más comunes y, por tanto, importantes en diferentes plataformas, incluidos los sistemas operativos móviles.

El almacenamiento inseguro de datos es una de esas categorías de fallos de seguridad que vemos seguido al analizar apps y se relaciona con almacenar datos de la aplicación, que debiesen ser secretos, a los cuales pueden acceder otras apps o el usuario. Esto puede ocurrir, por ejemplo, al guardarlos en las preferencias compartidas, bases de datos SQLite en texto plano o en almacenamiento externo.

Debe tenerse en cuenta que, incluso si los datos son guardados en el almacenamiento interno de la aplicación –es decir, aquella carpeta privada que el sistema crea para que sea accedida solo por esa app en particular–, esos archivos podrían ser accedidos por una aplicación maliciosa o atacante simplemente rooteando el terminal.

Imagen 1. Malware móvil con capacidad de rootear el teléfono.

Analicemos un caso práctico: la app de Gmail para Android. Esta aplicación negocia tokens de autenticación con la mayor parte de los proveedores de mensajería electrónica conocidos, tales como Outlook, Hotmail, Exchange, Yahoo, Yandex, FastMail y otros proveedores, incluido Gmail, por supuesto. No obstante, cuando la aplicación es forzada a conectar con una cuenta de servidores particulares con los que no puede negociar un token, entonces almacena las credenciales de acceso en texto plano en una base de datos en la carpeta de almacenamiento interno.

En la siguiente captura podemos que ver que las credenciales sin cifrar se encuentran en la ruta  /data/data/com.google.android.gm/databases/EmailProvider.db, en la tabla HostAuth.

Imagen 2. Credenciales en texto plano en las bases de datos de la app de Gmail para Android.

Muchos usuarios configuran sus cuentas corporativas utilizando Gmail, accediendo a servidores que no permiten la generación de tokens. Infortunadamente, el comportamiento anteriormente descrito podría poner en peligro las credenciales de acceso del usuario ante un atacante capaz de obtener una shell con privilegios de root. Más aún, siendo tan sencillo hoy en día utilizar mecanismos de almacenamiento seguro, es un riesgo innecesario.

El atacante podría construir un escenario exitoso de ataque explotando una vulnerabilidad del sistema (por ejemplo, Metaphor), una aplicación con privilegios elevados (como ocurrió con la vulnerabilidad en Samsung SwiftKey) o una app de usuario; también instalando un rootkit mediante Ingeniería Social o un malware en un teléfono previamente rooteado, o cualquier combinación de lo anterior.

Consideremos el siguiente video. En él se observa un ataque que inicia con una Wi-Fi Pineapple, explota la versión vulnerable de una aplicación (un conocido fallo de AirDroid que hace tiempo fue parchado), instala un payload generado con msfvenom y consigue el acceso al correo electrónico corporativo en él configurado.

Video 1. Ejemplificación de un escenario de ataque móvil.

#2. Descuidar protecciones físicas

Muchas aplicaciones móviles que manejan información sensible suelen permitir a sus usuarios establecer una contraseña para bloquear el uso de la app ante personas no autorizadas. No obstante, esas contraseñas suelen ser números de cuatro dígitos y, en la gran mayoría, sin ningún tipo de protección o delay contra fuerza bruta. Asumiendo que un atacante tiene acceso físico a un teléfono, solo bastaría con conectar un bad USB (Bash Bunny, Ninja USB, o cualquier otro) durante algunas horas para sobrepasar esas protecciones y lograr el acceso a la funcionalidad principal. En el siguiente video se observa este tipo de ataque sobre una app de control de un juguete sexual perteneciente a la marca We-Vibe.

Video 2. Bruteforcing de un PIN dedicado a la protección ante accesos no autorizados en la app We Connect.

#3. Descuidar transferencia de datos en la red interna

Mientras que las interacciones entre una app y los recursos en la nube son vistos como operaciones riesgosas dignas de un testeo de penetración, las interacciones entre dispositivos dentro de la misma LAN suelen basarse en la presunción de que no existe un actor malicioso espiando las conexiones. No es raro encontrar equipos con API que permiten el control absoluto sin ningún tipo de autenticación –lo que parece ser aún más frecuente en dispositivos IoT–, conexiones BLE sin ningún tipo de autenticación o credenciales de acceso a servicios en la nube transmitiéndose sin cifrado en la red. Este último es el caso de la aplicación TP-LINK tpCamera, donde podemos observar usuario y contraseña siendo transferidos simplemente codificados en base 64.

Imagen 3. Captura de tráfico con credenciales transmitiéndose en base 64.

#4. Descuidar el anonimato de los usuarios

Con el transcurrir de los años, las apps han ido ganando terreno sobre la intimidad de las personas, al punto en que hoy existen aplicaciones destinadas a las diferentes expresiones de la sexualidad en el mundo virtual: citas, sexting, videoconferencias y control remoto de juguetes sexuales. A medida que la información que se maneja se vuelve más sensible, mantener el resguardo de la privacidad del usuario es una tarea crítica para los desarrolladores.

La utilización de ID que permiten la identificación pública de un usuario, como ser un correo electrónico, puede ser una afronta a la privacidad si ese dato se comparte entre teléfonos que se presumen seguros sin certeza de que lo sean.

Por ejemplo, la siguiente captura de pantalla pertenece a las preferencias compartidas de la aplicación de Lovense, donde pueden observarse las direcciones de correo electrónico que se esconden detrás de nombres de usuarios ficticios con los que un hipotético atacante ha estado chateando, sirviendo como pie para la recolección de información en línea sobre esos usuarios y posteriores ataques vía Ingeniería Social, pudiendo derivar en sextorsión.

Imagen 4. Preferencias compartidas de la app de Lovense para sexting donde se publica información sensible de otros usuarios.

 

¿Qué podemos aprender de esto? Queda claro que no basta con implementar barreras de protección que sean efectivas solo bajo el supuesto de que el equipo permanecerá seguro. Cuando se trata de aplicaciones que manejan información sensible, debemos siempre considerar la posibilidad de que el terminal se vea comprometido mediante malware o un usuario mal intencionado, diseñando los mecanismos de seguridad necesarios para contrarrestar la situación.

Anexo

Código para ejecutar bruteforcing de un PIN de cuatro dígitos con un Bash Bunny.

[bash]

LED R

ATTACKMODE HID

for pin in {0000..9999}

do

Q STRING $pin

Q DELAY 500

done

LED G

[/bash]