Espameando a fotolog en C#

Iniciado por Nork, 22 Agosto 2008, 14:35 PM

0 Miembros y 1 Visitante están viendo este tema.

Nork



  • Presentación
  • Conceptos básicos
  • Resumen de lo que haremos
  • Ver código por funciones
  • Despedida

Presentación
 
Hola a todos, bueno pues en este artículo os voy a intentar mostrar una de las maneras para crear un bot en C#. En este caso nuestra victima será la página fotolog ya que nos puede ser útil para hacer publicidad o cualquier cosa que os ocurra. No se pretende que ahora quede inservible la página o que este llena de bots ya que para eso os tendréis que saltar el captcha y es una cosa que no daremos aquí. Este artículo es, como siempre, de información para asegurar nuestras aplicaciones web contra estos programas. Dicho esto vamos a ver los conceptos básicos para luego entender todo lo que sigue.

Conceptos básicos
 
HTTPWEBREQUEST
 
Según Microsoft, la comenta de la siguiente manera:
 
La clase HttpWebRequest hace que se admitan las propiedades y los métodos definidos en WebRequest y que las propiedades y los métodos adicionales permitan al usuario interactuar directamente con servidores que utilicen HTTP.
 

Tengo que decir que esta clase sin su acompañante HTTPWebResponse no haría mucho en este artículo sólo que por comodidad y estética me referiré únicamente a HttpWebRequest [HWR].
 
Sistema de cookies en HWR
 
Un tema esencial para crear este tipo de bots es utilizar las cookies para navegar por los directorios del dominio logueado. En este punto puede crear confusiones de cómo realmente funcionan las cookies en esta clase por lo que intentaré explicarme lo mejor que pueda.
 
Primero de todo necesitamos declarar un "espacio" para guardar todas las cookies que necesitemos, en HWR es así:
 
Código (csharp) [Seleccionar]
CookieContainer misgalletas = new CookieContainer();
   
Ahora imaginemos que "misgalletas" es una jarra vacía, como esta:

Ya tenemos nuestra jarra vacía preparada para llenarla. Ahora tenemos que hacer saber a la petición, que se comunicará con el servidor, que tiene a su disposición una jarra donde puede guardar todas las cookies. Es decir, así:

Código (csharp) [Seleccionar]
peticion.CookieContainer = miscookies;

Ahora ya sabe  petición donde tiene que meter las cookies que le mande el servidor. La petición añadirá las cookies a la jarra de esta manera:

Código (csharp) [Seleccionar]
misgalletas.Add(peticion.Cookies);

Ahora ya tenemos en la jarra las cookies que nos mando el Server al loguarnos, un dibujo resumen:


Espero que aunque sea "bastante" malo se pueda entender xD Ahora ya sabemos (o eso espero) como se puede trabajar con las cookies.

Argumentos que puedes necesitar en una petición POST

En una petición POST aparte del header de la petición donde se encuentra el user-agent, content-lenght y demás hay a veces que el servidor necesita de argumentos para rellenar las variables[/FONT]. Aunque es algo bastante fácil haré un breve resumen de cómo se pueden obtener dichos argumentos. Ya que la idea es aprender el concepto y en cada servidor te puede pedir a rellenar variables distintas.

En este caso yo usaré mozilla firefox y el addon Tamper Data. El tamper lo podéis descargar de aquí:

https://addons.mozilla.org/en-US/firefox/addon/966

Este programa trabaja como un Proxy, es decir, estará entre el cliente (tu) y el servidor (la página) analizando el trafico http que haya y dando la posibilidad de modificar las cabeceras y los parámetros.

Para activar la herramienta (estando ya delante de su interfaz) le daremos a comenzar modificación y a partir de ahí en cada petición saliente nos dará 3 opciones; modificar, podremos cambiar los parámetros de envío, enviar, se enviará la petición por defecto y abortar petición.

Argumentos para la petición POST de logueo

Ahora necesitamos ponernos en la página de logueo del fotolog, es decir, esta:

http://account.fotolog.com/login


Una vez ahí activaremos nuestro tamper data "Comenzar modificación". No cal poner ningún valor de momento. Ahora nos saldrán las 3 opciones y le damos a modificar. Dejo una screen para que veáis los datos que tenemos que tener en cuentra:


En verde tenemos el header de la petición, ahí de momento no nos sirve nada. En rojo tenemos los parámetros que tenemos que rellenar y como podemos observar estos son; redirect, u_name y p_word. Esto no hay que olvidar que son variables y que cuando hagamos la petición lo que realmente haremos será:

account.fotolog.com/login?redirect=&u_name=TUUSUARIO&p_word=TUPASSWORD

Esto lo digo porque después, al comenzar a escribir en C# los argumentos se escribirán de esa manera y lo que tendremos que hacer será formar una string con todo esto, por lo que no hay que olvidar el carácter "&" a partir de la segunda variable.

Argumentos para la petición POST para dejar un mensaje

Vamos a ver que argumentos tenemos que enviar junto con la petición. Dejaré ya directamente la screen del Tamper Data y pasaré a comentar un valor un tanto peculiar.


Vemos que aquí los parámetros son; ajax, t y message. Deducimos que message es el mensaje ya que he escrito "e" en el formulario :P, ajax tiene el valor de true por lo que podemos pensar que será algo así como una "variable boolean" (aunque ya te digo que siempre será true). El parámetro que nos puede resultar algo mas confuso es "t".

Te explicaré como he hecho yo para sacar el valor y deducir que es así no perdemos tanto tiempo.
Lo primero que hay que hacer es mirar el código fuente de la página. Para eso vamos a mirar cualquier fotolog y observamos en el form de posteo lo siguiente:

<form id="gb_post_form" action="/gb.post" method="POST">
        <input type="hidden" name="t" value="vPhoYDt86DsIcXowvUvEja2GF+XP55ahtn0jBTqBcny6DkbhDZtEhSmrxVbXlhb6tILleUf4Ezr6LD5IdJ4G3K+0duMa5PaMUanZpRXNWhO25cn2qgW/WjCiMyQQtQGRhme6">
        <h3>Deja un mensaje en el libro de visitas:</h3>
        <div id="counter">&darr; <var>1500</var> caracteres restantes</div>
        <textarea name="message" rows="8" cols="40" id="guestbookMessage">   
        </textarea>       
        <div id="message_limit" class="limit">Límite de 1500 caracteres</div>       
       <div style="margin-top: .4em;">               
       <button class="btSubmit0" type="submit">Dejar tuMensaje</button>               
        <img src="http://si.fotolog.com/i67/images/icon_ajax_bar.gif" id="gbAjaxIndicator">       
</div></form> 


Como podemos observar hay un valor oculto en este form y precisamente se llama "t". También vemos (yo ya lo he hecho) que si vamos a un fotolog distinto y miramos, tendremos otro valor de "t", por lo que deducimos que este valor se asocia al fotolog a postear ya que si no el servidor no sabría en cual queremos postear. Cal decir que este valor cambia bastante rápido por lo que necesitaremos sacarlo en el momento del posteo mediante expresiones regulares.

Creo que habiendo leído esto ya entenderemos el código y como trabaja un poco el servidor.

Resumen de lo que haremos

Creo que antes de ponernos a ver código hay que pensar y estructurar un poco como vamos hacer las cosas.[/FONT]
 
La idea principal es que el programa sea autónomo y él solo vaya navegando por el fotolog sin que nosotros tengamos que interferir. Para eso vamos a partir de un fotolog cualquiera y a partir de ahí mediante expresiones regulares sacaremos los amigos de este y haremos esto todo el rato.

Sé que estaréis pensando "¿Y si alguien no tiene amigos agregados?" (Si no lo pensabais ahora tenéis esa duda así que xD) Bien, si alguien no tiene amigos nosotros daremos al programa unos cuantos fotologs de reserva que primeramente habremos mirado que tengan bastantes amigos agregados y en el caso que no encuentre en el fotolog que este mirando pasaremos a usar esos de "reserva".

Teniendo mas o menos una idea ya creo que podemos pasar a ver el código.

Ver código por funciones:

Vamos a ver la función de logueo:

Código (csharp) [Seleccionar]
static CookieContainer sesion(string user, string pass)
          {
              //PASAMOS LAS PROPIEDADES A VARIABLES
              HttpWebRequest peticion;
              HttpWebResponse respuesta=null;
              CookieContainer misgalletas = new CookieContainer();
 
              string url = "http://account.fotolog.com/login"; //Sitio donde enviaremos la petición.
              string argumentos = string.Format("redirect=" + user + "&u_name=" + user + "&p_word=" + pass); //Los argumentos
              byte[] encodearg = Encoding.ASCII.GetBytes(argumentos);//pasamos a bytes los argumentos
              peticion = (HttpWebRequest)WebRequest.Create(url);//Creamos la petición a la url que indiquemos arriba            peticion.Referer = "http://www.fotolog.com"; //Ponemos un refer de fotolog por poner algo xd
              peticion.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13"; //Le decimos al server que navegamos con el explorador Mozilla
              peticion.AllowAutoRedirect = true; //Permitimos que nos redirecione ATENCIÓN aquí puede cambiar según el sistema de logueo pero en este caso si no lo permites no te loguea
              peticion.CookieContainer = misgalletas; //Explicado
              peticion.Method = "POST"; //El metodo sera POST y no GET
              peticion.ProtocolVersion = HttpVersion.Version10; //Usaremos la version10
              peticion.ContentType = "application/x-www-form-urlencoded"; //Códificamos los datos a enviar, aquí tener cuídado según el servidor tmb
              peticion.ContentLength = encodearg.Length; //Calculamos el tamaño de los argumentos
 
              Stream canal = peticion.GetRequestStream();//Creamos un canal para el envio y recibo de datos con el servidor
              canal.Write(encodearg, 0, encodearg.Length); //Enviamos datos
              canal.Flush();
              canal.Close(); //Limpiamos y cerramos
 
              try //INTENTAMOS OBTENER RESPUESTA
              {
                  respuesta = (HttpWebResponse)peticion.GetResponse(); //Cogemos lo que nos ha enviado el servidor
              }
              catch (Exception ex) //EN EL CASO DE NO SER POSIBLE...
              {
                  Console.WriteLine(ex.Message); //DEVOLVEMOS EL MENSAGE DE ERROR
              }
 
              misgalletas.Add(respuesta.Cookies); //AGREGAMOS A LA "JARRA" LAS COOKIES GENERADAS
 
              respuesta.Close(); //Cerramos
              return misgalletas; //Devolvemos las cookies generadas
          }


El código esta comentado lo mejor que he podido, si hay alguna duda se pregunta y ya esta ;).

Ahora la función para sacar el valor de t:

Código (csharp) [Seleccionar]
static string t(string urls, CookieContainer miscookies)
          {
              HttpWebRequest hRequest = ((HttpWebRequest)WebRequest.Create("http://www.fotolog.com/"+urls));Creamos la petición al fotolog que nos pasaron como argumentos
              hRequest.CookieContainer = miscookies; //Utilizamos la misma jarra que cuando el logueo ;)
              hRequest.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13";
              StreamReader reader = new StreamReader(hRequest.GetResponse().GetResponseStream()); //El canal para mantener la comunicación con el servidor
              string devuelto = reader.ReadToEnd();//Aquí todo lo que nos ha respondido el servidor lo ponemos en un string
              reader.Close();
 
              try
              {
                  //Conseguimos el valor de t para saber donde postear y mantener la sessión
                  string str = devuelto;
                  int first = str.IndexOf("/gb.post");
                  first += 63;
                  int last = str.LastIndexOf("<h3>Leave a Guestbook Message:");
                  string str2 = str.Substring(first, last - first);
                  last = str2.LastIndexOf(">");
                  string td = str2.Substring(0, last - 1);
 
                  //Remplazar los caracteres especiales a hexadecimales
                  td = td.Replace("+", "%2B").ToString();
                  td = td.Replace("=", "%3D").ToString();
                  td = td.Replace("-", "%27").ToString();
                  td = td.Replace("/", "%2F").ToString();
 
                  return td;
              }catch{
                  return "NADA";
              }
          }


Voy a explicar la parte del código en la que se obtiene el valor:

Código (csharp) [Seleccionar]
                  string str = devuelto;
                  int first = str.IndexOf("/gb.post");
                  first += 63;
                  int last = str.LastIndexOf("<h3>Leave a Guestbook Message:");
                  string str2 = str.Substring(first, last - first);
                  last = str2.LastIndexOf(">");
                  string td = str2.Substring(0, last - 1);


Primero de todo en la variable int first conseguimos el número entero que se encuentra la cadena de caracteres "/gb.post". Pongamos que se ha localizado en el número de carácter 200. Int last contiene tambien un valor de donde se encuentra la cadena <h3>Leave a Guestbook Message:
Pongamos en el ejemplo que se ha encontrado en el numero 100 ( ya que LastIndexOf indica que comience desde el último carácter).

Ahora en str2 lo que hacemos es pasar a string los caracteres que se encuentran entre el primer valor hasta el último. De esta manera obtenemos el valor de t. La otra comparación es para eliminar el carácter ">" que me salía, pero la idea es la misma.

Ahora la función de posteo:

Código (csharp) [Seleccionar]
static bool postear(string t, CookieContainer misgalletas, string msg, string name)
          {
              //PASAMOS LAS PROPIEDADES A VARIABLES
              HttpWebRequest peticion;
              HttpWebResponse respuesta;
 
              string url = "http://www.fotolog.com/gb.post"; //Sitio donde enviaremos la petición.
              string argumentos = string.Format("ajax=true&t="+t+"&message="+msg); //Los argumentos
              byte[] encodearg = Encoding.ASCII.GetBytes(argumentos);//pasamos a bytes los argumentos
              peticion = (HttpWebRequest)WebRequest.Create(url); //Creamos la petición a la url que indiquemos arriba
              peticion.Referer = "http://www.fotolog.com"; //Ponemos un refer de fotolog por poner algo xd
              peticion.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13"; //Le decimos al server que navegamos con el explorador Mozilla
              peticion.AllowAutoRedirect = true; //Permitimos que nos redirecione ATENCIÓN aquí puede cambiar según el sistema de logueo pero en este caso si no lo permites no te loguea
              peticion.CookieContainer = misgalletas; //Explicado
              peticion.Method = "POST"; //El metodo sera POST y no GET
              peticion.ProtocolVersion = HttpVersion.Version10; //Usaremos la version10
              peticion.ContentType = "application/x-www-form-urlencoded"; //Códificamos los datos a enviar, aquí tener cuídado según el servidor tmb
              peticion.ContentLength = encodearg.Length; //Calculamos el tamaño de los argumentos
 
              Stream canal = peticion.GetRequestStream(); //explicado
 
              canal.Write(encodearg, 0, encodearg.Length); //Enviamos datos
              canal.Flush();
              canal.Close(); //Limpiamos y cerramos
 
              try //INTENTAMOS OBTENER RESPUESTA
              {
                  respuesta = (HttpWebResponse)peticion.GetResponse(); //Explicado
                  string cojo = new StreamReader(respuesta.GetResponseStream()).ReadToEnd(); //Pasamos a la variable cojo la respuesta del servidor.
                  respuesta.Close(); //Cerramos
                  misgalletas.Add(respuesta.Cookies); //Aportamos las cookies en el caso que haya
                  return true;
              }
              catch
              {
                  return false;
              }
 
          }


Pasemos a obtener los fotologs amigos:

Código (csharp) [Seleccionar]
static string fotolog(string foto, string[] anterior)
{
              //CRAWLER
              HttpWebRequest hRequest = ((HttpWebRequest)WebRequest.Create("http://www.fotolog.com/"+foto+"/ff"));
              hRequest.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13";
              StreamReader reader = new StreamReader(hRequest.GetResponse().GetResponseStream());
              string devuelto = reader.ReadToEnd();
              reader.Close();
              string fotos="";
              bool existe=false;
              Regex r;
              //http://www.fotolog.com/
 
              r = new Regex(@"http://www.fotolog.com/\s*([^/]*)\s*>");
              //
              MatchCollection mc = r.Matches(devuelto);
              if (mc.Count > 0)
              {
                  foreach (Match m in mc)
                  {
                      //Console.WriteLine("{0}", m.Result("$1"));
                      string dato = m.Result("$1");
                      dato = dato.Replace("\"", "").ToString();
 
                      if (dato != foto&&dato!=foto+" class="+"goldcamera")
                      {
                          for (int i = 0; i<anterior.Length; i++)
                          {
                              if (dato != anterior[i])
                              {
                                  existe = false;
                              }
                              else
                              {
                                  existe = true;
                                  break;
                              }
                          }
                              if (!existe)
                              {
                                  fotos = dato;
                                  return dato;
                              }
                      }
                  }
              }
              return "hola";
          }


Aquí lo que hacemos es coger el código fuente de la página de amigos del fotolog que estemos viendo y mediante expresiones regulares buscamos coincidencias de las urls:
Código (csharp) [Seleccionar]

  r = new Regex(@"http://www.fotolog.com/\s*([^/]*)\s*>");
 
  MatchCollection mc = r.Matches(devuelto);


Luego observé que en los goldcamaras me cogía un valor que no era ningún fotolog por lo que hice una condición para que no cogiera ese valor ni tampoco los fotologs anteriores ( para no repetir):

Código (csharp) [Seleccionar]
if (dato != foto&&dato!=foto+" class="+"goldcamera")

Después devolvemos el valor que encontramos y listo.

Ahora pondré el código que nos dirá que nuestra fiesta de posteos se ha terminado  :-(

Código (csharp) [Seleccionar]
static bool captcha(CookieContainer misgalletas, string name, string devuelto)
          {
              //AQUÍ NO HABRÁ NINGÚN PROBLEMA PARA ENTENDERLO...
              HttpWebRequest peticion = ((HttpWebRequest)WebRequest.Create("http://www.fotolog.com/" + name));
              peticion.CookieContainer = misgalletas;
              peticion.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13";
 
              try
              {
                  string str = devuelto;
                  int first = str.IndexOf("antibot");
                  first += 100;
                  int last = str.LastIndexOf("antibot_note");
                  last -= 279;
                  string td = str.Substring(first, last - first);
 
                  //Remplazar los caracteres especiales a hexadecimales
                  td = td.Replace("+", "%2B").ToString();
                  td = td.Replace("=", "%3D").ToString();
                  td = td.Replace("-", "%27").ToString();
                  td = td.Replace("/", "%2F").ToString();
                  return true;
              }
              catch
              {
                  return false;
 
              }
          }


Devuelve true si se ha detectado el captcha. Podría decir que sale aproximadamente cada 32 post luego si lo validas desde tu Explorer te da para unos 60 post más... aunque esto me ha variado ligeramente así que puedes activar vuestra imaginación para saltar esto, introducir el captcha cada vez que se detecte, ejecutar el programa con diferentes cuentas y poner un sleep mas grande entre cada post... no sé apañárosla ;)

El main quedaría de esta manera:

Código (csharp) [Seleccionar]
using System;
  using System.Collections.Generic;
  using System.Text;
  using System.IO;
  using System.Net;
  using System.Web;
  using System.Text.RegularExpressions;
  using System.Threading;
 
  namespace Fotolog
  {
      class Program
      {
          static void Main(string[] args)
          {
              string blog = args[3];
              bool stat;
              string td;
              string[] anterior;
              anterior = new string[30];
              int post = 0;
              CookieContainer cokies;
              string msg = args[2].Replace("-", " ").ToString();
 
              do
              {
                  Console.WriteLine("Logueando...");
                  cokies = sesion(args[0], args[1]);
              } while (cokies.Count <= 1);
              Console.WriteLine("Logueo exitoso... comenzando el proceso.");
              do
              {
                  Console.WriteLine();
                  Console.WriteLine("------------------------------------------------------------------");
                  Console.WriteLine("Buscando amigos en {0}.", blog);
 
                  if (blog == "")
                  {
                      td = t(args[2], cokies);
                      blog = td;
                  }
                  else
                  {
                      blog = fotolog(blog, anterior);
                      td = t(blog, cokies);
                  }
                  Console.WriteLine("Posteando en {0}.", blog);
 
                  if (postear(td, cokies, msg, args[0]))
                  {
                      post += 1;
                      Console.WriteLine("Post número {1}.Se ha posteado correctamente en {0}.", blog, post);
                      stat = true;
                      Thread.Sleep(20000);
                  }
                  else
                  {
                      Console.WriteLine("No se ha podido postear.");
                      stat = false;
                  }
              } while (stat);
 
              Console.WriteLine("Error en el programa, pusla cualquier tecla para salir.");
              Console.ReadLine();
          }


Bueno pues este es el código entero así que a partir de aquí os dejo solos en el camino entre tú y la imaginación.

Despedida:

Espero que os haya gustado el artículo tanto como a mí escribirlo :D y que almenos hayáis aprendido algo nuevo que de eso se trata. Un saludo y cualquier duda sobre el artículo podéis hacermela.

S4ludos!!!

Nork [NullBytes]
C' Est La Vie

Eazy

No es ofenza ni nada eh, pero eso lo puedo hacer yo en 20 minutos con Autoit. Pero hiciste un gran trabajo de verdad, te felicito.. :)
[/url]

Nork

Pues no tengo nidea de Autoit pero supongo que si controlas las cookies se puede hacer igual que en cualquier otro lenguaje
C' Est La Vie

Rakzo-Fimbres

Muy interesante nork, tendré que probarlo

Nork

Cita de: Rakzo-Fimbres en 22 Agosto 2008, 21:53 PM
Muy interesante nork, tendré que probarlo

Gracias, si te surge alguna duda solo pregunta  ;)
C' Est La Vie

Thor

Una duda sobre la expresión regular:
http://www.fotolog.com/\s*([^/]*)\s*>
\s* ?
Entre el http://www.fotolog.com/ y el resto de la url puede haber "blancos"?
Al igual que después de encontrar la / de:
http://www.fotolog.com/xxxxxx/

Y tampoco entiendo porque se busca el ">".

Diria que vale con esto:
http://www.fotolog.com/[^/]*

A ver si me lo puedes aclarar, ya que esto de las expresiones regulares me parece algo muy útil.

Un saludo.


Nork

Cita de: Thor en 22 Agosto 2008, 22:37 PM
Una duda sobre la expresión regular:
http://www.fotolog.com/\s*([^/]*)\s*>
\s* ?
Entre el http://www.fotolog.com/ y el resto de la url puede haber "blancos"?
Al igual que después de encontrar la / de:
http://www.fotolog.com/xxxxxx/

Y tampoco entiendo porque se busca el ">".

Diria que vale con esto:
http://www.fotolog.com/[^/]*

A ver si me lo puedes aclarar, ya que esto de las expresiones regulares me parece algo muy útil.

Un saludo.

Hola Thor pues la verdad que si son muy útiles  ;D

Cita de: Thor en 22 Agosto 2008, 22:37 PM
Una duda sobre la expresión regular:
http://www.fotolog.com/\s*([^/]*)\s*>
\s* ?
Entre el http://www.fotolog.com/ y el resto de la url puede haber "blancos"?

En este caso sí, ya que como vemos en la expresión "\s*" indica que se puede encontrar cualquier cantidad de espacios, tabulaciones...

El "\s" indica que puede haber cualquier espacio en blanco o tabulaciones y el signo "*" la cantidad de ellos (en nuestro caso no ponemos límite)

Cita de: Thor en 22 Agosto 2008, 22:37 PM
Y tampoco entiendo porque se busca el ">".

Diria que vale con esto:
http://www.fotolog.com/[^/]*

La verdad que eso lo añadí como código auxiliar ya que los enlaces que me recogía sin buscar ">" no eran link validos del típico fotolog si no que habían otros enlaces que no nos servía y de esa manera los conseguí obtener. Igualmente si te fijas lo único añadido a lo que propones como válido es la aceptación de espacios en blanco y la ayuda del ">" que te comentaba. Espero haber respuesto mas o menos tus dudas  :xD

S4ludos!
C' Est La Vie

Thor

Gracias por la aclaración Nork.

OzX

buen articulo Brota¡
:=) lo tenias con unas ganas de postearlo ejejjejeje


Nork

Cita de: OzX en 23 Agosto 2008, 22:28 PM
buen articulo Brota¡
:=) lo tenias con unas ganas de postearlo ejejjejeje



Jaja si? porque?  :rolleyes:
C' Est La Vie