Advertisement
rplantiko

Block malignant SMTP authentication attempts

Jul 25th, 2015
606
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 3.08 KB | None | 0 0
  1. #!/usr/bin/perl
  2.  
  3. use strict;
  4. use warnings;
  5.  
  6. # The syslogs of the mail transfer agent - either in /var/log/mail.info or even in the central syslog -
  7. # often display many attempts of perpetrators trying to log in with different user / password combinations.
  8. # To make it less apparent, the attacks are stretched over several days, with 5 minutes or more between
  9. # successive attempts
  10.  
  11. # This script looks for log file entries that match the following pattern:
  12.  
  13. # Jul 25 13:28:57 smtp_auth: FAILED: user - password incorrect from 193.189.116.49.host.e-ring.pl [193.189.116.49]
  14. # Jul 25 15:42:19 smtp_auth: FAILED: webmaster - password incorrect from 241.nochost.ru [80.82.65.237]
  15.  
  16. # If it finds IP addresses in this way, they will be blocked and added to a logfile with all the blocked IPs.
  17. # (One could extend the script to check for defined exceptions or for multiple unsuccessful login attempts
  18. # in a short time interval in order to allow for some *own* unsuccessful login attempts due to mistyping!)
  19.  
  20. # When scheduling it as a cron job, you have to redirect >/dev/null, as the script writes informations to stdout
  21.  
  22. # On my server, I found thousands of unsuccessful login attempts
  23. # from the following IPs in the last days (starting July 22,2015):
  24. #
  25. #80.82.65.237
  26. #185.40.4.31
  27. #123.56.2.249
  28. #181.65.181.84
  29. #189.222.182.223
  30. #213.4.81.84
  31. #222.124.200.250
  32. #59.38.97.123
  33. #61.224.50.139
  34. #193.189.116.49
  35. #185.40.4.30
  36.  
  37. my $PATH_TO_BLOCKED_IP_FILE = "....";
  38.  
  39. my $xip = get_unauth_ip( );
  40. print("unauthorized :\n");
  41. do_print( $xip );
  42. my $yip = read_already_blocked( );
  43. print("already blocked:\n");
  44. do_print( $yip );
  45. remove_already_blocked( $xip, $yip );
  46. print("rest :\n");
  47. do_print( $xip );
  48. my $new_ips = [ keys %$xip ];
  49. if (scalar(@$new_ips) > 0) {
  50.   do_block( $new_ips );
  51.   add_ips_to_file( $new_ips );
  52. }
  53.  
  54. sub get_unauth_ip {
  55.   my %ip = ();
  56.   open (my $log, "</var/log/mail.info" ) or die "Can't open /var/log/mail.info";
  57. # Jul 25 13:28:57 lvps46-163-114-146 smtp_auth: FAILED: user - password incorrect from 193.189.116.49.host.e-ring.pl [193.189.116.49]
  58.   foreach (<$log>) {
  59.     $ip{$2} = 1 if /FAILED:\s*([@.\w]+)\s*\-\s*password incorrect.*\[([\d.]+)\]/;
  60.   }
  61.   return \%ip;
  62. }
  63.  
  64. sub do_print {
  65.   my $ip = shift;
  66.   foreach (sort keys %$ip) {
  67.     print "$_\n";
  68.    }
  69. }
  70.  
  71. sub read_already_blocked {
  72.   my %ip = ();
  73.   open IP_BLOCKED, "<$PATH_TO_BLOCKED_IP_FILE" or die "Can't open logfile for blocked IP's: $!\n";
  74.   foreach (<IP_BLOCKED>) {
  75.     $ip{$1} = 1 if /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/;    
  76.   }
  77.   close IP_BLOCKED;
  78.   return \%ip;
  79. }
  80.  
  81. sub do_block {
  82.   my $ips = shift;
  83.   foreach my $ip (@$ips) {
  84.     `/sbin/iptables -A INPUT -s $ip -j DROP`;
  85.     `/sbin/iptables -A OUTPUT -d $ip -j DROP`;
  86.   }
  87.  
  88. }
  89.  
  90. sub remove_already_blocked {
  91.   my ($xip,$yip) = @_;
  92.   foreach my $ip (keys %$yip) {
  93.     delete $xip->{$ip} if exists $xip->{$ip};
  94.     }
  95. }
  96.  
  97. sub add_ips_to_file {
  98.   my $ips = shift;
  99.   open IP_BLOCKED, ">>$PATH_TO_BLOCKED_IP_FILE" or die "Can't open ip.blocked: $!\n";
  100.   foreach my $ip (@$ips) {
  101.     print IP_BLOCKED "#$ip\n";
  102.     }
  103.   close IP_BLOCKED;
  104. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement