Lo hemos repetido en infinidad de ocasiones: lo más importante de actualizar el sistema operativo no es conseguir todas sus nuevas funciones o emojis, es la seguridad. Con cada nueva actualización que puede parecer que no aporta grandes novedades, se acompañan siempre parches de seguridad que cierran posibilidades y opciones de explotación de agujeros de seguridad que podrían comprometer nuestro equipo.
El gran problema, es que no hay una cultura o educación apropiada para entender estos conceptos porque, no nos engañemos, en sí son bastante complejos. Sin ir más lejos, la última actualización iOS 14.4 resolvió tres errores de seguridad bastante graves donde Apple decía explícitamente que “podrían haber sido explotados activamente”. Problemas que permitían tomar el control de nuestro smartphone o tableta sin nuestro consentimiento ni conocimiento.
Para ejemplificar la importancia de las actualizaciones, os vamos a contar los resultados de la investigación de Google Project Zero (equipo de seguridad que trabaja activamente en encontrar problemas de seguridad en todos los sistemas y dispositivos actuales) que ha descubierto que Apple ha mejorado sustancialmente la seguridad en iMessage, uno de los focos más activos de errores directos (errores 0-click que no requieren que ni siquiera intervengamos con el dispositivo). Para hacer esto han creado un nuevo componente llamado BlastDoor, que cierra gran parte de los importantes problemas de seguridad que presentaba iMessage hasta antes de iOS 14.
Aunque, como ya sabéis que suelo hacer en mis artículos, vamos a poner en claro conceptos previos y, por supuesto, añadiré mi propio conocimiento para que entendáis mejor todo lo que se explique. Y lo primero a entender es, ¿por qué existen los fallos de seguridad? ¿qué es eso exactamente? Vamos a intentar arrojar luz a este respecto de la forma más sencilla posible dentro de su complejidad.
Un sistema operativo es un programa
Esto parece muy obvio, pero a veces perdemos la perspectiva al respecto. Cuando yo ejecuto una app en mi dispositivo, esta no es más que un programa que se ejecuta (que corre) sobre otro programa. El programa principal, el de mayor nivel de cualquier sistema operativo, es el kernel o núcleo. Es el que se encarga de coordinar el funcionamiento del sistema y, por ende, es el elemento objetivo que cualquier atacante quiere conseguir controlar.
No solo se puede acceder al sistema de archivos del sistema, también se pueden activar servicios o periféricos. Como el GPS, las cámaras, los micrófonos... se puede acceder a controlar servicios como las llamadas de teléfono, las apps de mensajería... en definitiva: convertir el dispositivo en un zombie en que podemos hacer cualquier cosa con él sin que el usuario sepa que se está haciendo.
Por este motivo, el kernel tiene protecciones que impiden que pueda ser atacado. Pero hay que dejar un concepto muy claro desde el momento 0: NO existe el método 100% infalible para proteger ningún software en el mundo. Por muchas puertas que se pongan, siempre podrán encontrarse otras y es imposible conseguir un software 100% seguro. Por lo que lo mejor que podemos hacer es ir actualizando para ir cerrando agujeros que se vayan descubriendo por donde algún programa malicioso podría colarse para controlar el kernel.
¿Y por qué no existe ningún sistema 100% seguro? Porque todo el software está hecho por humanos que cometen errores. Todos. Y porque un sistema operativo son capas de programas que ejecutan otros programas, que ejecutan librerías (que son más programas) que a su vez ejecutan otros programas ejecutando... ¿adivinan? más programas. Y esas capas tienen que comunicarse las unas con las otras (con medidas de seguridad) para poder hacer que todo funcione. Pero si en una de ellas hay un error y alguien lo descubre, mal vamos.
El problema de base es C, el lenguaje. En su definición como lenguaje no se tuvo en cuenta la seguridad para darle prioridad al rendimiento y esta se dejó en manos de los desarrolladores. De esta forma, en C no se controlan cosas esenciales como que en un almacén de datos declarado con un tamaño, se metan más datos de los que se dijeron que iban a meterse. O no se controla que un dato que se dijo que iba a ser de un tipo, finalmente sea de ese y no de otro. O que un lugar donde se ha dicho que hay un dato, realmente tenga un dato o simplemente esté vacío. Eso por citar algunos ejemplos básicos. Esas comprobaciones se dejan a suponer que "el programador lo hará bien y no cometerá esos errores".
¿Qué provoca eso? Errores de ejecución. Que cuando lleguemos a un código donde no se ha controlado un fallo por error humano, se provoque un error de ejecución que permitirá a un atacante obtener información de dónde se ha producido el error, qué datos había en la memoria en ese momento e incluso, aprovechar un estado “vulnerable” del sistema por ese error para atravesar capas hacia abajo (hacia el kernel) y ejecutar código arbitrario malicioso al nivel del mismo. Es decir, un código que no es el que debería estar ahí y cuyo objetivo es hacer "algo malo".
Y toda esta estructura es tan arraigada en los sistemas, que para solucionarlo habría que recrearlo todo desde 0, lo que es impensable hoy día. Además, que podríamos intentar hacerlo todo desde 0 y volver al mismo estado actual en que sigamos teniendo errores de seguridad por fallos humanos. Errores en el código que no pueden detectarse en forma alguna hasta que creamos las condiciones específicas que provocan ese error de forma voluntaria. Y si no sabemos que está ahí ni cómo provocarlo, es bastante complejo que lo encontremos.
BlastDoor, un parseador de datos
Llegados a este punto, podemos hablar de BlastDoor, el nuevo componente que Apple ha incluido en iOS 14 y que, como es obvio, al ser un sistema de seguridad Apple no lo ha publicitado en forma alguna.
Una de las funciones más interesantes que tiene iMessage como plataforma de mensajería, es la capacidad de mostrar contenido enriquecido. Si comparto una web, es capaz de formar un cuadro con la imagen previa de dicha web, poner el título y crear una forma elegante para ir a ver ese contenido en modo previsualización. Si compartimos un vídeo de Youtube, es capaz de crearnos un mini-reproductor de Youtube que permite que lo veamos ahí mismo. Al igual que otras apps de mensajería, convierte un simple enlace o contenido en un contenido enriquecido para que sepamos qué hay detrás de dicho enlace.
El problema es que esa excelente funcionalidad ha tenido infinidad de problemas de seguridad históricamente. Cuando yo comparto un enlace de una página, el sistema parsea los datos: los analiza, captura lo que le interesa y lo transforma en la representación visual elegante que vemos. Pero en dicho proceso, tengo que activar el motor de interpretación del HTML para bajar la metainformación de una página y recuperar su imagen destacada, el extracto, el título de la propia página... eso requiere bajar la propia página y suponer que datos como el título, imagen y demás están donde yo lo espero… pero, ¿y si alguien cuela algo que no debería en un lugar que espero otra cosa? Podría conseguir engañar al sistema.
¿Cómo? Imaginen que se me olvidó comprobar que el dato X que descargo, que espero sea una imagen y que voy a tratar como tal, en realidad lo sea. Parece una imagen, pero en realidad es un código malicioso. Y yo, como desarrollador, olvidé comprobar la metainformación de la imagen y su correcto formato en el caso de un tipo concreto de imagen. De esa forma, alguien podría aprovechar esa vulnerabilidad (esa falta de comprobación que un dato es lo que esperamos que sea y no otra cosa) y colar algo que no es. Y tal vez el programa que procesa la imagen tenga otro error que no valida el formato o permite ejecutar algún tipo de código y puedo cambiar ese código por otro. Y entonces voy aprovechando una puerta entornada tras otra, para colarme y conseguir "bajar" capas hasta controlar el sistema a nivel de kernel. A comprometer el sistema.
No solo eso: el propio mensaje es un conjunto de datos antes de ser procesado, y puede que haya cosas que pretendan provocar errores en el código y colgar el proceso que interpreta la información que viene en el total de datos que luego se convierten en un mensaje (su payload). Y un cuelgue es una oportunidad para colarse a mirar y crear un proceso controlado que sea capaz de colocar un código en un sitio concreto donde vulnere la seguridad y permita bajar capas comprometiendo la seguridad.
Por este motivo Apple ha creado un nuevo programa llamado BlastDoor, que además está programado en Swift. ¿Y por qué en Swift? Porque Swift es un lenguaje desarrollado en C principalmente, pero que controla los errores más comunes que tiene C. Corrige como lenguaje los errores del lenguaje en que está desarrollado. En Swift, es imposible que un dato sea otro distinto al que dijo que sería. En Swift, no existen tamaños por lo que nunca guardaré más información que la que dije que tendría un dato. En Swift no se permiten los datos vacíos. En Swift no hay un motor de ejecución dinámico que permita inyectar procesos. De hecho, al ser código estático compilado y ofuscado (los símbolos o nombres de métodos o componentes no aparecen en el código) realizar ingeniería inversa al código se convierte en un proceso mucho más complejo para cualquier atacante y entender qué está haciendo el código.
¿Y qué hace este nuevo módulo BlastDoor? Pues es una API integrada dentro de la app de mensajería, encargado del parseo seguro del mensaje en sí, y luego de los enlaces o contenidos compartidos que pueda contener. Tiene una serie de comprobaciones que eliminan de raíz cualquier contenido sospechoso de ser un código o de ser algo que debería ser pero no es.
Cuando nuestro dispositivo recibe un nuevo mensaje, este viene en un payload (una carga). BlastDoor comprueba esa carga para verificar que nada raro viene y decodifica cada dato contenido de forma segura. Luego, cuando el mensaje ya es procesado y se manda a ser decodificado en su contenido se vuelve a mandar a BlastDoor. Para poner un ejemplo claro del paseo de un contenido con Swift hablemos de cómo se carga una imagen. Esta carga se hace sobre un dato opcional. Es decir: compruebo si el constructor del tipo imagen, con los datos en bruto que le paso, es capaz de construir una imagen. Si puede, pasa la imagen. Si no, devuelve un error controlado y rechaza el dato así que evita que algo que no debería pasar, pase por donde no debería. Y evita que el proceso se cuelgue por tener datos corruptos (una forma muy común de provocar errores y buscar vulnerabilidades).
Apple además ha metido algunas correcciones importantes como que si el programa que procesa un mensaje se cuelga (cosa que no debería pasar, pero puede ser provocado principalmente por un ataque), se genera una pausa en el sistema que no permite volver a levantar el proceso hasta pasado un tiempo, que cada vez es mayor. De esta forma, si se intenta un ataque por fuerza bruta o se intenta colgar el proceso para ir probando casos de ataque, este tardará cada vez más tiempo en ir respondiendo. Esto no impide un ataque continuado, pero hace tan lento y tedioso el proceso que puede que el atacante desista de seguir intentando abrir la puerta cerrada.
Seguridad, el vigilante silencioso
La seguridad es algo esencial en cualquier software porque la cantidad de información que puede extraerse de cualquier dispositivo que tenemos hoy día en nuestro bolsillo o en nuestras casas, conectado permanentemente a internet, vale mucho dinero. Puede que pensemos que nosotros no somos nadie y que tampoco tenemos nada que perder. Pero nos equivocamos. Nosotros somos un eslabón de una cadena que contiene (por ejemplo) una agenda a familiares y amigos. Y que contiene fotografías, históricos de uso, de navegación, preferencias... datos que nos dicen quienes somos, qué hacemos, qué nos gusta, qué no, dónde trabajamos, qué vida tenemos, dónde estudian nuestros hijos (si los tenemos), si tenemos animal doméstico...
Tal vez tú pienses que tampoco es para tanto y no actualices tu dispositivo. Pero puede ser que tu iPhone o tu iPad sea vulnerable y te roben la agenda (algo que puede parecer inócuo). Y en tu agenda tienes a tus padres que son mayores. Y entonces les llamen intentando engañarles o les manden un email de phising y consigan sus datos bancarios y les quiten su dinero (esto es algo que pasa todos los días, mucho más de lo que pensamos). Y todo porque hemos pensado que, ¿a mí que van a robarme?
Tenemos una responsabilidad. Aquella que tiene que ver con las empresas, se va cumpliendo y tienen equipos de trabajo muy especializados para ir garantizando que podamos estar lo más seguros posibles. Usar internet es como subirse en un coche. Es imposible pensar que tú jamás tendrás un accidente con el coche. Siempre existe una posibilidad que cada vez que te subes a un coche puedas tener un accidente. Por tu culpa o por la de otros. Yo me quedé sin coche hace más de un año porque, parado correctamente en un atasco, una señora despistada por el llanto de su hija embistió a varios coches detrás del mío y en el dominó, me tocó y me quedé sin coche. Y gracias que a mí no me pasó nada. Internet es igual. Entrar y navegar en él es ya un riesgo de ser engañados, de sufrir un ataque, que nuestra seguridad quede comprometida...
Como vemos las compañías trabajan porque cada día estemos más seguros, falta que nosotros pongamos de nuestra parte y actualicemos los sistemas. Nosotros seremos los primeros beneficiados.
Ver 4 comentarios