REBELION_EN_LA_GRANJA/docs/seguridad.md
s1to 74bfbe9437 Rebelión en la granja — investigación y laboratorio de dispositivos
Investigación sobre granjas de dispositivos y automatización completa para
levantar un laboratorio Android sobre un chasis de blades Debian.

Conclusión que ordena el repositorio: el cuello de botella nunca fue el
cómputo sino la identidad. Desde que la atestación de dispositivo pasó de
estadística a criptográfica, un servidor no puede hacerse pasar por un
teléfono — le falta una clave grabada en fábrica que ningún software produce.

Contenido:

- 01_investigacion/ — capa de identidad (verificación telefónica, eSIM,
  reputación de IP, atestación por hardware, correlación entre cuentas),
  mercado y players, stack técnico, marco legal en la UE
- 02_device_lab/ansible/ — Ansible para 16 blades: preflight de solo lectura
  que identifica el hardware por DMI, despliegue de redroid en Docker y
  control de flota por adb. Solo ansible.builtin, sin colecciones externas
- docs/ — requisitos, costes y repaso de seguridad con 11 hallazgos
- 03_charla/ — guion para HackMadrid / Hackmeeting València

Estado: la automatización está escrita pero SIN ejecutar contra hardware.
YAML validado, plantillas renderizadas en ambos modos de red y fleet.sh
comprobado con bash -n. El modelo de blade sigue sin confirmar.
2026-08-08 19:42:14 +02:00

8.7 KiB
Raw Blame History

Repaso de seguridad

Revisión del montaje completo — arquitectura, hardware y el código Ansible de 02_device_lab/ansible/. Fecha: 2026-08-08.

Incluye los fallos que introduce el propio código de este proyecto, no solo los del entorno.

Resumen

Hallazgo Severidad Estado
S1 adb sin autenticación + contenedor privilegiado → root del anfitrión Crítico Mitigado a medias
S2 Credenciales por defecto del CMC / iDRAC (root/calvin) Alto Sin verificar
S3 macvlan mete 45 Android en la LAN de producción Alto Por diseño, hay que aislar
S4 host_key_checking = False en ansible.cfg Medio Aceptado, documentado
S5 SSH como root en el inventario de ejemplo Medio Documentado
S6 Imagen de Android por tag mutable Medio Abierto
S7 Sin gestión de secretos Medio Abierto
S8 Estado persistente en /data sin cifrar Medio Abierto
S9 fleet install no verifica el APK Bajo Abierto
S10 Microcódigo antiguo en CPUs de 2011-2016 Bajo Aceptado
S11 Infraestructura de doble uso Contextual Ver legal_ue.md

S1 · adb sin autenticación sobre contenedor privilegiado — crítico

El fallo más serio, y es una cadena de tres eslabones que por separado parecen asumibles:

  1. adb no tiene autenticación cuando escucha en TCP. Quien llega al puerto, entra.
  2. Las imágenes de redroid son userdebug, así que adb root funciona: shell de root dentro del Android.
  3. El contenedor es privileged: true — redroid lo exige para acceder a binder. Un privilegiado ve los devices del anfitrión y puede montar su sistema de ficheros.

Encadenado: cualquiera que alcance el puerto 5555 de un blade acaba siendo root en ese blade. No hace falta ningún exploit, solo adb connect.

Y con 45 dispositivos son 45 puertas.

Qué se ha corregido hoy. El compose ataba adb a 0.0.0.0 — todas las interfaces. Ahora hay redroid_adb_bind_ip, así que se puede atar solo a la interfaz interna del chasis:

blade-02: { ansible_host: 10.0.0.12, redroid_adb_bind_ip: 10.0.0.12 }

Qué falta, y es lo que de verdad cierra el agujero:

  • Red de laboratorio aislada. VLAN propia para la granja, sin ruta hacia la LAN de casa ni hacia internet salvo lo imprescindible. Es la medida que importa; el resto son parches.
  • Cortafuegos en cada blade (nftables) que solo acepte 5555+ desde la IP del coordinador.
  • Nunca exponer estos puertos a internet. Ni con reenvío de puertos, ni con VPN mal segmentada.

En modo macvlan el problema es peor: adb queda escuchando en la IP de LAN del propio Android, donde redroid_adb_bind_ip no aplica. Ahí la única defensa es la VLAN.


S2 · Credenciales por defecto del CMC y de los iDRAC — alto

Los Dell PowerEdge salen de fábrica con root / calvin en iDRAC, y el CMC del M1000e con las mismas. Es la forma clásica en que se toma uno de estos chasis: no hay que romper nada, se entra.

El M1000e es de 2016 o anterior, así que el firmware de gestión arrastra años de CVEs conocidas y TLS antiguo.

Antes de enchufarlo a nada:

  • Cambiar las credenciales del CMC y de cada uno de los 16 iDRAC, no solo del CMC.
  • Actualizar firmware de CMC e iDRAC hasta donde Dell lo permita para esa generación.
  • VLAN de gestión separada, sin salida a internet. La gestión de un chasis nunca va en la misma red que el resto.
  • Desactivar IPMI sobre LAN si no se usa (cipher 0 es un clásico de acceso sin autenticar).

Esto es independiente de la granja: aplica al hierro desde el momento en que se encienda.


S3 · macvlan expone 45 Android en la LAN — alto

El modo macvlan es el que hace falta para el caso de los dos APKs de oasis_mobile, pero pone cada Android con IP real en la red, cada uno con S1 encima.

  • VLAN dedicada para la granja, con el coordinador como único puente.
  • Reservar el rango de IPs en el DHCP, o habrá colisiones con máquinas reales.
  • No usar la LAN de casa. Nunca.

S4 · host_key_checking = False — medio

Lo puse yo en ansible.cfg por comodidad de arranque. El coste: si alguien se hace pasar por un blade, Ansible se conecta igual y le entrega comandos de root y, si se usa, la contraseña de sudo.

Es asumible en el primer aprovisionamiento de una red aislada. Después:

ssh-keyscan -H 10.0.0.11 10.0.0.12 ... >> ~/.ssh/known_hosts

y poner host_key_checking = True.


S5 · SSH como root — medio

inventory/hosts.yml.example trae ansible_user: root. Funciona, pero:

  • Usuario dedicado con sudo en vez de root directo
  • Solo clave, sin contraseña: PasswordAuthentication no
  • PermitRootLogin no en los blades
  • Clave separada para la granja, no la personal

S6 · Imagen de Android por tag mutable — medio

redroid/redroid:13.0.0-latest es un tag que se mueve. Consecuencias reales:

  • Dos blades provisionados con una semana de diferencia acaban con imágenes distintas, y depurar eso es un infierno.
  • Cadena de suministro: si la cuenta del registro se compromete, el siguiente docker compose pull se trae otra cosa. Y entra en 45 contenedores privilegiados.

Fijar por digest:

redroid_image: "redroid/redroid@sha256:<digest>"

Con docker buildx imagetools inspect redroid/redroid:13.0.0-latest se saca el digest actual. Se actualiza a mano cuando se quiera subir de versión, que es justo lo que se quiere.


S7 · Sin gestión de secretos — medio

El inventario de ejemplo menciona ansible_become_password sin montar ansible-vault. Si se pone una contraseña ahí en claro, queda en el disco y en cualquier copia del proyecto.

ansible-vault create group_vars/granja/vault.yml
ansible-playbook site.yml --ask-vault-pass

Mejor aún: sudo sin contraseña para el usuario de despliegue, restringido a los comandos que necesita, y ninguna contraseña en ningún fichero.


S8 · Estado persistente sin cifrar — medio

Cada Android guarda su /data en {{ redroid_base_dir }}/data/device-NN del blade, sin cifrar. Si en las pruebas se entra con cuentas reales — cuentas SSB, credenciales de Gitea, lo que sea — esas credenciales quedan en el disco del blade en claro.

destroy.yml conserva los datos por defecto, a propósito, así que sobreviven a un redespliegue y a un cambio de manos del hardware.

  • Cuentas de prueba desechables, nunca las reales.
  • Cifrado de disco en los blades si van a manejar algo sensible.
  • Al dar de baja un blade: destroy.yml -e confirmar=si -e borrar_datos=si y borrado del disco.

S9 · fleet install no verifica nada — bajo

fleet install app.apk mete el APK en los 45 dispositivos sin comprobar firma ni hash. Como los APK son propios (oasis_mobile), el riesgo es bajo, pero el patrón es malo: un fichero equivocado se propaga a toda la flota de una vez.

Comprobar el hash antes, y a ser posible la firma con apksigner verify --print-certs.


S10 · Microcódigo antiguo — bajo

CPUs de 20112016 con microcódigo sin actualizar: las mitigaciones de Spectre/Meltdown dependen de microcódigo + kernel. En un laboratorio aislado que solo corre código propio, el riesgo es bajo. Subiría si algún día se corre software de terceros no confiable en los Android.

apt install intel-microcode en los blades, y aun así esa generación no recibe todo.


S11 · Infraestructura de doble uso — contextual

Técnicamente, esto es indistinguible de una granja de cuentas: 45 Android automatizados, con control central y despliegue masivo de APKs. Lo que separa un laboratorio de QA de una granja de fraude no es la infraestructura, son tres cosas que no están aquí: SIMs, proxies residenciales y cuentas de plataforma.

Para que siga siendo lo que es:

  • No conectar la granja a proveedores de SIM ni de números por API.
  • No meter proxies residenciales o móviles.
  • Documentar el propósito con evidencia — este repositorio ya lo hace.

El contexto legal está en legal_ue.md. Y recuerda el hallazgo de la investigación: estos Android son detectables como emulador, así que para las plataformas sociales no servirían aunque se quisiera.


Mínimos antes de encender

Por orden:

  1. Cambiar credenciales del CMC y de los 16 iDRAC (S2)
  2. VLAN aislada para granja y gestión, separadas entre sí (S1, S2, S3)
  3. redroid_adb_bind_ip a la IP interna de cada blade (S1)
  4. Claves SSH, sin root, sin contraseñas (S5)
  5. Poblar known_hosts y host_key_checking = True (S4)
  6. Fijar la imagen por digest (S6)

Los tres primeros no son opcionales. Sin ellos, la granja es 45 puertas abiertas a la red.