Requirements
This article assumes the user is comfortable with using SSH for navigation of Linux and the editing of files therein.
FIND, GREP & STAT
These three commands can easily uncover most kinds of malicious code and can often help point you towards the source of the attack, if they're used properly. I will break down how to use each command separately, and then later how they can be used in concert.
Find
The Linux manual defines this command as a utility that "recursively descends the directory tree for each path listed, evaluating an expression in terms of each file in the tree."
Simply put, the Find utility lets you search an area to look for files or folders as defined by a number of variables, such as by name, by owner, by time modified, etc.
For example, to search the directory "/home/mywebsite" for a file called foobar.txt, you can run the following command:
find /home/mywebsite -type f -name "foobar.txt"
This should return the following:
/home/mywebsite/folder/another-folder/foobar.txt
If you want to find a list of files in that same "/home/mywebsite" directory that have been changed in the last 7 days, you can run the following command:
find /home/mywebsite -type f -ctime -7
The (-7) after ctime means files changed within 7 days or less. if that was changed to a plus (+) symbol, it would mean any files changed a minimum or 7 days or longer.
Here is a more complex example: To find a list of all files inside "/home/mywebsite" with the extension .php that have been changed within 30 days, you can run the following command:
find /home/mywebsite -type f -name "*.php" -ctime -30
There are more commands that 'find' can handle. If you want to know more, see the manual page by typing "man find" in SSH.
Grep
The Linux manual defines this command as a utility that "searches the named input FILEs (or standard input if no files are named, or the file name - is given) for lines containing a match to the given PATTERN. By default, grep prints the matching lines."
Essentially, the grep utility lets you search files for a matching text pattern.
'Grep' is one of the greatest commands for finding malicious files, but it can also turn up a lot of false-positives. The following are the very basics of the command. These examples will be searching in the "/home/mywebsite" directory.
For example, to find the phrase "hello world", located in a file somewhere inside that directory, you can run the following command:
grep -r "hello world" /home/mywebsite
If there was a file that contains that phrase, 'grep' will post the path to the file, and the line containing the matching text:
/home/mywebsite/foo/bar/hello.txt: hello world!
Please note that grep searches are case-sensitive. To ignore case-sensitivity, use the '-i' flag
For more information, see the manual page for grep by typing 'man grep' in SSH.
Stat
The Linux manual defines this command as a utility that is used to "display file or filesystem status."
To expand on this, the stat utility is used to display permissions, ownership and various timestamps of a file.
To see an example of the 'stat' command output, let's take a look at that file we found earlier via the 'find' command, "/home/mywebsite/folder/another-folder/foobar.txt":
stat /home/mywebsite/folder/another-folder/foobar.txt
File: `home/mywebsite/folder/another-folder/foobar.txt'
Size: 19043 Blocks: 39 IO Block: 32768 regular file
Device: 17h/23d Inode: 140209072 Links: 1
Access: (0644/-rw-r--r--) Uid: (841608/mywebsite-user) Gid: (88432/mywebsite-user)
Access: 2011-10-22 21:10:09.106667057 -0700
Modify: 2011-11-14 15:14:19.493663971 -0800
Change: 2011-11-14 15:14:19.494043373 -0800
The line with "Access/Uid/Gid" simply lays out the read/write/execute permissions of the file, and who owns it in user and group. The last three lines deal with the time-stamp of the file. "Access" normally refers to when it was first created, or last written to. "Modify" refers to the last time the file changed permissions, or was renamed (among other things). "Change" refers to the last time the actual contents of the file were modified.
Many malicious scripts are able to keep the access and modify time-stamps unchanged, but the change time-stamp will always reflect that someone has been inside the file. If a file has been modified via FTP, all three time-stamps will be changed to the same date.
FINDING MALICIOUS CODE
Base64
Base64 code is often seen in attacked sites. Typically the attacker's script will inject the code into either the first or last line in a file, and can sometimes be painfully obvious to find. The 'grep' command is most useful for this, though as mentioned it does show a lot of false-positives. The following are commond patterns you can use to find base64-related activity:
- base64_decode
- gzinflate(base64_decode
- eval(gzinflate(base64_decode
- eval(base64_decode
The following is an example of Base64 encoding:
<?php eval(base64_decode(
ZWNobygiTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2ljaW5n
IGVsaXQsIHNlZCBkbyBlaXVzbW9kIHRlbXBvciBpbmNpZGlkdW50IHV0IGxhYm9yZSBldCBkb2xv
cmUgbWFnbmEgYWxpcXVhLiBVdCBlbmltIGFkIG1pbmltIHZlbmlhbSwgcXVpcyBub3N0cnVkIGV4
ZXJjaXRhdGlvbiB1bGxhbWNvIGxhYm9yaXMgbmlzaSB1dCBhbGlxdWlwIGV4IGVhIGNvbW1vZG8g
Y29uc2VxdWF0LiBEdWlzIGF1dGUgaXJ1cmUgZG9sb3IgaW4gcmVwcmVoZW5kZXJpdCBpbiB2b2x1
cHRhdGUgdmVsaXQgZXNzZSBjaWxsdW0gZG9sb3JlIGV1IGZ1Z2lhdCBudWxsYSBwYXJpYXR1ci4g
RXhjZXB0ZXVyIHNpbnQgb2NjYWVjYXQgY3VwaWRhdGF0IG5vbiBwcm9pZGVudCwgc3VudCBpbiBj
dWxwYSBxdWkgb2ZmaWNpYSBkZXNlcnVudCBtb2xsaXQgYW5pbSBpZCBlc3QgbGFib3J1bS4iKTs=
));?><?php
echo("Hello world, I am testing my website!");
?>
NOTE:
There are legitimate uses for base64. For example, plugin authors who are trying to hide their code and people who want to embed an image directly into a CSS file. You will need to take your 'grep' results, and compare them against known clean versions of those files.
JavaScript
JavaScript injections are most often seen in HTML files or in the header/footer of some PHP files, and they can sometimes be overlooked at first glance. Often the code will have a link to a country-code based URL (for example, co.nz, .ru, .br, etc.). Here is a rough example of what malicious JavaScript code can look like:
<script src="http://a.very.bad.website/attack.js">
As JavaScript is commonly used, a 'grep' for "<script src" is going to be too broad. If possible, find the malicious URL and run a 'grep' command for the referenced URL.