Atacando dispositivos VoIP

Normalmente los ataques contra sistemas de VoIP son ataques no dirigidos, es decir, aplicaciones que envían mensajes SIP bien formados a grandes rangos de red, bien tratando de localizar sistemas, de enumerar o crackear extensiones, o de intentar llamar aprovechando una mala configuración. Al ser herramientas más que conocidas, el 99% sobre UDP, y además ser ataques siempre contra una dirección IP y no contra un dominio, suele ser fácil su detección y bloqueo. Una política básica de seguridad donde bloqueemos ciertos agentes de usuarios y donde forcemos el uso de dominios suele eliminar un alto porcentaje de ataques.

A pesar de que cada vez estamos más concienciados sobre los problemas de seguridad en este tipo de sistemas, quizás nos enfocamos sólo en proteger los servidores y nos olvidamos un poco de los dispositivos. Sí, hablo del teléfono desde donde realizamos nuestras llamadas. Normalmente los teléfonos los tenemos en un red local, bien en nuestra casa o en una oficina, donde la salida a Internet es a través de un router, manteniéndolo seguro e inaccesible desde el exterior. Sin embargo, si buscamos en Shodan por marca, podemos encontrar bastantes dispositivos con una IP pública.

Búsqueda en Shodan de teléfonos Grandstream

No creo que nadie utilice una IP pública para conectar un teléfono, pero sin embargo, vemos que hay muchos dispositivos así. El causante de esto es el UPnP (Universal Plug and Play) de nuestro router. Normalmente está activado por defecto y esto provoca que el router sea capaz de abrir puertos de forma autónoma y automática. Es decir, el router detecta un servicio SIP en el puerto por defecto 5060/udp y decide abrirlo a todo el mundo y redirigir el tráfico hacia el teléfono, pensando que es un servidor de VoIP. Y lo mismo ocurre con el puerto 80/tcp dado que es una web en el puerto por defecto.

El lío viene cuando dejamos las claves por defecto del teléfono (por ejemplo admin/admin) pensando que al estar en una red local no hay ningún peligro. Y si alguien accede al panel de control de nuestro dispositivo puede hacer muchas cosas, además de robar información. El ataque más típico es el siguiente:

  • El atacante accede al panel web del teléfono con las claves por defecto.
  • Configura un desvío a un número externo, para que al recibir una llamada se desvíe a ese número (normalmente se usará un número premium de tarificación especial, lo que en España es un 806).
  • Como el puerto 5060/udp es accesible, mandará un mensaje INVITE al teléfono (solicitud de llamada).
  • El teléfono realizará el desvío al número premium.
  • Para el proveedor de servicios, será una llamada válida, ya que viene de un dispositivo registrado en el sistema.

Por tanto, se estarán generando llamadas de alto coste a través de un teléfono legítimo, perfectamente registrado en el servidor, y desde su propia dirección IP, por lo que la ubicación del atacante nunca se conocerá, a no ser que tengamos activado el registro de logs en el dispositivo, algo que sólamente se hace temporalmente para localizar problemas.

Al estar el teléfono accesible desde Internet, podemos hacer otro tipo de ataques, por ejemplo para intentar obtener las credenciales de la cuenta SIP. Uno de mis ataques favoritos ya se usaba por el año 2009 y aún sigue siendo efectivo. Se trata de una vulnerabilidad dificilmente parcheable, aunque sí que se pueden aplicar algunas medidas preventivas. De hecho la mayoría de dispositivos ya las incorporan, pero desactivadas por defecto. El problema es el siguiente:

El protocolo SIP realiza una autenticación del tipo digest de manera que si el servidor necesita que nos autentiquemos, nos devolverá un error 401 con un digest que deberemos resolver. Las contraseñas no viajan por la red, pero habrá que enviar un response con un hash, que deberá coincidir con el esperado por el servidor.

Autenticación

¿Cuándo se solicita autenticación? Pues normalmente en todos los mensajes REGISTER y en los mensajes INVITE si lo hemos configurado así, pero realmente para cualquier mensaje podríamos solicitar autenticación. Depende de lo que nos permita hacer el servidor y de lo paranoicos que seamos.

Por tanto, supongamos el siguiente caso donde el teléfono realiza un registro:

Mensaje REGISTER

Vemos que el teléfono manda un REGISTER al servidor. Este le devuelve un error 401 con un digest y solicitando autenticación. El teléfono vuelve a mandar un mensaje REGISTER con un response generado según los datos ofrecidos por el servidor. Finalmente queda registrado.

¿Cuál es la idea del ataque? como el teléfono es accesible desde Internet y podemos enviarle mensajes SIP, si conseguimos hacer que nos responda a un digest, tendremos un hash que podremos intentar crackear con un diccionario, y obtener su contraseña. Pero, ¿cómo conseguimos que el teléfono nos responda a una solicitud de autenticación? nosotros no podemos mandar un REGISTER o un INVITE pidiendo autenticación, sino que la tenemos que pedir como respuesta a un mensaje que nos envíe el dispositivo. Por tanto, hay que conseguir que el teléfono nos mande un mensaje a nosotros para responderle con una solicitud de autenticación.

Para hacer esto, la solución es:

  • Enviamos una llamada al teléfono (mensaje INVITE).
  • El teléfono descuelga la llamada (sí! nos tienen que descolgar).
  • Esperamos a que nos cuelguen la llamada (nos mandan un mensaje BYE).
  • Ya tenemos un mensaje enviado desde el dispositivo! Respondemos el BYE con un 401 y un digest.
  • El dispositivo nos devuelve otro mensaje BYE con el response del digest.
  • Con estos datos ya podemos intentar obtener la contraseña, por ejemplo usando la herramienta SIPCrack.

Este ataque se llama Sip Digest Leak y podemos explotarlo usando mi herramienta SIPPTS, concretamente con el script sipdigestleak.pl.

$ perl sipdigestleak.pl

SipDigestLeak - by Pepelux <pepeluxx@gmail.com>
-------------

Usage: perl sipdigestleak.pl -h <host> [options]
 
== Options ==
-f  <string>     = From user (default: 100)
-fn <string>     = From name (default blank)
-t  <string>     = To user (default: 100)
-p  <integer>    = Remote port (default: 5060)
-ip <string>     = Source IP (default: local IP address)
-ua <string>     = Customize the UserAgent
-sd <filename>   = Save data in format of SIPDump file
-v               = Verbose (trace information)
 
== Examples ==
$ perl sipdigestleak.pl -h 192.168.0.1
$ perl sipdigestleak.pl -h 192.168.0.1 -p 5080 -v
\$ perl $0 -h 192.168.0.1 -sd data.txt
\$ perl $0 -h 192.168.0.1 -f 666666666 -fn Devil
$ perl sipdigestleak.pl -h 192.168.1.127
[+] Connecting to 192.168.1.127
[+] Sending INVITE 100 => 100
[-] 100 Trying
[-] 180 Ringing
[-] 200 OK
[+] Sending ACK
[+] Waiting for the BYE message
[-] BYE received
[+] Sending 407 Proxy Authentication Required
[-] Auth: Digest username="testuser", realm="asterisk", nonce="treu3t1u", uri="sip:100@192.168.1.129:58134;transport=udp", response="c903022ba520f48292c24ddb376ba8a4", algorithm=MD5

Si usamos el parámetro -sd file.txt se almacenarán en el fichero los datos del digest en formato SIPDump para que pueda ser usado directamente con la herramienta SIPCrack.

Para proteger el dispositivo ante este tipo de ataques, los teléfonos suelen incorporar una opción para que sólo se acepten los mensajes INVITE provedentes del servidor donde estemos registrado. Como comentaba antes, estas opciones vienen deshabilitadas por defecto y es una buena idea activarlas. Por otro lado, es interesante usar puertos altos en el dispositivo y no el 5060, fácilmente identificable con un servicio SIP. Además, si el servidor nos permite conectar usando TLS, ya no tendremos este problema.

Por otro lado, tampoco debemos olvidarnos de mantener siempre actualizado el firware de nuestros dispositivos.

4 comentarios

Deja un comentario