Peticiones HTTP con Perl
Publicado por blaxter - 30 Ago 2006 a las 22:50En 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 :o, 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:
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:
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:
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):
$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.
15 Comentarios »
RSS feed para los comentarios de esta entrada.
Dejar un comentario
Esta obra está bajo una
licencia de Creative Commons.
Este blog funciona gracias a WordPress
con el theme GimpStyle
diseñado por Horacio Bella y adaptado por un servidor.
Feed entradas
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 ?
Comentario por txus — 31 Agosto, 2006 @ 0:27 #
Igual entiendo algo del post ehhhhh.
Ingenieros: no hay quien los entienda, pero sin ellos, menuda contienda.
Ala, saludetes.
Comentario por Miguel Daza — 31 Agosto, 2006 @ 0:43 #
txus, es un repositorio de librerías, si. Se instalan mediante sistema gestor de paquetes estilo apt-get que lleva el mismo perl.
Comentario por blaxter — 31 Agosto, 2006 @ 1:13 #
Nooooooooooo Blaxter, no sigas, en serio, NO entiendo vuestro lenguaje extraño.
Comentario por Miguel Daza — 31 Agosto, 2006 @ 2:30 #
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
Comentario por Blaxter — 31 Agosto, 2006 @ 8:32 #
suena interesante,zzzzzzzzz.
Comentario por manolito — 31 Agosto, 2006 @ 8:40 #
Ok, ahora sí, gracias.
Comentario por Miguel Daza — 31 Agosto, 2006 @ 13:28 #
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
Comentario por DraXus — 31 Agosto, 2006 @ 14:09 #
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
Comentario por TuXeD — 31 Agosto, 2006 @ 22:34 #
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);
*/
?>
Comentario por TuXeD — 31 Agosto, 2006 @ 22:41 #
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>
Comentario por blaxter — 31 Agosto, 2006 @ 23:01 #
Juas, no habia leido lo de las etiquetas xD
Demasiado acostumbrado al BBCode estoy … la próxima vez seguro que lo pongo jeje
Saludos
Comentario por TuXeD — 31 Agosto, 2006 @ 23:29 #
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
Comentario por TuXeD — 31 Agosto, 2006 @ 23:31 #
AARG se lo sigue comiendo… pues nada, http://www.php.net/curl
Comentario por TuXeD — 31 Agosto, 2006 @ 23:32 #
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)
Comentario por blaxter — 1 Septiembre, 2006 @ 1:02 #