A hint: This file contains one or more very long lines, so maybe it is better readable using the pure text view mode that shows the contents as wrapped lines within the browser window.
1 #!/usr/bin/perl -w 2 ######################################################## 3 # Security Check by Larry Long - larry@djslyde.com # 4 # [checksecurity] - 5/9 programs in checksuite v3.3 # 5 # # 6 # This script basically throws together some good # 7 # information to keep an eye on the security of your # 8 # server. # 9 ######################################################## 10 use strict; 11 use Getopt::Std; 12 use Net::SMTP; 13 14 $ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin'; 15 16 # Options: -h (help) -l (log) -o (output to screen) -r (RPM check) -e (email) 17 my %opt;getopts('hlore:', \%opt); 18 usage_info() unless defined @ARGV; 19 usage_info() if exists $opt{h}; 20 21 # Localize variables throughout the rest of the program 22 # A lot of data requires a lot of variables... 23 my($logdate,$host,$kernel,$rpmcheck,$dirtybins,$checkdev,$devlist,$checkroot,$rootlist,$rootcheck,$syncheck,$checksyn,$openlist,$connlist,$wholist,$devcheck,$email,$pam,$checkrootgroup,$checkwheelgroup,$logfile,$script,$logsnip,@note,@rootlist,@rootcheck,$suid,$suidfiles,$sgid,$sgidfiles,$hide,$hidden,$subject); 24 25 # Are we root? 26 if($> != 0) 27 { 28 print STDERR "\n$0: This program HAS to be ran as root!!!\n\nPlease su to root 29 or use 'sudo $0'!\n"; 30 exit 2; 31 } 32 33 # Define variables 34 $email = $opt{e};$email = 'root@localhost' unless defined $opt{e}; 35 $host = `hostname`; 36 $logfile = "/var/log/checksuite.d/checksecurity"; 37 $logdate = `date '+%m/%d/%Y %H:%M:%S' `; 38 $script = " - [checksuite] checksecurity\n"; 39 $logsnip = "----\n"; 40 $kernel = `uname -r`; 41 $subject = "[checksuite] advisory - security check on $host"; 42 chomp $host;chomp $logdate;chomp $kernel;chomp $subject; 43 44 push(@note, "\n"); 45 push(@note, "Security Check Summary on $host - $logdate\n"); 46 push(@note, "Kernel version: $kernel\n\n"); 47 48 # RPM system verification 49 if($opt{r}) 50 { 51 $rpmcheck = `rpm -Va|grep bin`; 52 chomp $rpmcheck; 53 if($rpmcheck ne "") 54 { 55 $dirtybins = $rpmcheck; 56 } 57 else 58 { 59 $dirtybins = "...none!"; 60 } 61 62 push(@note, "Modified binary files: $dirtybins\n"); 63 } 64 65 # Anything weird in /dev? 66 $checkdev = `find /dev -type f`; 67 $devlist = $checkdev; 68 chomp $devlist; 69 $devlist =~s/\/dev\/MAKEDEV//g; 70 $devlist =~s/\/dev\/.udev.tdb//g; 71 if($devlist ne "") 72 { 73 $devcheck = $devlist; 74 } 75 else 76 { 77 $devcheck = "...none!"; 78 } 79 push(@note, "Possible improper files found in /dev: $devcheck\n"); 80 81 # Got root? (this is gettin ugly...) 82 $checkroot = `fgrep "0:0" /etc/passwd|cut -d ':' -f 1`; 83 $checkrootgroup = `fgrep "root:x" /etc/group|cut -d ':' -f 4`; 84 $checkwheelgroup = `fgrep "wheel:x" /etc/group|cut -d ':' -f 4`; 85 86 chomp $checkroot;chomp $checkrootgroup;chomp $checkwheelgroup; 87 $checkroot =~s/root//g;$checkrootgroup =~s/root//g;$checkwheelgroup =~s/root//g; 88 push(@rootlist, "$checkroot $checkrootgroup $checkwheelgroup"); 89 90 if($checkroot ne "") 91 { 92 @rootcheck = @rootlist; 93 } 94 elsif($checkrootgroup ne "") 95 { 96 @rootcheck = @rootlist; 97 } 98 elsif($checkwheelgroup ne "") 99 { 100 @rootcheck = @rootlist; 101 } 102 else 103 { 104 @rootcheck = "...none!"; 105 } 106 push(@note, "Users with root/wheel perms: @rootcheck\n"); 107 108 # Any setuid files in /home could be bad... 109 $suid = `find /home -type f -exec file {} \\\; | grep setuid`; 110 chomp $suid; 111 if($suid ne "") 112 { 113 $suidfiles = $suid; 114 } 115 else 116 { 117 $suidfiles = "...none!"; 118 } 119 push(@note, "Files in /home with setuid's on: $suidfiles\n"); 120 121 # Any setgid files in /home could be bad... 122 $sgid = `find /home -type f -exec file {} \\\; | grep setgid`; 123 chomp $sgid; 124 if($sgid ne "") 125 { 126 $sgidfiles = $sgid; 127 } 128 else 129 { 130 $sgidfiles = "...none!"; 131 } 132 push(@note, "Files in /home with setgid's on: $sgidfiles\n"); 133 134 # Hidden directories are the devil's playground 135 $hide = `find / -name ". " && find / -name " ." && find / -name ".. " && find / -name " .." && find / -name "..." && find / -name " ..." && find / -name "... "`; 136 chomp $hide; 137 if($hide ne "") 138 { 139 $hidden = $hide; 140 } 141 else 142 { 143 $hidden = "...none!"; 144 } 145 push(@note, "Hidden directories found: $hidden\n"); 146 147 # Any SYN floods? 148 $syncheck = `netstat -na|grep SYN_RECV`; 149 chomp $syncheck; 150 if($syncheck ne "") 151 { 152 $checksyn = $syncheck; 153 } 154 else 155 { 156 $checksyn = "...none!"; 157 } 158 push(@note, "Possible SYN flooding: $checksyn\n\n"); 159 160 # What's going on right now? 161 $openlist = `lsof -i|grep TCP`; 162 chomp $openlist;push(@note, "Open file listing (TCP):\n$openlist\n\n"); 163 164 my $uopenlist = `lsof -i|grep UDP`; 165 chomp $uopenlist;push(@note, "Open file listing (UDP):\n$uopenlist\n\n"); 166 167 $connlist = `netstat -nap|grep tcp`; 168 chomp $connlist;push(@note, "Current TCP connections:\n$connlist\n\n"); 169 170 my $uconnlist = `netstat -nap|grep udp`; 171 chomp $uconnlist;push(@note, "Current UDP connections:\n$uconnlist\n\n"); 172 173 $wholist = `last -n 20 -a`; 174 chomp $wholist;push(@note, "Last 20 users that logged in:\n$wholist\n\n"); 175 176 $pam = `tail -5000 /var/log/messages |grep -i pam_unix`; 177 chomp $pam;push(@note, "PAM authentication log entries in last 5000 lines of /var/log/messages:\n$pam\n"); 178 179 # Define where the output goes 180 log_data() if exists $opt{l}; 181 email_data() if exists $opt{e}; 182 screen_data() if exists $opt{o}; 183 184 # Subroutines 185 sub usage_info 186 { 187 my $usage = " 188 Usage: $0 [-h | -lo] [-r] [-e <email>] 189 Options: 190 -h display this help 191 -l log the output to /var/log/checksuite.d/checksecurity 192 -o force output to screen 193 -r perform full system RPM check 194 -e e-mail the output to a specified e-mail address 195 Where: 196 <email> e-mail address of the recipient of the notification 197 default is 'root' 198 \n"; 199 die $usage; 200 } 201 202 sub log_data 203 { 204 open(LOG, ">>$logfile") or die "Can't open logfile!\n"; 205 print LOG $logdate,$script,@note,$logsnip; 206 close(LOG); 207 } 208 209 sub screen_data 210 { 211 print STDERR @note; 212 } 213 214 sub email_data 215 { 216 my $smtp = Net::SMTP->new($host); 217 if(! ref($smtp)) 218 { 219 log_die("Cannot connect to SMTP\n"); 220 } 221 $smtp->mail($email); 222 $smtp->to($email); 223 $smtp->data(); 224 $smtp->datasend("To: " . $email . "\n"); 225 $smtp->datasend("From: Checksuite Notification <root\@$host>\n"); 226 $smtp->datasend("Return-Path: " . $email. "\n"); 227 $smtp->datasend("Subject: " . $subject . "\n"); 228 $smtp->datasend("\n"); 229 $smtp->datasend(@note); 230 $smtp->datasend(); 231 $smtp->quit(); 232 }