Guest

Cisco IPS 4200 Series Sensors

Configure E-mail Notifications with Scripts for IDS Alerts Using CiscoWorks Monitoring Center for Security

Document ID: 47582

Updated: Jul 12, 2006

   Print

Introduction

Security Monitor has the ability to send e-mail notifications when an Event Rule is triggered. The inbuilt variables that can be used within the e-mail notification for each event do not include things such as the Signature ID, the source and destination of the alert, and so forth. This document provides instructions you can use to configure Security Monitor to include these variables (and many more) within the e-mail notification message.

Prerequisites

Requirements

There are no specific requirements for this document.

Components Used

This document is not restricted to specific software and hardware versions. However, be sure to use the appropriate Perl script based on what Sensor versions run in your environment.

Conventions

Refer to the Cisco Technical Tips Conventions for more information on document conventions.

E-mail Notification Configuration Procedure

Use this procedure to configure e-mail notifications.

Note:  In order to send e-mail to the correct e-mail address, be sure to change the e-mail address in the script.

  1. Copy one of these scripts into the $BASE\CSCOpx\MDC\etc\ids\scripts directory on the VPN/Security Management Solution (VMS) server. This allows you to select it later in the process when you define an event rule. Save the script as emailalert.pl.

    Note:  If you use a different name, ensure you reference that name in the Event Rule defined in these steps.

    • For version 3.x Sensors, use the 3.x Sensors Script

    • For version 4.x Sensors, use the 4.x Sensors Script

    • For version 5.x Sensors, use the 5.x Sensors Script

    • If you have a combination of Sensor versions, Cisco recommends you upgrade so that they all are at the same version level. This is because only one of these scripts can be run at any one time.

  2. The script contains comments that explain each portion and any required input. In particular, modify the $EmailRcpt variable (near the top of the file) to be the e-mail address of the person who is to receive the alerts.

  3. Define an Event Rule within Security Monitor to call a new Perl script. From the main Security Monitor page, choose Admin > Event Rules and add a new event.

  4. On the Specify the Event Filter window, add the filters that you want to trigger the e-mail alert (in the sample here, an e-mail is sent for any High severity alert).

    cisco-works-email-alerts-1.gif

  5. On the Choose the Action window, check the box to execute a script and select the script name from the drop-down box.

  6. In the Arguments section, enter "${Query}" as shown here.

    Note: This must be entered exactly as it is here, including the double-quotes. It is also case sensitive.

    cisco-works-email-alerts-2.gif

  7. When an alert, as defined in your event filters (in this example, a high severity alert) is received, the script called emailalert.pl is called with an argument of ${Query}. This contains additional information about the alert. The script parses out all the separate fields and uses a program called "blat" to send an e-mail to the end user.

  8. Blat is a freeware e-mail program used on Windows systems to send e-mails from batch files or Perl scripts. It is included as part of the VMS installation in the $BASE\CSCOpx\bin directory. In order to verify your path settings, open up a command prompt window on the VMS server and type blat.

    If you receive the File not found error, either copy the blat.exe file into the winnt\system32 directory, or find it and open it from the directory in which it is located. In order to install this, run:

    blat -install <SMTP server address> <source email address>
    

    Once this program is installed, you are done.

Scripts

These are the scripts referred to in step 1 of the configuration procedure:

3.x Sensor Script

Use this script for version 3.x Sensors.

3.x Sensors
#!/usr/bin/perl
#***********************************************************************
#
# FILE NAME : emailalert.pl
#
# DESCRIPTION : This file is a perl script that will be executed as an
# action when an IDS-MC Event Rule triggers, and will send an 
# email to $EmailRcpt with additional alert parameters (similar to
# the functionality available with CSPM notifications)
#
# NOTE:   this script only works with 3.x sensors, alarms from 4.0
#         sensors are stored differently and cannot be represented
#         in a similar format. 
#
# NOTE:   check the "system" command in the script for the correct
#         format depending on whether you're using IDSMC/SecMon 
#         v1.0 or v1.1, you may need the "-on" command-line option.
#
# NOTE :  This script takes the ${Query} keyword from the
#         triggered rule, extracts the set of alarms that caused
#         the rule to trigger. It then reads the last alarm of
#         this set, parses the individual alarm fields, and
#         calls the legacy script with the same set of command
#         line arguments as CSPM.
#
# The calling sequence of this script must be of the form:
#
#         emailalert.pl "${Query}"
#
# Where:
# 
#         "${Query}" - this is the query keyword dynamically
#         output by the rule when it triggers.
#         It MUST be wrapped in double quotes when specifying it in the Arguments
#         box on the Rule Actions panel.
#
#
#***********************************************************************
##
## The following are the only two variables that need changing. $TempIDSFile can be any
## filename (doesn't have to exist), just make sure the directory that you specify
## exists. Make sure to use 2 backslashes for each directory, the first backslash is
## so the Perl interpretor doesn't error on the pathname.
##
## $EmailRcpt is the person that is going to receive the email notifications. Also 
## make sure you escape the @ symbol by putting a backslash in front of it, otherwise 
## you'll get a Perl syntax error.
## 
$TempIDSFile = "c:\\temp\\idsalert.txt";
$EmailRcpt = "nobody\@cisco.com";

##
## pull out command line arg
##

$whereClause = $ARGV[0];

##
## extract all the alarms matching search expression
##

$tmpFile = "alarms.out";

## The following line will extract alarms from 1.0 IDSMC/SecMon database, if 
## using 1.1 comment out the line below and un-comment the other system line
## below it.

## V1.0 IDSMC/SecMon version
system("IdsAlarms -s\"$whereClause\" -f\"$tmpFile\"");

## V1.1 IDSMC/SecMon version.
## system("IdsAlarms -on -s\"$whereClause\" -f\"$tmpFile\"");
##

# open matching alarm output

if (!open(ALARM_FILE, $tmpFile)) {
    print "Could not open ", $tmpFile, "\n";
    exit -1;
}

# read to last line

while (<ALARM_FILE>) {
    $line = $_;
}

# clean up

close(ALARM_FILE);
unlink($tmpFile);

##
## split last line into fields
##

@fields = split(/,/, $line);

$eventType = @fields[0];
$recordId = @fields[1];
$gmtTimestamp = 0; # need gmt time_t
$localTimestamp = 0; # need local time_t
$localDate = @fields[4];
$localTime = @fields[5];
$appId = @fields[6];
$hostId = @fields[7];
$orgId = @fields[8];
$srcDirection = @fields[9];
$destDirection = @fields[10];
$severity = @fields[11];
$sigId = @fields[12];
$subSigId = @fields[13];
$protocol = "TCP/IP";
$srcAddr = @fields[15];
$destAddr = @fields[16];
$srcPort = @fields[17];
$destPort = @fields[18];
$routerAddr = @fields[19];
$contextString = @fields[20];


## Open temp file to write alert data into,

open(OUT,">$TempIDSFile") || warn "Unable to open output file!\n";

## Now write your email notification message. You're writing the following into
## the temporary file for the moment, but this will then be emailed. Use the format:
##
## print (OUT "Your text with any variable name from the list above \n");
##
## Again, make sure you escape special characters with a backslash (note the : in between $sigId
## and $subSigId has a backslash in front of it)

print(OUT "\n");
print(OUT "Received severity $severity alert at $localDate $localTime\n");
print(OUT "Signature ID $sigId\:$subSigId from $srcAddr to $destAddr\n");
print(OUT "$contextString");
close(OUT);

## then call "blat" to send contents of that file in the body of an email message.
## Blat is a freeware email program for WinNT/95, it comes with VMS in the 
## $BASE\CSCOpx\bin directory, make sure you install it first by running:
##
## blat -install <SMTP server address> <source email address>
##
## For more help on blat, just type "blat" at the command prompt on your VMS system (make
## sure it's in your path (feel free to move the executable to c:\winnt\system32 BEFORE
## you run the install, that'll make sure your system can always find it).

system ("blat \"$TempIDSFile\" -t \"$EmailRcpt\" -s \"Received IDS alert\"");

4.x Sensor Script

Use this script for version 4.x Sensors.

4.x Sensors
#!/usr/bin/perluse Time::Local;#***********************************************************************
#
# FILE NAME : emailalert.pl
#
# DESCRIPTION : This file is a perl script that will be executed as an
# action when an IDS-MC Event Rule triggers, and will send an 
# email to $EmailRcpt with additional alert parameters (similar to
# the functionality available with CSPM notifications)
#
# NOTE: this script only works with 4.x sensors. It will 
# not work with 3.x sensors.
#
# NOTES : This script takes the ${Query} keyword from the
# triggered rule, extracts the set of alarms that caused
# the rule to trigger. It then reads the last alarm of
# this set, parses the individual alarm fields, and
# calls the legacy script with the same set of command
# line arguments as CSPM.
#
# The calling sequence of this script must be of the form:
#
# emailalert.pl "${Query}"
#
# Where:
# 
# "${Query}" - this is the query keyword dynamically
# output by the rule when it triggers.
# It MUST be wrapped in double quotes
# when specifying it in the Arguments
# box on the Rule Actions panel.
#
#
#***********************************************************************
##
## The following are the only two variables that need changing. $TempIDSFile can be any
## filename (doesn't have to exist), just make sure the directory that you specify
## exists. Make sure to use 2 backslashes for each directory, the first backslash is
## so the Perl interpretor doesn't error on the pathname.
##
## $EmailRcpt is the person that is going to receive the email notifications. Also 
## make sure you escape the @ symbol by putting a backslash in front of it, otherwise 
## you'll get a Perl syntax error.
##

$TempIDSFile = "c:\\temp\\idsalert.txt";
$EmailRcpt = "yourname\@yourcompany.com";

# subroutine to add leading 0's to any date variable that's less than 10.
sub add_zero {
my ($var) = @_;
if ($var < 10) {
$var = "0" .$var
}
return $var;
}

# subroutine to find one or more IP addresses within an XML tag (we can have multiple
# victims and/or attackers in one alert now).
sub find_addresses {
my ($var) = @_;
my @addresses = ();
if (m/$var/) {
$raw = $&;
while ($raw =~ m/(\d{1,3}\.){3}\d{1,3}/) {
push @addresses,$&;
$raw = $';
}
$var = join(', ',@addresses);
return $var;
}
}

# pull out command line arg

$whereClause = $ARGV[0];

# extract all the alarms matching search expression

$tmpFile = "alarms.out";

# Extract the XML alert/event out of the database.

system("IdsAlarms -s\"$whereClause\" -f\"$tmpFile\"");

# open matching alarm output

if (!open(ALARM_FILE, $tmpFile)) {
print "Could not open $tmpFile\n";
exit -1;
}

# read to last line

while (<ALARM_FILE>) {
chomp $_;
push @logfile,$_;
}

# clean up

close(ALARM_FILE);
unlink($tmpFile);

# Open temp file to write alert data into,

open(OUT,">$TempIDSFile");

# split XML output into fields

$oneline = join('',@logfile);
$oneline =~ s/\<\/events\>//g;
$oneline =~ s/\<\/evAlert\>/\<\/evAlert\>,/g;
@items = split(/,/,$oneline);

# If you want to see the actual database query result in the email, un-comment out the
# line below (useful for troubleshooting):
# print(OUT "$oneline\n");

# Loop until there's no more alerts

foreach (@items) {

if (m/\<hostId\>(.*)\<\/hostId\>/) {
$hostid = $1;
}

if (m/severity="(.*?)"/) {
$sev = $1;
}

if (m/Zone\=".*"\>(.*)\<\/time\>/) {
$t = $1;
if ($t =~ m/(.*)(\d{9})/) {
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($1);

# Year is reported from 1900 onwards (eg. 2003 is 103).
$year = $year + 1900;

# Months start at 0 (January = 0, February = 1, etc), so add 1.
$mon = $mon + 1;

$mon = add_zero ($mon);
$mday = add_zero ($mday);
$hour = add_zero ($hour);
$min = add_zero ($min);
$sec = add_zero ($sec);
}
}

if (m/sigName="(.*?)"/) {
$SigName = $1;
}

if (m/sigId="(.*?)"/) {
$SigID = $1;
}

if (m/subSigId="(.*?)"/) {
$SubSig = $1;
}

$attackerstring = "\<attacker.*\<\/attacker";
if ($attackerstring = find_addresses ($attackerstring)) {
} 

$victimstring = "\<victim.*\<\/victim";
if ($victimstring = find_addresses ($victimstring)) {
} 

if (m/\<alertDetails\>(.*)\<\/alertDetails\>/) {
$AlertDetails = $1;
}

@actions = ();
if (m/\<actions\>(.*)\<\/actions\>/) {
$rawaction = $1;
while ($rawaction =~ m/\<(\w*?)\>(.*?)\</) {
$rawaction = $';
if ($2 eq "true") {
push @actions,$1;
}
} 
if (@actions) {
$actiontaken = join(', ',@actions);
}
}
else {
$actiontaken = "None";
}

## Now write your email notification message. You're writing the following into 
## the temporary file for the moment, but this will then be emailed.
## 
## Again, make sure you escape special characters with a backslash (note the : between
## the SigID and the SubSig). 
##
## Put your VMS servers IP address in the NSDB: line below to get a direct link 
## to the signature details within the email.

print(OUT "\n$hostid reported a $sev severity alert at $hour:$min:$sec on $mon/$mday/$year\n");
print(OUT "Signature: $SigName \($SigID\:$SubSig\)\n");
print(OUT "Attacker: $attackerstring ---> Victim: $victimstring\n");
print(OUT "Alert details: $AlertDetails \n");
print(OUT "Actions taken: $actiontaken \n");
print(OUT "NSDB: https\://<your VMS server IP address>/vms/nsdb/html/expsig_$SigID.html\n\n");
print(OUT "----------------------------------------------------\n");

}

close(OUT);

## Now call "blat" to send contents of the file in the body of an email message.
## Blat is a freeware email program for WinNT/95, it comes with VMS in the 
## $BASE\CSCOpx\bin directory, make sure you install it first by running:
##
## blat -install <SMTP server address> <source email address>
##
## For more help on blat, just type "blat" at the command prompt on your VMS system (make
## sure it's in your path (feel free to move the executable to c:\winnt\system32 BEFORE
## you run the install, that'll make sure your system can always find it).

system ("blat \"$TempIDSFile\" -t \"$EmailRcpt\" -s \"Received IDS alert\"");

5.x Sensor Script

Use this script for version 5.x Sensors.

5.x Sensors
#!/usr/bin/perl
use Time::Local;

#***********************************************************************
#
#  FILE NAME   : emailalertv5.pl
#
#  DESCRIPTION : This file is a perl script that will be executed as an
#                action when an IDS-MC Event Rule triggers, and will send an 
#                email to $EmailRcpt with additional alert parameters (similar to
#                the functionality available with CSPM notifications)
#
#                NOTE: this script only works with 5.x sensors.  
#
#  NOTES       : This script takes the ${Query} keyword from the
#                triggered rule, extracts the set of alarms that caused
#                the rule to trigger.  It then reads the last alarm of
#                this set, parses the individual alarm fields, and
#                calls the legacy script with the same set of command
#                line arguments as CSPM.
#
#                The calling sequence of this script must be of the form:
#
#                emailalert.pl "${Query}"
#
#                Where:
#                   
#                   "${Query}"  - this is the query keyword dynamically
#                                 output by the rule when it triggers.
#                                 It MUST be wrapped in double quotes
#                                 when specifying it in the Arguments
#                                 box on the Rule Actions panel.
#
#
#***********************************************************************
##
## The following are the only two variables that need changing.  $TempIDSFile can be any
## filename (doesn't have to exist), just make sure the directory that you specify
## exists.  Make sure to use 2 backslashes for each directory, the first backslash is
## so the Perl interpretor doesn't error on the pathname.
##
## $EmailRcpt is the person that is going to receive the email notifications.  Also 
## make sure you escape the @ symbol by putting a backslash in front of it, otherwise 
## you'll get a Perl syntax error.
##

$TempIDSFile = "c:\\temp\\idsalert.txt";
$EmailRcpt = "gfullage\@cisco.com";

# subroutine to add leading 0's to any date variable that's less than 10.
sub add_zero {
  my ($var) = @_;
  if ($var < 10) {
      $var = "0" .$var
  }
  return $var;
}

# subroutine to find one or more IP addresses within an XML tag (we can have multiple
# victims and/or attackers in one alert now).
sub find_addresses {
  my ($var) = @_;
  my @addresses = ();
  if (m/$var/) {
      $raw = $&;
      while ($raw =~ m/(\d{1,3}\.){3}\d{1,3}/) {
          push @addresses,$&;
          $raw = $';
      }
      $var = join(', ',@addresses);
      return $var;
  }
}

# pull out command line arg

$whereClause = $ARGV[0];

# extract all the alarms matching search expression

$tmpFile = "alarms.out";

# Extract the XML alert/event  out of the database.

system("IdsAlarms -os -s\"$whereClause\" -f\"$tmpFile\"");

# open matching alarm output

if (!open(ALARM_FILE, $tmpFile)) {
  print "Could not open $tmpFile\n";
  exit -1;
}

# read to last line

while (<ALARM_FILE>) {
   chomp $_;
   push @logfile,$_;
}

# clean up

close(ALARM_FILE);
unlink($tmpFile);

# Open temp file to write alert data into,

open(OUT,">$TempIDSFile");

# split XML output into fields

$oneline = join('',@logfile);
$oneline =~ s/\<\/sd\:events\>//g;
$oneline =~ s/\<\/sd\:evIdsAlert\>/\<\/sd\:evIdsAlert\>,/g;
@items = split(/,/,$oneline);

# If you want to see the actual database query result in the email, un-comment out the
# line below (useful for troubleshooting):
# print(OUT "$oneline\n");

# Loop until there's no more alerts

foreach (@items) {
  unless ($_ =~ /\<\/env\:Body\>/) {

    if (m/\<sd\:hostId\>(.*)\<\/sd\:hostId\>/) {
      $hostid = $1;
    }

    if (m/severity="(.*?)"/) {
      $sev = $1;
    }

    if (m/Zone\=".*"\>(.*)\<\/sd\:time\>/) {
      $t = $1;
      if ($t =~ m/(.*)(\d{9})/) {
        ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($1);
      
        # Year is reported from 1900 onwards (eg. 2003 is 103).
        $year = $year + 1900;
      
        # Months start at 0 (January = 0, February = 1, etc), so add 1.
        $mon = $mon + 1;

        $mon = add_zero ($mon);
	  $mday = add_zero ($mday);
	  $hour = add_zero ($hour);
	  $min = add_zero ($min);
	  $sec = add_zero ($sec);
      }
    }

    if (m/description="(.*?)"/) {
      $SigName = $1;
    }

    if (m/\ id="(.*?)"/) {
      $SigID = $1;
    }

    if (m/\<cid\:subsigId\>(.*)\<\/cid\:subsigId\>/) {
      $SubSig = $1;
    }

    if (m/\<cid\:riskRatingValue\>(.*)\<\/cid\:riskRatingValue\>/) {
      $RR = $1;
    }

    if (m/\<cid\:interface\>(.*)\<\/cid\:interface\>/) {
      $Intf = $1;
    }

    $attackerstring = "\<sd\:attacker.*\<\/sd\:attacker";
    if ($attackerstring = find_addresses ($attackerstring)) {
    } 

    $victimstring = "\<sd\:target.*\<\/sd\:target";
    if ($victimstring = find_addresses ($victimstring)) {
    } 
  
    if (m/\<cid\:alertDetails\>(.*)\<\/cid\:alertDetails\>/) {
      $AlertDetails = $1;
    }

    @actions = ();
    if (m/\<sd\:actions\>(.*)\<\/sd\:actions\>/) {
      $rawaction = $1;
      while ($rawaction =~ m/\<\w*?:(\w*?)\>(.*?)\</) {
         $rawaction = $';

         if ($2 eq "true") {
            push @actions,$1;
         }
      }
      if (@actions) {
        $actiontaken = join(', ',@actions);
      }
    }
    else {
        $actiontaken = "None";
      } 

## Now write your email notification message. You're writing the following into 
## the temporary file for the moment, but this will then be emailed.
## 
## Again, make sure you escape special characters with a backslash (note the : between
## the SigID and the SubSig). 
##
## Put your VMS servers IP address in the NSDB: line below to get a direct link 
## to the signature details within the email.

    print(OUT "\n$hostid reported a $sev severity alert at $hour:$min:$sec on $mon/$mday/$year\n");
    print(OUT "Signature: $SigName \($SigID\:$SubSig\)\n");
    print(OUT "Attacker: $attackerstring  --->  Victim: $victimstring\n");
    print(OUT "Alert details: $AlertDetails \n");
    print(OUT "Risk Rating: $RR,  Interface: $Intf \n");
    print(OUT "Actions taken: $actiontaken \n");
    print(OUT "NSDB: https\://sec-srv/vms/nsdb/html/expsig_$SigID.html\n\n");
    print(OUT "----------------------------------------------------\n");

   } 
}

close(OUT);

## Now call "blat" to send contents of the file in the body of an email message.
## Blat is a freeware email program for WinNT/95, it comes with VMS in the 
## $BASE\CSCOpx\bin directory, make sure you install it first by running:
##
##     blat -install <SMTP server address> <source email address>
##
## For more help on blat, just type "blat" at the command prompt on your VMS system (make
## sure it's in your path (feel free to move the executable to c:\winnt\system32 BEFORE
## you run the install, that'll make sure your system can always find it).

system ("blat \"$TempIDSFile\" -t \"$EmailRcpt\" -s \"Received IDS alert\"");

Verify

There is currently no verification procedure available for this configuration.

Troubleshoot

Follow these instructions to troubleshoot your configuration.

  1. Run this command from a command prompt in order to check that blat works properly:

    blat <filename> -t <customer's email> -s "Test message"
    

    <filename> is the full path to any text file on the VMS system. If the user to whom the e-mail script is directed receives this file in the body of an e-mail, then you know that blat works.

  2. If no e-mail is received after an alert is triggered, try to run the Perl script from a command prompt window.

    This highlights any Perl or path type issues. In order to do this, open a command prompt and enter:

    >cd Program Files/CSCOpx/MDC/etc/ids/scripts 
    >emailalert.pl ${Query} 

    You can potentially receive a Sybase error, similar to this example. This is due to the fact that the ${Query} parameter you pass does not actually contain information, unlike when it passes from the Security Monitor.

    cisco-works-email-alerts-3.gif

    Other than seeing this error, the script runs correctly and sends an e-mail. Any alert parameters within the e-mail body are blank. If you receive any Perl or path errors, they need to be fixed before an e-mail is sent.

Related Information

Updated: Jul 12, 2006
Document ID: 47582