How To Check for Infected Files Using Nagios Plugins

This example shows how to look for infection patterns inside all .php files in a directory tree using find and grep called from a Nagios NRPE plugin written in PERL.
You can adjust the behavior by modifying the script, described at the bottom of this post in the Advanced section.
On the host to be checked, create the two files /usr/lib/nagios/plugins/check_for_infections
and /usr/lib/nagios/plugins/infection.patterns
using the information below.
Make sure the path location matches your specific OS requirements.
check_for_infections
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
cat /util/check_for_infections #!/usr/bin/perl -wT use strict; use Getopt::Long; use vars qw($opt_V $opt_h $opt_w $opt_c $opt_H $opt_d $opt_p $opt_v $PROGNAME %ERRORS); ## common variables $PROGNAME = "check_index_php"; %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4); ## utility subroutines sub print_revision ($$) { my $commandName = shift; my $pluginRevision = shift; print "$commandName v$pluginRevision (nagios-plugins 1.4.15)\n"; print "The nagios plugins come with ABSOLUTELY NO WARRANTY. You may redistribute\ncopies of the plugins under the terms of the GNU General Public License.\nFor more information about these matters, see the file named COPYING.\n"; } sub support () { my $support='Send email to nagios-users@lists.sourceforge.net if you have questions\nregarding use of this software. To submit patches or suggest improvements,\nsend email to nagiosplug-devel@lists.sourceforge.net.\nPlease include version information with all correspondence (when possible,\nuse output from the --version option of the plugin itself).\n'; $support =~ s/@/\@/g; $support =~ s/\\n/\n/g; print $support; } sub usage { my $format=shift; printf($format,@_); exit $ERRORS{'UNKNOWN'}; } sub print_usage () { print "Usage: $PROGNAME -H <host> -w <warn> -c <crit>\n"; } sub print_help () { print_revision($PROGNAME,'1.0'); print "Copyright (c) 2016 Eric M. Stone, Wyzaerd Consulting, Inc. This plugin reports the presence of a hacked Wordpress index.php file. "; print_usage(); print " -H, --hostname=HOST Name or IP address of host to check -w, --warning=INTEGER Percentage strength below which a WARNING status will result -c, --critical=INTEGER Percentage strength below which a CRITICAL status will result -d, --directory=PATH Where to start looking, defaults to / -p, --patternFile=PATH List of infection patterns to look for in every file, one per line. defaults to /util/infection.patterns -v, --verbose List the file names that match "; support(); } $ENV{'PATH'}=''; $ENV{'BASH_ENV'}=''; $ENV{'ENV'}=''; ### PROCESS THE COMMAND LINE Getopt::Long::Configure('bundling'); GetOptions ("V" => \$opt_V, "version" => \$opt_V, "h" => \$opt_h, "help" => \$opt_h, "v" => \$opt_v, "verbose" => \$opt_v, "w=s" => \$opt_w, "warning=s" => \$opt_w, "c=s" => \$opt_c, "critical=s" => \$opt_c, "H=s" => \$opt_H, "hostname=s" => \$opt_H, "d=s" => \$opt_d, "directory=s" => \$opt_d, "p=s" => \$opt_p, "patternFile=s" => \$opt_p); if ($opt_V) { print_revision($PROGNAME,'1.4.15'); exit $ERRORS{'OK'}; } if ($opt_h) {print_help(); exit $ERRORS{'OK'};} my $verbose = $opt_v ? 1 : 0; ($opt_H) || usage("Host name/address not specified\n"); my $host = $1 if ($opt_H =~ /([-.A-Za-z0-9]+)/); ($host) || usage("Invalid host: $opt_H\n"); ($opt_w) || usage("Warning threshold not specified\n"); my $warning = $1 if ($opt_w =~ /([0-9]{1,2}|100)+/); ($warning) || usage("Invalid warning threshold: $opt_w\n"); ($opt_c) || usage("Critical threshold not specified\n"); my $critical = $1 if ($opt_c =~ /([0-9]{1,2}|100)/); ($critical) || usage("Invalid critical threshold: $opt_c\n"); ($opt_d) || ($opt_d = "/") ; my $dir = $1 if ($opt_d =~ /^(\/.*)/); (-d "$dir") || usage("Invalid dir: $dir\n"); ($opt_p) || ($opt_p = "/util/infection.patterns") ; my $patternFile = $opt_p if ($opt_p =~ /^\//); (-r "$patternFile") || usage("Invalid pattern file: $patternFile\n"); ### PERFORM THE SCAN - uses option lower-case ELL my @result; chomp(@result = `/bin/grep -RFl -f $patternFile --include "*.php" $dir/*`); my $found = scalar @result; ### PRINT RESULTS if ($found) { my $plural = $found == 1 ? '' : 's'; print "CRITICAL: Found $found Infected File$plural"; #print(': ', join(", ",@result)) if $found < 10; print ("\n", join("\n",@result)) if $verbose; print "\n"; } else { print "OK: No infected files found.\n"; } ## EXIT WITH PROPER CODE exit $ERRORS{'CRITICAL'} if ($found>=$critical); exit $ERRORS{'WARNING'} if ($found>=$warning); exit $ERRORS{'OK'}; |
infection.patterns
1 2 3 4 5 6 |
nike jersey Chr(rand base64_decode(str_rot13 eval(base64 eval($_POST |
Then, on the monitored host, edit the NRPE config file, add the command below, and restart NRPE:
vim /etc/nagios/nrpe.cfg
command[check_for_infections]=/usr/lib/nagios/plugins/check_for_infections -w 1 -c 1 -d /data
service nrpe restart
Finally, update the main Nagios server services definitions file, then restart the Nagios server daemon.
This is what I added to my services.cfg
:
1 2 3 4 5 6 7 8 |
define service{ service_description Check for Infections servicegroups aws_hosts host_name myWatchedHost123 check_command check_nrpe!check_for_infections contact_groups admin use generic-service } |
service nagios restart
ADVANCED: The key line of the script is:
chomp(@result =
/bin/grep -R -o -F -f $patternFile --include "*.php" $dir/*
);
Please note that the command is looking for all items listed in the pattern file. You could make several enhancements, including the ability to pass the include filespec (currently *.php) into the script via command-line arguments.
As always, YMMV!
This is a great troubleshooting document: https://assets.nagios.com/downloads/nagiosxi/docs/NRPE-Troubleshooting-and-Common-Solutions.pdf
Leave Your Comment
All fields marked with "*" are required.