Construyendo un Botnet en Android

Hace un par de meses, me presentaron una propuesta de una app móvil y me comentaron sobre su funcionamiento, durante el proceso me di cuenta que ésta no era una app empresarial, ni para un startup, ésta app estaba destinada como malware. Una app que cumple alguna función utilitaria, sincronizando todos tus datos con el desconocimiento del usuario. Al final lo construí por curiosidad, explicaré como construí este botnet de información mediante un ejemplo básico de código llamado Baby Bot.
Recordando sobre informática distribuida
En el año 2000 se da la primera chispa sobre los botnets. El joven llamado Michael Cale apodado Mafia Boy, sobrecargó las peticiones de los sitios web hasta que los sistemas de Yahoo, ETrade, Dell, eBay, Amazon colapsaran. No uso una botnet para su fechoría, pero expertos de seguridad aseguraron que un grupo grande de computadoras con un ataque de DDoS podía tener grandes repercusiones.
¿Como lograr un grupo grande de computadores?. Para ello ARPANET a principios del año 2000, tenía una gran cantidad de proyectos voluntarios y comunitarios, que permitían que muchos de sus usuarios donaran tiempo de inactividad en sus computadoras para estudiar enfermedades, estudiar el calentamiento global, buscar vida extraterrestre y hacer investigaciones de tipo científico, llamada informática distribuida. En el lado opuesto de la idea de informática distribuida voluntaria se encuentra un Botnet.
Una Botnet es una red informática distribuida donde los propietarios de las computadoras participantes no saben que sus computadoras están participando en la red.
Generalmente utilizados para actividades delictivas, existen los botnets para minería de datos, ataques DDoS, romper hashes, minar criptomonedas, spam y otros usos. Usualmente se instalan en el dispositivo de un usuario y persisten por años, brindando alguna función especifica. Estas redes de bots crecen en varios millones, son reconocidas y nombradas informalmente por miembros de la comunidad de ciberseguridad.
Hay un interesante articulo “Mobile Bots: The Next Evolution of Bad Bots”, donde se examinó las solicitudes de 100 millones de dispositivos móviles en la red Distil de seis importantes proveedores de telefonía celular durante un período de 45 días. La compañía descubrió que el 5,8% de esos dispositivos alojaban bots utilizados para atacar sitios web y aplicaciones, lo que equivale a 5,8 millones de dispositivos con actividad de la que sus propietarios no saben nada.
Fake Apps
Son aplicaciones en dispositivos móviles que engañan a los usuarios para que las descarguen utilizando compañías legítimas o referencias populares. También pueden hacerse pasar por aplicaciones extravagantes y atractivas, que brindan servicios interesantes como fondos de pantalla o herramientas de espionaje en tiempo real. También se hacen pasar por juegos o replican otras aplicaciones que son trending. Existe de todo tipo y sabor, las fakes apps son un buen lugar para ocultar el botnet.
En este caso es mediante una app de utilidad, algo sencillo, simple, que cumpla alguna funcionalidad esencial pero que por detrás tenga nuestro código para poder obtener la información que necesitamos.
La apps utilitarias que tiene un gran número de descargas, por ejemplo hablamos de apps que pasan el millón de descargas, estos se encuentra en diferentes sectores de moda, comida, belleza, entre otros. La mayoría de ellos tienen bastantes años en la Play Store y su UI no es amigable, por ahí es que podemos competir con ellos con UI mas moderna.
Botnet de información
Los datos básicos a obtener son las listas de contactos, cuentas de correos, los sms y información del dispositivo. Para poder obtener estos datos, de algún modo u otro es necesario que el usuario acepte los permisos, y por ahí realice un match entre los permisos requeridos para el Botnet y la app utilitaria que estaba construyendo.
En Android a partir de la versión 6.0 se añade permisos en tiempo de ejecución, en Android 11.0 tratamos con permisos granulares donde las apps pueden tener permisos una sola vez o sólo cuando se estén utilizando para acceder a determinadas funciones, incluso cuando se deniega el permiso varias veces las apps no vuelven a preguntar. En Android 12.0 se bloquean los eventos táctiles que no son de confianza. Durante los últimos años Android a tratado de añadir restricciones a los permisos.

Encontré una app que se asemeje a esos requerimientos y empecé a construir la app, la parte de la app utilitaria, tiene una funcionalidad esencial con una construcción normal como cualquier otra app, pero en este caso los permisos eran obligatorios para el usuario. Así que agregue en la primera pantalla una funcionalidad para pedir todos los permisos necesarios antes de continuar, si no acepta todos los permisos no puede continuar usando la app.
Ya teniendo la app con los permisos aceptados y haber construido la parte de función utilitaria de la app, solo utilice un patrón de arquitectura MVVM para la app utilitaria, podía pasar a construir la parte del botnet de la app.
Para la construcción del Botnet, se empleó un módulo independiente utilizando arquitectura Clean con el patrón MVVM, también use Work Manager, Broadcast Reciever, Room y Retrofit.
Modulo Picasso
La parte del botnet es un módulo de tipo Android Library. Para ello, el módulo puede ser renombrado como algún api o paquete conocido, para que cualquier investigador que le quiera realizar ingeniería inversa, no la pueda detectar o genere confusión. En Android tenemos algunas Apis comunes de construcción como Picasso, Glide, Volley, Retrofit, Logger, RxJava:

Este módulo creado como librería, tiene su propia BD y sus propios servicios, totalmente independiente de la funcionalidad de utilidad de la app.
Work Manager
Me permite realizar operaciones diferibles(donde no es necesario ejecutarlos inmediatamente), incluso si la app esta cerrada o el dispositivo se reinicia, años atrás de no tener este componente de JetPack hubiera utilizado APIs que tenían una complejidad elevada como FirebaseJobDispatcher, GcmNetworkManager y JobScheduler, pero WorkManager nos simplifica todo, tiene una limitación solo se puede ejecutar cada 15 minutos como mínimo pero tiene una configuración fácil, políticas de reintento y restricciones de trabajos.
WorkManager es una criptonita para un Botnet porque nos permite sincronizar de manera eficiente datos, teniendo en cuenta el nivel de batería del dispositivo, wifi y otros. Con éste componente la app cada 15 minutos recupera la lista de contactos, lista de sms, correos asociados e información del dispositivo. Guarda la información en una Base de Datos, con una lógica de un campo para indicar si ha sido enviado este registro o falta enviar, luego verifica los datos faltantes y los envía por servicio Rest. Esta lógica me permite enviar una sola vez la información del dispositivo al backend, si hay nuevos datos sincronizará solo esos datos.
Broadcast Reciever
Bien, ahora necesito que cada vez que el dispositivo reciba un sms se vea reflejado en el backend sin esperar los 15 minutos, para este propósito utilizaremos el broadcast reciever.
El Broadcast Reciever es un componente que se encarga de recibir y reaccionar frente a ciertos mensajes emitidos por el sistema Android. Son muchos los mensajes que emite el sistema a lo largo de su ejecución, por ejemplo si ha tomado una fotografía, si ha activado el GPS, si recibe una llamada, si recibe un sms. Los Broadcast Receiver no tienen interfaz asociada. Las apps también pueden enviar emisiones personalizadas.
Para que funcione un Broadcast Reciever, no es necesario que la app esté ejecutándose, al estar registrado, el propio sistema se encargara de lanzar la aplicación si hiciera falta cuando se reciba el mensaje. Si desea profundizar puede ayudar el post de Ankit Sinhal.
Para recibir sms utilizamos el método onRecive() de la clase Broadcast Reciever como se muestra en el ejemplo, cada vez que reciba un nuevo sms este será enviado por servicio rest si el dispositivo cuenta con internet.
Ahora si quisiéramos eliminar un sms como podríamos realizarlo. Desafortunadamente, eliminar mensajes SMS ya no es posible desde Android 4.4 (KitKat), a menos que su aplicación sea la aplicación de SMS predeterminada o el dispositivo esté rooteado, lo puedes verificar en la documentación oficial. Si estuviera disponible esta funcionalidad nos daría demasiado poder sobre los sms del usuario.
Identificador del Dispositivo
Para guardar toda esta información en el backend, nosotros debemos tener un identificador único para cada instalación de la app en el dispositivo. Google tiene algunas recomendaciones para este caso. Evitar el uso de identificadores de hardware, utilizar id de publicidad, Id de instancia o GUID privado, puede verificar en el siguiente enlace.
Para nuestro caso nos viene bien usar GUID. Este ID único global (GUID) identifica de forma exclusiva una instancia única de la app, es recomendable guardarlo en almacenamiento interno. Lo puedes generar con el siguiente código.
Ya teniendo este identificador lo persistimos en nuestra Base de Datos del modulo de utilidad, y cuando inicialicemos los Work Manager necesitaremos pasarle este identificador a través de data como parámetro de clave -valor.

Tips de Anonimato
Algunos tips de anonimato para ocultar el modulo del Botnet :

- Cambiar los nombres de paquetes: En la aplicación utilizamos el paquete de una librería conocida com.squareup.picasso, es recomendable utilizar el paquete de cualquier librería común del desarrollo Android como Glide, Retrofit, RxJava y otros. Esto servirá como distracción o confusión para cualquier persona que realice reversing a la aplicación. También es recomendable ofuscar la parte del modulo Picasso como mínimo.
- Cambiar el nombre de las clases: Al ofuscar tu código con Proguard no se cambian los nombres de las clases. Probado con las herramientas: dex2jar+Jd-gui y Apk Analyzer. Esto va en contra del código limpio de Robert C. Martin, pero será para añadir una capa distracción al momento de la ingeniería reversa. También sería bueno utilizar algunos acrónimos que conozcas.
- Eliminar tus huellas: Por ejemplo, en un desarrollo normal en cada clase va nombre del autor de la persona que desarrolló esa parte de la app. Si alguien encuentra alguna huella estarías comunicando que este código malicioso te pertenece.
- Eliminar los logs o utilizar un wrapper: Al momento de comprobar ciertas partes del código utilizamos los logs, si una persona ejecuta el apk desde una terminal de Android Studio tus logs serán visibles, ten cuidado.
- Eliminar el interceptor de Retrofit o solo ejecutarlo en modo debug: Los interceptores son un mecanismo poderoso para monitorear, reescribir y reintentar llamadas. En el botnet utilizo la clase HttpLoggingInterceptor que registra información de solicitud y respuesta a servicios web totalmente útil al momento del desarrollo, pero debe deshabilitarse antes de la publicación.
- Ocultar información privada: Existen varias formas de ocultar credenciales, puedes echarle una mirada a este documento. De acuerdo a las mejores practicas se recomienda mantener todas las credenciales en un archivo externo app.properties en la raíz de tu proyecto, aquí puedes ocultar la raíz del url, hostname, API keys, paswords y otros. Luego en el build.gradle llamas al archivo e ingresas a la información guardada.
No tiene mucho sentido ocultar la url, ya de por si es pública. Además por más que la ocultes la url con un wireshark puedes determinar la url sin ningún esfuerzo observando el tráfico. Pero si ocultas la información de la url y esto lo combinas con conexiones SSL Pining, esto si tendría sentido añadiendo una capa de seguridad para conexiones.
-Utilizar conexiones SSL Pining: Las conexiones ssl pinnig trabajan con un certificado válido que nuestro servidor conoce, esto lo utilizamos para evitar el ataque main in the middle de cualquier persona que quiera interceptar nuestras conexiones de red. Esto lo puedes implementar de manera fácil con OkHttp, en el código encontrarás comentarios donde realizar el cambio.
Desarrollo
Puedes revisar el código completo del ejemplo, Baby Bot contiene el código base del botnet de información.
Luego de ejecutar el botnet en un dispositivo, podemos obtener la siguiente información en panel web:

El botnet de información podria tener los siguientes usos:
- Minería de información.
- Saltar cualquier software que requiera código de confirmación por sms.
- Spam de cualquier tipo a la lista de contactos.
- Espionaje de pareja.
También podria servir como código base para agregar funcionalidad dependiendo del uso requerido (ataques DDoS, romper hashes, minar criptomonedas, spam y otros).
Conclusión
Para finalizar debemos tener cuidado con las aplicaciones que instalamos a nuestros celulares y que permisos les damos, a pesar de que en Android 6.0 en adelante necesitamos que el usuario confirme los permisos, casi nunca le damos la importancia debida a los permisos necesarios. Al mismo tiempo cada empresa dispone de una política de privacidad al iniciar una aplicación, son muy pocos las personas que lo leen. Nada nos dice si realmente estas políticas se cumple en empresas que no sean muy conocidas. Si una empresa quiere hacer mal uso de tus datos lo puede hacer, en oposición a ello, la ética de cada empresa será lo que los mantenga al limite de solo utilizar lo necesario.