findbot.pl find web malware

Skapad 1 år sedan, skriven i Perl, med 213 visningar.
URL http://kod.perl.se/view/8ea4301a Bädda in
Ladda hem koden eller visa koden i råformatVisa bredare version
  1. #!/usr/bin/perl
  2.  
  3. # Version 0.09 Sat Aug  1 02:42:13 UTC 2015
  4.  
  5. # The above line may need to be changed to point at your version of Perl
  6. #
  7. #       This script attempts to find malicious files/scripts on your machine.
  8. #       It specifically looks for spambots that we're aware of, as well
  9. #       as "suspicious" constructs in various scripting languages.
  10. #
  11. #       To use it, you should put this in a file on your computer called
  12. #       "findbot.pl" and make it executable by "chmod 755 findbot.pl".
  13. #
  14. #       By default, findbot.pl scans the directories /tmp, /usr/tmp, /home and
  15. #       /var/www.  This script isn't fast.  So if you know where to look you can
  16. #       speed things up by giving just the directories that you suspect has the
  17. #       malware.
  18. #
  19. #       You can often find out what user is infected by using:
  20. #               lsof -i | grep smtp
  21. #       and looking for processes that are NOT your mail server.
  22. #
  23. #       If you're successful finding the user, you need to look everywhere the user
  24. #       has write permissions - and you can run findbot.pl faster, by something like:
  25. #
  26. #       findbot.pl /tmp /usr/tmp /home/<user> <user's web directory>
  27. #
  28. #       There are two types of "detections" - "suspicious files" are files that contain
  29. #       things that -may- be malicious.
  30. #       "malware" is definitely malicious software.
  31. #
  32. #       This script needs the following command line utilities.  It will not run
  33. #       if it can't find them, you will have to install them yourself:
  34. #               - "md5sum" (Linux) or "md5" (FreeBSD etc) this appears to be standard
  35. #                       core utilities.
  36. #               - "strings" - on Linux this is in the "binutils" package
  37. #               - "file" - on Linux this is in the "file" package.
  38. #
  39. # Usage:
  40. #       findbot.pl [-c] [directories...]
  41. #
  42. #       If a list of directories is supplied, it's used, otherwise,
  43. #       /tmp, /usr/tmp, /home and /var/www are use by default.
  44. #
  45. #       The -c option is a shortcut to make finding cryptophp faster and
  46. #       easier, but this may not work in all situations
  47. #
  48. # Very simple web malware detection module.
  49. # .01 -> .02:
  50. #       - more strings of bad software
  51. #       - search for encoded perl scripts
  52. # .02 -> .03: 2013/01/10 Ray
  53. #       - speed up
  54. #       - MD5 stuff
  55. # .03 -> .04: 2013/01/13 Ray
  56. #       - improved docs
  57. # .04 -> .05: 2013/01/20 Ray
  58. #       - more patterns
  59. #       - MAXLINES way too small
  60. # .05 -> .06: 2014/10/31 Havriliuc Andrei, Hostvision srl, Romania
  61. #       - many more patterns/heuristics from hoster's experience
  62. #       - Thanks for the contribution!
  63. # .06 -> 07: 2014/11/22 Ray
  64. #       - Speed up specifically for current version of cryptophp
  65. # .07 -> 08: 2015/04/14 Ray
  66. #       - Stealrat patterns
  67. # .07 -> 08: 2015/07/31 Ray
  68. #       - User contributed pattern for new PHP script
  69.  
  70. my $access = '(\.htaccess)';
  71. my $accesspat = '(RewriteRule)';
  72.  
  73. ## Extensions scanned
  74.  
  75. my $scripts = '\.(php|pl|cgi|bak|sh|txt|jpeg|jpg|png|gif|bmp|css)$';
  76.  
  77. ## Patterns
  78. my $scriptpat = '(Edited By GuN-Jack|die\(PHP_OS.chr\(49\).chr\(48\).chr\(43\).md5\(0987654321\)|die\(PHP_OS.chr\(49\).chr\(49\).chr\(43\).md5\(0987654321\)|social\.png|r57|c99|web shell|passthru|shell_exec|base64_decode|edoced_46esab|PHPShell|EHLO|MAIL FROM|RCPT TO|fsockopen|\$random_num\.qmail|getmxrr|\$_POST\[\'emaillist\'\]|if\(isset\(\$_POST\[\'action\'\]|BAMZ|shell_style|malsite|cgishell|Defaced|defaced|Defacer|defacer|hackmode|ini_restore|ini_get\("open_basedir"\)|runkit_function|rename_function|override_function|mail.add_x_header|\@ini_get\(\'disable_functions\'\)|open_basedir|openbasedir|\@ini_get\("safe_mode"|JIKO|fpassthru|passthru|hacker|Hacker|gmail.ru|fsockopen\(\$mx|\'mxs\.mail\.ru\'|yandex.ru|UYAP-CASTOL|KEROX|BIANG|FucKFilterCheckUnicodeEncoding|FucKFilterCheckURLEncoding|FucKFilterScanPOST|FucKFilterEngine|fake mailer|Fake mailer|Mass Mailer|MasS Mailer|ALMO5EAM|3QRAB|Own3d|eval\(\@\$_GET|TrYaG|Turbo Force|eval \( gzinflate|eval \(gzinflate|cgi shell|cgitelnet|\$_FILES\[file\]|\@copy\(\$_FILES|root\@|eval\(\(base64_decode|define\(\'SA_ROOT\'|cxjcxj|PCT4BA6ODSE|if\(isset\(\$s22\)|yb dekcah|dekcah|\@md5\(\$_POST|iskorpitx|\$__C|back connect|ccteam.ru|"passthru"|"shell_exec"|CHMOD_SHELL|EXIT_KERNEL_TO_NULL|original exploit|prepare_the_exploit|RUN_ROOTSHELL|ROOTSHELL|\@popen\(\$sendmail|\'HELO localhost\'|TELNET|Telnet|BACK-CONNECT|BACKDOOR|BACK-CONNECT BACKDOOR|AnonGhost|CGI-Telnet|webr00t|Ruby Back Connect|Connect Shell|require \'socket\'|HACKED|\@posix_getgrgid\(\@filegroup|\@posix_getpwuid\(\@fileowner|\&\#222\;\&\#199\;\&\#198\;\&\#227\;\&\#229\;|open_basedir|disable_functions|brasrer64r_rdrecordre|hacked|Hacked|\$sF\[4\]\.\$sF\[5\]\.\$sF\[9\]\.\$sF\[10\]\.|\$sF\="PCT4BA6ODSE_"|\$s21\=strtolower|6ODSE_"\;|Windows-1251|\@eval\(\$_POST\[|h4cker|Kur-SaD|\'Fil\'\.\'esM\'\.\'an\'|echo PHP_OS\.|\$testa != ""|\@PHP_OS|\$_POST\[\'veio\'\]|file_put_contents\(\'1\.txt\'|\$GLOBALS\["\%x61|\\\40\\\x65\\\166\\\x61\\\154\\\x28\\\163\\\x74\\\162\\\x5f\\\162\\\x65\\\160\\\x6c\\\141\\\x63\\\145|md5decrypter\.com|rednoize\.com|hashcracking\.info|milw0rm\.com|hashcrack\.com|function_exists\(\'shell_exec\'\)|Sh3ll Upl04d3r|Sh3ll Uploader|S F N S A W|\$\{\$\{"GLOBALS"\}|\$i59\="Euc\<v\#|\$contenttype \= \$_POST\[|eval\(base64|killall|1\.sh|\/usr\/bin\/uname -a|FilesMan|unserialize\(base64_decode|eval \( base64|eval \(base64|eval\(unescape|eval\(@gzinflate|gzinflate\(base64|str_rot13\(\@base64|str_rot13\(base64|gzinflate\(\@str_rot13|\/\.\*\/e|gzuncompress\(base64|substr\(\$c, \$a, \$b|\\\x47LOB|\\\x47LO\\\x42|\\\x47L\\\x4f\\\x42|\\\x47\\\x4c\\\x4f\\\x42|eval\("\?\>"\.base64_decode|\|imsU\||\!msiU|host\=base64|exif \= exif_|"\?Q\?|decrypt\(base64|Shell by|die\(PHP_OS|shell_exec\(base64_decode|\$_F\=|edoced_46esab|\$_D\=strrev|\]\)\)\;\}\}eval|\\\x65\\\x76\\\x61\\\x6c\\\x28|"e"\."va"\."l|\$so64 \=|sqlr00t|qx\{pwd\}|OOO0000O0|OOO000O00|OOO000000|\/\\\r\\\n\\\r\\\n|\$baseurl \= base64_decode|\$remoteurl\,\'wp-login\.php\'|\'http\:\/\/\'\.\$_SERVER\[\'SERVER_NAME\'\]|kkmvbziu|\$opt\("\/292\/e"|\$file\=\@\$_COOKIE\[\'|phpinfo\(\)\;die|return base64_decode\(|\@imap_open\(|\@imap_list\(|\$Q0QQQ\=0|\$GLOBALS\[\'I111\'\]|base64_decode\(\$GLOBALS|eval\(x\(|\@array\(\(string\)stripslashes|function rx\(\)| IRC |BOT IRC|\$bot_password|this bot|Web Shell|Web shell|getenv\(\'SERVER_SOFTWARE\'\)|file_exists\(\'\/tmp\/mb_send_mail\'\)|unlink\(\'\/tmp\/|imap_open\(\'\/etc\/|ini_set\(\'allow_url|\'_de\'\.\'code\'|\'base\'\.\(32\*2\))';
  79.  
  80. my @defaultdirs = ('/tmp', '/usr/tmp', '/home', '/var/www');
  81.  
  82. my $MAXLINES = 40000;
  83.  
  84. my($strings, $md5sum, $file, %badhash);
  85.  
  86. &inithelpers;
  87. &badhashes;
  88.  
  89. #my $executable = '^(sshd|cache|exim|sh|bash)$';
  90.  
  91. if ($ARGV[0] =~ /^-c/) {
  92.     $patterns = '(social\.png)';
  93.     $scripts = '\.(php)$';
  94.     shift(@ARGV);
  95. }
  96.  
  97. if ($ARGV[0] =~ /^-/) {
  98.     my $l = join(',', @defaultdirs);
  99.     print STDERR <<EOF;
  100. usage: $0 [-c] [directories to scan...]
  101.  
  102.     If no directories specified, script uses:
  103. $l
  104.     If -c specified, searches just for one set of cryptphp
  105.     markers.  May miss newer versions
  106.  
  107. EOF
  108.     exit 0;
  109. }
  110.  
  111.  
  112.  
  113. if (!scalar(@ARGV)) {
  114.     push(@ARGV, @defaultdirs);
  115. }
  116.  
  117. for my $dir (@ARGV) {
  118.     &recursion($dir);
  119. }
  120.  
  121. sub recursion {
  122.     my ($dir) = @_;
  123.     my (@list);
  124.     if (!opendir(I, "$dir")) {
  125.         return if $! =~ /no such file/i;
  126.         print STDERR "$dir: Can't open: $!, skipping\n";
  127.         return;
  128.     }
  129.     @list = readdir(I);
  130.     closedir(I);
  131.     for my $mfile (@list) {
  132.         next if $mfile =~ /^\.\.?$/;    # skip . and ..
  133.         my $cf = $currentfile = "$dir/$mfile";
  134.  
  135.         $cf =~ s/'/'"'"'/g;     # hide single-quotes in filename
  136.         $cf = "'$cf'";          # bury in single-quotes
  137.  
  138.         if (-d $currentfile && ! -l $currentfile) {
  139.             &recursion($currentfile);   # don't scan symlinks
  140.             next;
  141.         }
  142.         next if ! -f $currentfile;
  143.         if ($mfile =~ /$scripts/) {
  144.             &scanfile($currentfile, $scriptpat);
  145.         } elsif ($mfile =~ /$access/) {
  146.             &scanfile($currentfile, $accesspat);
  147.         }
  148.  
  149.         # up to here it's fast.
  150.  
  151.         next if -s $currentfile > 1000000 || -s $currentfile < 2000;
  152.  
  153. #print STDERR "$currentfile\n";
  154.  
  155.         my $type = `$file $cf`;
  156.  
  157.         if ($type =~ /(ELF|\d\d-bit).*executable/ || $currentfile =~ /\.(exe|scr|com)$/) {
  158. #print STDERR "cf: $cf\n";
  159.             my $checksum = `$md5sum $cf`;
  160.             chomp($checksum);
  161.             $checksum =~ s/\s.*//;
  162.             if ($badhash{$checksum}) {
  163.                 print STDERR "$currentfile: Malware detected!\n";
  164.                 next;
  165.             }
  166.  
  167.             my $strings = `$strings $cf`;
  168.             if ($strings =~ /\/usr\/bin\/perl/sm) {
  169.                 print STDERR "$currentfile: possible binary-encoded-perl\n";
  170.                 next;
  171.             }
  172.         }
  173.     }
  174. }
  175.  
  176. sub scanfile {
  177.     my ($currentfile, $patterns) = @_;
  178. #print $currentfile, "\n";
  179.     open(I, "<$currentfile") || next;
  180.     my $linecount = 1;
  181.     while(<I>) {
  182.         chomp;
  183.         if ($_ =~ /$patterns/) {
  184.             my $pat = $1;
  185.             my $string = $_;
  186.  
  187.  
  188. ## Wasn't printing the result correctly, so we gave up on this code.
  189. #           if ($string =~ /^(.*)$pat(.*)$/) {
  190. #               $string = substr($1, length($1)-10, 10) .
  191. #                                     $pat .
  192. #                                     substr($2, 0, 10);
  193. #           }
  194.             #$string =~ s/^.*(.{,10}$pat.{,10}).*$/... $1 .../;
  195.             print "$currentfile: Suspicious($pat):\n $string\n\n";
  196.             last;
  197.         }
  198.         last if $linecount++ > $MAXLINES;
  199.     }
  200.     close(I);
  201. }
  202.  
  203. sub inithelpers {
  204.     if (-x '/usr/bin/md5sum') {
  205.         $md5sum = '/usr/bin/md5sum';
  206.     } elsif (-x '/sbin/md5') {
  207.         $md5sum = '/sbin/md5 -q';
  208.     }
  209.     for my $x (('/bin', '/usr/bin')) {
  210.         if (-x "$x/strings") {
  211.             $strings = "$x/strings";
  212.         }
  213.         if (-x "$x/file") {
  214.             $file = "$x/file";
  215.         }
  216.     }
  217.     die "Can't find 'md5' checksumming tool - normally in Linux coretools package" if !$md5sum;
  218.     die "Can't find 'strings' tool - normally in Linux bintools package" if !$strings;
  219.     die "Can't find 'file' tool - normally in Linux 'file' package" if !$file;
  220. }
  221.  
  222. sub badhashes {
  223.     map { $badhash{$_} = 1; } ((
  224.         'f7536bb412d6c4573fd6fd819e1b07bb',
  225.         '0fdb34f48166dae57ff410d723efd3f7',
  226.         '396d1fb94d79b732f6ab2fa6c5f3ed39',
  227.         'fd3c01133946d59ace4fdb49dde93268', #Directmailer .exe Windows binary
  228.         ));
  229. }
  230.  

Svara på "findbot.pl find web malware "

Här kan du skriva ett svar till kodsnutten ovan