Permitiendo llamadas no autenticadas del exterior (con restricciones)

26 Abr

Fuente: http://www.datacenta.com/Pictures/stop.jpg

En este blog y en muchos otros se ha discutido el uso de aplicaciones como fail2ban para impedir ataques de fuerza bruta combinado junto con iptablespara denegar el acceso a fuentes no autorizadas. Existe un caso especial que es cuando tenemos que aceptar las llamadas anónimas del exterior sin importar desde donde se originen, y ese es el caso del que voy a comentar a continuación.

Recibir llamadas anónimas no es malo, pero hay que saber lo que se hace y tomar las precauciones necesarias. Al permitir las llamadas entrantes desde cualquier fuente estamos permitiendo que cualquiera nos contacte via IP, para que así el interesado no tenga que paga costos de LD, ni tampoco tenga que hacer algún setup muy elaborado en su conmutador. Ofrecer un peer de autenticación a cada usuario sería un poco difícil, ya que lo que se espera de estos escenarios es que la comunicación sea en un solo sentido (de afuera nos marcan a nosotros hacia adentro) y también, buscas hacerla lo más fácil de marcar para el usuario final.

En nuestro caso, nosotros permitimos llamadas provenientes del exterior pero solo hacia nuestras extensiones internas. De esta manera, no hay costos relacionados con ataques porque las llamadas nunca vuelven a salir hacia la PSTN. Solo pueden comunicarse a nuestras extensiones internas y DIDs. El único problema, es que a veces los equipos que atacan piensan que al no negar las llamadas, vamos a permitirlas salir, así que nos mandan intentos de ataques de unas 40 llamadas simultáneas, lo que hace que nuestros teléfonos comiencen a sonar una y otra vez.

Para evitar que nuestro conmutador se atiborre de llamadas que no deseamos, pero que al mismo paso permita las llamadas que si queremos, debemos permitir lo siguiente desde nuestro GUI:

  • Permitir llamadas anónimas: si

Y luego hacemos esta combicación de plan de llamadas personalizado y fail2ban (estamos usando FreePBX). Dentro del archivo extensions_custom.conf ponemos:

[ext-did-post-custom]
exten => _X.,1,Macro(contador,${SIPCHANINFO(peerip)},3)
exten => _X.,n,Goto(ext-did-catchall,${EXTEN},1)

[macro-contador]
exten => s,1,GotoIf($[${GROUP_COUNT(${ARG1})}<=${ARG2}]?Permite)
exten => s,n,Noop(LLAMADAS EXCEDIDAS POR ${ARG1}. BLOQUEANDO)
exten => s,n,Congestion()
exten => s,n(Permite),Set(GROUP(${CDR(uniqueid)})=${ARG1})

Lo que estoy haciendo aquí es que siempre que reciba una llamada en mi FreePBX que no esté especificada hacia una extensión y/o DID que tenga dado de alta, el contexto [ext-did-post-custom] lo procesará y hará un análisis del número máximo de llamadas simultáneas que debe permitir.

  • Si se exceden 3 llamadas de acuerdo al ejemplo, debo cortar el paso y enviar un mensaje a consola que diga «LLAMADAS EXCEDIDAS»
  • Si no se excede, permito el paso enviando la llamada hacia la cláusula default [ext-did-catchall]
  • Si recibo llamadas desde una fuente «no autorizada» hacia un número que si existe en mi sistema, el contexto [ext-did] lo procesará de manera normal
  • Si el origen ya fuera autorizado, caerá en el contexto que sea que yo le haya especificado y hará caso omiso de esta configuración

Tras hacer la modificación correspondiente y recargar, el mensaje de «LLAMADAS EXCEDIDAS» ya aparece en mis logs. Ahora debo modificar mi fail2ban para que tome en cuenta este texto y bloquee a nivel de firewall a aquellos que nos manden llamadas en bruto.

Basándome en el artículo de fail2ban anterior que publicamos hace unos meses, modifico el /etc/fail2ban/filter.d/asterisk.conf para que quede así:

failregex = Registration from '.*' failed for '(:[0-9]{1,5})?' - Wrong password
Registration from '.*' failed for '(:[0-9]{1,5})?' - No matching peer found
Registration from '.*' failed for '(:[0-9]{1,5})?' - Device does not match ACL
Registration from '.*' failed for '(:[0-9]{1,5})?' - Username/auth name mismatch
Registration from '.*' failed for '(:[0-9]{1,5})?' - Peer is not supposed to register
LLAMADAS EXCEDIDAS DESDE (:[0-9]{1,5})?
NOTICE.* failed to authenticate as '.*'$
NOTICE.* .*: No registration for peer '.*' (from )
NOTICE.* .*: Host failed MD5 authentication for '.*' (.*)
VERBOSE.* logger.c: -- .*IP/-.* Playing 'ss-noservice' (language '.*')
LLAMADAS EXCEDIDAS POR

Si el fail2ban atrapa estas líneas, bloqueará al host por el tiempo que le hayamos especificado en el archivo jail.conf.

Debo destacar que este es un caso muy especial que pocos querrán utilizar, pero es bueno saber que se puede ser precavido y a la vez, flexible con el uso de tu conmutador. Dado que permitir llamadas anónimas expone tu conmutador, la responsabilidad de este código recae en quien lo usa, por lo que no debes aplicarlo si no estas seguro de que es lo que hará.

¡Suerte!

Explotando vulnerabilidades en teléfonos autenticados: Yealink

24 Abr

Actualización 30/julio/2013: Podemos confimar que al usar el firmware más reciente en este momento (9.70.0.140) la funcionalidad de marcación sin autenticación que provocaba este problema de seguridad viene desactivado, y es necesario configurar el teléfono con la IP autorizada que podrá hacer uso del API, por lo que este problema ya no existe. Sin embargo, nunca está de más asegurar su red y cambiar las contraseñas default del teléfono para impedir cualquier acceso no autorizado.

Yealink T20P: teléfono básico

Hace unos días recibí una llamada de uno de mis clientes. La historia comienza con una de las frases que menos me gusta escuchar en mi medio:

– Christian, ¿puedes venir? Nos hackearon el conmutador de la oficina…

Acudí en menos de una hora al sitio (yo no tenía acceso remoto y ni siquiera tenía conocimiento de este equipo) y me dí a la labor de revisar los logs para tratar de reconstruir el caso. Sin embargo, me encontré con lo siguiente:

  • El equipo tenía servicios de iptables y fail2ban protegiéndolo
  • Las contraseñas de SIP eran seguras
  • No se recibían conexiones ni por SIP ni por HTTPS del exterior
  • Todas las llamadas habían sido originadas desde una extensión
  • Apache no tenía registros de IPs externas, tampoco Asterisk.

Todo parecía indicar que hubiera sido un inside job, y en efecto (al menos parcialmente), así fue.

Por más que busqué no encontré señales de como había logrado entrar, pero las llamadas estaban en el CDR y en el gateway SIP que terminaba la comunicación. ¿Qué ocurrió entonces?

De pronto, el empleado al que pertenece el teléfono cuya cuenta SIP ocasionó todas las llamadas, exclamó lo siguiente:

– Mi teléfono ha estado raro. Varias veces en la mañana estuvo «marcando solo» y yo solamente escuchaba una grabación a veces de que la llamada no había podido ser completada

Momento… ¿marcando solo? ¿Desde cuando los teléfonos se marcan solos? Se trataba de un Yealink T20, el cual es un modelo extremadamente sencillo y económico. ¿Qué funcionalidad podría tener que hiciera que marcara solo?

La respuesta es: los Yealink ofrecen la posibilidad de marcación automática a través de una simple y sencilla petición HTTP que requiere autenticación, pero si nunca cambian la contraseña de usuario y administrador del teléfono (lo cual casi nadie hace), cualquiera puede hacer que el teléfono marque solo hacia cualquier destino.

Si tienen un teléfono Yealink consigo (cualquier modelo), prueben hacer esto en su casa/oficina:

Supongamos que la IP de nuestro Yealink sea 192.168.1.101. Asumimos que en nuestro Asterisk existe un plan de marcación que nos permite marcar larga distancia. Imaginemos el número 018881234567. Ahora bien, abran el siguiente URL en su navegador favorito (recuerden cambiar los valores según corresponda):

http://user:user@192.168.1.101/cgi-bin/ConfigManApp.com?Id=34&Command=1&Number=018881234567&Account=0

¿Y qué ocurre? Simple y sencillamente, su teléfono marcará por ustedes hacia el número indicado usando la primer cuenta que tengan configurado en él. Si Asterisk no los autentica a nivel de usuario, ustedes tienen un severo problema de seguridad ya que cualquier persona podría manipular su teléfono para marcar hacia donde le viniera en gana.

Y bien, ¿qué pasa si abren el URL repetidas ocasiones? Fácil. El teléfono marcará una y otra vez a ese número sin colgar las otras llamadas. De manera que un solo teléfono podría hacer 100 llamadas a Afghanistan, Sierra Leona o cualquier otro destino caro del mundo. Esto es muy fácil de lograr con un script en Linux que invoque al wget. Lo demostré en laboratorio y creanme, los resultados asustan.

Imaginen por un momento que alguien tuviera acceso a su red interna, pero no conoce las contraseñas de los teléfonos. Con este truco no es necesario saberlas, ya que el teléfono se encuentra ya autenticado en su red interna y por lo tanto, las llamadas saldrán aún si ustedes confían en que su firewall no recibirá conexiones del exterior.

Por tal motivo, si ustedes deciden abrir erróneamente los puertos en su firewall y exponen la configuración del teléfono, le están abriendo la puerta a alguien a que haga cientos de llamadas sin autorización. En la historia que les acabo de contar, alguien aprovechó esta vulnerabilidad e hizo más de 40,000 minutos de llamadas a los destinos más caros del mundo en tan solo 12 horas, y sin tener que usar su ancho de banda para generar esas llamadas.

Piénsenlo muy bien antes de que expongan equipos al internet. Hay un mundo peligroso allá afuera, y si no se protegen, más temprano que tarde acabarán siendo víctimas de la cyber delincuencia.

¡Suerte!