Simple program to report successful/fail ip logins and sorted by count

Discuss your pilot or production implementation with other Zimbra admins or our engineers.
User avatar
JDunphy
Outstanding Member
Outstanding Member
Posts: 272
Joined: Fri Sep 12, 2014 11:18 pm
Location: Victoria, BC
ZCS/ZD Version: Release 8.7.11_GA_1854.RHEL6_64.P6
Contact:

Simple program to report successful/fail ip logins and sorted by count

Postby JDunphy » Sat Jan 28, 2017 12:17 am

In case anyone wants to track ip's with user login and the counts by ip. I use it to look for compromised accounts or ones that will be soon. ;-)

It resulted from an active dictionary attack on one of our 8.7.1 servers so this quick/dirty script to see what was happening.

Run the program without any arguments and as the zimbra user. You need read access to /opt/zimbra/log for whatever user to run the script as.

Output is by user and sorted by ip reference count and looks like this.

user_a@example.com
[ 4] - 189.170.193.209
[ 4] - 164.136.12.177
[ 4] - 144.136.12.187
[ 3] - 51.62.160.157
[ 1] - 118.253.220.248
[ 1] - 129.55.121.74
[ 1] - 47.115.1.60
[ 1] - 127.244.31.10
[ 4] - 174.136.12.187 failed imap
[ 4] - 188.170.193.209 failed imap
[ 4] - 174.136.12.177 failed imap
[ 3] - 50.62.160.157 failed imap
[ 1] - 117.253.220.248 failed imap
[ 1] - 119.55.121.74 failed imap
[ 1] - 117.244.31.10 failed imap
[ 1] - 37.115.1.60 failed imap

user_b@example.com
[ 9] - 137.142.50.234
[ 2] - 25.170.150.130
[ 1] - 137.142.50.234 failed web

So user_b@example.com mistyped their zimbra login information but was able to login 9 times correctly.

Code: Select all

#!/usr/bin/perl

use Data::Dumper qw(Dumper);

%ip_list = ();  #ip list
%fip_list = ();   #failed ip list
$audit_log = 0;   #todays logging

chdir "/opt/zimbra/log";

for (glob 'audit.log*') {

  # audit.log is always todays stuff
  #print "Opening file $_";
  if ($_ eq 'audit.log')
  {
     $audit_log = 1;
     open (IN, sprintf("cat %s |", $_))
       or die("Can't open pipe from command 'zcat $filename' : $!\n");
  }
  else
  {
     $audit_log = 0;
     open (IN, sprintf("zcat %s |", $_))
       or die("Can't open pipe from command 'zcat $filename' : $!\n");
  }

  while (<IN>)
  {
   if (m#invalid password#i)
   {
      #print $_;
      if (m#ImapServer#i) {
      my($ip,$user) = m#.*\s+\[ip=.*;oip=(.*);via=.*;\]\s*.* failed for\s+\[(.*)\].*$#i;
      $uagent = "imap";
      #print " - ip is $ip, user is $user, agent is $uagent\n";
      #print $_;

      ++$ip_list{$user}{$ip};      #we loop by this for report
      ++$fip_list{$user}{$ip}{'count'};
      ++$fip_list{$user}{$ip}{'imap'};
      }
      elsif (m#Pop3Server#i)
      {
      my($ip,$user) = m#.*\s+\[ip=.*;oip=(.*);\]\s*.* failed for\s+\[(.*)\].*$#i;
      $uagent = "pop";
      #print " - ip is $ip, user is $user, agent is $uagent\n";
      #print $_;
      ++$ip_list{$user}{$ip};      #we loop by this for report
      ++$fip_list{$user}{$ip}{'count'};
      ++$fip_list{$user}{$ip}{'pop'};
      }
      elsif (m#http#i)
      {
      my($user,$ip,$uagent) = m#.*\s+\[name=(.*);oip=(.*);ua=(.*);\].*$#i;
      $uagent = "web";
      #print " - ip is $ip, user is $user, agent is $uagent\n";
      #print $_;
      ++$ip_list{$user}{$ip};      #we loop by this for report
      ++$fip_list{$user}{$ip}{'count'};
      ++$fip_list{$user}{$ip}{'web'};
      }
   }
   elsif (m#AuthRequest#i && ($_ !~ m/zimbra/i))
   {
      my($user,$ip,$uagent) = m#.*\s+\[name=(.*);oip=(.*);ua=(.*);\].*$#i;
      ++$ip_list{$user}{$ip};
      #$ip_list{$user}{'Agent'} = $uagent;
      if ($audit_log == 1) { print $_; }
      #print " - ip is $ip, user is $user, agent is $uagent\n";
   }
  }
  close (IN);

}


#debug
#print Dumper \%ip_list;
#print Dumper \%fip_list;

for $user (sort {$ip_list{$b} <=> $ip_list{$a}}  keys %ip_list )
{

  print "\n",$user,"\n";


   for $ip (sort {$ip_list{$user}{$b} <=> $ip_list{$user}{$a}}  keys %{$ip_list{$user}} )
   {
      #  See count of how many times
      printf (" [%4d] - %s\n", $ip_list{$user}{$ip},$ip);
      #printf ("%s\n",$ip);
   }

   # failed
   for $ip (sort {$fip_list{$user}{$b} <=> $fip_list{$user}{$a}}  keys %{$fip_list{$user}} )
   {
      #  See count of how many times
      printf (" [%4d] - %s ", $fip_list{$user}{$ip}{count},$ip);
      printf " failed web " if exists $fip_list{$user}{$ip}{'web'};
      printf " failed imap " if exists $fip_list{$user}{$ip}{'imap'};
      printf " failed pop " if exists $fip_list{$user}{$ip}{'pop'};
      printf ("\n");
#%%% we can have different user's in fip_list that ip_list doesn't have.
      #printf ("%s\n",$ip);
   }
}



It might be useful to others.


MedfastSupport
Posts: 2
Joined: Fri Jun 08, 2018 12:28 pm

Re: Simple program to report successful/fail ip logins and sorted by count

Postby MedfastSupport » Thu Jun 14, 2018 1:50 pm

I love it. great script
milauria
Advanced member
Advanced member
Posts: 57
Joined: Mon Aug 15, 2016 12:32 pm

Re: Simple program to report successful/fail ip logins and sorted by count

Postby milauria » Thu Jun 14, 2018 9:32 pm

This is why I love open-source! Nice and easy... thanks
User avatar
DavidMerrill
Posts: 45
Joined: Thu Jul 30, 2015 2:44 pm
Location: Portland, ME
Contact:

Re: Simple program to report successful/fail ip logins and sorted by count

Postby DavidMerrill » Thu Jun 14, 2018 11:37 pm

Nicely done...and in Perl!
___________________________________
David Merrill - Zimbra Practice Lead
Reliable Networks - Zimbra Hosting, Licensing and Professional Services
Zeta Alliance

Return to “Administrators”

Who is online

Users browsing this forum: No registered users and 27 guests