Archivo de la categoría ‘Sistemas Operativos’

DNS Over HTTPS/TLS: Encriptado del tráfico DNS

 

A lo largo de los años, la mayoría de los protocolos “base” con los que se constituyó el Internet que hoy conocemos han ido evolucionando, algunos más algunos menos. Es cierto que la base en la que se sostiene es a groso modo la misma, pero no así los protocolos que están encima de la mesa. El mejor ejemplo es el propio protocolo HTTP, que aunque parezca muy antiguo, realmente su primera especificación es de 1991. Vale, son 27 años, pero Internet podemos datarla más o menos por 1980. Sí, a día de hoy el protocolo HTTP es la base de toda la Internet navegable, pero muy poco queda de esa primera especificación de 1991. En 1996 aparecería la especificación HTTP/1.0, en 1999 HTTP/1.1 (la más usada a día de hoy) y en 2015 HTTP/2.0. HTTP ha evolucionado y es posible que continúe haciéndolo, y HTTP/2.0 ofrece grandes mejoras en todos los aspectos frente a especificaciones más viejas.

HTTPS apareció en 1992, un modo ingenioso, práctico y seguro de poder enviar/recibir la información HTTP de forma cifrada punto a punto, es decir, se cifra y descifra en origen, permitiendo conocer si ha existido manipulación en medio y además añadiendo identificación de las partes por medio de certificados digitales. Ahora, en 2018, HTTPS lo vemos como imprescindible, y con los certificados digitales más a mano que nunca hemos visto como el % de webs que lo han implementado se han disparado. ¿Por qué? Porque después de años de hartazgo de las propias instituciones gubernamentales, de fallos de seguridad, de robos de datos… ahora somos más desconfiados que nunca, y nos gusta pensar que, aunque lo que estemos mirando en Internet sea donde comprar un colchón, nadie va a poder saberlo (Bueno, todo tiene sus limitaciones, claro). Realmente su importancia principal fue y ha sido y será, debido al intercambio de datos privados entre usuario y servidores. Desde usuarios y contraseñas, direcciones postales, tarjetas de crédito, expedientes médicos… todo. Cualquier información que no vaya cifrada punto a punto corre el riesgo de ser leída… y ya no solo por posibles “cucarachas” que se conecten a nuestra red interna, sino (y siendo un poco conspiranoicos), gobiernos, entidades, los mismos ISP…

Pero si existe otro protocolo de igual importancia en Internet, o incluso más, es sin duda el protocolo DNS (siempre por supuesto hablando de protocolos a nivel de aplicación).

 

DNS

Lo primero que debemos de tener en Internet es, como todo el mundo sabe, una IP. Una IP es un identificador numérico que no solo nos hace accesible desde el exterior, sino también poder ir a cualquier rincón de Internet. Las IPs son las verdaderas direcciones en Internet, pero en cambio rara vez tenemos que usarlas. El 99% del tiempo que estamos en Internet, nos valemos de un sistema de nombres (aka dominios) para poder acceder a un servicio/sitio u otro. ¿Por qué? Porque nuestra mente, nuestro cerebro, se le da infinitamente mejor recordar nombres o cadenas de caracteres que una sucesión de números. Para nosotros es infinitamente más sencillo recordar “google.es” que “216.58.201.163”. Basados en esta premisa fundamentalmente, se creó un sistema de nombres (de dominios), llamado DNS (Domain Name System).

Posiblemente el protocolo DNS es de los más sencillos de entender. DNS funciona como un “traductor”, algo así como unas páginas amarillas gigantes. Cuando introducimos un nombre de dominio en cualquier navegador o aplicación, esta envía la solicitud al servidor DNS que tenga especificado, y este será el encargado de resolver la dirección correspondiente al nombre de domino especificado, y el tipo de registro solicitado. En este artículo de hace tiempo puede verse mejor como funciona DNS. Es un poco más complejo debido a que el sistema DNS es distribuido e incluso jerárquico, pero en lo que nos atañe, es tan simple como eso.

El protocolo DNS no ha evolucionado en nada. Es cierto que se ha expandido con los años con la inclusión de nuevos tipos de registros DNS, e incluso mejoró notablemente la seguridad con la inclusión de DNSSec, pero el protocolo en sí mismo es el mismo que el que se empezó a desplegar en 1983. Eso no es malo, cuando algo ha evolucionado tan poco y aun así es usado tan extensamente, es que funciona realmente bien. No obstante, la sociedad ha cambiado, y tal como sucedió con HTTP, DNS no se creó con la privacidad en mente, por entonces había mejor voluntad y posiblemente mejores ideales. A día de hoy sería impensable crear un protocolo sin que la encriptación y autentificación no estuviesen desde el comienzo del desarrollo.

DNSSec ha dotado a DNS de un sistema de “autentificación”, de modo que las peticiones DNS resueltas por los servidores DNS pueden verificarse/autentificarse, que proceden realmente del servidor DNS raíz a quien pertenecen. Sin DNSSec, se podría envenenar la caché de un cliente DNS, de modo que peticiones realizadas de dicho cliente fuesen respondidas con una IP falsa. Este tipo de ataques ha sido muy efectivo en el pasado… los mismos resolvers tienen que escalar la petición DNS a los servidores DNS, y en ese proceso puede ser bombardeado con respuestas DNS falsas, con lo que el resolver creer que la IP falsa es la real, y ser la IP que al final devolvería al equipo en cuestión. Cuando DNSSec es usado, el servidor DNS firmará la respuesta DNS con cifrado asimétrico, y las enviará en otro registro DNS conjunto a la petición original, y dicha firma el resolver/cliente puede verificarla con los registros del servidor DNS, que contienen a su vez la clave pública con la que se firmaron. De este modo el cliente puede saber con exactitud si la respuesta que hemos recibido proviene realmente del servidor DNS legítimo.

DNSSec es importante, añade autentificación, pero… ¿que pasa con la encriptación?

 

DNS Over HTTPS/TLS

Los datos que se transfieren por DNS son muy importantes. Vale, no van a contener datos confidenciales de tipo contraseñas, usuarios y otros, pero todo el tráfico DNS que generamos indica perfectamente nuestra actividad en la red. Es por medio de DNS que se filtran contenidos (controles parentales por ejemplo), se bloquean contenidos (autoridades/entidades), los ISP pueden crear enormes bases de datos con nuestras costumbres… simplemente mirando el tráfico DNS podemos saber de una persona una cantidad de información que ni imaginamos!! Pues imaginar eso aplicado a una red local entera, o a una red de una empresa, o, por qué no, toda la red de un ISP.

El protocolo DNS se transmite en formato plano, “legible”. Desde hace muchos años han existido varias técnicas para “camuflar” o enmascarar el tráfico DNS, esto no es para nada nuevo. Estas técnicas han sido en su mayoría el uso de servidores VPN por ejemplo, donde las peticiones DNS se enviaban a través del mismo túnel, o usando el conocido DNSCrypt, una solución presentada hace tiempo por OpenDNS, unos servidores DNS independientes y gratuitos que ofrecen una buena tanda de opciones y filtrados para los hogares. No obstante este tipo de técnicas siempre ha tenido un impacto muy pequeño, y un poco por las razones de siempre: Soporte y estandarización.

Ya han pasado muchos años desde que Microsoft no dejase de implementar en su navegador Internet Explorer características propias. A día de hoy intentamos basarnos lo más posible en estándares, protocolos y técnicas que pueden ser usadas en cualquier sitio, que todos los dispositivos puedan entender y poder interaccionar unos con otros obteniendo resultados similares. Puede que DNSCrypt sea/fuese un sistema muy inteligente, pero sin ser un estándar ¿qué servidores DNS o que clientes iban a implementarlo? Por supuesto, era posible usando su servidor DNS y otros software, pero no es una solución real.

Por suerte, y aunque ha costado mucho mucho trabajo, se ve el final del problema gracias a DNS Over HTTPS/TLS (DoH). Me gustaría pensar que los retrasos se han debido al tiempo necesario para crear un estándar sólido, pero honestamente lo que creo es que a la gran mayoría de empresas, gobiernos y otros, cifrar el tráfico DNS es poner fin a un negocio multimillonario, a bloqueos, filtros… es una de esas cosas que públicamente nadie puede estar en contra, pero por detrás es raro encontrar quien esté de acuerdo. Sea como sea, y después de muchos tiros y afloja, DNS Over HTPS ya está “terminando” su camino para ser ratificado por la IETF como estándar, mientras que DNS Over TLS ya está estandarizado. Pero… ¿no son iguales? Bueno, en realidad no, son muy similares. Al igual que el protocolo DNS se usa mediante el puerto 53, DNS Over TLS usa un puerto específico para ello, el 853, y por él envía de forma serializada y ya bajo TLS las peticiones DNS. DNS Over HTTPS en cambio se basa en peticiones HTTPs estándares, usando por ello por defecto el puerto 443, y las peticiones son serializadas dentro de la propia petición HTTPS, creando una pequeña sobrecarga de protocolo inicial.

Aunque ambos sistemas encriptan por igual las peticiones DNS, realmente la diferencia de ellas desde un punto de vista práctico es que usar DNS Over TLS implica usar un puerto dedicado para ello, de modo que resulta mucho más sencillo bloquearlo, filtrarlo, discriminarlo o incluso como veremos luego obtener información de los dominios visitados de forma más sencilla… dicho de otro modo, es más fácil que terceros vuelvan a las andadas, aunque por otro lado es lógico que use un puerto propio. Por otro lado, DNS Over HTTPS usa el mismo puerto 443 que cualquier web HTTPS, con lo que el tráfico no solo pasa mucho más desapercibido, sino que además bloquearlo por puerto/servicio no sería una opción, a todos los efectos la conexión se vería como una conexión HTTPS más.

Usando por tanto DNS Over HTTPS enmascara todas nuestras peticiones DNS de forma doble. Por un lado encripta todo el tráfico DNS de modo que no pueda ser visible para terceros, y por otro lado “engaña” a cualquiera que pueda estar espiando el tráfico, a todos los efectos como si se tratase de tráfico HTTPS convencional.

Esto tiene infinidad de aplicaciones prácticas. Las más evidentes, nos blindan frente al exterior, impidiendo en la medida de lo posible que terceros puedan saber que Webs estamos o no visitando. Por otro lado este sistema permite “pasar por alto” innumerables filtros impuestos por gobiernos/ISP/entidades. Estos no pueden hacer filtros IPs por lo general, así que se filtran a nivel de DNS. Las primeras soluciones a esto eran usar servidores DNS alternativos, pero nada impide a un ISP interceptar las peticiones DNS a otros servidores. Con DoH no pueden evitarlo, las resoluciones nos son devueltas cifradas y bajo un tráfico que podría ser cualquier cosa.

 

Inconvenientes

Visto así, todo parecen grandes ventajas. No obstante el sistema no es perfecto, y además añade algunos “problemas” que no están presentes en las resoluciones DNS estándares.

El primer y posiblemente el mayor inconveniente es el retardo, la latencia. Negociar una conexión HTTPS completa con el resolver DoH, enviar la petición, y obtener la respuesta, consume sensiblemente más tiempo que una resolución DNS estándar. Este tiempo puede reducirse de diversas formas, por ejemplo manteniendo la conexión abierta con el resolver para futuras peticiones DNS o haciendo uso de HTTPS/2.0. Pero aun con todo, no podemos suprimir la negociación requerida para establecer una conexión HTTPS, que es la que se llevará la mayor parte del tiempo. Muchos creen que la mejor forma de evaluar un servidor DNS es ver la latencia hacia ellos, pero eso solo es un % del tiempo, lo que nos importa no es la latencia hacia el servidor DNS, sino el tiempo que va a tardar en respondernos con la dirección.

¿Cuanto es esta aportación a la latencia? Bueno, el mejor modo de comprobarlo es con pruebas reales. Para esta prueba se ha usado el servidor DNS de Google convencional 8.8.8.8, y por otro lado un resolver usando también el servicio DoH de Google, “https://dns.google.com/experimental”, en ambos casos deshabilitando todo tipo de cache

URL Servidor DNS 8.8.8.8 DoH https://dns.google.com/experimental
wikipedia.com 35ms 37ms
nic.es 31ms 39ms
facebook.com 11ms 38ms
google.es 32ms 42ms
theliel.es 32ms 38ms
twitter.com 12ms 38ms
elpais.com 38ms 40ms
microsoft.com 12ms 40ms
github.com 30ms 43ms
instagram.com 10ms 36ms

Los datos no son demasiado malos. Para dominios bien conocidos como Facebook, Twitter y otros, la latencia para resoluciones convencionales es mínima, ronda siempre los 10ms, mientras que el resto de hosts ronda una media de 33-34ms. Por contra, las resoluciones a través de DoH muestran un incremento claro, haciendo una media de 40-42ms. Estos resultados son simplificados y realizando medias entre 10 pruebas cada uno. En algunos casos existiendo gran variabilidad entre prueba y prueba.

 

El segundo inconveniente, es su soporte, su implementación. Mientras que el sistema DNS convencional está totalmente integrado en la propia estructura de Internet y podemos lanzar peticiones DNS desde nuestros equipos hacia cualquier servidor DNS, DoH es algo más complejo. Tal es así que actualmente requiere por un lado tener resolvers DoH, “servidores DNS” que sean compatibles con DNS Over HTTPS, que puedan traducir esas peticiones DNS encriptadas, resolverlas y devolvernos la dirección IP. Como es obvio, esos resolvers no elevan la petición DNS a servidores raíces por medio de DoH, sino por el modo convencional, pero esto no nos afecta, a menos que el resolver DoH fuese hackeado y guardase un registro de todas las peticiones realizadas. En todas las pruebas, en mi caso, he usado el servidor/resolver de Google DNS Over HTTPS que tienen habilitado: https:/dns.google.com/experimental.

Pero esto no es todo, así mismo requiere que los dispositivos sean compatibles también con DoH, ya sea a nivel integral en el propio OS, ya sea a nivel de aplicación. Esto es importante, porque como debemos de usar otro modo para realizar las peticiones DNS, requerimos de un software específico para ello, o que la aplicación esté preparada. En nuestro caso, por ejemplo, si usamos las últimas versiones de Firefox podemos habilitar el soporte para DoH de este, o podemos instalar un proxy en nuestro OS para que sea capaz de gestionar todas las peticiones DNS directamente de nuestra red.

En ambos casos, vemos que no es una opción que tengamos que habilitar si/no, requiere más que eso.

 

El tercer problema, y no menos importante, sea llama SNI. La idea detrás de DoH es cifrar las peticiones DNS, entre otras cosas para ocultar completamente los dominios que queremos visitar. El problema es que el uso de DoH no impida totalmente el “escape” de información que podemos tener referidos a los dominios visitados cuando son páginas webs HTTPS. Esto no es un problema de DoH realmente, sino del propio uso de los certificados digitales. Cuando realizamos una conexión HTTPS a cualquier host, el servidor remoto nos enviará en plano su certificado digital en el handbrake TLS. Los certificados digitales poseen una extensión llamada SNI, un campo que permite especificar los diferentes dominios para los cuales se aplica dicho certificado. Este campo no es obligado, es solo una extensión. Antes los certificados se emitían directamente para direcciones IPs específicas, pero con el agotamiento de estas ha sido cada vez más habitual que los servidores webs alojen bajo la misma IP muchas webs diferentes. Esto provoca que la emisión de certificados para una sola IP no sea viable, y se comenzó a usar SNI. Con SNI podemos especificar en el certificado los diferentes dominios, aun cuando todos ellos están bajo la misma IP.

El problema se ve claro, si un certificado que nos envía un servidor especifica el dominio para el cual ha sido emitido (el mismo), esa información también es potencialmente interceptable y usarla para conocer que hemos visitado dicho servidor. Eso no quiere decir que DoH sea inservible ni mucho menos. Para empezar un mismo certificado se emite muchas veces para diferentes dominios, así como consiguientes conexiones al mismo dominio tampoco requerirían de nuevo el certificado del servidor remoto. Otros servidores no usan siquiera SNI, y dentro de poco con la llegada de IPv6 es posible que en un futuro incluso sea común volver a certificados pre SNI, donde lo normal era su emisión para IPs.

Si un servidor nos responde con su certificado donde se especifica en SNI el/los dominios, nada evita que de nuevo se use software que rastree cada certificado que nos respondan los servidores remotos para hacer un perfil de nosotros de las webs visitadas. Pero estos sistemas al margen de ser más raros, tienen muchas limitaciones que de otro modo sería extremadamente sencillo tener un mapa completo del uso que hacemos en Internet, simplemente mirando las peticiones DNS.

 

El cuarto y último problema es que a veces falla. El software actual es limitado y tiene aun fallos que podemos encontrarnos, sin contar los problemas que pueden tener los resolvers actuales. Repito, todo esto es bastante nuevo, con lo que es de esperar algunos problemas, los más normales son resoluciones DNS que no son respondidas correctamente. Para atenuar esto, la mayoría de software cliente que existe permite configurar un servidor DNS convencional como fallover, en caso que DoH nos falle en alguna petición.

 

Como configurarlo

Bueno, por desgracia, y lo hemos visto en sus inconvenientes, no es algo que sea ejecutar y listo. Vamos a depender primero de un resolver DoH que actuará a modo de “proxy” entre DoH y peticiones de resolución DNS estándares. Cuando a estos resolvers les llegue una petición por DoH, la resolverán y nos la devolverán. Obviamente la confianza es esencial, a fin de cuentas que pasaría si dicho Resolver igualmente guardase una base de datos con las IPs originarias de las peticiones y una lista de los dominios accedidos.

Por otro lado como decíamos, requerimos de software o aplicaciones que sean capaz y compatibles con DoH. Ahora que es un estándar es de suponer que el soporte será ampliado enormemente, sobre todo en aplicaciones que nos gustan que sean seguras. Actualmente hay que decir que quedan cosas por pulir, el estándar DoH aun no ha sido alcanzado y algunas cosillas pueden cambiar. Algunos proveedores conocidos ya han lanzado resolvers DoH para poder ser usados de forma pública y gratuita, como Google o CloudFlare. Así mismo existen actualmente también la otra parte, software cliente para que podamos hacer uso de dichos resolvers. En este caso, quizás los dos casos más importantes en este punto sería el propio Navegador Web Firefox y DNSCrypt-Proxy. Al margen de ello, Google ya implementó DoH en Android también.

 

Firefox

El caso más básico y más sencillo de todos vamos a verlo con Firefox. Para ello necesitamos al menos Firefox 62, que si la memoria no me falla debería de estar ahora mismo en el canal Beta, Firefox 63 en Alpha. A partir de aquí es muy sencillo. Por defecto el soporte para DoH viene deshabilitado, ya que es un cambio importante. Básicamente necesitamos sólo realizar un par de ajustes en el editor de configuración. Para quien no lo conozca, el editor de configuración de Firefox se accede desde la barra de direcciones accediendo a: about:config.

 

network.trr.mode: (el modo de funcionamiento de DoH)

0: Deshabilitado
1: Usa ambos modos, DoH y resoluciones convencionales, el navegador usará la que resuelva antes
2: Usa DoH de forma predeterminada, y DNS convencionales como fallover
3: Usa solo DoH
4: Lanza ambas peticiones, pero solo usa las resoluciones convencionales.

network.trr.uri: (URL del resolver a usar)

Google: https://dns.google.com/experimental
CloudFlare: https://cloudflare-dns.com/dns-query
Mozilla/CloudFlare: https://mozilla.cloudflare-dns.com/dns-query

network.trr.bootstrapAddress: (opcional)

Si forzamos el uso del modo 3, como en mi captura, es necesario especificar la dirección IP del resolver. No podemos usar DoH sin conectarnos al resolver, con lo que necesitamos su IP, pero si forzamos usar solo DoH entramos en un bucle del que no salimos. De este modo preestablecemos la IP del resolver. No se requiere para el resto de los modos.

 

Hay muchos modos para conocer si DoH está funcionando en nuestro equipo. Un modo sería consultar la página de estado de Firefox sobre las peticiones DNS:

about:networking#dns

Podemos localizar la columna TRR y ver si para dicha resolución se está usando DoH o no.

Otra opción es usar un analizador de paquetes, y comprobar que no aparece tráfico DNS, al menos generado por el navegador web.

 

DNSCrypt-Proxy

DNSCrypt-Proxy es un proyecto de código abierto y multiplataforma. Actúa básicamente como un proxy que toma las peticiones DNS convencionales y las envía a un resolver por DoH. El proyecto lo tenemos en Github.

DNSCrypt-Proxy no es para nada nuevo, pero si ha sido recientemente cuando han añadido soporte para DoH. Anteriormente funcionaba con DNSCrypt de OpenDNS, de ahí su nombre, pero actualmente es compatible también con resolvers DoH. Este software es muy interesante porque nos permite pasar por ejemplo todas nuestras peticiones DNS (de todo el equipo, con independencia de que aplicación se use) a DoH. O mejor aun, si lo instalamos y configuramos en un Router, podemos asegurar directamente toda la red local, haciendo que absolutamente todas las peticiones DNS pasen por él. Esta última alternativa sería la ideal en entornos domésticos, pero ojo, de hacerse así no nos protegería de terceros conectados a nuestra red local, ya que las peticiones que se enviasen de nuestros equipos al Router si serían resoluciones DNS convencionales, sería el Router quien las convertiría en peticiones DoH y las enviaría hacia fuera.

En mi caso he optado por este último esquema, configurarlo directamente en el Router y no tener que tocar absolutamente ningún equipo ni dispositivo de mi red. El como hacer esto, es algo ya más complejo y que excede el artículo original. Para poder instalarlo en un Router se debería de descargar los binarios precompilados (o compilarlos) para nuestro dispositivo, crear la configuración necesaria, crear scripts para levantar los servicios… y como último paso decidir si queremos añadir reglas en iptables para forzar las peticiones DNS enviadas a servidores externos ser tratadas también de forma interna. En mi caso, y por cuestiones varias, prefiero no forzar las peticiones DNS externas. Es decir, que si alguna aplicación lanza una resolución DNS hacia un servidor DNS específico que no sea mi Router, serán convencionales, si usa las DNS del sistema, usará el Router y por ende irán bajo DoH.

La mejor forma de ver si funciona en este caso, es colocar un analizador de paquetes en la interfaz WAN PPPoE del Router, y capturar las peticiones DNS.

Esta primera prueba lanza una petición DNS a los servidores convencionales de google, 8.8.8.8. Dig es lanzado desde cualquier equipo de la red, tcpdump desde el Router:

dig theliel.es +noall +answer +stats @8.8.8.8

theliel.es. 599 IN A 188.121.46.128
;; Query time: 50 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Fri Jul 20 18:19:02 Hora de verano romance 2018

tcpdump -i ppp0 udp port 53

16:19:02.137737 IP xxx.red-xxx-xxx-xxx.dynamicip.rima-tde.net.57185 > google-public-dns-a.google.com.domain: 14372+ [1au] A? theliel.es. (51)
16:19:02.384289 IP google-public-dns-a.google.com.domain > xxx.red-xxx-xxx-xxx.dynamicip.rima-tde.net.57185: 14372 1/0/1 A 188.121.46.128 (55)

Esto es el comportamiento normal, tcpdump está escuchando el tráfico en el puerto 53 que es por donde se realizan las peticiones DNS, y por tanto no solo registra la petición DNS realizada con Dig, sino que además incluso nos muestra directamente tanto la petición como la respuesta del servidor de Google.

Esta segunda prueba lanza la misma petición, pero esta vez usando los servidores DNS predefinidos por el servidor DHCP del Router (el mismo Router), que a su vez enviará las peticiones hacia el resolver configurado en DNSCrypt-Proxy:

dig theliel.es +noall +answer +stats

theliel.es. 573 IN A 188.121.46.128
;; Query time: 43 msec
;; SERVER: 192.168.2.1#53(192.168.2.1)
;; WHEN: Fri Jul 20 18:25:49 Hora de verano romance 2018

tcpdump -i ppp0 udp port 53

tcpdump -i ppp0 tcp port 443

16:28:41.849811 IP xxx.red-xxx-xxx-xxx.dynamicip.rima-tde.net.57197 > mad07s09-in-f14.1e100.net.https: Flags [P.], seq 8119:8303, ack 48627, win 4006, options [nop,nop,TS val 16309141 ecr 1452692457], length 184
16:28:41.859322 IP mad07s09-in-f14.1e100.net.https > xxx.red-xxx-xxx-xxx.dynamicip.rima-tde.net.57197: Flags [.], ack 8303, win 1050, options [nop,nop,TS val 1452694899 ecr 16309141], length 0
16:28:41.881146 IP mad07s09-in-f14.1e100.net.https > xxx.red-xxx-xxx-xxx.dynamicip.rima-tde.net.57197: Flags [P.], seq 48627:48721, ack 8303, win 1050, options [nop,nop,TS val 1452694921 ecr 16309141], length 94
16:28:41.881295 IP mad07s09-in-f14.1e100.net.https > xxx.red-xxx-xxx-xxx.dynamicip.rima-tde.net.57197: Flags [P.], seq 48721:48811, ack 8303, win 1050, options [nop,nop,TS val 1452694921 ecr 16309141], length 90

En este caso, a pesar de que Dig lanzó la petición DNS y quedó resuelta correctamente, tcpdump no es capaz de detectar tráfico por el puerto udp 53. Para poder “capturar” el tráfico, tendríamos que escuchar con tcpdump en el puerto TCP 443, como podemos ver… o no ver, porque el tráfico va encriptado, como mucho podemos saber que se está lanzando tráfico https a un servidor de google, pero imposible saber de que se trata, y menos aun pensar que es tráfico DNS.

 

Conclusiones

Es muy interesante que por fin tengamos un sistema fiable (y más importante, usable) para el cifrado DNS, y que por supuesto esté siendo estandarizado. Mozilla se ha puesto a trabajar duro en ello, Google está dando pasos agigantados también en la misma dirección, con lo que es de esperar que el resto se vayan uniendo a la fiesta. Esto no quiere decir que en dos días, un mes o un año todo el tráfico DNS irá cifrado, ni muchísimo menos. Del mismo modo que desde hace años disponemos de DNSSec, lo cierto es que solo un % pequeño lo usa, la mayoría de las Webs tampoco están adaptados para esto. DNS no se puede sustituir, pero si podemos imaginar que cada vez más servidores DNS convencionales permitirán su uso como resolvers DoH. Esto, sumado a que puede ser incorporado de forma transparente en las aplicaciones que se requieran, hace previsible su uso en muchos campos.

De los modos sistemas mostrados aquí, posiblemente para el usuario normal el que puede empezar a usar si así lo quiere es a través de Mozilla Firefox. Que yo sepa, a día de hoy Chrome no puede configurarse de un modo similar, pero es solo cuestión de tiempo, si es que no se puede ya. Esto no nos protegerá la red de nuestra casa, pero si todo el tráfico que generemos desde el navegador.

Para quien quiera aventurarse un poco más, puede instalar en local DNSCrypt-Proxy y configurarlo en su equipo para aplicarlo de un modo integral a su propio equipo, y por último, los más osados, pueden hacerlo en el Router, y afectar a todo el tráfico que genere nuestra red local.

Esto no va a saltarse de golpe todos los bloqueos existentes, no va a hacer que nadie bajo ningún concepto pueda saber las direcciones que visitamos, pero sin duda alguna es un plus muy importante a nuestra privacidad, sobre todo si tenemos un portatil o un dispositivo móvil el cual usamos en redes de datos de los ISP o en redes WIFIs públicas o que no controlamos, es aquí donde la configuración por aplicación es igualmente importante. Es decir, ya se use en el Router o en las propias aplicaciones, un uso no sustituye el otro.

Los problemas de rendimiento están presentes, no podemos engañarnos, pero es cierto que la inmensa mayoría de las veces son imperceptibles, y solo de cuando en cuando notamos realmente un “parón” en la resolución DNS y tarda algo más de lo habitual. Pero el 99% del tiempo no notaremos ninguna degradación.

Hay que entender que de cualquier modo todo es muy experimental, el estándar no se ha terminado de aprobar y algunas cosas aun cambiarán, por suerte para mejor con seguridad.

Saludos.

Vuelve a pasar, “un carácter de la muerte” vuelve a los equipos de Apple

Para quien no esté al corriente de otras ocasiones, digamos que actualmente cualquier dispositivo de Apple (iOS o MacOS) por actualizado que esté (excepto versiones betas) provocará el cierre/bloqueo de la aplicación si esta tiene que renderizar un carácter concreto. En este caso es un carácter Telegu, un dialecto Indio: జ్ఞ‌ా

Sí, eso significa que incluso este mismo post producirá el bloqueo/cierre de la aplicación que lo abra en los dispositivos de Apple. Pero esto no es nuevo. Hace ya algunos años pudimos ver algo similar, aunque en aquella ocasión era más bien una cadena de texto: “سمَـَّوُوُحخ ̷̴̐خ ̷̴̐خ ̷̴̐خ امارتيخ ̷̴̐خ”. Ya en su día escribí un pequeño artículo al respecto:

La Cadena de la Muerte

La historia es la misma, de echo todo lo que puse en ese post se podría volver a poner aquí. La única salvedad es que en esta ocasión es un carácter, en vez de una pequeña cadena.

Vemos fallos de seguridad y bugs a diario, nadie se salva de ellos. La mayoría no suelen tener una gran transcendencia por grave que sean debido a que explotarlos es algo complicado. Es aquí donde este tipo de errores alcanza una importancia capital, aunque sea algo inocuo y que no afecte demasiado. Es decir, para que un fallo de seguridad o un bug sea realmente importante se deben de dar una de estas dos premisas: O que el grado de peligrosidad, a lo que afecta, sea enorme aunque sea muy complicado usarlo, o que con independencia de lo peligroso que sea, sea extremadamente sencillo disparar el fallo.

Algo similar vimos hace poco cuando se descubrió que cualquier usuario de MacOS podía resetear la contraseña de administrador de forma extremadamente sencilla, sin conocerla, sin tener los credenciales necesarios. En dicho caso, la peligrosidad, al margen del efecto logrado, es que era algo tan simple como hacer clic dos veces en un botón.

Vivimos ahora mismo en el mundo de las comunicaciones. Es más, la mayoría que lea este artículo lo hará posiblemente desde un teléfono. La mayoría del tiempo que pasamos con nuestros dispositivos es usando aplicaciones de mensajería instantánea, redes sociales, webs… es decir, precisamente los vectores por donde cualquiera, repito cualquiera, podría usar dicho carácter. Muchos podrán pensar que bueno, es cuanto menos “divertido” pero realmente no tiene mucha importancia, quien ha visto alguna vez ese carácter, y que en nuestros círculos no va a suceder. El problema es que mientras que Apple lance la actualización o no, y más sitios se hagan eco, más copias de dicho carácter veremos, en todos lados.

Usas WhatsApp?? No importa, como alguien lo use de esto, los usuarios de iOS que lo tengan a él en la agenda y vea la lista de estos no podrán abrirlo. Y en grupos?? Prueba y verás la gracia. No es peligroso desde el punto de vista que no van a robarte información ni acceder a ella, ni van a producir un daño a tu dispositivo irreparable, ese no es el problema. El problema es que sencillamente cualquiera puede dejarte inutilizada la mayoría de aplicaciones que se usan a día de hoy, ya sea por diversión, a modo de prueba…

Actualmente, como he dicho, no hay solución. Sólo la versión Beta de iOS última parece solucionarlo. Pasarán posiblemente días o alguna semana antes de que Apple lance una actualización formal. Quien use Apple, no puede protegerse de otro modo, en todo caso actuar si se ha recibido el carácter o hay sospecha de ello. Dependiendo del medio, tendrá que realizar diferentes acciones. Así por ejemplo si el carácter lo recibió por Safari al acceder a una web, tendrá que evitar dicha dirección, e incluso a lo mejor necesario eliminar del historial la página. Si es por WhatsApp en un estado, eliminar a dicho contacto, si es en un mensaje, eliminar dicho mensaje o incluso es muy posible que eliminar el historial de dicho contacto, o todo el historial… etc etc etc.

Así que amigos manzaneros, cuidado, si estos días el terminal se bloquea en algunas aplicaciones, cierres forzados de estas, congelaciones… puede ser que algún bromista (me declaro culpable de serlo también) esté causando estragos en tu dispositivo. Pero antes de las consabidas críticas, tener presente algo: No justifico en modo alguno quien lo haga de forma lesiva o para molestar o producir mal a otros, pero en el peor de los casos pensar que es como darle un caramelo a un niño pequeño, si se lo das se lo va a comer, lo que tendría que tener más cuidado Apple (o los padres) es que estos escenarios no vuelvan a producirse, que con este ya son 3-4 las veces que ha sucedido.

¿Y por qué sucede? Es por el modo que Apple renderiza las fuentes. Mientras no se cambien o al menos modifiquen como interacciona con el sistema, es muy posible que antes o después vuelva a aparecer otro “carácter” o frase o… y que la historia, de nuevo, vuelva a repetirse.

Saludos.

¿Un fallo de seguridad en High Sierra (MacOS) permite acceso Root a cualquiera? Sí, y más simple imposible

Generalmente no suelo hacer eco de estas noticias a menos que el fallo de seguridad (o el exploit) tenga una relevancia/peligrosidad tan elevada. Y es que creo que a estas alturas el que más o el que menos (y si tiene High Sierra espero que seguro) que esté en el “mundillo” habrá escuchado las noticias por todos lados. Sinceramente, creo que nos tenemos que remontar a la famosa “Cadena de la Muerte“, en 2013, para encontrar algo tan flagrante, y en esta ocasión Apple se ha superado, lo ha logrado, nadie lo sabe bien pero lo ha conseguido, basta invocar la cuenta Root en el sistema para que este la cree en ese momento y le asigne una contraseña en blanco. Dicho de otro modo, si cualquiera se pone delante del sistema tenga la cuenta que tenga e intenta entrar/usar el usuario “root”, sin especificar ninguna contraseña, al segundo intento generalmente entra (El primero la crea, el segundo accede).

Bien, no hace falta decir que el usuario root es por lo general la cuenta/usuario maestro en casi todos los sistemas UNIX/Linux, el super administrador. Es decir, que como tal usuario tendremos acceso total al sistema. La cosa es aun peor, porque si el equipo tiene habilitados servicios de acceso remoto, la gracia se puede mascar en el aire.

No es un exploit remoto que permita ejecución arbitraria de código, es un bug en principio con alcance local, y como tal requiere acceso físico al equipo. No obstante a nadie se le escapa la gravedad del asunto. Para usuarios particulares que usen el equipo en entornos digamos de confianza o familiares o… generalmente no va a suponer un gran problema si los que nos rodean tenían acceso igualmente al equipo de forma indiscriminada, pero en entornos más empresariales, equipos portátiles que en cualquier momento puede ser “dejado” en cualquier lugar, el problema no tiene parangón.

La cosa es aun peor, y es posiblemente una de esas políticas que tanto tiempo llevo recriminando a Apple con más intensidad. La falta de actuación y transparencia. Este fallo no ha sido descubierto hoy, Apple lleva tiempo con conocimiento de ello. Es más, hace más de dos semanas se comentaba abiertamente en los foros de soporte, e incluso por lo que dicen, se daba como solución a usuarios que necesitaban acceder a sus propios equipos como Root. En cambio, como siempre, silencio. Hoy, por el motivo que sea a saltado a la prensa, y nos hemos enterado la mayoría (personalmente no tenía constancia de ello), y como Apple hace siempre, es cuando lanza un comunicado diciendo que tendrán la actualización lista para solucionarlo “pronto”. No dudo en absoluto que lo solucionen pronto, eso no me preocupa, ni siquiera en realidad este bug por grave que sea, lo que me preocupa es la falta de inacción por parte de Apple, y que sólo se pone las pilas cuando el problema se escala a los medios de comunicación. La “cadena de la muerte” estuvo funcionando durante semanas sin que se solucionase incluso siendo ya un “vox populi”. Dicho de otro modo… si algo tan sencillo y tan absurdo como este bug (y tan grave) lleva semanas rondando por los foros oficiales de Apple y no han hecho nada, ¿qué exploits/bugs habrá en la trastienda (con conocimientos o sin ellos por parte de Apple) que no conocemos?

Siempre he dicho y “defendido” el error humano. Nadie es perfecto y todas las empresas cometen errores, y de todos los tamaños por cierto. A veces esos errores son tan tontos como es este caso y otras veces la gran genialidad de expertos de seguridad logran meterse en los resquicios más insospechados para hacer saltar un sistema. Esto sucede constantemente y no pasa nada, lo asumimos y lo aceptamos porque en cierto modo nos fiamos de los desarrolladores que, en función de la gravedad y la importancia, tal como los problemas vayan apareciendo, se irán solucionando de igual modo. Puedo perdonar a Apple de que alguno de sus programadores haya metido la pata hasta donde la ha metido, lo que no puedo perdonar es que la vulnerabilidad lleve circulando semanas por su propio foro, y no haya dicho ni hecho absolutamente nada. Eso sí, hoy que salta la noticia a la prensa es cuando se mojan. Deleznable.

Router Mitrastar HGW-2501GN-R2: Shell e Ingeniería inversa (para crear firmwares modificadas, por ejemplo) (Actualizado)

mitrastar
Introducción

La historia es sencilla. Aunque en la medida de lo posible siempre uso mis propios dispositivos, me gusta igualmente exprimir cualquier otro chisme que tenga por casa. Unos fuman… yo cacharreo.

En este caso, este fue el router que me entregó el ISP para mi conexión de Fibra, Mitrastar HGW-2501GN-R2. Duró conectado a la línea el tiempo de irse el instalador, pero lo saqué recientemente del “trastero” al ver por los foros de soporte oficiales (y no oficiales) que estaba dando un sin fin de problemas a los usuarios. Como siempre he dicho, opinar podemos hacerlo todos, pero si queremos dar soluciones que sean lo más acertadas posibles, es mejor comprobar las cosas por uno mismo y poder estudiarlas como dios manda. Así que le saqué el polvo y me puse a desentrañar sus más y sus menos.

Un dispositivo es bueno o malo sencillamente a razón de dos cuestiones sencillas, y es lo bueno o malo que sea su hardware y su software. Si el hardware es “malo” las ataduras de manos siempre son mucho peores, porque salvo modificaciones directamente en el hardware poco podemos hacer. Un hardware bueno tampoco hace del dispositivo algo bueno, es fundamental el Software, y sobre el software podemos decir lo mismo.

En el caso del Mitrastar, tenemos un poco de todo. Respecto al hardware no es ni mucho menos de lo peor que podemos encontrarnos en un router como muchos puedan pensar, pero eso no quiere decir que no se hubiese podido mejorar sustancial, sobre todo lo referente a su interfaz wifi. Eso no podemos cambiarlo, tenemos que aguantarnos con lo que hay. No he conectado aun el router por puerto de serie ni lo he sacado de su carcasa, así que los siguientes datos pueden no ser exactos del todo. Por lo que podemos saber el hardware se compone de una arquitectura MIPS:

CPU1: Ralink RT63368F (En Placa)/RT63365 (En Software)
Switch: Realtek RTL8368MB
Wl0: Ralink RT5392
RAM: 128MB
Flash: 64MB

El Switch debe de contar con unos 7 puertos diferentes, apoyado principalmente por el SOC RT63365. El adaptador inalámbrico dista mucho de ser una maravilla, nos encontramos ante un disposotivo 802.11n de dos streams unibanda. Por otro lado contamos con una cantidad más que suficiente de RAM y Flash para todo, lo cual siempre se agradece el no ir siempre bajo mínimos.

El principal problema que se ha tenido es que el software del router (la firmware) ha estado lejos de ser aceptable, salvaguardando por supuesto las propias limitaciones del hardware. Entre las quejas más frecuentes han sido los enormes problemas de batería causados por el router a dispositivos portátiles, la interfaz web de configuración con constantes problemas… En un mundo ideal, como se trata de Software, en el peor de los casos podríamos decir: “Pues si no quieren hacer ellos su trabajo, al menos voy a ver si puedo yo mejorar o corregir alguno de esos problemas de software”. Pero nunca suele ser tan sencillo, las firmwares y los sistemas se protegen precisamente para impedir cualquier tipo de modificaciones al software, siguen sin entender que cuanto más abierto sea un software más probabilidad hay que funcione mejor y con menos fallos/problemas.

 

Acceso Básico

Manos a la obra, partamos desde cero. Instalamos el router, lo tenemos todo funcionando… ¿ahora que?. Aquí entra en juego el primer escollo, y la culpa de esto la tiene principalmente los ISP, nada que ver con los fabricantes del hardware o el software que se instala (por lo general). Los dispositivos que nos entregan actualmente (No solo Movistar) vienen precargados con una configuración básica por defecto con los ajustes básicos de la compaña, como puedan ser los SSID, ajustes de WAN… ahora debido a los servicios avanzados como VoIP o IPTV suele ser necesario además de todo esto ajustes adicionales específicos para cada cliente, así que el router está preparado para conectar a los servidores de ellos después de un reset o cada X tiempo para reconfigurarse con los datos de la línea del cliente. Esto es perfecto porque evita configuraciones manuales uno a uno.

Lo primero que quiero o puede querer cualquiera es realizar pequeños ajustes a nuestro router, ya sea abrir un puerto, configurar una IP diferente… eso lo hacemos como toda la vida de dios, lo más básico y sencillo: La interfaz web del Router. El problema aparece porque la mayoría de los ISP se preocupan y hacen TODO LO POSIBLE para que el usuario, el cliente, tenga acceso a cuantas menos funciones posible del router mejor. Esto se hace por lo general con la creación de usuarios con permisos mucho más restrictivos a los usuarios tipo admin/root con acceso completo. Estos usuarios que crean tienen al final acceso para modificar 3 parámetros y medio y no poder consultar muchas otras configuraciones que pueden ser de interés, con lo que nos limita enormemente, incluso a usuarios con un perfil básico. Esto es algo que la mayoría no toma en cuenta cuando contrata un ISP u otro, pero para mí es esencial y marca mucho el tipo de compañía que tienes delante. Muchos de los amigos que me leen saben mi opinión sobre Apple, y se resumen sencillamente en que no permito que una compañía me diga que puedo hacer o no hacer con mi hardware.

Dependiendo del dispositivo que tengamos instalado y dependiendo del ISP, podremos acceder de mejor modo o no la configuración de nuestro router. En el caso concreto del Mitrastar, tengo que decir sinceramente que chapó por Movistar, ha hecho lo que tenía que haber echo hace tiempo y hacer TODOS. El Mitrastar, como viene siendo ya costumbre desde hace tiempo en los dispositivos de Movistar tiene dos interfaces web, una sencilla para usuarios nóveles que quieren cambiar 3 cosas (llamada Movistar Home Station, aka mhs, y una avanzada. El Mitrastar posee 3 usuarios (en realidad son 4, pero el usuario samba lo obviamos), cada uno con permisos diferentes enfocados a necesidades diferentes:

-“admin”: La contraseña de este usuario podemos encontrarla debajo del router en una pegatina. Este usuario y contraseña nos da acceso a las dos interfaces del router. Es el acceso normal a la interfaz mhs, y si accedemos a la avanzada a través de mhs (o a través de la dirección http://IP/cgi-bin/main.html) nos encontraremos con limitaciones en cuanto que podemos modificar. Esta cuenta por otro lado carece de acceso por terminal (SSH/Telnet…)

-“1234”: La contraseña coincide con la contraseña anterior, y en este caso sería lo más similar a un usuario root. Tiene acceso completo a las opciones de configuración de la interfaz, y es la cuenta que usa el portal Alejandra igualmente para configurar de forma remota nuestros dispositivos (si los tenemos asociados al portal).

-“supervisor”: La contraseña en este caso es siempre la misma, zyad1234, y posee permisos similares al usuario 1234, con el añadido de que con este usuario se tiene acceso por la interfaz web a poder modificar los permisos de los otros usuarios y de sus contraseñas igualmente.

mhs
web

Ahora entenderéis porqué digo que en este caso chapó por Movistar. Cualquiera puede tener acceso completo (al menos por web) al Mitrastar, sin hacer cosas extrañas, sin tener que pelearse, sin acudir a… dicho de otro modo, los técnicos de Movistar no tienen un mejor acceso que nosotros. Gracias a estos usuarios podremos no sólo consultar la mayoría de todas las configuraciones del router, sino que también ajustarlas a nuestro antojo.

Por otro lado, lo primero que se le ocurre a cualquiera es ver como son los archivos de configuración (backup) del router, así que como primer paso para entender un poco todo lo que cualquiera haría sería descargar dicho archivo desde mantenimiento, quizás sea legible o haya algo o algún ajuste que pueda ser de interés. El archivo de configuración del Mitrastar, por suerte, no está cifrado y parece ser un xml totalmente legible, pero que algunas opciones curiosamente las enmascara, todas aquellas donde hay contraseñas. Por qué es esto interesante?? Bueno, yo he dicho que la contraseña de admin y 1234 es la misma, pero a veces no es tan sencillo como prueba/error, o mejor dicho… a veces es más sencillo no tener que estar probando… pero como vemos el archivo de configuración no permite ver estos datos. En cualquier caso, vemos que estos campos llamados “encrypted” comienzan todos por: “41455300”, casualidad que 41 45 53 = AES, lo cual nos daría a pensar que el resto es posible que sea el texto codificado en AES.

 

Acceso Limitado por Terminal

El 99% de las veces nos sobra la interfaz web, pero que pasa cuando nos gustaría poder modifica o consultar cualquier cosilla que no esté presente o tengamos acceso por la interfaz web?? A fin de cuenta presuponemos que nuestro router estará corriendo algún tipo de Linux debajo de él. Para eso es indispensable acceso mediante SSH o Telnet. El problema es que como aplican la mayoría de fabricantes, para negarnos la posibilidad de toquetear las tripas, lo que nos dan es acceso es a una shell limitada… muy limitada. Así, en el caso del Mitrastar si intentamos acceder mediante supervisor o 1234, nos encontramos ante un panorama… “triste”:

ssh

Así pues podemos acceder con las credenciales por defecto, pero los únicos comandos que nos muestra la interfaz como válidos son: ?, exit, save, sys, restoredefault, lan, igmp, wlan, nat. La mayoría de todos ellos tienen subcategorías. No hay nada interesante a priori que podamos hacer desde la shell que no podamos hacer desde la interfaz web. Dos comandos “al azar” muestran dos resultados interesante: mtd y sh, ninguno de los dos listados en los comandos disponibles. El primero nos devuelve que el comando está prohibido, el segundo directamente que introduzcamos una contraseña… ¿quizás existe una contraseña para poder acceder a la shell que hay debajo? Por descontado ninguna de las contraseñas que disponemos es aceptada como válida.

Algo relativamente común a las shell limitadas es que permiten realizar copias de la configuración. A priori podríamos pensar que esos “dump” son iguales que los que podemos obtener desde la interfaz web, pero… que pasa si introducimos por shell limitada “sys dumpcfg”?? Sí, nos devuelve en la consola exactamente el archivo de configuración que pudimos descargar con anterioridad… pero con una salvedad, en esta ocasión los campos de contraseña están en texto plano. Bingo!!

username=”supervisor” web_passwd=”zyad1234″ console_passwd=”zyad1234″

La contraseña es la misma, pero en cambio en el archivo de configuración cifrado vemos que el “resultado” es diferente. Asumimos que además de poder estar cifrado con AES usa algún tipo de SALT, y no sólo una key cualquiera. Aun así esto tampoco nos abre la puerta a mucho más, esta contraseña es de hace mucho conocida y compartida en muchos productos.

 

Acceso a la Shell que hay debajo

Lo que nos interesa es acceder detrás de la shell limitada a la que tenemos acceso. Parece que para esto existe directamente un medio para hacerlo, a través del comando “sh” desde la shell limitada, pero esto nos solicita una contraseña que es totalmente desconocida para nosotros. Aquí empieza realmente el trabajo duro, ingeniárselas de algún modo para poder acceder debajo, aunque sólo sea una vez, y poder echar un vistazo desde una shell completa. No voy a detallar, por cuestiones de seguridad, como logré ese primer acceso, pero sí de que se trata.

Presuponemos que tenemos Linux debajo, con lo que realmente lo primero que desearíamos sería echarle un ojo al archivo /etc/passwd y/o /etc/shadow. Estos dos archivos, en linux, son los que contienen las credenciales de los usuarios y sus contraseñas (cifradas claro está). Pero además contienen la shell que será ejecutada a cada usuario. Es posible que el router posea otro usuario/contraseña que desconocemos o a saber…

Pongamos que gracias a la interfaz web logramos ejecutar de algún modo algún comando dentro de la shell y sacar los datos por el navegador. “cat /etc/shadow” cat /etc/passwd” sería sin duda alguna las primeras pruebas, y pongamos que en un momento dado la interfaz web nos devuelve lo deseado, nada para shadow, y para passwd:

1234:$1$$xxxxxxxxxxxxxxxxxxxx:0:0:root:/:/bin/cmdsh
admin:$1$$xxxxxxxxxxxxxxxxxxxx:0:0:root:/:/bin/sh
supervisor:$1$$xxxxxxxxxxxxxxxxxxxx:0:0:root:/:/bin/cmdsh
samba:$1$$xxxxxxxxxxxxxxxxxxxx:500:500:Linux User,,,:/home/samba:/bin/sh

Bingo!! (de nuevo). Parece ser que además de existir un cuarto usuario, samba, el usuario 1234 y el usuario supervisor (que son los dos únicos que tienen acceso por shell) ejecutan una shell extraña llamada “cmdsh”. Sea como sea, si logramos ejecutar con suerte cat, podríamos igualmente intentar sobrescribir el contenido del archivo, igual no existe una protección contra escritura… como dicen, probar no cuesta nada… usando incluso de nuevo cat, se puede enviar el mismo archivo pero modificando la shell a ejecutar, en vez de /bin/cmdsh, /bin/sh. Lanzamos la petición, volvemos a lanzar otra para ver el contenido y… se ha modificado!!. Ejecutemos de nuevo una sesión Telnet/SSH, usuario 1234 (es al usuario que le cambie la Shell), su contraseña… y efectivamente no más shell limitada:

login as: 1234
1234@192.168.1.1’s password:
# ls
bin      boaroot  dev      etc      lib      linuxrc  proc     sbin     sys      tmp      userfs   usr      var
# uname -a
Linux MitraStar 2.6.36 #1 SMP Thu Aug 13 14:04:19 CST 2015 mips unknown
#

 Llegados a este punto ya lo tendríamos todo?? Sí y no. Esto habría que repetirlo siempre, porque si reiniciásemos el router veríamos que el cambio que habíamos realizado al archivo passwd se perdería, teniendo que repetir todo el proceso constantemente. Aun así al menos ya habríamos logrado acceder a la Shell de debajo con plenos permisos administrativos. ¿Podemos mejorar esto? Por supuesto.

Lo primero que viene a la cabeza es: Bien, puedo acceder gracias un exploit, pero parece ser que la shell cmdsh tenía un comando “sh” que solicitaba una contraseña para acceder, y no hay que ser muy listo que lo que permite es acceder precisamente a una shell completa. ¿Donde puede estar esta contraseña? Personalmente el primer lugar donde miraría, teniendo en cuenta que no parece existir otros usuarios en el archivo /etc/passwd, es en el binario de la propia shell, o sino este sabrá de donde obtenerla, dado que es esta shell la que lo solicita. Ya sabemos donde está, así que sólo tenemos que extraerlo. Esto puede hacerse de mil y una forma, dependiendo de las herramientas que tengamos disponibles claro está en la firmware del router:

-ssh/sftp/ftp/scp
-curl/wget
-netcat/nc
-base64
-usb
-…

Cualquier sistema nos vale para enviar donde queramos el archivo en cuestión y poder manipularlo en condiciones, la elección de un sistema u otro dependerá de las utilidades que tenga la firmware y de lo sencillo o no que nos resulte a nosotros mover los archivos. Una vez tengamos el archivo, tan solo tendríamos que decompilarlo y echar un vistazo rápido. Vamos a lo sencillo, si cuando introducimos a través de sh una contraseña cualquiera recibimos: “Password incorrect !” Podemos empezar buscando por ahí, o mirar directamente las posibles funciones… eso nos lleva al siguiente trozo de código:

diss

Curiosamente, justo unas líneas de ahí encontramos una extraña cadena alfanumérica. Bueno, además de que el código en ensamblador es bastante legible, lo que está claro es que compara un string (lo que introducimos por teclado) con el string “c93vu02jp4z04“. Si la comparación es incorrecta, vemos que salta a la posición 0x00402408 (=contraseña incorrecta), mientras que salta a otra posición en caso de que la comparación sea acertada. Dicho y hecho, tan solo tenemos que verificar que ese string es realmente la contraseña para acceder a la shell completa desde la shell limitada. Y no hace falta decir que efectivamente esa es la contraseña de acceso a la Shell.

Llegados a este punto lo tenemos todo, hemos podido acceder gracias a un exploit, hemos podido extraer la contraseña que nos da acceso a la shell completa, con lo que podemos ya hacer con nuestro router lo que deseemos… ¡No tan rápido! ¿Seguro que ya tenemos total libertad?.

 

Acceso (y modificación) a la “nvram” – Autentificarse

Como vimos en la parte del exploit, y si empezamos a jugar con la shell interna, antes o después nos topamos con un problema bastante importante. Sí, podemos usar todas las utilidades de nuestro router, podemos añadir reglas a iptables, ver el estado de todo, controlarlo todo!! ¿Pero como podemos hacer para que los cambios que hagamos sean persistentes?

Vimos que si intentábamos modificar el archivo passwd este volvía de nuevo a su “ser” al reiniciar. Esto nos dice que al menos la raiz de la firmware está protegida contra escritura de algún modo, y de echo no hay que ser demasiado imaginativo para ir entendiendo que el sistema de archivo del router usa SquashFS, un sistema de archivos de sólo lectura que se monta en cada inicio. Ademeás, si miramos realmente la ubicación de la carpeta /etc tenemos esto:

# ls -la /etc
lrwxrwxrwx    1 1234     root            8 Aug 13  2015 etc -> /tmp/etc

La carpeta /etc desde la cual accedemos a /etc/passwd ni siquiera se encuentra en el sistema de archivos SquashFS, sino que el bootloader/kernel genera el archivo de algún modo en cada inicio, por eso pudimos modificarlo con el exploit entre otras cosas, está fuera de la “prisión” de SquashFS. Se genera en cada inicio, con lo que nuestros cambios se pierden. Pero sabemos que todo no es tan negro, porque en realidad debe de existir una zona o partición donde se puedan inscribir datos y estos sean persistente, o algún sistema para poder hacerlo, ya que a fin de cuenta podemos configurar el router a través de la interfaz web, y los datos son persistentes a cada reinicio. Si cambiamos por ejemplo la contraseña del usuario 1234 dicho archivo al iniciar será diferente al original y reflejará el cambio que hicimos por la interfaz Web. Quizás no podamos modificar el sistema de archivo raiz (lo haremos, pero más adelante), pero cuanto menos en teoría deberíamos de ser capaces de realizar cualquier cambio persistente que permita la interfaz web, y eso como mínimo, porque es de suponer que esté donde esté ese “espacio” contendrá quizás otros datos de interés.

Así es realmente como funcionan la mayoría de dispositivos. Los routers suelen tener una zona llamada nvram (RAM no volatil), que contiene parámetros que pueden ser leídos y almacenados con independencia del sistema de archivos. Esto es necesario para poder realizar configuraciones de cualquier tipo, pero incluso el propio router necesita este “espacio” para poder funcionar y configurarse a sí mismo. En muchos dispositivos es bien conocida la herramienta “nvram”, pero si lo intentamos veremos que aquí al menos no disponemos de una herramienta similar. Así que queda hacer un poco de detective y ver si disponemos de alguna utilidad que nos brinde algo similar.

Como podemos acceder a la shell podemos recorrer rápidamente los directorios donde sabemos que es más que posible que se encuentren: /bin, /sbin, /usr/bin… la mayoría de todas las utilidades podemos conocerlas los amantes de linux y muchas otras deducirlas. Otras en cambio podemos ir directamente probando a ver que pasa. Si no damos con la “tecla”, tenemos otro sistema sencillo para hacernos una idea… si la interfaz web cambia los ajustes, la interfaz web debe de saber o tener idea de como realizar esto. Antes o después llegaremos a la conclusión de que hay ciertos binarios que parecen ser los encargados de manejar todo esto, aquellos que empiezan por “tc” que es el acrónimo de TrendChip. Si nos movemos por las carpetas de la interfaz web (/boaroot) veríamos también rápidamente las referencias constantes a tcwebapi, y mira tu por donde tenemos un binario llamado: “tcapi”. Si lo invocamos:

# tcapi
set unset get show commit save read readAll staticGet

 Parece ser que hemos dado con la interfaz que interactúa con la nvram. Con un poco de paciencia y de estudio aprendemos a usar esta interfaz. tcapi funciona de un modo similar a nvram, con show podemos mostrar lo que deseemos (no existe un show all), pero tenemos que especificar que nodo queremos visualizar. Los nodos son precisamente las etiquetas xml que están dentro de nuestros archivos de configuración. Si miramos nuestro archivo de configuración veremos por ejemplo uno de los primeros nodos, “Wan”, así que “tcapi show Wan” nos devuelve efectivamente todo lo almacenado en ese nodo. Podemos pensar que esto no tiene demasiada utilidad ya que a fin de cuenta tenemos el archivo de configuración, pero no hay que ser muy listo para presuponer que el archivo de configuración es sólo una parte de todo. De echo podemos almacenar los valores que queramos en la nvram existan o no existan en el arcivo de configuración, o modificar cualquier otro.

Si alguien ha usado anteriormente nvram (la utilidad) sabrá que para que los cambios se apliquen hace falta realizar un “commit” y seguido de un “save” si se quiere que los cambios se guarden (aplicar no significa guardar, y viceversa). Aquí tenemos lo mismo. “tcapi save” guarda todos los cambios realizados en la nvram, mientras que “tcapi commig nodo” aplica los cambios efectuados al nodo citado. Cuidado!! Estamos modificando la nvram, si guardamos los cambios y estos han sido incorrectos podemos encontrarnos en que sea necesario resetear el router para que vuelva a sus ajustes por defecto.

Quien llegue a este punto se habrá dado cuenta que, de echo, aunque puede usar show, no puede realizar un save y peor aun, un set, devolverá lo mismo que sucedía cuando intentábamos teclear mtd. El acceso por alguna razón a ciertos comandos, incluso teniendo permisos administrativos y a la shell completos, siguen estando restringidos, hace falta algo más para desbloquear esto. Aquí tendríamos de nuevo que empezar a investigar donde buscar y encontrar esto. Podríamos empezar por cmdsh y encontraríamos referencias a un supuesto archivo llamado “/tmp/Authentication”. Antes o después (grep es un gran amigo), daríamos con el binario /usr/bin/syscmd. Si decompilamos y echamos un ojo llegaríamos pronto a una sección bastante interesante:

auth

Vemos demasiada información, pero todo de gran utilidad. Por un lado vemos que aparece de nuevo el archivo nombrado, pero esta vez precedido de un comando completo, y además curiosamente justo encima vemos un “Correct Key imput. Auth…”. Eso ya nos está diciendo que el sistema parece importarle más que el usuario esté “autentificado” ante ciertos comandos que cualquier otra cosa, y que parece que lo verifica seteando el archivo /tmp/Authentification con authenticated. Podríamos hacer la prueba: “echo authenticated > /tmp/Authentication” y veríamos que funcionan mágicamente a partir de este momento tcapi set/save y otros

Antes de irnos a otro lado, podemos ver igualmente en el trozo desensamblado de nuevo la contraseña de acceso a la Shell, y un “EncryptKey” y un “Account_Common”. Quien haya estado ya jugando con la nvram sabrá que en esta se separan los nodos de otros subnodos con guiones, así que por curiosidad si miramos la información del nodo “Account_Common” con tcapi:

# /userfs/bin/tcapi show Account_Common
EncryptKey=MSTC

El resultado es un string: MSTC, que según aparece en la nvram es un “EncryptKey”. Demasiado cerca del código que hace estar autentificado para no tener nada que ver. Si vemos desde la shell que podemos hacer con syscmd, vemos que existe curiosamente un comando que es authKey, y que efectivamente:

# syscmd authKey
Error!
# syscmd authKey MSTC
Correct key input. Authentication done.

Así que en realidad el proceso “real” implicaría autentificarse a través de syscmd con la EncryptKey almacenada en la nvram, MSTC, y eso a su vez produce que el sistema setee el archivo anteriormentes citado. Así que en realidad podríamos realizar la autentificación de cualquiera de las dos maneras: por lo “legal” y a lo “bruto”. Ahora sí, después de esto, podríamos usar algunos de los comandos más particulares (y también peligrosos), como puedan ser: sys memwl, sys memww, sys erase, sys romd, tcapi set, tcapi save…

La nvram permite acceder a todos los parámetros almacenados en nuestra configuración, y además acceder a otros parámetros que podrían ser interesantes, pero eso para otro día. Veamos mejor que más podemos hacer… podemos modificar la nvram, podemos ejecutar cualquier herramienta que tengamos dentro del router, ahora iremos un pasito más, esta vez como poder “modificar” lo que nos queda, el sistema de archivos, e incluso poder instalar/actualizar componentes en ella.

 

Ejecución de comandos desde el archivo de configuración (Nuevo)

Por azares de la vida, me topé días después con que resultaba relativamente sencillo realizar ejecución de código directamente desde el archivo de configuración del router, que no deja de ser gran parte de la nvram. El secreto reside en el nodo “Autoexec”, que si miramos en nuestro archivo tan sólo existe como cierre.

El cfg_manager, por suerte para nosotros, parsea el cfg en cada inicio para cargarlo a la nvram. Al llegar a dicho nodo, si no está vacío, pasa TODO lo que hay en él (sin el nombre de la entrada, sólo los valores de estas) a un archivo llamado autoexec.sh en /etc/, le da permisos de ejecución y acto seguido lo ejecuta. Dicho de otro modo, podemos añadir todo el código que queramos ahí, que será ejecutado al inicio en el Router. Evidentemente de saber esto anteriormente, el proceso de acceso inicial al router hubiese sido mucho más sencillo.

El potencial de esto ya no está realmente en los expertos que sepan modificar la firmware o entrar y salir del Router de forma sencilla, sino que el usuario novel puede de forma sencilla gracias a esto solucionar problemas que pueda tener en el router, o aplica ajustes concretos especiales.

El formato que siguen estas instrucciones es similar al de otros nodos:

<Autoexec>     <Entry
arp_fix=”sysctl -w net.ipv4.neigh.br0.mcast_solicit=0″
dhcp_fix=”echo ‘* * * * * ebtables -D FORWARD -p ipv4 –ip-proto 17 –ip-source-port 67:68 -j DROP’ &gt; /etc/admin; crond -c /etc/” />
</Autoexec>

Ese por ejemplo sería el bloque modificado para realizar dos fixs a la firmware B21, uno el problema de la batería y otro el problema que posee el router que bloquea todo el tráfico DHCP que no sea el suyo propio. Es sólo un ejemplo sencillo, en realidad podríamos realizar casi cualquier cosa. Como vemos la entrada en sí no importa su nombre, es su contenido el que será pasado al archivo autoexec.sh. Tan sólo hay que añadir el bloque que queramos, guardar, cargar la configuración y solucionado.

 

 

Modificando el sistema de archivos raíz

El router usa como hemos dicho SquashFS para montar su raíz. El problema que esto nos origina es que no podemos realizar cambios en él directamente. Para poder hacer esto, en principio, lo que se necesita es modificar directamente la imagen SquashFS con los cambios que deseemos y volver a cargarla. En un sistema más potente o con otras herramientas podríamos incluso pensar hacer el proceso directamente bajo la misma shell, pero aquí estamos limitado tanto en espacio, herramientas y memoria del router, con lo que esta opción no es muy viable. La opción que nos queda es realizar la modificación fuera del router, y volver a escribir el sistema de archivos de vuelta al router.La teoría en realidad es sencilla, la práctica es algo más complicada porque hay que ver como podemos hacer esto.

A priori se me ocurren dos formas. Una, extrayendo en la partición que se encuentre (en caso de ser así) el sistema de archivos, modificarlo, copiarlo de nuevo dentro y volver a copiarlo a su partición con dd/mtd (lo cual puede resultar bastante peligroso si hacemos algo mal y tampoco tengo claro que pueda realizarse sin hacerlo desde el bootloader), o aprovecharnos del propio sistema de actualización de firmware del router, es mucho más seguro pero implica conocer bastante bien como es la imagen de actualización, para poder no solo modificarla, sino también hacer que el router la acepte. Yo he tomado la segunda opción, no quiero tener que llamar a Movistar para decirles que misteriosamente el Mitrastar ha muerto.

Dicho esto, se abren por desgracia una serie de puntos que pueden ser “largos”, pero necesarios. Si queremos modificar la firmware, lo primero que necesitamos es precisamente al firmware, el binario de actualización, y dado que las actualizaciones se realizan por telecarga puede no ser tan sencillo tener una copia de ella, a menos que conozcamos a algún amigo de un amigo que buenamente nos la suministre. Por suerte… hoy tenemos respuestas y medios para todos.

 

Estructura interna de las particiones de memoria

Antes que nada hay que “estudiar” como está organizada la memoria flash del router, hay que ver realmente que particiones hay:

# mount
/dev/mtdblock3 on / type squashfs (ro,relatime)
proc on /proc type proc (rw,relatime)
ramfs on /tmp type ramfs (rw,relatime)
devpts on /dev/pts type devpts (rw,relatime,mode=600)
usbfs on /proc/bus/usb type usbfs (rw,relatime)
sysfs on /sys type sysfs (rw,relatime)
# cat /proc/mtd
dev: size erasesize name
mtd0: 00020000 00020000 “bootloader”
mtd1: 00020000 00020000 “romfile”
mtd2: 0014e7e3 00020000 “Kernel_main”
mtd3: 01090000 00020000 “Rootfs_main”
mtd4: 00006292 00020000 “Defcfg_main”
mtd5: 01d40000 00020000 “Tclinux_main”
mtd6: 0014e7e3 00020000 “kernel”
mtd7: 010b0000 00020000 “rootfs”
mtd8: 00006292 00020000 “defcfg”
mtd9: 01d40000 00020000 “tclinux”
mtd10: 00020000 00020000 “romd”
mtd11: 00020000 00020000 “second_romfile”

Con eso tenemos una visión más que completa del mapa del router, de como se compone internamente.Efectivamente comprobamos que la partición raiz es SquashFS, las particiones /sys, /proc son las habituales. A parte de ello se monta una partición como “ramfs” que como vimos contenía el archivo /etc/passwd, y por otro lado uan con el extraño nombre “usbfs”… es posible que el router tenga internamente puertos USB después de todo, y de echo la interfaz tiene configuraciones para SAMBA.

Lo que se refiere al particionado de la Flash, vemos hasta 12 particiones, y por suerte para nosotros los nombres son relativamente descriptivos. Vemos además que las particiones mtd2-5 estan duplicadas, o al menos eso parece, lo que nos hace pensar en un sistema de doble imagen, muy usado en los sistemas para evitar una mala actualización. Bootloader, kernel, rootfs y rom/cfg parecen evidentes su contenido, mientras que tenemos otra partición algo más extraña con el nombre de tclinux. El tamaño de las diferentes particiones también nos dan otra idea, siendo tclinux la partición más grande con diferencia, más que la suma de las demás, lo que posiblemente nos indique que tclinux es de algún modo “todo”, y de echo, lo es.

Pero pongamos por caso que tenemos la imagen de actualización, nos será más sencillo para explicar su estructura, y más adelante veremos como poder extraerla si queremos desde el router, que es secundario.

 

Estructura de la imagen de la firmware

Actualmente tan sólo existe una firmware completamente oficial, la B14, aunque la B21 se ha distribuido a muchos usuarios debido a los problemas ocasionados por la B14:

Mitrastar b14 113WJI0b14.bin b79d53bb663cbae480532942cc0e961a
Mitrastar b21 113WJI0b21.bin 770a5a52069066dc87978dba949cb1fd

Tomemos la segunda por caso. En lo personal, me gusta siempre antes de cualquier otra cosa, echarle un vistazo a través de un editor hexadecimal a ver que veo. Haciendo un barrido sin demasiada observación, vemos en primer lugar lo que parece claramente una cabecera al comiendo de la imagen, y curiosamente al final de todo el archivo nos encontramos también que termina con “</ROMFILE>” que es precisamente como termina también nuestro archivo de configuración. Si hacemos una pequeña búsqueda con esto, podemos localizar también el inicio de esta parte, que parece que tiene una pequeña cabecera que lo precede especificando que está comprimido y el tamaño que posee, eso lo vemos en el offset 0x011d27d6.

firmware

Como sabemos también que se supone es una imagen SquashFS, podemos buscar su cabecera y ver si se encuentra alguna correspondencia, buscando por los valores “68737173”, y sí… encontramos también una correspondencia de este en el offset ox0014e7e3, que termina de echo justo cuando comienza el archivo de configuración antes citado. Con esto tenemos prácticamente, y sin necesidad de usar ninguna utilidad, el contenido completo de la firmware (aunque queda ver y analizar aun unas cuantas cosas). Lo único que nos queda es una parte, que se encuentra después de la cabecera y antes de la imagen squashfs. Teniendo en cuenta que tenemos la información anterior de las particiones mtd, la respuesta es evidente: Es el kernel. Recordemos que en las particiones teníamos 3 en concreto que estaban duplicadas con el mismo nombre, con la única diferencia a priori de que las particiones más bajas tenían la coletilla main. Bien, por pura lógica asociamos defcfg al archivo de configuración que hemos encontrado, roofs a la imagen squashfs y el otro pedazo que nos queda es el Kernel. Además, como tenemos el tamaño de las particiones vemos también que efectivamente, si dividimos cada parte independientemente, corresponden sus tamaños a los tamaños de las particiones (ojo que dado que el tamaño de erasesize es de 0x00020000, el espacio de las particiones es múltiplo siempre de este valor, con lo que el tamaño excedente se rellena). Con este pequeño análisis, podríamos ya extraer la imagen squashfs a nuestro equipo, y a priori modificarla como nos diese en gana, volver a crear la imagen squashfs y ver como poder volver a montar la imagen de actualización con todo sin romper nada.

 A partir de aquí, tendríamos el trabajo farragoso. Es necesario comprender las cabeceras, el contenido tan sólo es lo sencillo. Diseccionar las cabeceras es un trabajo más meticuloso y estar haciendo comprobaciones, sumas, cuentas, mirar binarios del router en busca de más información… es tedioso. En mi caso empiezo siempre desde el comienzo, identifico lo que parecen ser los “Magic Number”, cadenas de texto descriptivas que pueden indicar versiones, conjuntos de bytes que indiquen tamaños y desplazamientos, checksums… en definitiva, lo que se puede esperar de cualquier cabecera. Diseccionar totalmente la cabecera (las dos que hay) fue lo que más tiempo me llevó. Os desgloso lo que sería la estructura integral de la firmware, incluyendo por supuesto la estructura de su cabecera. Digamos que la imagen de actualización se compone de tres “partes”. La cabecera, la firmware en sí (compuesta de kernel+rootfs/sistema_archivos) y el archivo de configuración:

0x00000000 Header
    0x0000 Cabecera “Magic Number” 04 D0 FC 9C
    0x0004 chipID = “36 33 33 36 38 00 00 00” = 63368 (8Bytes)
    0x000C Padding (16 Bytes)
    0x001C ModelID = 5A596004 (4Bytes)
    0x0020 Tamaño total archivo .bin, incluído cabeceras (4Bytes)
    0x0024 Offset en Memoria rootfs (0x40000 + offset bin) | 0x40000 = Bootloader 0x20000 + romfile 0x20000
    0x0028 Tamaño Rootfs (4Bytes)
    0x00CC Offset en Memoria Kernel
    0x0030 Tamaño Kernel (4Bytes)
    0x0034 Offset en Memoria cfgfile
    0x0038 Tamaño cfgfile (4Bytes)
    0x003C ¿Magic Number?? 01 00
    0x003E Tipo de imagen | main (0x0003),  esclava (0x0002), bin de actualización (0x0001)
    0x0040 Versión Firmware (32Bytes)
    0x0060 Descripción Firmware (32Bytes)
    0x0080 Checksum Rootfs (4Bytes)
    0x0084 Checksum Kernel (4Bytes)
    0x0088 Checksum cfgfile (4Bytes)
    0x008C Padding

0x00000100 Firmware
    0x00000000 Header
        0x000 Cabecera “Magic Number” 32 52 44 48 (4Bytes)
        0x004 Tamaño de cabecera (4 Bytes)
        0x008 Tamaño de la “Firmware” incluyendo su cabecera
        0x00C checksum SquashFS, las particiones _main no llevan CRC, la firm no lo computa en cualquier caso.
        0x010 versión de 2rdh?? Termina con salto de linea (32Bytes)
        0x030 “Salto de linea”/padding (32Bytes)
        0x050 Offset squashfs/tamaño kernel (4Bytes)
        0x053 Tamaño squashfs (4Bytes)
        0x058 Padding
        
    0x00000100 Kernel, lzma
    0x0014e6e3 rootfs Squashfs 4.0 lzma | Sistema de archivos

0x011d27d6 Configuración romfile
    0x0000 Header
    0x0028 romfile comprimido.  ¿Algoritmo fastlz?

 

 Modificación/Creación de una firmware nueva

Bien, teniendo toda la estructura de la imagen de actualización, debería de ser trivial realizar cualquier cambio (añadir, eliminar, modificar) dentro de la firmware. Con linux tan sólo necesitaremos tener las herramientas para crear y extraer squashfs, teniendo en cuenta que la imagen original fue creada en SquashFS 4.0+, usando la compresión LZMA. Esto significa que si no usaron un SquasFS modificado tuvieron que usar SquasFS 4.1, 4.2 o 4.3, ya que hasta la versión 4.1 no se dio soporte oficial a LZMA. Yo lo he realizado todo con SquasFS 4.3, usando como compresor LMZA el SDK de 7zip. Es necesario eso sí, modificar el makefile para habilitar lzma.

Extraída la imagen en nuestro equipo y modificada a voluntad (o añadido los archivos/paquetes que deseemos…) volvemos a empaquetar nuestra imagen squashFS. De nuevo, recordemos que debemos de usar LZMA y realizar la creación sin el padding a 4K. Llegados a este punto, como tenemos toda la estructura de como tiene que la estructura de la imagen de actualización, tan sólo tenemos que realizar el proceso inverso y corregir todas las cabeceras que sean necesarias. Sería muy sencillo crear una pequeña utilidad que pasándole la imagen modificada, el kernel y el archivo de configuración nos crease el archivo final de actualización con todas las cabeceras corregidas. Pero ni he tenido tiempo ni tengo ganas de hacerlo. Así que sigamos.

Con la imagen SquashFS ya modificada, podemos empezar a empaquetar nuestra nueva imagen de actualización. Por suerte para nosotros, la cabecera de la sección perteneciente al kernel+rootfs no se verifica en ningún momento, y aunque podemos por supuesto calcularla, no es necesario ser muy rigurosos. La parte más tediosa es el cálculo del checksum, así que podemos establecerlo tan ricamente como “00 00 00 00” y no pasa nada.

Añadimos al final de la imagen squashfs el archivo de configuración previamente extraído de la imagen inicial. Añadimos encima de este el kernel, y encima del kernel la cabecera secundaria. No es necesario, pero por tener un mínimo de decencia corregimos en esta el tamaño de la “firmware” (que es el tamaño de la cabecera secundaria+kernel+squashFS), el checksum no nos complicamos y lo dejamos en 00 00 00 00, el offset de squashfs no ha cambiado con lo que lo dejamos igual y modificamos el nuevo tamaño que tiene nuesetra imagen squashfs (ahora sí, tan sólo el tamaño de nuestro squashfs modificado)

Por último queda realmente lo que es más delicado, que es reconstruir realmente la cabecera que va a judgar si nuestra firmware es válida, por no decir que si metemos la pata siempre podemos bloquear e inutilizar el router, así que cuidado aquí. Los valores a modificar en realidad son pocos, si tan sólo hemos tocado el sistema de archivos:

    0x0020 Tamaño total archivo .bin -> Es necesario modificarlo porque el tamaño de nuestro squashFS será diferente
    0x0028 Tamaño Rootfs -> El valor es el mismo que se puso en la cabecera secundaria, y hay que modificarlo por lo mismo que el anterior
    0x0034 Offset en Memoria cfgfile -> Al cambiar el tamaño del rootfs, el offset del archivo de configuración cambia. Recordemos que hay que sumar siempre 0x40000
    0x0080 Checksum Rootfs (4Bytes) -> Que checksum??

Bien, tenemos todo menos el checksum de rootfs, el resto son los mismos porque no hemos realizado ninguna modificación. La pregunta del millón es como diablos calcula Mitrastar este valor, puesto que ha podido usar cualquier técnica conocida o desconocida. La mala noticia es que usa un algoritmo propio para calcularlo, la buena noticia es que ya lo tengo recreado, y la mejor noticia es que incluso nos podemos ahorrar su cálculo si sabemos donde mirar (una pena que descubriese esto último más tarde, pero al menos tengo igualmente el algoritmo.

El checksum usado por Mitrastar es una modificación al conocido CRC32, usando una lockup table para agilizar los cálculos, y podemos encontrarlo en el binario cfg_manager. Se puede buscar la función y decompilarla. Es necesario este valor porque el bootloader y el propio cfg_manager comprobarán dicho valor, y si no corresponde al que ellos calculan, el router rechazará dicha imagen. No sólo se usa este checksumo para verificar la firmware, igualmente se verifican tamaños y otros, pero ya hemos dado por supuesto que la cabecera la hemos calculado bien.

Bien, he dicho que aunque tengo creado el algoritmo para calcular el crc32 modificado no es necesario. Esto es porque por suerte para nosotros ya lo calcula el cfg_manager por nosotros. Cuando actualizamos el router (o lo intentamos), justo antes de que este se reinicie (sea la firmware válida o no) escupe en la consola de registro los cálculos pertinentes, sacando por pantalla los checksum calculados y los que tenemos en nuestra firmware. Dicho de otro modo… si actualizamos aun con la cabecera con los checksum incorrectos, y mientras esta el proceso miramos el registro con dmesg, obtendremos algo como esto:

***** MitraStar Confidential Firmware *****
compressedLen = 25194
pTag->kernelChksum = 11b8cc8b
pTag->rootfsChksum = da3878fa
pTag->defcfgChksum = 35842e0b
cal kernelChksum = 11b8cc8b
cal rootfsChksum = da3878fa
cal defcfgChksum = 35842e0b

pTag->modelId = 5a596004
pTag->chipId = 63368
len = 011d8a68
mrd->modelId = 5a596004
mrd->chipId = 63368

Update slave image version

Ready to flash image…

Si los checksum calculados no se corresponden a los nuestros, el proceso fallará, pero podremos anotar el crc calculado, modificar los nuestros para que correspondan y volver a actualizar. Eso le quita a cualquiera tener que decompilar el código en cfg_manager, extraer el algoritmo de verificación y recrearlo en C o en el lenguaje que le guste. Por supuesto el echo de que se calcule el CRC no hay que verlo sólo como para impedir que se realicen modificaciones, sino para garantizar la integridad de estas y evitar una mala actualización.

Si todo ha ido bien, el cfg_manager copiará la imagen de actualización a 4 particiones esclavas, mtd6-9, cada una con su contenido. Al reiniciar el router, el bootloader realizará comprobaciones similares a las realizadas por cfg_manager, y si todo es correcto procederá a copiar las particiones esclavas mtd6-9 a las principales mtd2-5. Si el router se reiniciase (funcionando) sin aparentemente ningún cambio efectuado, posiblemente el bootloader encontró algún problema en la firmware modificada y anuló la copia a las particiones principales, con lo que habría que ver el problema, solucionarlo y volver a cargarla.

Si todo ha sido correcto, llegados a este punto, tendríamos nuestra propia firmware modificada con lo que necesitásemos, ya fuesen arreglos de los problemas que tiene la firmware oficial o nuestros propios añadidos.

Recordemos que dije que no es necesario tener una imagen de actualización. Podemos extraerla a partir de las particiones mtd5 o mtd9, tan sólo con una apreciación: Las particiones mtd5 y 9 estarán posiblemente padeadas para rellenar el resto del erasesize, con lo que hay que eliminar dicho bloque. Por otro lado hay que modificar un byte en la cabecera que especifica el “tipo de partición”. El archivo de actualización tiene que estar en 01, no en 02 o 03. Quitando estos dos cambios, el resultado será una copia 1:1 (exacta) del archivo de actualización original. No es mal truco después de todo.

 

¿Instalación/Actualización de componentes y otros paquetes?

Ahora mismo no he añadido ningún componente extra, pero es más que factible. Hay que tener en cuenta que el router usa una arquitectura MIPS, y que tendríamos que recompilar cualquier paquete o binario para esta arquitectura. Aquí la idea he de decir que no fue mía y me llegó leyendo a un blogero en algún lado, y es que el router usa uClibc como motor, y el proyecto uClibc posee por suerte para nosotros imágenes listas para iniciar desde linux en las que podremos tener las herramientas necesarias para compilar el códígo y paquetes que deseemos, y una vez realizado sacarlo de ahí y meterlo en nuestra firmware modificada:

http://www.uclibc.org/downloads/binaries/0.9.30/


 

Conclusión

Bien, creo que eso ha sido todo. Sin duda alguna un buen entretenimiento del que siempre se aprende, y yo el primero. Quizás lo más útil en este caso no es instalar paquetes o actualizar otros (al menos en principio), pero puede que sí lo sea el poder realizar pequeños cambios aquí y allá, instalar algunos binarios extras como tcpdump, aplicar configuraciones específicas, filtros… tenemos espacio en memoria de sobra a fin de cuenta, y posiblemente tardemos nosotros mismos menos tiempo en corregir algunos de los problemas de la firmware, que esperar que Mitrastar los arregle por nosotros y que Movistar la distribuya.

Por ejemplo, para corregir el problema de la batería de los ARP en la B21, bastaría en principio con hacer el siguiente cambio permanente:

echo 0 > /proc/sys/net/ipv4/neigh/br0/mcast_solicit

Aunque como digo, tan solo es un ejemplo más…

La cadena de texto “de la muerte” de iOS y OSX: سمَـَّوُوُحخ ̷̴̐خ ̷̴̐خ ̷̴̐خ امارتيخ ̷̴̐خ

Por desgracia no he tenido tiempo antes para hablar sobre la ya famosa “cadena de la muerte” que afecta a los productos de Apple, así que aprovecho para dedicarle unas cuantas letras a ello, puesto creo sin duda alguna que merece la pena por lo absurdo del caso. Pero antes que nada hagamos un poco de recapitulación para aquellos que no saben nada de ello.

¿Algún usuario de iPhone ha observado últimamente que sus aplicaciones se cierran sin mucho sentido?

Hace ya más de 6 meses, expertos de seguridad reportaron a Apple un fallo crítico en sus sistemas operativos, tanto iOS como OSX, afectando en ambos casos incluso sus versiones más actuales. El fallo provoca un ataque de denegación de servicio (DoS) producido por el motor de renderizado de texto del sistema operativo ante una cadena unicode concreta: “سمَـَّوُوُحخ ̷̴̐خ ̷̴̐خ ̷̴̐خ امارتيخ ̷̴̐خ”. En términos profanos, cada vez que cualquier dispositivos de Apple (iPhone, iPod Touch, OSX…) tiene que renderizar (dibujar/interpretar) en pantalla dicha cadena de texto (pues usa el motor de texto del OS), la aplicación que esté en primer plano que esté accediendo a dicho texto se cerrará. Si mandamos un WhatsApp con dicha cadena, el usuario de iOS no podrá abrir WhatsApp (por poner un ejemplo sencillo)

En primer lugar, encontrar un fallo en cualquier aplicación que pueda producir un DoS en ella, no es algo demasiado extraño. Encontrar un fallo en un OS que pueda producir un DoS en él es algo que suele ser mas extraño pero todos los años solemos tener unos cuantos. Lo que realmente hace peculiar este fallo (y de ahí su gran importancia) es el método para “dispararlo”, puesto que tan solo es necesario una sencilla cadena de texto unicode que cualquiera puede enviar, copiar/pegar… o hacer el uso que sea de ella. No es necesario dispararlo por medio de un exploit complejo, no es necesario un conocimiento avanzado informático, no es necesario ser un experto… cualquier persona puede producirlo en un dispositivo objetivo, sencillamente haciendo llegar al objetivo dicha cadena de texto. Tan simple como eso.

En segundo lugar, otra cosa que hace de este fallo crítico en los productos de Apple algo tan severo, es la inacción por parte de Apple (como de costumbre) ante un fallo de seguridad o de cualquier otra índole en su software y sistema operativo. El error fue reportado hace más de 6 meses, 6 meses en los que cualquiera ha podido estar explotando dicha vulnerabilidad a su antojo. Pero aun peor que todo ello, es que después de que hace una semana saltara en todos los medios de noticias, Apple sigue sin hacer absolutamente nada, siendo afectados todas las versiones de iOS (exceptuando la beta de iOS 7) y prácticamente todas las versiones de OSX.

Para cualquier usuario de iOS (y mayoría de OSX) no pueden hacer sencillamente nada. Si el texto es puesto en cualquier sitio y sus dispositivos lo reciben, la aplicación que lo muestre en pantalla se cerrará sin remedio alguno. Esto es un problema, porque incluso el simple echo de escribir un artículo con ello, provocará que a los usuarios de iOS/OSX se les cierre el navegador web si abren mi blog. Para tener constancia de la gravedad de ello, voy a exponer unos sencillos ejemplos y el efecto que tendría en los dispositivos de Apple. Otro gran problema de todos los ejemplos que veamos, es que el usuario de Apple ni siquiera será consciente de que ha pasado o porqué sus aplicaciones no funcionan correctamente.

-En una página web

El navegador del dispositivo se cerrará cada vez que se intente acceder a dicha web, puesto que la cadena de texto hará por mostrarse en él. La única solución pasa por no acceder a dichas webs, lo cual es complicado, cualquier webmaster podría poner la cadena de texto en cualquier parte de su web/blog/foro… En este caso el ataque sería indiscriminado, no iría dirigido concretamente a nadie.

-En un correo electrónico

En el caso sencillo, bastaría incluir la cadena de texto en el cuerpo de cualquier correo electrónico dirigido a cualquier usuario de Apple. Este al abrir dicho corro provocará que el gestor de correo electrónico o el navegador web (en caso de acceso por web) se cierre.

Un caso más maligno de este sería usar dicha cadena de texto como asunto y no como cuerpo de mensaje. En este caso, dado que los gestores de correo y los webMail tienen a mostrar directamente el asunto del mensaje SIN NECESIDAD de abrir el correo, sería suficiente de nuevo para provocar el cierre del navegador web o del gestor de correo.

Usado de forma “maligna”, cualquier usuario de forma muy muy sencilla podría dejar inutilizable de un modo efectivo el gestor de correo de los usuarios de iOS o de OSX (puesto que por lo general el asunto se muestra directamente lo cual provocaría el cierre de la aplicación), y de forma menos agresiva también el navegador cuando se acceda por webMail

En este caso, tan solo sería necesario conocer el correo electrónico del usuario al que dirigirse.

-Facebook, Twitter, Google+…

Independientemente de si se accede a estas aplicaciones desde una aplicación móvil o desde el navegador, parece evidente pensar que pasaría si se publicase en las redes sociales dicha cadena de texto, y el efecto que tendría a todos los usuarios de Apple. Este pensamiento no son pocos los que lo han tenido… y muchos los que lo han hecho. Así pues, son muchos los que han twitteado el mensaje, haciendo que a los usuarios de Apple les fallase tanto la aplicación como e navegador web al intentar visualizar dichos Twitts.

En caso de Facebook, estos bloquearon prudentemente la posibilidad de poder escribir dicha cadena de texto de forma directa, pero existen multitud de formas de evadir este sistema, como por ejemplo estableciendo manualmente como ubicación de la publicación la cadena de texto, pero las opciones son múltiples. La cuestión siempre es la misma, cuanto más ingenioso se sea a la hora de exponer la cadena de texto…

En este caso, se podría usar las redes sociales sin tener un objetivo concreto, o por supuesto bastaría con poder enviar un mensaje o publicar lo que fuese en el perfil del usuario.

-HangOut, SMS, WhatsApps…

A nadie se le escaparía tener en cuenta la mensajería instantánea y los SMS. En estos casos posiblemente el vector de ataque sería mucho peor.

En el caso de los SMS el daño a provocar es evidente, tan solo basta con mandar un SMS a cualquier iPhone para bloquear de forma sencilla la aplicación iMessage del dispositivo. Si la aplicación realiza un pequeño preview del texto maligno, será suficiente para provocar el cierre de la aplicación, y de volver a intentarlo el resultado sería el mismo. En este caso tan solo sería necesario tener el número de teléfono de la persona a afectar.

En el caso de WhatsApp las opciones son múltiples. En primer lugar sería suficiente con mandar un WhatsApp a cualquier dispositivo. Esto provocaría que al abrirse (o incluso en la previsualización) fuese suficiente para provocar la inutilización de WhatsApps. El usuario se vería forzado a tener que reinstalar WhatsApps en algunos casos. Otra opción de WhatsApps sería establecer el texto como mensaje de estado, un sistema pasivo que provocaría que cualquier usuario que nos tuviese en su lista de contactos (usuario de iPhone) no pudiese acceder a su lista de contactos, puesto que cargaría nuestro estado y de este modo WhatsApp se cerraría. Como tercera opción en WhatsApp, y la más efectiva, pasaría por crear un grupo de WhatsApp y establecer en su nombre el texto dañino. Dado que los grupos se regrean aun cuando WhatsApp se reinstala, a cualquier atacante le bastaría el número de telefono de cualquier usuario con iPhone para crear un grupo de WhatsApp, establecer el nombre a la cadena de texto dañina y añadir a dicho miembro al grupo. Dado que el nombre del grupo es visible en la lista misma de WhatsApp, el usuario de iPhone no podría abrir WhatsApp, y aun cuando reinstalase los grupos se recrearían igualmente, haciendo muy complicado evitarlo. De este modo se quedaría totalmente inutilizada la aplicación, se cerraría nada más abrirla constantemente.

En realidad, cualquier sistema de mensajería instantanea los efectos serían similares. La diferencia quizás radica en quien puede o no mandarnos mensajes. En el caso de los SMS por ejemplo, cualquiera con nuestro teléfono puede mandarnos uno. En caso de WHatsApp cualquiera con nuestro número puede hacerlo… esto hace de este fallo de Apple un problema en mayúsculas sin duda alguna.

 

Podríamos expandir la lista todo lo que quisiésemos. Desde establecer el SSID de nuestra red WIFI al texto en cuestión y ver que le ocurre a los iPhone cercanos, códigos QR, firmas… en realidad cualquier sitio donde podamos escribir un texto en unicode y que vaya a ser leído por el usuario en sus pantallas.

Lo peor de todo ello como ya he dicho, es que al contrario de otros fallos de seguridad, en este caso puede dispararse el error sencillamente con una cadena de texto, lo cual no solo hace que el vector de ataque sea increiblemente grande, sino que cualquiera puede explotar esta vulnerabilidad. Si a eso le sumamos que Apple continúa sin solucionar este problema que se conoce desde hace más de 6 meses…

Cada cual que haga sus propias conclusiones… o pruenas

Un saludo amigos, y ser buenos… no seamos demasiado… “traviesos” con los fanboys 🙂

Volver a arriba

Sobre Mí

Alma Oscura por Theliel is licensed under a Creative Commons Reconocimiento-No comercial-Sin obras derivadas 3.0 Unported License.
Política de Privacidad.
Para otros permisos que puedan exceder el ámbito de esta licencia, contactar en blog.theliel.es/about/contactar.