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-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 ;