Peticiones HTTP con Perl
En la última Campus Party, como comenté en su post, estuve bastante tiempo con el concurso de seguridad web. Muchas veces para ir probando a mandar peticiones web concretas, GET o POST, había que usar "algo" que lo hiciese. Las opciones son varias, se podría usar un proxy, pero con él nos limitamos el poder tratar la respuesta del servidor o hacer cosas algo más complejas que una simple petición, esto mismo se puede aplicar a usar un telnet contra el servidor web remoto, así que al final, hay que usar un lenguaje de programación desde el cual abrimeros un socket contra el puerto 80 del servidor web en cuestión, por el cual hablaremos HTTP 1.1.
Un amigo que también participó en el concurso, OddBug, como es un poco windosero (aunque ahora es medio GentooManPr0 xD) usó Visual Basic
, en mi caso opté por usar Perl porque mola mogollón
. Así que vamos al asunto!, como narices crear una petición (y obtener la respuesta por parte del servidor) http. Vamos a crear un socket y ya está, más facil no puede ser
. Tenemos dos formas, la tradicional:
#! /usr/bin/perl -w use Socket; use strict; my( $host, $in_addr, $proto, $port, $addr, $file); $host = "www.marca.es"; $file = "/"; # el index vamos... $port = 80; $proto = getprotobyname('tcp'); $in_addr = inet_aton($host); $addr = sockaddr_in($port, $in_addr); # creamos el socket y conectamos al servidor socket(S, AF_INET, SOCK_STREAM, $proto) or die "socket: $!"; connect(S, $addr) or die "connect: $!"; # para flushear nada mas escribir en el socket select(S); $| = 1; select(STDOUT); # Una peticion normal GET print S "GET $file HTTP/1.1\nHOST: $host\n\n"; while(<S>) { print; }
Que es un poco fea, bastante similar a C, y no muy limpia. Y la forma maja, usar los modulos de CPAN que hacen grande a Perl. Lo anterior queda simplificado a esto:
#! /usr/bin/perl -w use IO::Socket; use strict; my $host = "www.marca.es"; my $file = "/"; # el index vamos... my $port = 80; my $S = IO::Socket::INET->new ( Proto => "tcp", PeerAddr => "$host", PeerPort => "$port", ) or die "cannot connect!"; # para flushear nada mas escribir en el socket select($S); $| = 1; select(STDOUT); print $S "GET $file HTTP/1.1\nHOST: $host\n\n"; while(<$S>){ print }
Más simple ya, imposible. Ahora ya solo queda variar las peticiones que se mandan. Un GET no tiene mucha complejidad, solo recordar que en HTTP 1.1 hay que indicar el host y al final hay dos saltos de linea:
$peticion = 'GET /fichero/que/quiero/lala.php HTTP 1.1 HOST: www.LAwebQUEsea.com'."\n\n"; print $S $peticion
Para una peticion POST, tenemos que indicar la longitud de los datos que se envían, podemos usar algo del estilo (es un ejemplo inventado de un supuesto formulario para votar):
$voto = 10; $discoID = 28912; $peticionPost='POST /discos/votar.asp HTTP/1.1 Host: www.paginaQUEsea.com Content-Type: application/x-www-form-urlencoded Content-Length: '; $post = 'accion=votar&id='.$discoID.'&voto='.$voto $peticion = $peticionPost.length($post)."\n\n".$post print $S $peticion;
Además de esto podemos enviar muchas más cabeceras (Cookies con sesiones php u otras cosas, Referer's, User-Agents, etc, etc...). Luego ya, según el escenario, después de obtener el resultado del servidor, se podría tratar y buscar patrones o lo que nos interesase, las combinaciones y posibilidades son infinitas.
Agosto 31st, 2006 at 0:27
o por ejemplo para subir o bajar la nota de ciertas peliculas en cierta pagina de cine xD
por lo que veo, los modulos de CPAN es en plan librerias hechas por otros, no ?
Agosto 31st, 2006 at 0:43
Igual entiendo algo del post ehhhhh.
Ingenieros: no hay quien los entienda, pero sin ellos, menuda contienda.
Ala, saludetes.
Agosto 31st, 2006 at 1:13
txus, es un repositorio de librerías, si. Se instalan mediante sistema gestor de paquetes estilo apt-get que lleva el mismo perl.
Agosto 31st, 2006 at 2:30
Nooooooooooo Blaxter, no sigas, en serio, NO entiendo vuestro lenguaje extraño.
Agosto 31st, 2006 at 8:32
jaja, joer si no tiene ninguna palabra rara lo de antes.
Repositorio ~= “almacen”.
librería ~= conjunto de ficheros de código que realizan una función similar y concreta.
apt-get ~= programa muy conocido usado por debian para la gestión de paquetes.
paquete ~= “programa”.
debian = de las mejores distro de linux.
distro = “distribucion”.
distribucion = conjunto de aplicaciones reunidas para formar un sistema GNU/Linux.
perl = lenguaje de programación, concretamente del que hablo en el post
Agosto 31st, 2006 at 8:40
suena interesante,zzzzzzzzz.
Agosto 31st, 2006 at 13:28
Ok, ahora sí, gracias.
Agosto 31st, 2006 at 14:09
Me va a venir de perlas para cierto script para cierto juego…
El caso es que ya sabía algo de Perl, pero nunca he hecho nada con sockets. Gracias
Agosto 31st, 2006 at 22:34
Interesante
. Para eso yo usé php compilado con la extensión de linea de comandos (CLI) y cURL. Algo así:
[code]
$valor\n\n\n";
$url="http://172.16.1.2/index.php?level=Nivel_5&vc=\"".$myMatches[1]."\" el siguiente passwd: ".$valor;
echo "Mandare a ".$url."\n\n";
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST,true);
curl_setopt($ch,CURLOPT_COOKIE,$sid);
curl_setopt($ch,CURLOPT_POSTFIELDS,"password=".$valor);
$data = curl_exec($ch);
echo $data;
/*
//curl_setopt($ch,
$data=curl_exec($ch);
echo "***** ATTENTION!!! *************\nLa pagina es: \n\n\n".$data;
//$matrix=preg_match("/&vc=\"(%s)\"/",$data);
//print_r($matrix);
curl_close($ch);
*/
?>
[/code]
Como se ve, primero abrimos un ‘curl handler’ (no se como se llama, pero lo he llamado así y au xD), luego le pasamos ciertas opciones (URL, método, variables, cookies…) y lanzamos la peticion con curl_exec().
Luego, recogemos de $data la respuesta.
Saludos
PD: Esto era la solución del nivel5 del concurso xD
Agosto 31st, 2006 at 22:41
Me he colado en el código, no está completo :S Esta vez creo que sí va bien
Aquí va, por si interesa a alguien:
$valor\n\n\n”;
$url=”http://172.16.1.2/index.php?level=Nivel_5&vc=\”".$myMatches[1].”\” el siguiente passwd: “.$valor;
echo “Mandare a “.$url.”\n\n”;
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST,true);
curl_setopt($ch,CURLOPT_COOKIE,$sid);
curl_setopt($ch,CURLOPT_POSTFIELDS,”password=”.$valor);
$data = curl_exec($ch);
echo $data;
/*
//curl_setopt($ch,
$data=curl_exec($ch);
echo “***** ATTENTION!!! *************\nLa pagina es: \n\n\n”.$data;
//$matrix=preg_match(”/&vc=\”(%s)\”/”,$data);
//print_r($matrix);
curl_close($ch);
*/
?>
Agosto 31st, 2006 at 23:01
172.16.1.2!! había conseguido olvidarme de esa ip! ahora ya no se me irá de la cabeza de nuevo xD
No conocía esa extensión de php, parece interesante, habrá que echarle un ojo, thx.
pd: para copypastear sin que molesten los tags html y tal en vez de [code] usa <code>
Agosto 31st, 2006 at 23:29
Juas, no habia leido lo de las etiquetas xD
Demasiado acostumbrado al BBCode estoy … la próxima vez seguro que lo pongo jeje
Saludos
Agosto 31st, 2006 at 23:31
Joder, no me había dado cuenta que el script entero sigue sin salir :S Le falta un preview a esto jeje
Ahi va ahora con la etiqueta que toca:
$valor\n\n\n"; $url="http://172.16.1.2/index.php?level=Nivel_5&vc=\"".$myMatches[1]."\" el siguiente passwd: ".$valor; echo "Mandare a ".$url."\n\n"; curl_setopt($ch,CURLOPT_URL,$url); curl_setopt($ch,CURLOPT_POST,true); curl_setopt($ch,CURLOPT_COOKIE,$sid); curl_setopt($ch,CURLOPT_POSTFIELDS,"password=".$valor); $data = curl_exec($ch); echo $data; /* //curl_setopt($ch, $data=curl_exec($ch); echo "***** ATTENTION!!! *************\nLa pagina es: \n\n\n".$data; //$matrix=preg_match("/&vc=\"(%s)\"/",$data); //print_r($matrix); curl_close($ch); */ ?>Espero que ahora sí haya salido bien. Saludos
Agosto 31st, 2006 at 23:32
AARG se lo sigue comiendo… pues nada, http://www.php.net/curl
Septiembre 1st, 2006 at 1:02
omg! se niega a salir xD. Teoricamente con la etiqueta code pilla todo sin excusas que yo sepa
(he puesto un preview ahora, que hacía falta, si)
Enero 31st, 2009 at 15:25
hola amigos saludos desde colombia, he estado leiendo sobre el tema solo le pido un favor …. sera posible que publicaran un ejemplo completo pera tenerlo estudiarlo y tenerlo como guia con la siguiente peticion
GET / CHANGEAVATAR? NombreDeUsuario = = eterte y SessionID y C31a08d9ca PLANTILLA = 2 & RoomID = R29_3-1 y = 7So AVATAR
esto es supuestamente para hacer inyecciones en latinchat
gracias