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 :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:

#! /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.

15 Comentarios »

RSS feed para los comentarios de esta entrada.

  1. avatar

    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 #

  2. avatar

    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 #

  3. avatar

    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 #

  4. avatar

    Nooooooooooo Blaxter, no sigas, en serio, NO entiendo vuestro lenguaje extraño.

     

    Comentario por Miguel Daza — 31 Agosto, 2006 @ 2:30 #

  5. avatar

    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 #

  6. avatar

    suena interesante,zzzzzzzzz.

     

    Comentario por manolito — 31 Agosto, 2006 @ 8:40 #

  7. avatar

    Ok, ahora sí, gracias.

     

    Comentario por Miguel Daza — 31 Agosto, 2006 @ 13:28 #

  8. avatar

    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 #

  9. avatar

    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 :P

    PD: Esto era la solución del nivel5 del concurso xD

     

    Comentario por TuXeD — 31 Agosto, 2006 @ 22:34 #

  10. avatar

    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 #

  11. avatar

    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 #

  12. avatar

    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 #

  13. avatar

    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 #

  14. avatar

    AARG se lo sigue comiendo… pues nada, http://www.php.net/curl

     

    Comentario por TuXeD — 31 Agosto, 2006 @ 23:32 #

  15. avatar

    omg! se niega a salir xD. Teoricamente con la etiqueta code pilla todo sin excusas que yo sepa :o (he puesto un preview ahora, que hacía falta, si)

     

    Comentario por blaxter — 1 Septiembre, 2006 @ 1:02 #

Dejar un comentario

XHTML permitido: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Creative Commons License 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