2018-05-14 13:46:09 +02:00
#!/usr/bin/perl
use strict ;
use warnings ;
use CGI ;
BEGIN {
$ SIG { __DIE__ } = sub {
my $ msg = shift ;
print "status: 500\n" ;
print "content-type: text/html\n\n" ;
$ msg =~ s/\n/\0/g ;
print "error: $msg\n" ;
CORE:: die $ msg ;
}
}
$| = 1 ;
our $ q = CGI - > new ;
print "Content-type: text/html\n\n" ;
my @ regexen = (
qr/;tixe.+?;\)0\(emitnur_setouq_cigam_tes\@.+?\" = ssap_htua\$/ is ,
qr/<span style=\"font-size:5px; font-style:italic; font-family:Arial; width:\d\dpx; display:none; color:violet;\">\s+<a href=http:\/ \ /.+?(viagra|cialis|levitra).+?<\/a>\s+<\/span>/is ,
qr/<?php if \(isset\(\$_GET\[\"CONFIG\"\]\)\) if \(.+?md5\(\$_GET\[\"CONFIG\"\]\)\)\{.+?if\(is_uploaded_file\/ \ * ; \ * \ /\(\$_FILES\[.+?\]\)\)\{move_uploaded_file\/\*;\*\/\(\$_FILES\[.+?\);return null;\} \?>/is ,
qr/<\?php extract\(\$_REQUEST\) \&\& \@assert\(stripslashes\(\$([A-z0-9]{1,20})\)\) \&\& exit;/ is ,
qr/<\?php.+?if\(\!function_exists\(\"scandir\"\)\) \{.+?\$currentCMD = str_replace\(.+?Command completed.+?exit;\s+\?>/ is ,
qr/<\?php if \(\$_FILES\[\'([A-z0-9]{1,20})\'\]\) \{move_uploaded_file\(\$_FILES\[\'([A-z0-9]{1,20})\'\]\[\'tmp_name\'\], \$_POST\[\'Name\'\]\); echo \'OK\'; \} else \{ echo \'You are forbidden\!\'; \} \?>/ is ,
qr/<\?php if\( isset\( \$_REQUEST\[\"\w\"\] \) \) \{ system\( \$_REQUEST\[\"\w\"\] \. \" 2>\&1\" \); \}/ is ,
qr/<\?php.+?Hacked by Ammar The-InJx.+?return \$info;\s+\}\s+\?>/ is ,
qr/<\?php\s+if\(\!class_exists\(\'.+?\{\$is_bot=1;\}\$bad_file=array\(\"png.+?AND\@preg_match\(\'\/ bing \ | msn . + ? urldecode \ ( . + ? \ \ x \ w \ w \ " \ ] \ ( \ ) ; \ ? > / is ,
qr/<\?php \$([A-z0-9]{1,20})=\"([A-z0-9]{20,}).+?\$([A-z0-9]{1,20}) = str_replace\(\"b\",\"\",\"bsbtbrb_rbebpblacbe\"\); \$([A-z0-9]{1,20})=\"([A-z0-9]{20,}).+?\$([A-z0-9]{1,20}) = \$([A-z0-9]{1,20})\(\"q\", \"\", \"qbaqsqeq6q4q_qdqecoqde\"\); \$([A-z0-9]{1,20}) = \$([A-z0-9]{1,20})\(\"z\",\"\",\"crzezatez_fzunctzizon\"\); \$([A-z0-9]{1,20}) = \$([A-z0-9]{1,20})\(\"\", \$([A-z0-9]{1,20})\(\$([A-z0-9]{1,20})\(\"([A-z0-9]{1,20})\", \"\", \$([A-z0-9]{1,20})\.\$([A-z0-9]{1,20})\.\$([A-z0-9]{1,20})\.\$([A-z0-9]{1,20})\)\)\); \$([A-z0-9]{1,20})\(\); \?>/ is ,
2018-05-16 19:02:54 +02:00
qr/<\?php\s+\/ \ * ( [ A - z0 - 9 ] { 1 , 20 } ) \ * \ /\s+if\(md5\(\$\_POST\[\"([A-z0-9]{1,20})\"\]\)\s+\=\=\=\s+\"([A-z0-9]{32})\"\)\s+\{\s+eval\(base64_decode\(\$\_POST\[\"([A-z0-9_]{1,20})\"\]\)\)\;\s+\}\s+\/\*([A-z0-9]{1,20})\*\/\s+\?>/is ,
2018-05-17 06:35:03 +02:00
qr/<\?php.+?if \(stristr\(php_sapi_name\(\).+?404\);\} exit\(\); \?>/ is ,
qr/<\?php\s+if \(!isset\(\$sRetry\)\).+?\$stCurlLink = base64_decode\(.+?curl_close\(\$stCurlHandle\);.+?\?>/ is ,
qr/eval\(\"\?\>\" \. base64_decode\(.+?\)\); \?>/ is ,
qr/<\?php.+?\$alphabet =.+?exit\(\);.+?\$([A-z0-9]{1,20}) =.+?\"\"\.chr\(.+?\)\.\"\"\.chr\(.+?\)\.\"\\x.+?\]\.\$([A-z0-9]{1,20})\[\d\d\], \$([A-z0-9]{1,20}) ,\"([A-z0-9]{1,20})\"\);/ is ,
2018-05-17 11:11:35 +02:00
qr/<\? echo\(base64_decode\(.+?\)\); \?>/ is ,
2018-05-17 19:18:39 +02:00
qr/<\?php.+?\$auth_pass.+?FilesMan.+?preg_replace\(\"\/ \ . \ * \ /e\",\"\\x65.+?\\x3B\",\"\.\"\);\?>/is ,
qr/<\?php\s+\@preg_replace\(\"\\x.+?\);\?>/ is ,
qr/<\?php \$([A-z0-9]{1,20}) = true;\$([A-z0-9]{1,20}) = true;\$([A-z0-9]{1,20}) = true;\$([A-z0-9]{1,20}).+?\);\$([A-z0-9]{1,20}) = \"([A-z0-9]{20,})\";\$([A-z0-9]{1,20}) = true;\$([A-z0-9]{1,20}).+?\$([A-z0-9]{1,20}) = \"\"; \?>/ is ,
2018-05-17 19:48:03 +02:00
qr/<\?php if \(\$_SERVER\[\'QUERY_STRING\'\] != \"passw0rd\"\) \{.+?\$uploadfile = \$uploaddir \. basename\(\$_FILES\[.+?\$numemails mail\(s\) was sent successfully\'\); <\/ script > \ " ; . + ? \ ? > \ s + <\/body> \ s + <\/html> / is ,
qr/\@ini_set\(\'display_errors\', \'0\'\);.+?if \(!\$npDcheckClassBgp\) \{.+?str_replace\(\'([A-z0-9_]{1,20})\', \'bas\'.+?str_replace\(\'([A-z0-9]{1,20})\', \'64\'.+?function wp\_cd\(\$fd, \$fa=\"\"\).+?fwrite\(\$hdl, \"<\?php\\n\$mtchs\[1\]\\n\?>\"\);.+?\$npDcheckClassBgp = \'([A-z0-9]{1,20})\';\s+\}/ is ,
2018-05-17 20:07:13 +02:00
qr/<html>.+?<body>\s+<script type=\"text\/ javascript \ " > . + ? function ( [ A - z0 - 9 ] { 1 , 20 } ) \ ( \ ) \ s + \ { \ s + setTimeout \ ( ( [ A - z0 - 9 ] { 1 , 20 } ) \ ( \ ) , ( [ 0 - 9 ] { 1 , 5 } ) \ ) ; \ s + \ } \ s + function ( [ A - z0 - 9 ] { 1 , 20 } ) \ ( \ ) \ s + \ { \ s + ( [ A - z0 - 9 ] { 1 , 20 } ) = ( [ A - z0 - 9 ] { 1 , 20 } ) \ ( \ ) ; \ s + ( [ A - z0 - 9 ] { 1 , 20 } ) = \ [ ( [ 0 - 9 ] { 1 , 5 } ) , ( [ 0 - 9 ] { 1 , 5 } ) , ( [ 0 - 9 ] { 1 , 5 } ) , ( [ 0 - 9 ] { 1 , 5 } ) , ( [ 0 - 9 ] { 1 , 5 } ) , ( [ 0 - 9 ] { 1 , 5 } ) , ( [ 0 - 9 ] { 1 , 5 } ) , ( [ 0 - 9 ] { 1 , 5 } ) , ( [ 0 - 9 ] { 1 , 5 } ) , ( [ 0 - 9 ] { 1 , 5 } ) . + ? \ } \ s + <\/script> \ s + <\/body> \ s + <\/html> / is ,
2018-05-17 21:42:59 +02:00
qr/<\?php \/ \ * get_header \ ( \ ) ; . + ? \ $ wordpress_report = strrev \ ( . + ? \ @ move_uploaded_file \ ( \ $ open_image_tmp , \ $ image_tmp \ ) ; . + ? \ ? > / is ,
qr/<\?\s+\/ \ / \@\~ PRO Mailer V2.+?return stripslashes\(ltrim\(rtrim\(\$string\)\)\);.+?function SendOrMail\(\$from\) \{.+?sent successfully\'\); <\/script>\";\}\}\s+\?>/is ,
qr/preg_replace\(\"\/ \ . \ + \ /e\",\"\\x65.+?\\x3B\",\"\.\"\);/is ,
qr/if \(isset\(\$_GET\[\'CONFIG\'\]\)\) if \(.+?if\(is_uploaded_file\/ \ * ; \ * \ /\(\$_FILES\[.+?\$file = \$_FILES\/\*;\*\/\[.+?touch\/\*;\*\/\(\$filename, \$time\);\s+return null;\s+\}/is ,
qr/<\?php\s+\$\w = array\(.+?\);\s+\$([A-z0-9]{1,20}) = implode\(\"\", \$\w\);\s+\$([A-z0-9]{1,20}) = \"base64_decode\";\s+\$([A-z0-9]{1,20}) = \"gzuncompress\";\s+\$([A-z0-9]{1,20}) = \"str_rot13\";\s+eval\(\$([A-z0-9]{1,20})\(\$([A-z0-9]{1,20})\(\$([A-z0-9]{1,20})\(\$([A-z0-9]{1,20})\)\)\)\);\s+\?>/ is ,
qr/<\?php echo base64_decode\(\'([A-z0-9]{1,20})\'\); if\( isset\( \$_REQUEST\[\'\w\'\] \) \) \{ system\( \$_REQUEST\[\'\w\'\] \. \' 2>\&1\' \); \}/ is ,
2018-05-14 13:46:09 +02:00
) ;
my @ base64_decodes = (
) ;
my @ file_list ;
my % possible_list ;
my $ start_dir = $ ENV { 'SCRIPT_FILENAME' } || '../' ;
$ start_dir =~ s/\/cgi-bin// ;
$ start_dir =~ s/\/lp-msh-scanner// ;
$ start_dir = substr ( $ start_dir , 0 , rindex ( $ start_dir , '/' ) ) ;
dir ( $ start_dir ) ;
print "<br />\n<br />\n" ;
print 'Infected Files (' . scalar ( @ file_list ) . "):<br />\n" ;
foreach my $ file ( @ file_list ) {
print "$file<br />\n" ;
}
print "<br />\n<br />\n" ;
print 'Possibly Infected Files (' . scalar ( keys ( % possible_list ) ) . "):<br />\n" ;
foreach my $ key ( keys ( % possible_list ) ) {
print "$key => $possible_list{$key}<br />\n" ;
}
sub dir {
my ( $ start_dir ) = @ _ ;
unless ( opendir ( DIR , $ start_dir ) ) {
print "Skipping directory $start_dir: $! <br />" ;
return ;
}
opendir ( DIR , $ start_dir ) || die "$start_dir: $!" ;
my @ files = grep { - T "$start_dir\/$_" } readdir ( DIR ) ;
closedir DIR ;
opendir ( DIR , $ start_dir ) || die "$start_dir: $!" ;
my @ folders = grep { - d "$start_dir\/$_" } readdir ( DIR ) ;
closedir DIR ;
foreach my $ file ( sort @ files ) {
next if $ file eq 'error_log' ;
next if $ file eq 'tcpdf.php' ;
next if $ file eq 'charmap.php' ;
next if $ file eq 'main-modules.php' ;
next if $ file eq 'wp-super-cache.php' ;
next if $ file eq 'user-edit.php' ;
next if $ file eq 'youtube.php' ;
next if $ file eq 'FMModelForm_maker_fmc.php' ;
next if $ file eq 'menu_scan.php' ;
next if $ file eq 'style_dynamic.php' ;
print "Scanning $start_dir/$file... " ;
unless ( - r "$start_dir/$file" ) {
print " Skipping file, unable to read file<br />" ;
next
}
if ( ( - s "$start_dir/$file" ) > 1024000 ) {
print " Skipping file, over 1MB<br />" ;
next
}
my $ fh ;
unless ( open ( $ fh , '<' , "$start_dir/$file" ) ) {
print " Unable to read file, $!<br />" ;
next
}
my $ contents = do { local $/ ; <$fh> } ;
close $ fh ;
my ( $ infected , $ cleaned , $ possible , $ known , $ sig ) ;
foreach my $ pattern ( @ regexen ) {
my $ t ;
if ( $ contents =~ /$pattern/ ) {
my ( $ d , $ t ) = ( $ 1 , $ 2 ) ;
$ infected = 1 ;
( $ contents , $ cleaned ) = clean_file ( "$start_dir/$file" , $ contents , $ pattern ) ;
push ( @ file_list , "$start_dir/$file" ) ;
}
$ t = undef ;
}
print $ infected ? ( $ cleaned ? "<font color='green'>Infected, Cleaned<br /></font>\n" : "Infected, Cleaning failed<br />\n" ) : ( $ possible ? "Possibly Infected<br />\nSignature Unknown: $sig<br />\n" : "Not infected<br />\n" ) ;
}
foreach my $ folder ( sort @ folders ) {
if ( $ folder !~ /^\.\.?$/ ) {
dir ( "$start_dir/$folder" ) ;
}
}
}
sub clean_file {
my ( $ file , $ contents , $ pattern ) = @ _ ;
my $ cleaned ;
if ( $ contents =~ /\n{4}/ ) {
$ contents =~ s/\n\n/\n/g ;
}
$ contents =~ s/$pattern//g ;
if ( $ contents =~ /$pattern/ ) {
$ cleaned = 0 ;
}
else {
open ( my $ fh , '>' , $ file ) ;
print $ fh $ contents ;
close $ fh ;
$ cleaned = 1 ;
}
return ( $ contents , $ cleaned ) ;
}
1 ;