HackIt! Nivel 2: resumen criptográfico

Seguimos con la prueba 2 del HackIt!, donde lo dejamos ayer. Algunos lectores me comentan que mejor no dé la solución directamente sino que vaya dando pistas progresivas. Me parece bien.

Lo primero que haremos, en este y otros niveles, será mirar el código fuente de la página en busca de…. bueno, !pistas! 🙂

La página del nivel 2 incluye una función Javascript llamada Login() que tiene el siguiente aspecto:

function Login() { var user = document.login.username.value; var pass = document.login.password.value; if (user=="euskal" && hex_cypher(pass)=="c79cc1714419a4aaf3c4c53360843294") { location.href = 'level3-' + pass + '.html'; } else { alert("ACCESS DENIED!"); }; }

Es decir, está claro que el nombre de usuario es ‘euskal’, pero del password sólo sabemos que al pasarlo por una función llamada hex_cypher devuelve como resultado la cadena «c79cc1714419a4aaf3c4c53360843294». Podemos hacer dos cosas, analizar la función hex_cypher(), que según el código fuente de esa misma página : < script type="text/javascript" src="cypher.js" > </script> se encuentra en el fichero cypher.js o bien usar «pensamiento lateral» 🙂 La primera opción siempre es viable dado el código fuente, por ingeniería inversa, pero nos llevará mucho (MUCHO) tiempo. La segunda opción, es más interesante. Pensemos que estamos en la segunda fase, la solución por tanto no debe de ser muy difícil… el algoritmo usado debe de ser conocido, y el resultado de aplicar ese algoritmo a una cadena de texto devuelve otra cadena de 32 caracteres de longitud… no hay muchas funciones de uso común en seguridad informática con esas características… Dada esa pista, tal vez se os ocurra qué función implementa hex_cypher(). Cuando la conozcáis, habrá que pensar en cómo romperla, es decir, ¿es posible a partir de la cadena resultado (32 caracteres) obtener el passwordoriginal sabiendo la función que se aplicó? (o dicho de otra forma, si la función es f, existe la inversa de f?

UPDATE: bueno, pues ya tenemos respuestas al reto 🙂 Efectivamente, se trata de la función md5, que según la Wikipedia:

«En criptografía, MD5 (Message-Digest algorithm 5) es una función criptográfica de dispersión, ampliamente utilizada e insegura [1] [2] , que dado un texto, devuelve un valor hash de 128 bits (32 caracteres). MD5 es un estándar de Internet, documentado en el RFC 1321, y ha sido utilizado en una gran variedad de aplicaciones de seguridad, así como para comprobar la integridad de archivos. Un hash MD5 se expresa típicamente como una cadena de 32 números hexadecimales.»

Una función hash, o función de dispersión como MD5, NO TIENE INVERSA. Es decir existe f(x) pero no f-1 (x). Sin embargo, se puede atacar el problema por fuerza bruta… de hecho, existen en Internet diversas webs con enormes bases de datos precalculadas («al password x, le corresponde el hash y»). Por ejemplo, plain-text.info, una web que añade además la posibilidad de unirse a una red distribuída de obtención de hash md5 (nuestro ordenador puede participar, generando miles y miles de hashes cada día y añadiéndolos a la enorme base de datos de esa web… por cierto, no sólo de md5, sino también lm o ntlm, algoritmos usados en el cifrado de claves en Windows.

Si pasamos el hash c79cc1714419a4aaf3c4c53360843294 por esa web, nos da la clave de acceso al siguiente nivel : 3m3d35.

Nota: existe un método más elaborado que permite conocer todas (hasta cierto tamaño de clave ) las posibles combinaciones de x (y sus hash) sin tener que guardar explícitamente cada una de ellas (estoy hablando de las Rainbow Tables).

HowTo: Debian+OpenSSL+Bind9+Postfix+OpenLDAP+Courier

UPDATE 22/02/2008: lo prometido es deuda. Actualizado con la última parte (por ahora, hasta que Basaburu escriba más 🙂 del HowTo que enseña a instalar paso a paso un completo servidor con servicios Bind, OpenLDAP, Postfis y Courier IMAP.

UPDATE 21/02/2008: tras recibir una queja de mi amigo Basaburu (el autor del artículo) por tardar en publicar la sección de OpenLDAP que él escribió hace tiempo ya, aprovecho este post para pedirle disculpas por la tardanza en la publicación, para alabar el enorme trabajo que se está pegando con este extraordinario artículo y pedir a todos los lectores de DiarioLinux que se estudien detalladamente todo lo que él publica aquí, en especial la nueva sección que he añadido hoy (aunque Basaburu la escribió ¡hace ya un mes!): la sección sobre configuración y puesta a punto de un servidor y cliente OpenLDAP. Mañana mismo, sin falta, actualizaré la última parte del artículo, sobre instalación de Postfix.

UPDATE 6/01/2008: añadida la sección «Crear nuestra CA particular y los certificados de cliente y servidor» UPDATE 3/01/2008: añadida la sección de configuración de Bind9 en chroot. Mañana más.

BasaBuru, como regalo al terminar la rotación alrededor del Sol:

Copyleft 15-11-2007 por BasaBuru y Sramos ver. 0.5

Este HowTo es la consecuencia de una tragedia, he perdido mi server casero. Con lo que no me queda otra que volver a montarlo.

En consecuencia he decidido dedicarle algo más de tiempo y documentar el proceso desde cero. Y que así esta tragedia pueda ser reutilizada por otros.

Este HowTo se lo dedico con todo mi cariño, afecto y admiración a la comunidad de sistemas de mi curro: igomez, pastelero, sramos, moebius, snaker, lynks, dvazquez y apardo. Pues ellos han sido mi apoyo, acicate y sostén intelectual los últimos 24 meses. Además a ellos les he dado mucho la brasa…. pero que mucho, sobre todo a sramos, igomez y pastelero y esta dedicatoria es una forma de mostrarles mi agradecimiento por sus muestras de solidaridad afectuosa.

Evidentemente este es un servidor casero lo que quiere decir que le faltan muchas de las virguerias que nuestras Hackers de sistemas meten en nuestras máquinas en producción. Pero como server casero suficiente, en mi opinión

La verdad es que uno se queda mucho mejor, pero que mucho, cuando comparte con los demás. Para todos vosotros que lo disfrutéis y que le saquéis algo de jugo.

Ahhhhhh y lo más importante que matéis todos los bichos que encontréis.

Lo he dividido en dos partes, ésta comprende hasta la instalación y configuración de los buzones pop3 courier. En la siguiente entrega el resto.

Instalación de alai server

Alai server está alojada en un k7 1800, con 80Gb de disco, con ip fija, bajo el dominio alai.org. Es una máquina imaginaria que como su nombre indica (alai=alegre en euskera) es alegre y feliz 🙂 por que confía en que dejemos todo como debe ser sin que “nada” de problemas. A ver que hacemos… je, je.

Bueno sobre la elección de una debian me abstengo de explicar por qué; soy debianero, a Chessy, por ejemplo, le va Fedora y somos amigos que nos llevamos muy bien, para gustos los colores, vive libre. Sobre el proceso de instalación hay documentación más que de sobra, así que no comentaré nada al respecto.

Como una referencia podéis consultar: The Perfect Setup – Debian Etch (Debian 4.0)

Se instala una Debian 4.0 r1 etch (otra cosa que stable para un server es una imprudencia) por medio de una iso net-install dejando un sistema básico (esto es seleccionando solo “sistema estandar” en tasksel). Lo vamos a ir instalando todo poco a poco, servicio a servicio según necesidades.

Solo señalar que el disco se particiona en cuatro, /boot, /, /var y /swap. Y como es un server con una partición /var bien hermosa.

Servicios en alai server

  • bind9 DNS para la resolución de nombres y como secundario de un dominio
  • Servidor web apache2
  • OpenSSL Entidad certificadora CA, llaves y certificados
  • OpenLDAP slapd
  • Cyrus-SASL autentificación
  • PHP 5
  • Servidor de correo postfix
  • Buzones de correo Courier
  • Servidor de bases de datos MySql
  • Servidor de Backup BackupPc
  • Servidor de listas de correo sympa
  • Servidor de contenidos Drupal
  • Wiki DokuWiki
  • WebDav
  • Servidor CUPS

Como cuestión previa dado que Debian etch no lo instala por defecto en el “Sistema base” y necesitamos trabajar en remoto con el server, instalamos ssh y openssh-server: alai:~# apt-get install ssh openssh-server

Y vamos a hacer una instalación inicial de apache2 para ir tirando mientras vamos montando cosas, para phpldapadmin por ejemplo. El tema de apache2 se tratará con detalle cuando le toque 🙂

alai:~# apt-get install apache2 Se instalarán los siguientes paquetes NUEVOS: apache2 apache2-mpm-worker apache2-utils apache2.2-common libapr1 libaprutil1 libexpat1 libpq4 libsqlite3-0

DNS bind9 enjaulado

Primero el bind9 DNS mas que nada porque actua como secundario del dominio y se resuelven nombres más rápidamente en la red local que usando los DNS del ISP y por que la peña se me queja de que no anda internet igual desde que mate nuestro server casero. 80)

Así que no siendo estrictamente necesario ser el primer paso….. empezamos por aquí

alai:~# apt-get install bind9 Desempaquetando bind9 (de .../bind9_1%3a9.3.4-2etch1_i386.deb) ... Configurando bind9 (9.3.4-2etch1) ... Adding group <code>bind' (GID 104) ... Hecho. Adding system userbind’ (UID 104) … Adding new user bind' (UID 104) with groupbind’ … Not creating home directory `/var/cache/bind’. wrote key file «/etc/bind/rndc.key» Starting domain name service…: bind.

Bueno así lo deja debian. Vamos a configurar. Si fuera un primario la cosa se complicaría pero siendo un secundario, chupao. Editamos el fichero de configuración local, esto es: /etc/bind/named.conf.local

// // Do any local configuration here // zone "alai.org" { type slave; file "bigarren.alai.org"; allow-query { any; }; masters { 23.211.45.78; }; };

// Consider adding the 1918 zones here, if they are not used in your // organization //include «/etc/bind/zones.rfc1918»; Osea le decimos que la zona es alai.org, que es un esclavo y que el fichero para guardar la info es bigarren.alai.org (bind9 lo mete en /var/cache/bind) que permitimos cualquier pregunta y le decimos quien es nuestro maestro (su ip).

Enjaulando a bind9 Vamos a meter a bind9 en una jaula. De esta forma conseguimos mas seguridad, en el caso de que bind9 se vea comprometido y dado que sus actividades están limitadas a la jaula las consecuencias se minimizan.

Empezamos por parar el servicio alai:~# /etc/init.d/bind9 stop Editamos el fichero /etc/default/bind9 para hacer que el demonio corra como el usuraio bind sin privilegios encerrado en una jaula en /var/lib/named. Y substituimos la línea OPTIONS=”-u bind” por la nuestra OPTIONS=”-u bind -t /var/lib/named” alai:~# vim /etc/default/bind9 Ahora creamos la jaula, sus directorios: alai:~# mkdir -p /var/lib/named/etc alai:~# mkdir /var/lib/named/dev alai:~# mkdir -p /var/lib/named/var/cache/bind alai:~# mkdir -p /var/lib/named/var/run/bind/run Movemos el directorio de configuraciones desde /etc a /var/lib/named/etc alai:~# mv /etc/bind /var/lib/named/etc Creamos un enlace simbólico del nuevo directorio de configuraciones desde la vieja localización (para evitar problemas cuando bind sea actualizado en el futuro) alai:~# ln -s /var/lib/named/etc/bind /etc/bind Creamos los dispositivos null y random. Fijamos también los permisos de los directorios: alai:~# mknod /var/lib/named/dev/null c 1 3 alai:~# mknod /var/lib/named/dev/random c 1 8 alai:~# chmod 666 /var/lib/named/dev/null /var/lib/named/dev/random alai:~# chown -R bind:bind /var/lib/named/var/* alai:~# chown -R bind:bind /var/lib/named/etc/bind Necesitamos modificar /etc/default/syslogd a fin de que podamos seguir recibiendo mensajes registrados en el registro del sistema. Hay que modificar la línea: SYSLOGD=”” por esta otra: SYSLOGD=”-a /var/lib/named/dev/log”:

Abrís el fichero con vuestro editor favorito y hacéis las modificaciones alai:~# vim /etc/default/syslogd # #</p> <h1>Top configuration file for syslogd</h1> <p># # #</p> <h1>Full documentation of possible arguments are found in the manpage</h1> <h1>syslogd(8).</h1> <p># # #</p> <h1>For remote UDP logging use SYSLOGD="-r"</h1> <p># #SYSLOGD="" # SYSLOGD="-a /var/lib/named/dev/log" Rearrancamos el servicio: alai:~# /etc/init.d/sysklogd restart Arrancamos bind, y chequeamos /var/log/syslog en busca de posibles errores alai:~# /etc/init.d/bind9 start Enlaces de interés sobre Bind9 y su jaula De todas formas si alguna necesita bregar con un primario o documentarse sobre la jaula para bind9, ahí van unos enlaces. * DNS, BIND, DHCP, LDAP and Directory Services (bind9.net)

Microsoft anuncia una iniciativa de interoperabilidad Open Source

Leo en UnixCraft que la «Open Source Interoperability Initiative», según la propia Microsoft, existe para promover un mayor acercamiento entre las comunidades open source y Microsoft. La iniciativa ofrecerá un gran rango de facilidades, eventos y recursos con soporte de interoperabilidad, y recursos que den soporte a la interoperabilidad, incluyendo laboratorios, contenido técnico y otras oportunidades para promover el desarrollo cooperativo. Microsoft planea publicar APIs y protocolos usados por Windows Vista (incluyendo el Framework .NET), Windows Server 2008, SQL Server 2008, Office 2007, Exchange Server 2007 y Office SharePoint Server 2007 — así como sus futuras versiones. Microsoft ha indicado también que no pedirá a los desarrolladores que accedan y usen estas APIs el pago de regalías por esta información. En concreto, Microsoft está implementando 4 nuevos principios de interoperabilidad y las acciones correspondiente en su gran lista de productos: (1) asegurar conexiones abiertas; (2) promover la portabilidad de datos; (3) mejorar el soporte de estándares industriales; y (4) promover un acercamiento más abierto con clientes e industria, incluyendo a las comunidades open source.Microsoft también ha mostrado su intención de no denunciar a los desarrolladores de software open source y a publicar de forma abierta gran parte del API que mantiene cerrado a día de hoy. Más información en la nota de prensa de Microsoft y en el Anuncio sobre Interoperabilidad. Que cada cual saque sus conclusiones sobre este anuncio.

HackIt! 2007 : un repaso a las pruebas

Ayer, los miembros de diariolinux.com nos apuntamos a la Euskal Encounter 2008. Como ya comenté, este año iremos con más experiencia y ganas si cabe a participar en el HackIt! . No nos hacemos demasiadas ilusiones porque hay grupos muy, muy buenos compitiendo. El caso es que me interesaba repasar la solución a las pruebas del HackIt2007, por varias razones: para ir desempolvando mis conocimientos de ensamblador (muy oxidados ya :-), de GDB, OllyDBG…, para ahorrarle trabajo al organizador ( txipi ), y para que queden por escrito algunos apuntes sobre el tema, que usaré más adelante en mis clases de seguridad informática.

He colgado de http://hackit2.diariolinux.com el concurso del año pasado, que analizaré a lo largo de estos días, al menos hasta llegar a la prueba 11, donde nos atascamos (así, si algún lector la superó en su día o la supera ahora que está colgada en DL, pues mejor que mejor, porque podrá explicarnos al resto cómo lo hizo 🙂

Sin más dilación, pasamos con la primera prueba, que como toda «primera» , su resolución es bastante sencilla. Lo primero que se nos ocurre es analizar el código fuente de la página, centrándonos en el ćodigo Javascript que recoge los datos (login y password) y los envía al servidor:

<script src="JavaScript">
        function Login() {
          var user = document.login.username.value;
          var pass = document.login.password.value;
          if (user=="euskal" & pass=="p4rt7") {
        location.href = 'level2-' + pass + '.html';
      } else {
        alert("ACCESS DENIED!");
      };
        }
  script>

A primera vista parece que el login(username) debería de ser euskal y el password p4rt7, pero si probamos esos datos en el formulario veremos que son incorrectos (!). ¿Dónde está el truco? En la primera línea del código anterior:

<script src="JavaScript">

Esto que a primera vista podría parecer una línea que dice «el código fuente que viene a continuación está escrito en JavaScript», resulta que no dice eso, sino «insertar aquí el código fuente de un script almacenado en un fichero que se llama… tachán, tachán, ‘JavaScript’ «. El dichoso archivo podría haber tenido otro nombre, como funcion.js o algo similar, pero no, le han llamado JavaScript, para hacerlo un poco menos trivial 😉

Si abrimos ese fichero, veremos la clave que nos lleva al nivel 2.