Un post algo más técnico para inaugurar el miércoles técnico (MT) que últimamente está esto muy filosófico (que tampoco está mal pero en la diversidad está la virtud).

Los cortafuegos Palo Alto (muy de moda últimamente, no entremos si mejores o peores, bla bla bla) permiten realizar pruebas sobre las reglas desde la línea de comando entrando por ssh. Esto permite probar sin necesidad de tener que generar tráfico real, lo cual viene muy bien para comprobar reglas, solventar incidencias, etc.

Sin embargo, es un poco coñazo por varias razones:

  • Tienes que escribir un chorizo directamente en la línea de comando cada vez
  • Si quieres repetir más adelante (por ejemplo, después de un commit) tienes que volver a escbirilo
  • Si quieres probar varias reglas, tienes que ir una a una

Lo ideal sería poder tener un fichero con las pruebas que quieres hacer, lanzarlo de golpe, ver los resultados, hacer cambios, añadir pruebas o lo que sea, y poder volver a lanzarlo. Y cuando se realicen cambios, poder comprobar como afectan a estas pruebas.

Para eso, os incluyo aquí este pequeño script en expect que permite tener en un fichero las pruebas a realizar, se conecta por ssh y automáticamente lanza las pruebas que haya definidas. Si tenéis clave ssh, mejor. Si no, podéis descomentar las líneas para introducir la contraseña.

Instrucciones sobre cómo usarlo las podéis ver en el propio script.

Espero que os sirva para algo a los que tengáis cortafuegos Palo Alto.

Happy testing!

Unas dudas recurrentes en el mundo de la informática son «¿qué lenguaje de scripts aprendo?» y «¿qué lenguaje de scripts uso para esto?«. Y como todo en la vida, estas discusiones están llenas de fanáticos, de medias verdades y de desconocimiento.

En el caso de dedicaros a seguridad, además, surge siempre la duda debido a que, normalmente, no somos programadores ni tampoco nos dedicamos a automatizar tareas constantemente.

Recientemente, en Security By Default ha habido una discusión similar y quería aportar aquí mi impresión al respecto. Intentaré ser, en la medida de lo posible, imparcial aunque no ocultaré lo que pienso.

Shell script

El lenguaje de scripting que todo el mundo debe saber y sobre el que no hay que discutir es shell script. Esto supone normalmente aprender bash. Aunque hay otras shells bastante usadas, tales cómo kshzsh.

La ventaja principal de la shell es la capacidad de enlazar comandos de forma rápida desde la línea de comandos por medio de ‘tuberías’. A mí me encanta hacer ‘oneliners’ para tratar ficheros, resultados de comandos, etc.

Si bien no puedes usar librerías o módulos de terceros, como indican en el artículo de SBB, sí que puedes lanzar cualquier comando del sistema. Y muchos comandos están pensados para tomar entrada estándar, escupir por la salida estándar y tienen opciones para formatear los resultados de forma que puedan ser usados por otros programas.

No es de extrañar que sh sea el mejor lenguaje puntuado en el scriptometer.

Desde el punto de vista de seguridad, es imprescindible para realizar tareas cotidianas y automatizar la ejecución y el análisis de comandos de forma sencilla.  Comandos como find, sed, awk, cut, seq, xargs, nc o curl puedes combinarlos hasta que se te acabe la imaginación.

Siempre que puedas hacer algo en shell no te compliques en hacerlo en otro lenguaje a menos que tengas alguna otra razón (rendimiento, extensibilidad, etc.).

La mayor parte de los scripts de sistema operativo están escritos en shell  script, por lo que aprenderlo sirve para poder analizarlos y conocer qué se está ejecutando (scripts de inicio, crons, scripts de administradores, etc.).

Ruby

Ruby es mi lenguaje de scripting favorito. Empecé a usarlo gracias a un artículo en Linux Magazine por el año 2001, creo recordar. Por aquel entonces yo hacía mis scripts en Perl. En el artículo de la revista descubrí este lenguaje que, decían «te hará feliz». Intrigado, lo instalé y… tenían razón. Era un lenguaje genial, intuitivo y… te hacía sentir contento programando en él. Y la siguiente vez que mirabas un script lo entendías, cosa que no siempre ocurría con Perl.

Así que, pasé a usar únicamente Ruby en mis scripts.  Posteriormente vino el Ruby on Rails y el lenguaje alcanzó mucha más popularidad… pero asociada principalmente al desarrollo de aplicaciones web. Por lo que mucha gente piensa que no es adecuado para otra cosa. Cuando no es así, claro. Por ejemplo, os recomiendo el libro Practical Ruby for System Administration para conocer las capacidades de este lenguaje para desarrollar scripts de administración de sistemas.

Quizá el mayor impacto en seguridad sea la decisión de desarrollar Metasploit en Ruby. No sólo el framework está desarrollado en Ruby sino que, además, los módulos de metasploit (scanners, exploits, payloads, post explotation) están escritos en Ruby.

Desde luego es un incentivo para aprender este lenguaje y poder expandir su funcionalidad o entender exploits, etc.

Otro software interesante, desde el punto de vista de la seguridad, son los cada vez más usados gestores de configuración. Aunque los hay en otros lenguajes, quizá los más conocidos son puppet y chef, ambos desarrollados en Ruby.

La distribución de software y módulos se realiza, normalmente, en forma de ‘gemas’, las rubygems. Este sistema es similar a los paquetes de software del sistema operativo y hacen muy fácil poder instalarlos, actualizarlos y mantenerlos.

Una funcionalidad que uso muchísimo a diario es irb (Interactive Ruby). Con esta aplicación tienes una línea de comando que interpreta código Ruby. Es muy útil no sólo para probar trozos de tus scripts sino también para efectuar actividades de análisis puntual empleando la funcionalidad de los módulos disponibles.

Por ejemplo, la última vez que lo usé fue la semana pasada para analizar la configuración XML de un cortafuegos PaloAlto. Cargas el fichero XML como un objeto y vas haciendo queries XPath para extraer colecciones con las que listar, contar y analizar las reglas del cortafuegos.

Y como no todo puede ser color de rosa, Ruby tiene un problema y es que es lento. Probablemente el más lento de los lenguajes de script. Dicen que mejora mucho con la versión 1.9, pero aún no la he probado. De todos modos, para lo que lo uso yo tampoco es un problema muy grave.

Python

Python es el favorito de los niños. No sólo porque es un lenguaje mucho más conocido que Ruby sino también porque cuenta con el respaldo de Google. Y todo lo que toca Google se convierte en oro… (bueno, menos el Wave :) ). Que conste que mis conocimientos de programación en Python son bastante cortitos.

Yo creo que prácticamente todo el que conozco que hace alguna cosa con scripts prefiere Python. Quizá debido al desconocimiento que indico algo más arriba se tiene la impresión de que Python es mucho más versátil o ‘mejor’ que Ruby. Y aunque yo suelo tener discusiones al respecto realmente es por echar unas risas y crear cizaña.

Realmente pienso que Ruby y Python son muy similares y depende un poco de gusto personal o de que haya soporte para lo que quieres hacer en este lenguaje. Sobre esto último, es bastante común que los que usan Python esgriman el argumento de que tiene muchos módulos ya hechos para cualquier cosa. Pero vamos, que si miras, hay muchísimos también para Ruby o Perl.

Eso sí, Python es más rápido que Ruby, aunque parece que carezca de las capacidades de meta-programación extrema de este último.

Muchos empiezan en Python porque piensan que es el  ‘ganador’, aunque yo creo que lo mejor sería probarlos todos y decidir el que más nos gusta.

Desde el punto de vista de seguridad, hay multitud de mini-herramientas de seguridad escritas en Python. Quizá la más famosa sea el analizador de seguridad web w3af o el detector de SQLi sqlmap.

Además, cada vez más se ven exploits individuales escritos en este lenguaje, compitiendo directamente con Perl en este aspecto.

En definitiva, desde el punto de vista de seguridad conviene aprender, al menos, lo suficiente para entender exploits y scripts sencillos en Python.

Perl

Perl es el primer lenguaje de scripts moderno (que algunos llaman dinámicos).  Como tal tiene sus problemillas. A diferencia de Python o Ruby, que beben de lenguajes académicos, Perl es más ‘callejero’ que el resto.

Tarde o temprano os habréis encontrado con scripts Perl. Entre otras cosas, es característico por ser difícil de leer, incluso si el script lo has hecho tú mismo. Merece la pena aprender lo básico porque hay muchos exploits y herramientillas desarrolladas en Perl.

Actualmente mi impresión es que está en desuso, con preferencias por otros lenguajes más modernos.

Lua

Lua es un silencioso lenguaje de scripting enfocado en ser pequeñito y amigable, que se puede integrar fácilmente en otros entornos. No es causalidad que sea usado por múltiples entornos sin que sepas que está ahí, desde juegos on-line hasta… seguridad.

Dos de las aplicaciones de análisis de red (cada uno en su estilo) más conocidas, Wireshark y Nmap, pueden ser extendidas empleando Lua.

Particularmente, el Nmap Scripting Engine (NSE)  es básicamente Lua con librerías desarrolladas por la gente de Nmap. Si tenéis una versión relativamente nueva de Nmap echad un vistazo a /usr/local/share/nmap/scripts/ para ver las posibilidades.

Lua es un lenguaje que me cae ciertamente simpático sin una razón clara. Estoy interesado en aprenderlo sólo por trastear un poco con el NSE.

Tcl

Tcl es el típico lenguaje antiguo que nunca querrías aprender y siempre has evitado… hasta que te llega la hora.

Particularmente, en mi caso, me ha tocado aprender un poco (lo mínimo necesario) para entender y hacer alguna iRule sencillita para balanceadores BIG-IP. Estos cacharros tienen un motor de Tcl  con módulos para casi cualquier protocolo que se ejecuta para aquellos servicios que tú quieras. Si quieres saber por qué usa Tcl y si creen que fue una buena elección en su día lee este artículo.

También se usa Tcl en expect y netexpect. Para expect hace falta poca presentación.

Netexpect es similar pero para interaccionar con la red. Merece la pena echarle un ojo aunque, a decir verdad, es complicado que os sirva de algo. Echad un ojo a los ejemplos para ver las posibilidades. Entran ganas de ponerse a trastear con la red ¿eh?

Al creador (Eloy Paris) lo conocimos en la First Conference que hubo en Sevilla en 2007 y parecía muy buena gente.

Otros

Hay otros legnaujes de scripting por ahí aunque los anteriores son los más comunes, creo yo. Sin embargo, se me escapaba uno fundamental, aunque ciertamente distinto: Javascript.

Javascript se ha convertido en el lenguaje más usado. Aunque es considerado un lenguaje de scripting, realmente hasta hace poco sólo se usaba en el navegador. Como tal, es esencial entender Javascript para revisar la seguridad de una aplicación web.

Recientemente, sin embargo, con el advenimiento de node.js, empieza a ser común usarlo en la consola. De hecho existe un package manager para aplicaciones Javascript que usan node.js.

Por ejemplo, este paquete sirve para hacer auditorías de seguridad de CouchDB.

Mucho más se podría decir de este querido y odiado lenguaje pero eso es objeto de otro artículo igual más largo que este :).

Conclusiones

Sea como fuere, si trabajas en seguridad tarde o temprano tendrás que aprender algún lenguaje de scripts. Espero que estas divagaciones te sirvan para algo. En cualquier caso, siempre conviene tener un conocimiento mínimo de la sintaxis de todos los lenguajes de scripts citados.

Yo diría que, como regla mnemotécnica:

  • Aprende shell scripting bien
  • Aprende bien uno de los tres ‘principales’ (Ruby, Python o Perl) para hacer tus propios scripts y el resto lo suficiente para entender/modificar scripts ajenos
  • Si vas a trabajar intensamente con alguna herramienta de seguridad (nmap, wireshark, metasploit, w3af,  etc.) te conviene aprender el lenguaje principal de scripting asociado
  • Por último, si vas a trabajar en seguridad web, ya estás tardando en aprender javascript, al menos lo suficiente como para poder auditar una web y comprender los riesgos asociados

Y nada más por mi parte, ¿cuál es vuestro lenguaje favorito, para qué lo usas?

El cortador de césped es una de esas películas sobre el ciberespacio y la inmersión en ‘mundos digitales’. Cuando la vi de pequeño en el cine me impresionó mucho, aunque supongo que ahora, si la viese, me parecería más bien floja.

En cualquier caso, una cosa que se me quedó grabada es el final de la película en la que, finalmente, el cortador de césped, viviendo en el ciberespacio, consigue escapar a la ‘prisión’ donde le intentan atrapar y hace sonar todos los teléfonos de la Tierra.

Pues bien, gracias a Sevilla Sec&Beer ahora tú también puedes hacer realidad este sueño de juventud, hacer sonar muchos teléfonos a la vez, gracias a la  voz sobre IP y a las credenciales por defecto.

Lo primero que tienes que conseguir es un sitio donde haya muchos teléfonos IP con alguna interfaz de configuración a la que puedas llegar. Luego tienes que tener la suerte de que no hayan cambiado las credenciales de acceso por defecto para administrar. Y por último sólo te hace falta tener unos mínimos conocimientos de scripting para lanzar los mismos comandos a todos a la vez.

Recientemente he tenido la suerte de encontrarme un entorno de estas características. Sesenta y tantos teléfonos IP de la marca Thomson (ya sabéis, no comprad sin Thom ni Son). Estos teléfonos tienen una interfaz web y otra telnet. El usuario administrador tiene como credenciales por defecto ‘administrator/784518′.

Echando un ojo a la interfaz telnet nos encontramos que podemos hacer de todo con el teléfono. Entre otras cosas, podemos hacer que se enciendan los leds y que suene el tono de llamada que queramos.

Pues ya sólo nos queda preparar un script. Para eso, y sin que sirva de precedente, yo he usado expect, que está especialmente pensado para interaccionar con sistemas remotos en base a dos comandos principales expect "algo" y send "algo".

El script en cuestión es el siguiente (le he llamado thomson.ip).

set address [lrange $argv 0 0]
spawn ncat -tC $address 23
expect "Login: "
send "administrator\r"
expect "Password: "
send "784518\r"
expect "#"
send "music start 1\r"
expect "#"
send "exit"

Este script acepta una dirección IP como argumento y hace que suene el teléfono. He usado ncat en vez de telnet porque, por alguna causa, no acababa de autenticarse bien.

Ahora sólo nos queda lanzarlo a la vez para todos los teléfonos. Para ello usaremos las capacidades de paralelismo de xargs. También puedes usar GNU parallel que precisamente es un xargs que lanza en paralelo los comandos.

Suponiendo que has creado un fichero llamado tlfs.ip con una línea por cada dirección IP que pertenezca a un teléfono, podemos hacer lo siguiente para hacerlos sonar todos a la vez.

cat tlfs.ip | xargs -n 1 -P `cat tlfs.ip | wc -l` expect thomson.expect

Y ya está. Riiingggg, riiiiiingggg, riiiiinggggggg, riiiiiingggg, riiiiiingggg….

Bueno, aparte de la chorrada de hacer sonar los teléfonos, la moraleja de todo esto es que hay que tener cuidadito con cambiar las credenciales por defecto, por un lado, y desactivar los servicios si no se usan, por otro. Si no, que suenen todos los teléfonos a la vez va a ser el menor de tus problemas.