No Somos Libres

October 2, 2007

Videos: Crackear WEP en menos de 2 y 10 minutos

Filed under: Cracking, Wifi — Adrián @ 11:45 am

Le copio a CrackVan esta entrada y esta otra y las resumo en una aquí. El primer vídeo es una muestra de cómo con aircrack-ptw se puede obtener la clave en un par de minutos, inyectando tráfico y con pocos paquetes capturados.
Vídeo 1

El segundo, muestra cómo creando una asociación ficticia (y cambiando la mac por seguridad) se puede conseguir tráfico suficiente en 10 minutos para obtener la clave con aircrack-ng.

Vídeo 2

Recordad hacer esto sólo en redes con autorización.

October 1, 2007

Wep Cracking, o cómo de roto está el protocolo WEP

Filed under: Cracking, Wifi, Internet — Adrián @ 8:21 pm

Con los nuevos gadgets que me ha regalado mi novia, decidí probar de una vez cómo de vulnerable era el protocolo wep. No es que no lo supiera, e incluso había obtenido alguna clave con la tarjeta integrada del portátil, pero como ésta no permite inyección, el proceso se eternizaba. Ahora la cosa es más rápida.

Las herramientas que vamos a utilizar son Kismet y la suite aircrack-ng. Necesitamos una tarjeta inalámbrica capaz de inyectar paquetes en la red. En mi caso, el chipset de la tarjeta es Atheros, por lo que los drivers utilizados son los de madwifi. Por desgracia, los drivers que trae Ubuntu de madwifi no están preparados para la inyección, por lo que hay que parchearlos. Podéis descargar la última versión de madwifi aquí.

Una vez los tengáis descomprimidos, debéis editar el fichero ath/if_ath.c y añadir las dos lineas en negrita:

struct ath_softc *sc = dev->priv;
struct ieee80211com *ic = &sc->sc_ic;
struct ath_hal *ah;
HAL_STATUS status;
[…]

wh = (struct ieee80211_frame *) skb->data;
try0 = ph->try0;
try0 = (ic->ic_opmode == IEEE80211_M_MONITOR) ? 1 : ph->try0;

También tenéis parches para madwifi con aircrack aquí. Una vez hecho esto, volvemos al directorio padre y ejecutamos make, si todo va bien, ejecutamos make install y tenemos los drivers listos. Ahora un modprobe ath_pci cargará el módulo de los drivers en el kernel. Se puede añadir una entrada en /etc/modules para que el módulo se cargue cada vez que arranque el sistema.

Bien, tenemos los drivers instalados y parcheados, ahora toca instalar kismet y configurarlo. Este paso es opcional, ya que uso kismet sólo por comodidad, puesto que me da más información sobre las redes y los clientes conectados. En fin, si decides usar kismet, lo primero que tienes que hacer es descargarlo (aptitude install kismet) y configurarlo editando kismet.conf. Son sólo dos cosas las que hay que tocar en este fichero, en primer lugar:

suiduser=adrian
source=madwifi_b,wifi0,kismet

Estos son los valores en mi caso. El suiduser es el nombre del usuario de tu máquina. Source incluye chipset, nombre de interfaz, nombre de servidor (este último que sea siempre kismet). El chipset se puede consultar en la documentación de kismet, en el punto 12. Los usuarios de atheros, aseguraos de poner la interfaz wifiX, no athX, o no funcionará. Una vez hecho esto, debemos ejecutar kismet como root desde la terminal. Igual la interfaz asusta un poco, pero es sencilla, podemos ver las redes: verde encriptada, amarillo abierta. Con ’s’ podemos ordenar las redes en función de la calidad de la señal, del número de paquetes capturados… Con ‘i’ te muestra toda la información de una red en concreto, y con ‘c’ el número de personas conectadas a esa red. Se retrocede con ‘q’.

0. Poner la interfaz en modo monitor

Los usuarios de chipset atheros, debemos iniciar el modo monitor con:

airmon-ng start wifiX

donde X es el número de la interfaz. Esto creará una interfaz ath1 en modo monitor, que será la que usaremos a partir de ahora. Otros chipsets pueden funcionar con:

iwconfig ethX mode monitor

Este paso es imprescindible, si no, no podrás capturar los paquetes de las redes que haya a tu alrededor.

1. Capturando paquetes

Usaremos airodump-ng para este propósito. Existen cantidad de opciones para según cómo queramos realizar la captura. Como ya hemos fijado el objetivo con kismet, podemos reducir la captura a un canal determinado y a una red en concreto con:

airodump-ng -bssid XX:XX:XX:XX:XX:XX –channel N -w captura.cap ath1

NOTA: channel va precedido de guión doble, pese a que no se vea.

Analicemos esto. La opción -bssid indica la red a la que queremos capturar paquetes, donde las X representan la dirección mac del punto de acceso, que podemos obtener del kismet. Fijamos el canal en el que escuchamos con –channel e indicamos al programa en qué fichero realizar las capturas con -w. Si no se va a utilizar aircrack-ptw (recomiendo usarlo, es más rápido) se puede añadir la opción –ivs, ya que aircrack-ng sólo hace uso de las IVs.

Capturando paquetes

2. Atacando

Tenemos varias técnicas a nuestro alcance para llevar a cabo nuestro objetivo. En realidad son 5, pero veremos las 3 más útiles (las otras dos os las dejo de deberes)

  • 2.1. Desautenticación

Este ataque desconecta a los usuarios de la red, provocando tráfico ARP cuando tienen que volver a conectarse. Como habréis adivinado, es un ataque inútil si no hay clientes conectados.

aireplay-ng -0 5 -a XX:XX:XX:XX:XX:XX -c ZZ:ZZ:ZZ:ZZ:ZZ:ZZ ath1

Bien. El -0 indica el tipo de ataque (desautenticación), las X son la mac del punto de acceso contra el que realizaremos el golpe, y las Z el cliente al que queremos desconectar. Si no se especifica -c, el ataque se realiza contra todos los clientes conectados a la red. Este ataque es útil para averiguar el ESSID en redes con ESSID oculto, ya que al generar una petición de autenticación nueva podremos capturar ese dato.

  • 2.2. Falsa autenticación

¿Cómo atacamos una red sin clientes? Fácil, nos autenticamos contra el AP y capturamos nuestro propio tráfico. Tened en cuenta que en realidad esto no es que hayamos accedido a la red, sino que de alguna manera nos hemos “vinculado” al router.

aireplay-ng -1 0 -e ESSID -a XX:XX:XX:XX:XX:XX -h ZZ:ZZ:ZZ:ZZ:ZZ:ZZ ath1

El -1 indica el tipo de ataque. El 0 indica cada cuanto tiempo se realizará el ataque, en este caso cada 0 segundos indica una sola vez. Si se sustituye por 10 intentará autenticarse cada 10 segundos. Con -e se indica el ESSID, con -a la mac del AP (punto de acceso) y con -h la mac que vamos a utilizar. En principio la mac especificada con -h no tiene porque ser la nuestra, ni tiene por qué ser real, si bien algunos AP no aceptan falsas macs, para los que sí lo hagan es más seguro utilizar una falsa. Existen varios motivos por los que la autenticación puede fallar, que yo haya visto:
Distancia: Estamos demasiado lejos del AP. Podemos probar a reducir la velocidad de la tarjeta con:

iwconfig interfaz rate 1M

Esto puede producir que el ataque no termine. Con la opción 0 es probable que llegue a acabar, pero con un valor distinto, puede que se trate de autenticar de nuevo antes de haber terminado la autenticación anterior. Si este es el caso, lo mejor es realizar el ataque con la opción 0 repetidas veces, con un pequeño script en bash o similar.

Filtrado MAC: La cosa se ha puesto difícil, pero no del todo. Si está activo un filtro mac, el AP rechazará nuestra autenticación, salvo que utilicemos una mac admitida. Podemos fijarnos en las macs de los clientes y anotarlas para autenticarnos con ellas cuando se hayan desconectado. También podemos realizar el ataque 0, desautenticarlos y conectarnos nosotros, pero es una manera innecesaria de dar la nota (¡el cliente real se queda sin red!).

Si funciona, obtendremos una salida similar a “Association succesfull :)”

  • 2.3. Reinyección de paquetes ARP.

El airodump-ng está capturando, pero va despacio. Depender sólo de los paquetes del cliente conectado o de los que generamos nosotros con autenticaciones falsas podría alargar el proceso ad aeternum, o hacemos algo o el valor de la columna Data (el que realmente interesa) nos hará desesperar. El asunto será recoger una serie de paquetes ARP generados por el AP con los ataques 0 o 1 y los reinyectaremos para generar tráfico adicional.

aireplay-ng -3 -b XX:XX:XX:XX:XX:XX -h ZZ:ZZ:ZZ:ZZ:ZZ:ZZ ath1

El -3 indica, como siempre, el tipo de ataque, con -b indicamos la mac del AP y con -h la de algún cliente conectado a la red (Podemos ser nosotros mismos con una mac falsa del ataque 1). Adicionalmente se puede añadir con -x el número de paquetes por segundo. Suele funcionar mejor cuando se fija un valor distinto al default, que si no recuerdo mal es 400. Es importante realizar el ataque 0 o 1 para que este ataque pueda obtener algún ARP que reinyectar. Podemos poner a correr este ataque en una terminal y en otra tratar de desautenticar algún cliente o autenticarnos con una mac falsa. Si funciona, el número que hay entre paréntesis debería empezar a aumentar, y en airodump-ng, la columna Data debería crecer con rapidez.

Reinyectando ARP

3. Obteniendo la clave

Si usamos aircrack-ng en lugar de aircrack-ptw (recordad no usar –ivs para este método) necesitaremos alrededor de 400 000 paquetes para una clave de 64 bits, y cerca de 1 000 000 para una clave de 128 bits. Con aircrack-ptw los números son bastante menores. En cualquier caso, la ventaja es que no hace falta parar de capturar paquetes para poner a trabajar aircrack (cualquiera de los dos). Abrimos una terminal mientras se está capturando tráfico y probamos suerte con:

aircrack-ng -a 1-n 64 captura.cap

Existen otros parámetros adicionales, como -f que indica el nivel de fuerza bruta del ataque, con -a el tipo de encriptación (1 para WEP), y con -n el número de bits de la clave. Por defecto busca claves de 128 bits, así que si queremos que busque 64 se le especifica. Al buscar claves de 128 bits, también encontrará las de 64, aunque tardará algo más. Si queremos usar aircrack-ptw:

aircrack-ptw captura.cap

Bueno, eso ha sido todo por hoy, que ya me parece bastante. Espero que sea útil y si hay alguna duda o alguna puntualización, usad los comentarios que para eso están.

Página oficial de aircrack (documentación, troubleshoting…)

Nuevos juguetitos: tarjeta pcmcia y antena

Filed under: Wifi, Gadgets — Adrián @ 6:15 pm

Esta semana mi novia se ha adelantado a mi cumpleaños (¡gracias mi vida!) y me ha regalado una tarjeta Proxim ORiNOCO 8470-WD 11 b/g PC Card Gold - WORLD. Lleva chipset Atheros, por lo que es compatible con linux y además se puede poner en modo promiscuo…

Tarjeta PCMCIA y antena

Pero para completar, me ha regalado también una antena Hypergain Omnidireccional 5dbi con base magnética (con. MC) que me aporta cierta ganancia a la hora de detectar redes inalámbricas. Habrá que probar las herramientas… ;)

Tarjeta PCMCIA y antena

September 28, 2007

Plantillas para webs en PHP

Filed under: php — Adrián @ 6:48 pm

He estado trabajando en unas plantillas php para webs personales del personal en el trabajo. No es que sean muchas líneas de código ni una cosa muy complicada, pero me parece que han quedado bastante bien y quería comentarlo aquí, y mostrar parte del código que he utilizado. Se trata de unas plantillas que generan la web en función de los ficheros html, php o txt que se encuentren dentro de la carpeta de contenidos definida por el usuario.

Una de las partes que me han parecido más interesantes de programar ha sido la pequeña caché de los directorios de contenidos. El pequeño código es el siguiente:

Code (php)
  1. $info = array();
  2. if (!isset($_SESSION[’subdirs’])){
  3.     $_SESSION[’subdirs’] = array();
  4.     $_SESSION[’subdirs’][$content_dir] = 0;
  5. }
  6. foreach ($_SESSION[’subdirs’] as $key => $value){
  7.     $info = stat($key);
  8.     if ($_SESSION[’subdirs’][$key] != $info[’mtime’]){
  9.         $_SESSION[’subdirs’][$key] = $info[’mtime’];
  10.         $_SESSION[’menu’] = menu_walk($content_dir);
  11.        //echo "ACTUALIZANDO CACHE…<br>";
  12.     }
  13. }

En la variable de sesión subdirs se almacenan todos los directorios por debajo de $content_dir, incluido él mismo. La clave del array es el nombre del subdirectorio y el valor es la fecha de última modificación. Así cada vez que se recarga la página se realiza un stat sobre cada elemento del array y se comprueba si ha sido modificado, y si lo ha sido, se vuelve a indexar el directorio de contenidos y a generar nuevamente las entradas de menú. Para cada tipo de fichero se realiza un tratamiento distinto del contenido, un include si es php, un echo si es html y un formateo por párrafos si es texto plano. El código que realiza esta parte no tiene demasiado interés.

Sí que vamos a ver el código de la función menu_walk () que tiene que ver con la caché en tanto que actualiza el sistema de ficheros virtual ($_SESSION[’subdirs’]) si el cambio que se ha producido en el contenido ha sido la creación de un nuevo directorio:

Code (php)
  1.  
  2. function menu_walk ($directorio)
  3. {
  4.     if (is_dir($directorio)){
  5.         if ($gestor = opendir($directorio)) {
  6.             /* El menú se compone de un array de pares (arrays) cuya primera componente es el nombre del directorio o fichero y su segundO
  7.              * componente el enlace
  8.              * al archivo. En el caso de que se trate de un directorio, la segunda componente es un array con los archivos de ese subdirectorio.
  9.              */
  10.             $menu = array();
  11.             $cont = 1;
  12.            //Iteramos en el directorio hasta haberlo leído todo.
  13.             while (false !== ($archivo = readdir($gestor))) {
  14.                 if (strpos($archivo,"_") === 0){
  15.                     //El archivo no debe ser mostrado y por tanto no generamos las entradas de menú.
  16.                 }else{
  17.                     //La funcion de php is_dir está rota y requiere el directorio padre para detectar si un archivo es directorio
  18.                     $d = $directorio."/".$archivo;
  19.                     if (is_dir($d) && ($archivo != "..") && ($archivo != ".")){
  20.                         $menu[$cont] = array("<a href="http://www.nosomoslibres.com/#">".ucwords(strtolower($archivo))."</a>",menu_walk($d));
  21.                         /*
  22.                          * Actualizo el "sistema de ficheros" con el nuevo subdirectorio creado, de tal forma que se pueda actualizar la caché
  23.                          * sin tener que recorrer de nuevo el directorio. De esta forma se puede realizar stat() sobre todos los subdirectorios
  24.                          * y comprobar si han sido actualizados desde la última vez.
  25.                          */
  26.                         $info = stat($directorio."/".$archivo);
  27.                         //Comrpobamos que el directorio no había sido añadido anteriormente a la caché.
  28.                         if (!in_array($directorio."/".$archivo,$_SESSION[’subdirs’])){
  29.                                 $_SESSION[’subdirs’][$directorio."/".$archivo] = $info[’mtime’];
  30.                         }
  31.                     }else{
  32.                         //comprobamos que se trata de un archivo con extensión permitida (html, htm, txt o php)
  33.                         $partes_ruta = pathinfo($archivo);
  34.                         $extension = $partes_ruta[’extension’];
  35.                         $basename = $partes_ruta[’basename’];
  36.                         if (strtolower($extension) == "html" || strtolower($extension) == "htm" || strtolower($extension) == "txt" || strtolower($extension) == "php") {
  37.                             $menu[$cont] = array(basename($basename,".".$extension),"<a href="http://www.nosomoslibres.com/contenedor.php?display=%22.$directorio.%22/%22.$archivo.%22">".ucwords(strtolower(basename($basename,".".$extension)))."</a>");
  38.                         }
  39.                     }
  40.                 }
  41.                 $cont++;
  42.             }
  43.             closedir($gestor);
  44.             return $menu;
  45.         }
  46.     }else{
  47.         echo "El parámetro especificado no es un directorio";
  48.         return $menu;
  49.     }
  50. }

El código no queda demasiado legible debido a los comentarios y las frases demasiado extensas, pero si lo copiáis a un editor de texto está tabulado y se entiende mejor. menu_walk() actualiza el array menú y el “sistema de ficheros” para que la caché siga funcionando. Existe una función menu_print() que es la encargada de mostrar el menú formateado como es debido. El fichero contenedor.php es el encargado de leer el fichero a mostrar y darle el formato apropiado, como he comentado más arriba. En fin, eso es todo lo interesante. Si alguien quiere ver el código completo o utilizarlo para él, que me lo pida y se lo envío encantado.

September 22, 2007

Zattoo, por fin TV en el PC

Filed under: Internet, TV — Adrián @ 9:20 pm

Esta tarde he estado probando Zattoo, el mejor sistema para ver la televisión por internet. Los que no tenemos tarjeta sintonizadora de TV (o toma de TV en la sala del pc) agradecemos esta iniciativa gratuita. Funciona con flash, corre en Linux, Mac y Windows (así se hacen las cosas) y se ve bien con internet de 1 MB (claro, que con más pues mejor, por si estás haciendo otras cosas por internet mientras). Tan sólo hay que registrarse en su web y podrás descargar el cliente, en formato .deb en mi caso. Lo ejecutas y listo. ¡Mentira! Me pide unas dependencias, librerías varias, que una vez instaladas te dejan configurar Zattoo. AcTualmente están disponibles los siguientes canales: Antena 3, Telecinco, Canal 24h, Cuatro, Extremadura TV, TVE 1, La 2, La Sexta, Teledeporte y algunos canales extranjeros. Recomendado, sin duda, sobretodo la posibilidad de grabar directamente la emisión con la ayuda de algún software adicional (cosa que probaré en cuanto pueda).

September 20, 2007

Peculiar novela de Zombies

Filed under: Novelas, Zombies, General — Adrián @ 7:06 pm

Hace un par de días que descubrí este blog, en el que se narra un apocalipsis zombie en primera persona, como si el autor fuera uno de los supervivientes del alzamiento de los muertos. La historia es bastante larga y aún no se ha terminado. Hubo rumores de que había editores interesados y de que acabaría en una novela física. La verdad es que la tensión está bien llevada, y pese al estilo algo descuidado y las numerosas faltas de ortografía te mantiene enganchado e interesado. Si tenéis un ratejo cada día para ir echando un vistazo a la historia os lo recomiendo. Es una paliza ponerse al día, pero una vez hecho no supone mucho tiempo seguir la trama, aunque es un fastidio esperar la siguiente entrega.

August 22, 2007

Sobre el Software Libre

Filed under: Soft Libre, General — Adrián @ 5:28 pm

Estos días estoy estudiando bastante, así que estoy dejando algunos posts interesantes para finales de septiembre. Aún así he leído esta entrada en el blog de Ricardo Galli y creo que no está de más que lo leáis todos.

¡En la cabeza no, que estoy estudiando! ;)

August 4, 2007

¿Y si los protagonistas de Héroes fueran Informáticos?

Filed under: Series, Informática — Adrián @ 11:17 pm

heroespc1fs6.jpgHace ya bastante tiempo, localicé por la red -no recheroespc2df2.jpguerdo donde-, este par de pósters que explican qué poderes tendrían los protagonistas de la serie Héroes si fueran informáticos. Esta serie no ha tenido mucho calado en España, pese a que la primera temporada cumple expectativas, en parte imagino porque se ha emitido en Telemadrid, en lugar de en alguna cadena  de difusión nacional. Para los que hayáis seguido la serie, y los que seáis un poco geeks, disfrutaréis de estas imágenes.

August 1, 2007

Cómo montar un sencillo servidor de Subversion

Filed under: Informática, GNU/Linux — Adrián @ 1:58 pm

Subversion es un Sistema de Control de Versiones, similar a CVS, pero que incluye muchas características que lo hacen, desde mi punto de vista, más útil que CVS. Para más información sobre las diferencias y las similitudes entre estos dos sistemas mirad en los links que os he dejado arriba.

Subversion tiene paquete en las distribuciones basadas en Debian, así que si sois los afortunados usuarios de una de estas, tan sólo tendréis que teclear en vuestro terminal (o buscar en sinaptic):

aptitude install subversion

Si no, lo bajáis de la página oficial y seguimos. Después creáis la carpeta (ya sabéis, mkdir …) que queréis que contenga los repositorios de subversion. Yo he elegido /var/svn. Después tendréis que usar el comando svnadmin (como root) para crear el repositorio que queráis. Por ejemplo:

montseny:/# cd /var/svn/
montseny:/var/svn# svnadmin create myrepo

Con esto tenemos creado el repositorio myrepo dentro de /var/svn, pero aún nos queda configurar el acceso al mismo y configurar subversion para que sirva ese repositorio al exterior. Los ficheros de configuración están dentro de la carpeta myrepo/conf. El fichero authz puede dejarse tal como viene, todo comentado, siempre que todos los usuarios vayan a tener acceso total a todos los repositorios. Si se quiere especificar quién tendrá acceso a qué repositorio y con qué permisos, o incluso crear grupos de usuarios, ese es vuestro fichero. Vienen ejemplos bastante sencillos así que no haremos más hincapié en él. En el fichero passwd debemos poner los usuarios que esperamos manejen el repositorio y trabajen en él:

[users]
adrian = mypassword
billy_puertas = supassword

Nos queda svnserve.conf, donde debemos descomentar las siguientes lineas, y configurarlas según nuestra preferencia. Yo he especificado que los usuarios autenticados tienen permisos de escritura en los repositorios y los no autenticados no pueden hacer nada:

[general]
anon-access = none
auth-access = write
password-db = passwd

La directiva password-db indica a subversion dónde autenticar a los usuarios. Existen muchas variedades, pero puesto que aquí se trata de montar un repositorio sencillo, para uso “doméstico”, dejaremos passwd, que es el fichero donde hemos añadido nuestros usuarios. Con esto tenemos perfectamente configurado el servidor, sólo nos queda lanzar el demonio que lo sirva a través de internet, con la siguiente linea:

montseny:~# svnserve -d –listen-host xxx.xx.xx.xxx -r /var/svn

El parámetro -d indica que se comportará como un demonio y correrá en background, listen-host es la ip del servidor y -r el directorio que contiene los repositorios. Aseguraos de abrir el puerto de subversion si tenéis firewall, que por defecto es el 3690 udp y tcp. Ahora sí que sí, tenéis funcionando subversion. Esto se puede complicar mucho, hasta el punto de montar clones de sourceforge como gforge, que usan subversion por debajo pero con la configuración almacenada en base de datos. Fue tan complicado montar gforge que creo que me llevaría un libro escribir un tutorial, así que de momento no creo que lo haga.

Un ejemplo de gforge: http://gforge.org
El clásico sourceforge: http://sourceforge.net

De vuelta de vacaciones, o se acabó lo bueno.

Filed under: General — Adrián @ 1:25 pm

Tirao en la playa¡Ya estoy de vuelta! Volví el sábado de Londres, después de haber empalmado -casi- tres vacaciones consecutivas: Tenerife, Mil Palmeras, y Londres. Este año no me puedo quejar de vacaciones, pues han sido todos los viajes magníficos y lo he pasado en grande en los tres. ¡Y aún me quedan unos días que cogerme en Navidad! Fuera de todo eso, lo cierto es que probablemente el viaje más enriquecedor haya sido el de Londres. Estuve una semana con mi novia y pudimos ver prácticamente toda la ciudad. No sólo los sitios típicos, fuimos andando a casi todas partes, si bien los últimos días cogimos el metro porque ya nos dolían los pies. Creo que la parte que más me gustó de Londres fueron sus casas y su ambiente. Sin dudarlo me iría a vivir allí si encontrara un buen trabajo, aunque fuera una temporada. Con mi novia delante del StonehengeComo podéis ver en la foto, tuvimos ocasión de ver el stonehenge -del que hice decenas de fotos-, así como los baños romanos y el pueblo de Bath, así como el Castillo de Windsor y la Capilla. Todo esto a pesar de las inundaciones, que por suerte, no tuvimos ocasión de sufrir. Y hoy ya es uno de agosto, así que toca empezar a estudiar los exámenes de septiembre, ¡y me da una pereza…! Por si fuera poco, como ya viene siendo habitual, me coinciden dos exámenes el mismo día, y dos días después tengo otro. En fin, yo no sé qué pasa con las planificaciones de exámenes que siempre me pasa lo mismo. Por suerte hoy empiezo a trabajar nada más cuatro horas al día, que esto empezaba a ser una pesadilla, así que tendré que aprovechar las mañanas para estudiar. Creo que ya está bien por hoy de autocompadecerse, vamos a ver  si subo el mini-howto de subversion.

Next Page »

Powered by WordPress