logo.png

VI

EMACS

CVS

GIT

LATEX

ICALENDAR

ROBOTS

CORBA

QEMU

MAKEFILE

AUTOTOOLS

GNUPLOT

SCREEN

GRUB

MAO

VHS

ISO

Home Up


Contents



1 Outils


1.1 Installation

# apt-get install ngrep

# apt-get install libwww-mechanize-shell-perl
# apt-get install libwww-mechanize-perl
# apt-get install libhttp-proxy-perl
# apt-get install libhttp-recorder-perl


1.2 Documentation

$ man WWW::Mechanize::Shell
$ dpkg -L libwww-mechanize-perl | grep man.*gz


2 Espionner


2.1 Sniffer

Afin d'avoir un premier aperçu des échanges, on pourra avoir recours à cette version orienté HTTP de TCPDUMP.

# ngrep -d lo


2.2 Via Proxy (port 8080)

Il n'empêche que le plus simple reste de se placer en intermédiaire. Le proxy suivant est un script glané via le Linux Magazine 75.

#!/usr/bin/perl -w
use strict;
use HTTP::Proxy;
use HTTP::Proxy::HeaderFilter::simple;
use HTTP::Proxy::BodyFilter::simple;
use CGI::Util qw( unescape );

# récupération des paramètres de configuration
# spécifiques au script et pas à HTTP::Proxy
my %args = (
    peek   => ["planet-gis"],
    header => [],
);
{
    my $args = '(' . join( '|', keys %args ) . ')';
    for ( my $i = 0 ; $i < @ARGV ; $i += 2 ) {
        if ( $ARGV[$i] =~ /$args/o ) {
            push @{ $args{$1} }, $ARGV[ $i + 1 ];
            splice( @ARGV, $i, 2 );
            redo if $i < @ARGV;
        }
    }
}

# les en-têtes à afficher
# envoyées par le serveur
my @srv_hdr = (
    qw( Content-Type Set-Cookie Set-Cookie2 WWW-Authenticate Location ),
    @{ $args{header} }
);

# envoyées par le client
my @clt_hdr =
  ( qw( Cookie Cookie2 Referer Referrer Authorization ), @{ $args{header} } );

# NOTE: dans le cas d'une méthode POST, les filtres de requête
#       recoivent toujours le corps de la requête en une seule fois
my $post_filter = HTTP::Proxy::BodyFilter::simple->new(
    sub {
        my ( $self, $dataref, $message, $protocol, $buffer ) = @_;
        print STDOUT "\n", $message->method, " ", $message->uri, "\n";
        print_headers( $message, @clt_hdr );

        # ceci est copié de CGI.pm, méthode parse_params
        my (@pairs) = split( /[&;]/, $$dataref );
        for (@pairs) {
            my ( $param, $value ) = split( '=', $_, 2 );
            $param = unescape($param);
            $value = unescape($value);
            printf STDOUT "    %-20s => %s\n", $param, $value;
        }
    }
);

my $get_filter = HTTP::Proxy::HeaderFilter::simple->new(
    sub {
        my ( $self, $headers, $message ) = @_;
        my $req = $message->request;
        if ( $req->method ne 'POST' ) {
            print STDOUT "\n", $req->method, " ", $req->uri, "\n";
            print_headers( $req, @clt_hdr );
        }
        print STDOUT $message->status_line, "\n";
        print_headers( $message, @srv_hdr );
    }
);

sub print_headers {
    my $message = shift;
    for my $h (@_) {
        if ( $message->header($h) ) {
            print STDOUT "    $h: $_\n" for ( $message->header($h) );
        }
    }
}

# création du proxy avec les paramètres restants
my $proxy = HTTP::Proxy->new(@ARGV);

# pour espionner CERTAINS sites
if ( @{ $args{peek} } ) {
    for ( @{ $args{peek} } ) {
        $proxy->push_filter(
            host    => $_,
            method  => 'POST',
            request => $post_filter
        );
        $proxy->push_filter( host => $_, response => $get_filter );
    }
}

# sinon, on espionne TOUS les sites
else {
    $proxy->push_filter(
        method  => 'POST',
        request => $post_filter
    );
    $proxy->push_filter( response => $get_filter );
}
$proxy->start;


3 Enregister via proxy

Quite à être au milieu de l'échange, autant en profiter pour enregistrer les requêtes.

  • Il faut préalablement corriger un bug dans le fichier /usr/share/perl5/HTTP/Recorder.pm
    sub unmodify {
         my $self = shift;
         my $content = shift;
    
         return $content unless $content;
    
         # get rid of the arguments we added
         my $prefix = $self->{prefix};
    
         #HIDE THIS
         #for my $key ($content->query_param) {
         #if ($key =~ /^$prefix-/) {
         #    $content->query_param_delete($key);
         #}
         #}
    
         #ADD THIS
         $content =~ s/$prefix-(.*?)\?(.*?)&//g;
         $content =~ s/$prefix-(.*?)&//g;
         $content =~ s/$prefix-(.*?)$//g;
         $content =~ s/&$//g;
         $content =~ s/\?$//g;
    
         return $content;
    }
    
  • Cf: man HTTP::Recorder pour le code du proxy ci-dessous.
    #!/usr/bin/perl
    
    use HTTP::Proxy;
    use HTTP::Recorder;
    
    my $proxy = HTTP::Proxy->new();
    
    # create a new HTTP::Recorder object
    my $agent = new HTTP::Recorder;
    
    # set the log file (optional)
    $agent->file("replay.pl");
    
    # set HTTP::Recorder as the agent for the proxy
    $proxy->agent( $agent );
    
    # start the proxy
    $proxy->start();
    
    1;
    
    Ce scripts enregistre les requettes dans le script replay.pl


4 Rejouer


4.1 Tenter sa chance

On doit compléter le script replay.pl de la manière suivante :

#!/usr/bin/perl -w
use strict;
use WWW::Mechanize;
my $agent = WWW::Mechanize->new();

# facultatif
$agent->proxy(['http'], 'http://127.0.0.1:8080/'); # le premier proxy espion

# copier/coler de replay.pl
...

#wget
print $agent->content, "\n";


4.2 Pas à pas

Nous nous inspirons du script replay.pl.

$ perl -MWWW::Mechanize::Shell -eshell
(no url)>get http://planet-gis/xoops
http://planet-gis/xoops/>forms
http://planet-gis/xoops/>form 1                                                                                            
http://planet-gis/xoops/>fillout                                                                                           
http://planet-gis/xoops/>get http://planet-gis/xoops/modules/piCal/index.php?smode=List&op=all
http://planet-gis/xoops/modules/piCal/index.php?smode=List&op=all>form 3
http://planet-gis/xoops/modules/piCal/index.php?smode=List&op=all>fillout
http://planet-gis/xoops/modules/piCal/index.php?smode=List&op=all>get http://planet-gis/xoops/modules/piCal/?output_ics=1

....
>script


4.3 Script

Nous modifions le script replay.pl en conséquence.
#!/usr/bin/perl -w
use strict;
use WWW::Mechanize;
#-------------------
my $login="admin";
my $passwd="admin";
#-------------------
my $agent = WWW::Mechanize->new();

# Get cookie and connect
$agent->get('http://planet-gis.ias.u-psud.fr/xoops/index.php');
$agent->form_number(1);
$agent->field('uname', "$login");
$agent->field('pass', "$passwd");
$agent->click();

# Get event list
$agent->get('http://planet-gis/xoops/modules/piCal/index.php?smode=List&op=all');
my $page=$agent->content; 
$agent->form_name('MainForm');
$agent->tick('dummy', 'on');

# Mark all events into checkbox
my $dummy="";
my $number="";
do {
  ($dummy, $page) = split(/<input type='checkbox' name='ids\[\]' value=/, $page, 2);
  if (defined($page))
  {
    ($dummy, $number) = split(/'/, $page, 3);
    $agent->tick('ids[]', "$number");
  }
}
while (defined($page));

# Post form
$agent->click('output_ics_confirm');

# Ask for iCalendar (Windows) format
$agent->form_number(1);
$agent->click('do_output');

# Print iCalendar file
print $agent->content;

Home Up

This document is also available in PDF and PostScript format.



2016-02-15