To continue our series on WordPress hacks and cleanups, we present a very quick and dirty method of detecting and cleaning up wordpress based pages that may have been infected by the good ol’ Base64 hack. The PERL code listed below recursively searches down the root web folder, searches files for any hints of a “base64” string that has a middle content greater than 500 (arbitrary but usually pretty spot on for this attack) and replaces the instance.
This is a VERY VERY quick and dirty script and will not guarantee that you’re site is clean of all of the hundreds of variants of this hack-attack (see our post on changing tactics)
Only an experienced applications expert should be called in to perform a thorough remediation of both the website AND server software.
We have had experience in cleaning off nearly every type of web system whether it be a system defacement or continuous page “overwrite” attack. We figure out the what/who and then plug up the why and where. Contact us for more details: http://www.silvatechsolutions.com/main/contact-us/
SiteClean.pl
use File::Find qw(finddepth); my @files; my $start="/link/to/your/site/directory"; finddepth(sub { return if($_ eq '.' || $_ eq '..'); my $name=$File::Find::name; if(isInfected($name)==1) { print "\n NAME: $name";cleanFile($name);}; }, $start); sub isInfected{ my $file=shift; $memfile=" ".getFileAsString($file); if($memfile =~/eval\(base64\_decode(.*?)\"\)\)\;\?\>/gi){ return 1; }else{ return 0; } } sub cleanFile{ my $file=shift; $memfile=" ".getFileAsString($file); $clean=''; if($memfile =~s/(.*?)\<\?php \/\*\*\/ eval\(base64\_decode(.*?)\"\)\)\;\?\>//gi){ #assume that the base64 is larger than 500 chars if(length($2)>500){ print "***INFECTED!***"; writeStomp($file,$memfile); } } } sub getFileAsString{ my $file=shift; open(DAT, $file) || eval{die("err OPENING $file")}; @raw_data=<DAT>; close(DAT); #string my $data=""; foreach (@raw_data) { $data.=$_; } return $data; } sub writeStomp{ my $file=shift; my $text=shift; open(MYOUTFILE, ">".$file); print MYOUTFILE "$text"; #write newline close(MYOUTFILE); } |
use File::Find qw(finddepth);
my @files;
my $start=”/link/to/your/site/directory”;
finddepth(sub {
return if($_ eq ‘.’ || $_ eq ‘..’);
my $name=$File::Find::name;
if(isInfected($name)==1) { print “\n NAME: $name”;cleanFile($name);};
}, $start);
sub isInfected{
my $file=shift;
$memfile=” “.getFileAsString($file);
if($memfile =~/eval\(base64\_decode(.*?)\”\)\)\;\?\>/gi){
return 1;
}else{
return 0;
}
}
sub cleanFile{
my $file=shift;
$memfile=” “.getFileAsString($file);
$clean=”;
if($memfile =~s/(.*?)\<\?php \/\*\*\/ eval\(base64\_decode(.*?)\”\)\)\;\?\>//gi){
#assume that the base64 is larger than 500 chars
if(length($2)>500){
print “***INFECTED!***”;
writeStomp($file,$memfile);
}
}
}
sub getFileAsString{
my $file=shift;
open(DAT, $file) || eval{die(“err OPENING $file”)};
@raw_data=<DAT>;
close(DAT);
#string
my $data=””;
foreach (@raw_data) {
$data.=$_;
}
return $data;
}
sub writeStomp{
my $file=shift;
my $text=shift;
open(MYOUTFILE, “>”.$file);
print MYOUTFILE “$text”; #write newline
close(MYOUTFILE);
}