Search code examples
php.htaccessterminalcpanel

Command in terminal to delete multiple files - CPanel, shared hosting infected with virus


Today, Hosted gator reported that I have 30K files infected on my shared hosting. Around 25K was the same file, multiple times. I deleted them in one shot through the terminal with:

find . -name "0x1337.php" -delete

Reference:
Delete large batch of files with same file name in different directories - cpanel/LAMP

One such example path was:

/home1/..../public_html/.........com/wp-includes/js/tinymce/skins/lightgray/fonts/0x1337.php: SL-PHP-BACKDOOR-GENERIC-md5-cavg.UNOFFICIAL FOUND

Around 6K are still left:

/home1/.../public_html/......com/blog/wp-content/plugins/related-posts-slider/styles/.htaccess: SL-HTACCESS-GENERIC-xo.UNOFFICIAL FOUND

If I used this to delete:

find . -name ".htaccess" -delete → All .htaccess will be deleted. Is there was to refactor so only infected files can be deleted?

Can this be taken as a clue → -xo.UNOFFICIAL FOUND?


Solution

  • In an attempt to clarify the steps I mentioned in the comments, I'll write it all out here.

    I'm going to be super verbose here to explain what's happening.

    My assumption is that Hostgator has provided you with a file named malware.txt that contains entries that look like this:

    /path/to/file.php: SOME-MALWARE FOUND
    /path/to/another/file.php: SOME-OTHER-MALWARE FOUND
    /path/to/clean/file.php: CLEAN
    

    In other words: malware.txt contains a mix of files that were flagged as containing malware and files that were considered clean and you want to keep.

    The first step is to turn this file into a new file that only contains the file paths. We'll use grep and cut for this.

    grep 'SOME-MALWARE' malware.txt | cut -d ':' -f1 > filelist.txt
    
    • grep 'SOME-MALWARE' malware.txt will find all lines in malware.txt that contain the string SOME-MALWARE anywhere. This is on purpose so you can break the list down into smaller sets and target individual malwares at a time.
    • | will send each line to the next command
    • cut -d ':' -f1 will split each line by a delimiter (:) and keep only the given field (1 -- the first field, so everything from the beginning of the line up to the first : character)
    • > filelist.txt will send the results to filelist.txt.

    Now, with the sample set, filelist.txt should contain the following:

    /path/to/file.php
    

    (to target /path/to/another/file.php change grep to look for SOME-OTHER-MALWARE)

    The next step is to delete those files. We will use cat and rm for that. Since we cannot pipe directly to rm using |, we will use the xargs command to do that.

    cat filelist.txt | xargs -n1 -p rm
    
    • cat filelist.txt will read all lines in filelist.txt one by one
    • | will send each line to the next command
    • xargs -n1 -p rm will send each line as an argument to the rm command.
      • -n1 will ensure it processes one line at a time (without this, it will bunch lines together into a single rm command to delete multiple files at once)
      • -p will prompt you to confirm that you want to continue before actually performing the rm command

    The reason for -p is so you can verify that this all works correctly. Once you've verified that, you can remove the -p argument if you want.

    Note that this assumes all your filenames are pretty basic. If they contain special characters or spaces, these will need to be escaped or it will break.

    For example, if you have a file named /path/to/some file.php, this code will try to remove the files /path/to/some and file.php.

    If you notice trouble here, you can adjust the xargs command like this:

    cat filelist.txt | xargs -I "{}" -n1 -p rm {}
    

    The -I "{}" part will wrap the input argument (the filename from cat) in double quotes, the {} at the end will make sure rm uses the wrapped argument instead of the original.

    If you run this command multiple times, you will probably see a lot of "file not found" errors. That is expected for files that were already deleted the last time you ran it so shouldn't be anything to worry about.

    I hope this clarifies things, let me know if this is unclear in any way.