Misc:Abuse Log: Difference between revisions

From Amar
Jump to navigationJump to search
comment2, http://himalaya.com.hk/ viagra hong kong, :[[, http://www.retakemanhattan.com/ buy viagra singapore, 86342,
No edit summary
 
(14 intermediate revisions by 3 users not shown)
Line 1: Line 1:
comment2, http://himalaya.com.hk/ viagra hong kong, :[[, http://www.retakemanhattan.com/ buy viagra singapore, 86342,
<pre>
#!/usr/bin/perl -w
 
use strict;
use Data::Dumper;
use DBI;
use Config::IniFiles;
use Net::Telnet;
 
$| = 1;
 
our $user = 'admin';
our $pass = 'xxxxxxxxx';
my $host1 = '192.168.20.1';
my $name1 = 'A';
my $host2 = '192.168.20.3';
my $name2 = 'B';
my $badip = '';
 
 
 
# Requests of interest. Remember to do the regular expression
my $log_events = { '.page' => 1,
'.wmv' => 2,
'.mov' => 2,
'.cgi' => 3,
'.pl' => 3,
'.html' => 4,
};
my $ids_events = { '.jpg' => 5,
'.bmp' => 5,
'.png' => 5,
'.gif' => 5,
};
my $log_exts = join("\|",keys(%$log_events));
$log_exts =~ s/\./\\\./g;
my $log_ext_match = qr/($log_exts)$/;
my $ids_exts = join("\|",keys(%$ids_events));
$ids_exts =~ s/\./\\\./g;
my $ids_ext_match = qr/($ids_exts)$/;
 
my $dir_match = qr{/};
my $max_hits = { 1 => 60,
2 => 12,
3 => 30,
4 => 120,
5 => 20,
};
 
my $pattern = qr/([0-9]+\.[0-9]+\.[0-9]+)\.[0-9]+/;
 
# print Data::Dumper->Dump([$log_exts, $log_ext_match],[qw(log_exts log_ext_match)]);
 
my $exclude = {};
&check_ip($exclude);
 
my $db = 'ABUSE';
my $cfg = Config::IniFiles->new( -file=> '/etc/db_connect.conf', -default=> 'DEFAULT');
my $dbi = "DBI:mysql:".$cfg->val($db,"name").":".$cfg->val($db,"host");
my $dbh = DBI->connect($dbi,$cfg->val($db,'user'),$cfg->val($db,'password'), {RaiseError => 1, AutoCommit => 0});
my $sth_ins = $dbh->prepare(
qq[INSERT INTO abuse_log
(IP,event_id,bucket_id,hits)
VALUES (?,?,MINUTE(NOW()),1)
]);
my $sth_upd = $dbh->prepare(
qq[UPDATE abuse_log
SET hits = hits + 1
WHERE IP = ? AND event_id = ? AND bucket_id = MINUTE(NOW())
]);
my $sth_get = $dbh->prepare(
qq[ SELECT hits FROM abuse_log
WHERE IP = ? AND event_id = ? AND bucket_id = MINUTE(NOW())
]);
 
my $sth_log = $dbh->prepare(
qq[ INSERT INTO blocked
(IP,event_id,hits)
VALUES (?,?,?)
]);
 
open ("STDOUT", ">>$ARGV[0]") || die $!;
 
while (my $line = <STDIN>) {
chomp $line;
my @fields = split /\|/, $line;
my %fields = map { split /\=/,$_ } @fields;
if ( $fields{U} =~ /$log_ext_match/ ) {
# print STDOUT Data::Dumper->Dump([\%fields],[qw(*fields)]);
my $event = $1;
my $ip = $fields{I};
my $subnet = undef;
if ($ip =~ $pattern) {
$subnet = $1;
};
if (exists($exclude->{$ip}) || exists($exclude->{$subnet})) {
print STDOUT $line."\n";
next;
}
my $event_id = $log_events->{$event};
my $max = $max_hits->{$event_id};
# Assume UPDATE and catch error
eval{
$sth_get->execute($ip,$event_id);
};
unless ($@) {
my ($hits) = $sth_get->fetchrow_array();
$hits ||= 0;
# print STDOUT Data::Dumper->Dump([$ip,$event,$event_id,$max,$hits],[qw(ip event event_id max hits)]);
if ($hits > $max) {
print STDOUT "***** ABUSE **** $ip $event ( $hits )\n";
&disable_ip($ip);
eval {
open ABUSE_LOG, ">>/nfsroot/logs/log_abuse.log" or print STDOUT $!;
print ABUSE_LOG "***** ABUSE **** $ip $event ( $hits )\n";
print ABUSE_LOG Data::Dumper->Dump([\%fields, $hits, $max],[qw(*fields hits max)]);
close ABUSE_LOG;
};
eval {
$sth_log->execute($ip,$event_id,$hits);
};
}
my $rv;
eval{
# print STDOUT "Updating";
$rv = $sth_upd->execute($ip,$event_id);
# print STDOUT "Error : '$@".$dbh->errstr."' rv = '$rv'\n";
};
if ($@ || $rv == 0) {
eval{
# print STDOUT "Inserting ";
$sth_ins->execute($ip,$event_id);
};
}
if ($@) {
print STDOUT "BAD db: $@\n";
$dbh->rollback();
} else {
$dbh->commit();
}
}
print STDOUT $line."\n";
} elsif ( $fields{U} =~ /$ids_ext_match/ ) {
my $event = $1;
my $ip = $fields{I};
my $subnet = undef;
if ($ip =~ $pattern) {
$subnet = $1;
};
if (exists($exclude->{$ip}) || exists($exclude->{$subnet})) {
print STDOUT $line."\n";
next;
}
my $event_id = $ids_events->{$event};
my $max = $max_hits->{$event_id};
 
# IDS case #1
# /home/www/v3/images/images/images/images/images/images/images/images/images/images ....
# count the no of / and if above a #, kill the IP
my @dirs = split($dir_match, $fields{U});
my $hits = scalar(@dirs);
# Log it
if ($hits>$max) {
print STDOUT "***** ABUSE **** $ip $event ( $hits )\n";
&disable_ip( $ip);
eval {
open ABUSE_LOG, ">>/nfsroot/logs/log_abuse.log" or print STDOUT $!;
print ABUSE_LOG "***** ABUSE **** $ip $event ( $hits )\n";
print ABUSE_LOG Data::Dumper->Dump([\%fields, $hits, $max],[qw(*fields hits max)]);
close ABUSE_LOG;
};
eval {
$sth_log->execute($ip,$event_id,$hits);
};
}
}
 
# Temp LOG ALL - bad bad bad
# print STDOUT $line."\n";
}
 
close (STDOUT);
$sth_log->finish;
$sth_ins->finish;
$sth_upd->finish;
$sth_get->finish;
$dbh->disconnect;
 
exit 0;
 
sub hold_it {
 
my ($host,$name, @IPs) = @_;
 
my $session = Net::Telnet->new (Timeout => 10, Prompt => '/.*#.*$/', Dump_log => '/tmp/telnet.log');
# print "$host: @IPs\n";
$session->open($host);
$session->put($user."\n");
$session->waitfor ('/.*Password:.*/');
$session->put($pass."\n");
# $session->login($user, $pass);
#print $session->cmd(String => 'admin');
 
# $session->waitfor('/ Name/');
 
#$session->waitfor('/Password.*/');
#print $session->cmd('g0dm0d3');
$session->waitfor('/.*'.$name.'#.*/');
my @output = $session->cmd('config t'."\n");
my $res = join("\n",@output);
$res .= "\n";
# $session->waitfor('/.*A\(config\)#.*/');
 
 
 
  # Execute a command
  # my @output = $session->cmd('show server real l83'."\n");
# $session->waitfor('/.*\(config\)#.*/');
foreach my $badip (@IPs) {
$res .= "$badip \n";
@output = $session->cmd("security hold-source-ip $badip 60\n");
$res .= join("\n",@output);
$res .= "\n";
}
@output = $session->cmd('end');
$res .= join("\n",@output);
$res .= "\n";
if (0) {
@output = $session->cmd('exit');
$res .= join("\n",@output);
$res .= "\n";
# $res .= $session->cmd('exit');
}
$session->close;
 
print STDOUT $res;
};
 
 
sub disable_ip {
 
my (@ips) = @_;
&hold_it($host1,$name1,@ips);
&hold_it($host2,$name2,@ips);
 
}
 
sub check_ip {
my ($exclude) = @_;
my $ips = [qw(
195.92.67.71
166.102.104.65
24.191.101.131
211.50.250.249
152.163.207.214
213.154.134.157
68.47.133.228
63.118.66.11
166.102.104.65
206.154.135.67
208.236.105
209.217.134.7
12.8.9.140
157.130.79.70
209.217.134.10
65.116.11.120
65.116.11.115
4.36.232
4.36.233
4.36.234
66.28.24
208.62.228
208.62.229
208.62.230
66.194.164.160
66.194.164.162
66.194.164.157
66.194.164.200
69.25.84.2
66.165.178
65.223.64
64.38.240
64.38.241
66.37.115
64.74.164
38.118.131
)];
%$exclude = map {$_ => 1 } @$ips;
}
</pre>

Latest revision as of 03:07, 8 November 2011

#!/usr/bin/perl -w

use strict;
use Data::Dumper;
use DBI;
use Config::IniFiles;
use Net::Telnet;

$| = 1;

our $user	= 'admin';
our $pass	= 'xxxxxxxxx';
my $host1	= '192.168.20.1';
my $name1	= 'A';
my $host2	= '192.168.20.3';
my $name2	= 'B';
my $badip	= '';



# Requests of interest. Remember to do the regular expression
my $log_events	= { '.page'	=> 1,
				'.wmv'	=> 2,
				'.mov'	=> 2,
				'.cgi'	=> 3,
				'.pl'	=> 3,
				'.html'	=> 4,
			};
my $ids_events	= { '.jpg'	=> 5,
				'.bmp'	=> 5,
				'.png'	=> 5,
				'.gif'	=> 5,
			};
my $log_exts	= join("\|",keys(%$log_events));
$log_exts		=~ s/\./\\\./g;
my $log_ext_match	= qr/($log_exts)$/;
			
my $ids_exts	= join("\|",keys(%$ids_events));
$ids_exts		=~ s/\./\\\./g;
my $ids_ext_match	= qr/($ids_exts)$/;

my $dir_match	= qr{/};
			
my $max_hits	= { 1	=> 60,
					2	=> 12,
					3	=> 30,
					4	=> 120,
					5	=> 20,
				};

my $pattern	= qr/([0-9]+\.[0-9]+\.[0-9]+)\.[0-9]+/;

# print Data::Dumper->Dump([$log_exts, $log_ext_match],[qw(log_exts log_ext_match)]);

my $exclude		= {};
&check_ip($exclude);

my $db	= 'ABUSE';
my $cfg	= Config::IniFiles->new( -file=> '/etc/db_connect.conf', -default=> 'DEFAULT');
my $dbi	= "DBI:mysql:".$cfg->val($db,"name").":".$cfg->val($db,"host");
my $dbh	= DBI->connect($dbi,$cfg->val($db,'user'),$cfg->val($db,'password'), {RaiseError => 1, AutoCommit => 0});
my $sth_ins	= $dbh->prepare(
				qq[INSERT INTO abuse_log 
					(IP,event_id,bucket_id,hits) 
					VALUES (?,?,MINUTE(NOW()),1)
				]);
my $sth_upd	= $dbh->prepare(
				qq[UPDATE abuse_log
					SET hits = hits + 1
					WHERE IP = ? AND event_id = ? AND bucket_id = MINUTE(NOW())
				]);
my $sth_get = $dbh->prepare(
				qq[ SELECT hits FROM abuse_log
					WHERE IP = ? AND event_id = ? AND bucket_id = MINUTE(NOW())
					
				]);

my $sth_log = $dbh->prepare(
				qq[ INSERT INTO blocked
					(IP,event_id,hits) 
					VALUES (?,?,?)
				]);

open ("STDOUT", ">>$ARGV[0]") || die $!;

while (my $line = <STDIN>) {
	chomp $line;
	my @fields = split /\|/, $line;
	my %fields = map { split /\=/,$_ } @fields;
	if ( $fields{U} =~ /$log_ext_match/ ) {
		# print STDOUT Data::Dumper->Dump([\%fields],[qw(*fields)]);
		my $event		= $1;
		my $ip			= $fields{I};
		my $subnet		= undef;
		if ($ip =~ $pattern) {
			$subnet	= $1;
		};
		if (exists($exclude->{$ip}) || exists($exclude->{$subnet})) {
			print STDOUT $line."\n";
			next;
		}
		my $event_id	= $log_events->{$event};
		my $max			= $max_hits->{$event_id};
		# Assume UPDATE and catch error
		eval{
			$sth_get->execute($ip,$event_id);
		};
		unless ($@) {
		my ($hits)	= $sth_get->fetchrow_array();
		$hits	||= 0;
		# print STDOUT Data::Dumper->Dump([$ip,$event,$event_id,$max,$hits],[qw(ip event event_id max hits)]);
		if ($hits > $max) {
			print STDOUT "***** ABUSE **** $ip $event ( $hits )\n";
			&disable_ip($ip);
			eval {
				open ABUSE_LOG, ">>/nfsroot/logs/log_abuse.log" or print STDOUT $!;
				print ABUSE_LOG "***** ABUSE **** $ip $event ( $hits )\n";
				print ABUSE_LOG Data::Dumper->Dump([\%fields, $hits, $max],[qw(*fields hits max)]);
				close ABUSE_LOG;
			};
			eval {
				$sth_log->execute($ip,$event_id,$hits);
			};
		}
		my $rv;
		eval{
			# print STDOUT "Updating";
			$rv = $sth_upd->execute($ip,$event_id);
			# print STDOUT "Error : '$@".$dbh->errstr."' rv = '$rv'\n";
		};
		if ($@ || $rv == 0) {
			eval{
				# print STDOUT "Inserting ";
				$sth_ins->execute($ip,$event_id);
			};
		}
		if ($@) {
			print STDOUT "BAD db: $@\n";
			$dbh->rollback();
		} else {
			$dbh->commit();
		}
		}
		print STDOUT $line."\n";
	} elsif ( $fields{U} =~ /$ids_ext_match/ ) {
		my $event		= $1;
		my $ip			= $fields{I};
		my $subnet		= undef;
		if ($ip =~ $pattern) {
			$subnet	= $1;
		};
		if (exists($exclude->{$ip}) || exists($exclude->{$subnet})) {
			print STDOUT $line."\n";
			next;
		}
		my $event_id	= $ids_events->{$event};
		my $max			= $max_hits->{$event_id};

		# IDS case #1
		# /home/www/v3/images/images/images/images/images/images/images/images/images/images ....
		# count the no of / and if above a #, kill the IP
		my @dirs		= split($dir_match, $fields{U});
		my $hits		= scalar(@dirs);
		
		
		# Log it
		if ($hits>$max) {
			print STDOUT "***** ABUSE **** $ip $event ( $hits )\n";
			&disable_ip( $ip);
			eval {
				open ABUSE_LOG, ">>/nfsroot/logs/log_abuse.log" or print STDOUT $!;
				print ABUSE_LOG "***** ABUSE **** $ip $event ( $hits )\n";
				print ABUSE_LOG Data::Dumper->Dump([\%fields, $hits, $max],[qw(*fields hits max)]);
				close ABUSE_LOG;
			};
			eval {
				$sth_log->execute($ip,$event_id,$hits);
			};
		}
	}

		# Temp LOG ALL - bad bad bad
		# print STDOUT $line."\n";
}

close (STDOUT);
$sth_log->finish;
$sth_ins->finish;
$sth_upd->finish;
$sth_get->finish;
$dbh->disconnect;

exit 0;

sub hold_it {

	my ($host,$name, @IPs)	= @_;

	my $session	= Net::Telnet->new (Timeout => 10, Prompt => '/.*#.*$/', Dump_log => '/tmp/telnet.log');
	# print "$host: @IPs\n";
	$session->open($host);
	$session->put($user."\n");
	$session->waitfor ('/.*Password:.*/');
	$session->put($pass."\n");
	# $session->login($user, $pass);
	#print $session->cmd(String => 'admin');

	# $session->waitfor('/ Name/');

	#$session->waitfor('/Password.*/');
	#print $session->cmd('g0dm0d3');
	$session->waitfor('/.*'.$name.'#.*/');
	my @output = $session->cmd('config t'."\n");
	my	$res	= join("\n",@output);
		$res	.= "\n";
	# $session->waitfor('/.*A\(config\)#.*/');
	



  # Execute a command
  # my @output = $session->cmd('show server real l83'."\n");
	# $session->waitfor('/.*\(config\)#.*/');
	foreach my $badip (@IPs) {
		$res	.= "$badip \n";
		@output = $session->cmd("security hold-source-ip $badip 60\n");
		$res	.= join("\n",@output);
		$res	.= "\n";
	}
	@output = $session->cmd('end');
		$res	.= join("\n",@output);
		$res	.= "\n";
	if (0) {
		@output = $session->cmd('exit');
		$res	.= join("\n",@output);
		$res	.= "\n";
		# $res .= $session->cmd('exit');
	}
	$session->close;

	print STDOUT $res;
};


sub disable_ip {

	my (@ips) = @_;
	&hold_it($host1,$name1,@ips);
	&hold_it($host2,$name2,@ips);

}

sub check_ip {
	my ($exclude)	= @_;
		my $ips = [qw( 
		195.92.67.71 
		166.102.104.65 
		24.191.101.131 
		211.50.250.249 
		152.163.207.214 
		213.154.134.157 
		68.47.133.228 
		63.118.66.11 
		166.102.104.65 
		206.154.135.67 
		208.236.105
		209.217.134.7 
		12.8.9.140 
		157.130.79.70 
		209.217.134.10 
		65.116.11.120 
		65.116.11.115
		4.36.232
		4.36.233
		4.36.234
		66.28.24
		208.62.228
		208.62.229
		208.62.230
		66.194.164.160 
		66.194.164.162
		66.194.164.157
		66.194.164.200
		69.25.84.2
		66.165.178
		65.223.64
		64.38.240
		64.38.241
		66.37.115
		64.74.164
		38.118.131
		)];
		
		%$exclude = map {$_ => 1 } @$ips;
}