0

By coincidence I noticed that quite some of the PHP files of the sites I host have had malware injected: They all have the following line before the original/correct code:

<?php eval(gzinflate(base64_decode('[malware code]')));?>

What is the best way to do a recursive scan through all my sites, and remove this line (it's always the 1st line) from any files that contain it?

I have full root access to the box. I'm not sure whether this came in through a now-closed hole, or whether the box is still vulnerable therefor I want to do a clean-sweep and closely monitor the files for changes.

regards, Evert

Evert
  • 162
  • 1
  • 3
  • 14
  • 4
    Removing it isn't going to do any good if you don't repair the hole it got in through.. – NickW Mar 10 '14 at 09:42
  • Is your site hosted on a Linux/Unix server, and if so do you have commandline access? If not, what tools do you have access to? – Josh Jolly Mar 10 '14 at 10:05
  • 2
    You need to reinstall AT LEAST anything the compromised user had access to. If you are not completely sure that there were no local root exploits on the machine, reinstall the whole machine. And of course, you need to find out how the malware was inserted and close that hole. – ThiefMaster Mar 10 '14 at 10:32

2 Answers2

3

You could use a command line like the following to remove lines containing malware code in all *.php files recursivly :

find . -name "*.php" -exec sed -i '/malware code/d' {} \;

Not sure if "malware code" is a replacement you have used to anonymise, so you could use :

find . -name "*.php" -exec sed -i '/eval(gzinflate(base64_decode/d' {} \;

However, i advice you to run a backup before running this.

Then, your best bet is to fix your security hole.

krisFR
  • 12,830
  • 3
  • 31
  • 40
  • Thanks! :-) [malware_code] was indeed a replacement of the actual malware code (wasn't sure whether it would be appreciated if I were to post the original here), so your 2nd example is the one I'll use. After this I'll actively monitor the system for changes so I can figure out how this happened. – Evert Mar 10 '14 at 10:58
1

This solution will work on UNIX like systems. It will also work on Windows systems if you install Cygwin or something similar.

If the offending line is always the first line then "tail +2" would be the best way to get rid of it.

I would suggest that you redirect the output of "tail" to a new file so that you can do a bit of validation. Using a third file that contains just the malware line (e.g. malware_line.txt) would enable you to verify that you did not change your files in some unexpected way.

If the script outputs the following message you will want to manually inspect the file:

Files FILENAME.orig and FILENAME.check differ

Here is a script that will only strip the first line form files named *.php or *.PHP (An alternate solution is given if the malware line exists elsewhere in the file but then then validation won't work.)

find . -name "*.php" -o -name "*.PHP" 2>/dev/null | while read FILENAME
do
    BADFILE=0

    # If the file contians the malware line, we want to remove it
    grep -q 'eval(gzinflate(base64_decode' $FILENAME && BADFILE=1

    if [[ $BADFILE != 0 ]]
    then
        echo "Processing: $FILENAME"

        cp $FILENAME ${FILENAME}.orig  # Save a backup copy of  file

        # Remove the offending "first" line.
        tail +2 ${FILENAME}.orig > ${FILENAME}.fixed
        ##
        ## Alternatively, you could use "grep -v" here instead of the above "tail +2" 
        ## to stip the malware line form anywhere in the file.
        ##grep -v 'eval(gzinflate(base64_decode' $FILENAME > ${FILENAME}.fixed

        # Validate that we did not munge up our file
        cat malware_line.txt ${FILENAME}.fixed > ${FILENAME}.check  # Recreate the bad file

        # Compare the original with the recreated file to prove that you only removed 
        # the malware line
        diff -q ${FILENAME}.orig ${FILENAME}.check && cp ${FILENAME}.fixed $FILENAME

        # Cleanup after ourselves
        rm -f ${FILENAME}.check
    fi
done
alexcarr
  • 11
  • 2