Fix Hack

This is a script to fix a known FTP 'man in the middle' attack that has been floating around recently: http://frazierit.com/blog/?p=103&cpage=2#comment-179

If I were to give this virus/worm/hack a name, I would probably dub it: toolbarqueries exploit/hack as it uses google's toolbarqueries service to determine page rank of the victim in order to determine if the site is worth hacking or not.

Current as of this writting: May 6, 2011

<?php
//Create back files?
define('CREATE_BACKUPS', FALSE);

if (!
is_dir($argv[1]))
{
   echo
"You must enter a valid path such as /home/infected_dir or infected_dir for this script to function.\n";
   exit;
}

//Search the path for all php files, opening each one, and checking to see if it's infected

//First, get an array list of all valid .php files.


$files = listdir($argv[1]);
foreach (
$files as $filename)
{
  
//We only need to check php files, so we add that here
  
if (file_extension($filename) == 'php')
   {
     
//This is a php file so lets check it to see if it's infected.
     
$contents = file_get_contents($filename);
     
$backup = $contents;

     
//There will always be 2 opening tags in an infected file and since the hack is always at the top, it's easiest to test for this right away.
     
$test = between('<?php', '<?php', $contents);

     
//This particular hack likes to use toolbarqueries so we test to see if our chunk is an infected chunk.  If your website uses this url somehow, then add extra if statements as necessary.
     
if (after('toolbarqueries', $test))
      {
        
//This chunk is infected.  So lets replace it and resave the file.
        
$contents = str_replace('<?php'.$test.'<?php', '<?php', $contents);

        
//Now save it! Woohoo!
        
file_put_contents($filename, $contents);
         if (
CREATE_BACKUPS)
         {
           
file_put_contents($filename.'.orig', $backup);
         }

         echo
"$filename has been cleaned.\n";
      }
   }
}

function
after ($this, $inthat)
    {
        if (!
is_bool(strpos($inthat, $this)))
        return
substr($inthat, strpos($inthat,$this)+strlen($this));
    };

    function
after_last ($this, $inthat)
    {
        if (!
is_bool(strrevpos($inthat, $this)))
        return
substr($inthat, strrevpos($inthat, $this)+strlen($this));
    };

    function
before ($this, $inthat)
    {
        return
substr($inthat, 0, strpos($inthat, $this));
    };

    function
before_last ($this, $inthat)
    {
        return
substr($inthat, 0, strrevpos($inthat, $this));
    };

    function
between ($this, $that, $inthat)
    {
     return
before($that, after($this, $inthat));
    };

    function
between_last ($this, $that, $inthat)
    {
     return
after_last($this, before_last($that, $inthat));
    };

   
// USES
   
function strrevpos($instr, $needle)
    {
       
$rev_pos = strpos (strrev($instr), strrev($needle));
        if (
$rev_pos===false) return false;
        else return
strlen($instr) - $rev_pos - strlen($needle);
    };

    function
listdir($dir='.') {
    if (!
is_dir($dir)) {
        return
false;
    }

   
$files = array();
   
listdiraux($dir, $files);

    return
$files;
}

function
listdiraux($dir, &$files) {
   
$handle = opendir($dir);
    while ((
$file = readdir($handle)) !== false) {
        if (
$file == '.' || $file == '..') {
            continue;
        }
       
$filepath = $dir == '.' ? $file : $dir . '/' . $file;
        if (
is_link($filepath))
            continue;
        if (
is_file($filepath))
           
$files[] = $filepath;
        else if (
is_dir($filepath))
           
listdiraux($filepath, $files);
    }
   
closedir($handle);
}

function
file_extension($filename)
{
  
$info = pathinfo($filename);
   return
$info['extension'];
}
?>