Pete Finnigan's Oracle Security Forum (http://www.petefinnigan.com/forum/yabb/YaBB.cgi)
Oracle Security >> Oracle Security >> Detecting brute forcing listener password
(Message started by: Pete Finnigan on Dec 9th, 2005, 2:32pm)

Title: Detecting brute forcing listener password
Post by Pete Finnigan on Dec 9th, 2005, 2:32pm
Hi,

Pete and others have talked about the listener security. It has no features like lock out after x failures, no password aging/management, etc. So the password can be brute forced. I have written a perl script that continuously scans the listener log file for tns-01169 errors. Tns-01169 is not necessarily  a synonym for a bad password but IMHO it is a valid assumption that a tns-01169 error will follow after a wrong password. A hacker would try a password and then (eg.) a status command to see if he has guessed the correct password. In case he chooses a wrong password this would generate the tns-01169 error. In case he guesses the correct password we are in trouble :(
My perl script checks the listener log for the tns-01169 every minute and email the administrator in case it founds an tns-01169 in the log for the scan period. Tns-01169 previously found are not emaild again. The scan period is one minute. It is a very simple script that can be easily converted to a Shell script. It can be easily improved: for example instead of emailing an alert it could be programmed to stop the listener after x attempts (=tns-01169).
Anyway I'm posting the script and use it at your own risk.
You have to enable the listener logging.

Ivan

-------------------- perl script --------------------

Code:
#!/usr/bin/perl

# Function: scans continuously every minute the Oracle
#           listener-log file for tns-1169. If such an event occurs then
#           email the administrator.
# Author  : I.A. Saez Scheihing (saezscheihing@gmail.com)
# Version : 1.0.x.x.
# Date    : 09-Dec-2005
# Run     : To have it active day & night : nohup perl ./scan_listener_log.pl &

my $command,$commandcode,$tmp1,$tmp2,$tmp3,$tmp4;
my $listener_log = "$ENV{'ORACLE_HOME'}".'/network/log/listener.log';
my $scan_debug   = 0;          # change to 1 to see  debug information
my $search_for   = '\* 1169';  # tns-01169 means: The listener has
                              # not recognized the password
my $date_time    = '';
my $email        = 'youremail\@yours.com';  # email-address administrator

print "$listener_log\n" if $scan_debug;

while (1==1) {  # while forever
  $date_time       = &datum;
  print "$date_time\n" if $scan_debug;
  #
  # open log file and start searching for $search_for in $date_time period

  open(LOG, $listener_log) || die "Can't open listener log: $listener_log\n";
  print "scanning for $date_time and $search_for\n" if $scan_debug;
  while (<LOG>) {
   chop;
   if (/$date_time/ && /$search_for/) {
    # in this period ($date_time) some tried  an unauthorized command and
    # got a tns-01169 error
    ($tmp1,$tmp2,$tmp3,$command,$tmp4,$commandcode) = split(/ /);
    $message = "At $date_time someone issued an unauthorized $command command(TNS-$commandcode)";
    &email_admin;                       # email alert message to admin
    print "Alert!! $message\n" if $scan_debug;
   }                                    # if (/$date_time/ && /$search_for/) {
  }                                     # while (<LOG>) {
  close(LOG);
  sleep 60;  # sleep 1 minute
}                                    # while (1==1)

exit;

sub datum {
my $sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst;

($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$mon  = (JAN,FEB,MAR,APR,MEI,JUN,JUL,AUG,SEP,OCT,NOV,DEC)[$mon];
$mday  = sprintf("%02d",$mday);  #leftpad day if necessary: 9 gets converted to 09
$hour  = sprintf("%02d",$hour);
$min   = sprintf("%02d",$min);
$year = $year+1900;
return ($mday . "-" . $mon . "-" . $year . " " .$hour.":".$min);
}

sub email_admin {
my $sendmail = '/usr/lib/sendmail -t -oi';

my $fromname = "Oracle";
open(MAIL,"| $sendmail") || die "Could not fork sendmail: $!";

print MAIL <<EOM;
Subject: Alert! Unauthorized listener commands!
From: $fromname
To: $email


$message
EOM

close(MAIL);
}

Title: Re: Detecting brute forcing listener password
Post by Pete Finnigan on Dec 10th, 2005, 9:53pm
Hi Ivan,

Thanks very much for this script. It will prove useful as a starting point for people who want to monitor their listener logs.

Great!

cheers

Pete

Title: Re: Detecting brute forcing listener password
Post by Pete Finnigan on Dec 12th, 2005, 5:53pm
Hey, I have a smiliar script I use to monitor my listener log file.  The only caveat is if you rotate your logs then you'll have to restart it.  I keep a file pointer open to the logfile and just scan what has changed since the last round.  I have a similiar script I use to monitor the alert log.


Code:
#!/usr/bin/perl -w

if ($#ARGV !=1) {
 die "Usage:  check_alert.pl <hostname> <path_to_listener_log> ex.  MyHost /var/opt/oracle/listener.log.\n";
}
sleep 2;

$interval=1200;        # How many seconds before we check to see if data has been written to the logfile;
$email_threshold=5;  # How many errors within the interval before an email gets sent;
$hostname=$ARGV[0];
$file=$ARGV[1];
open(filePtr, $file) or die "Can't find $file\n";


for (;;) {
 @errors=("Subject: Listener Password  Errors for $hostname\n");
 $currTime = localtime(time);
 push(@errors,"Here are some errors found at $currTime for $hostname.\n");

 while (<filePtr>) {
  chop $_;
  if (/TNS-01169/) {
      push(@errors, "$_\n");
  }
 }

 if ($#errors > $email_threshold)  {
  $rndExt = time;
  $rndFile = "alert_errors_$rndExt";
  open (TMPFILE, ">/tmp/$rndFile");

  foreach $error (@errors) {
       print TMPFILE $error;
  }
  close(TMPFILE);
  system ("mail user\@mycompany.com < /tmp/$rndFile");
  system ("rm /tmp/$rndFile");
 }

 sleep $interval;
 seek filePtr, 0, 1;
}

Title: Re: Detecting brute forcing listener password
Post by Pete Finnigan on Dec 14th, 2005, 6:26pm
Thanks a lot for this script.

cheers

Pete

Title: Re: Detecting brute forcing listener password
Post by Pete Finnigan on Dec 15th, 2005, 11:45pm
Pete,

I use swatch (http://swatch.sourceforge.net/) for the listeners at my site.  I have a config file which I use to notify us when there are issues:

watchfor /TNS\-01169:.* not recognized the password/
 mail=it-help@here,subject=TNS password failure
 throttle 01:00:00

Fortunately, I have had not atttempts to hack the listener.

It does present an issue for log rotation, but I have overcome this by stopping the listener and then the swatch process, move the log file, and then restart the processes.

I could have rolled my own Perl solution, but this looked interesting and we use swatch now for many other log file watching.

Ron Reidy

Title: Re: Detecting brute forcing listener password
Post by Pete Finnigan on Dec 16th, 2005, 9:30pm
Thanks very much for this Ron, this is a very simple solution to the issue of monitoring the listener log. This method as can be seen would be very easy to apply to other logs and easy to configure to watch for anything in them. I recommend the use of swatch in the SANS course and the book. This is a great, simple example.

thanks

Pete



Powered by YaBB 1 Gold - SP 1.4!
Forum software copyright © 2000-2004 Yet another Bulletin Board