Perl script.  Detects descriptor-sapping port 80 worms.  Substitute in your
own specific values for $city and "whereever.com".  Everything else should
be fairly straightforward.  Run it every five minutes out of cron.

I hope this helps some people.  Worms were becoming a headache for me.

Paul
#!/usr/bin/perl

$city = 'CityName';

main: {
        open( SQUID, "tail -9000 /var/log/squid/access.log |" );
        $x = <SQUID>;
        @w = split(/\s+/, $x );
        @x = split(/\./, $w[0] );
        $seconds = time - $x[0];
        $minutes = $seconds / 60;
        $limit = int(30 * $minutes);
        while( <SQUID> ) {
                @w = split(/\s+/, $_ );
                @x = split(/\//, $w[6] );
                $xip = $w[2] .'-'. $x[2];  # client ip - requested host
                unless (defined $unique{$xip}) {
                        $ip{$w[2]}++;
                        $unique{$xip}++;
                } else {
                        $un_ip{$w[2]}++;
                }
        }
        close( SQUID );

        @ips = keys( %ip );

        foreach $ip ( @ips ) {
                my $tot = $un_ip{$ip} + $ip{$ip};
                my $ratio = $ip{$ip} / $tot * 100;
                # print "$ip   $ip{$ip}   $limit    $ratio \n";
                if ($ip{$ip} > $limit && $ratio > 90) {
                        $ipt1 = '/sbin/iptables -t nat -I PREROUTING -s';
                        $ipt2 = '-p tcp -m tcp --dport 80 -j DROP';
                        system( "$ipt1 $ip $ipt2" );

                        send_email( '[EMAIL PROTECTED]' );
                }
        }
}

sub send_email {
        my $email = shift;

        my $message =
"To: $email
From: [EMAIL PROTECTED]
Subject: IP blocked in $city

Server: $city

The IP address $ip tried to scan $ip{$ip} hosts
in $seconds seconds ($minutes min).

The IP as been automagically blocked in the IP tables
of the squid server. The customer should be contacted
immediately of the infection.

He or she will be unable to surf the web until we manually remove
the IPTABLE entry.
.
";


        use Net::Telnet();

        $t = new Net::Telnet( Timeout => 600,
                                Port => 25,
                                Prompt => '/.*/');
        $t->dump_log( "dump_log" );
        $t->open("smtp.whereever.com");

        $t->waitfor( '/220 .*\n/' );
        $t->print( 'helo Squid_Killer' );

        $t->waitfor( '/250 .*\n/' );
        $t->print( 'mail from: <[EMAIL PROTECTED]>' );

        $t->waitfor( '/250 .*\n/' );
        $t->print( 'rcpt to: <'. $email .'>' );

        $t->waitfor( '/250 .*\n/' );
        $t->print( 'data' );

        $t->waitfor( '/354 .*\n/' );
        $t->print( $message );

        $t->waitfor( '/250 .*\n/' );
        $t->print( 'quit' );

        $t->close;
}

Reply via email to