Looking for bad guys.
This script looks for traces of malicious code including code injections, modified .htaccess that makes images executable, and so on.
");
if($UseAbsoluteFilePaths)
$StartPath = $RealPath;
# ================================================================================
# START OF SEARCH ROUTINES.
# ================================================================================
/*
This program does two things: 1) finds files, and 2) does something with each one.
When designing a search, the two questions to ask are:
1) Which types of files (by their names) do I want to find or perform an action on?
2) What action do I want to do on each one?
Each search requires these data items to be defined:
1) An array that is a list of Perl-Compatible Regular Expressions (PCRE) of filenames to match.
The program searches directories for all the filenames that match any of the regexes.
2) Another array that is a list of PCREs of fullpaths NOT to match.
This allows excluding files in certain directories.
If a file's NAME matches any regex in list 1)
and its PATH+NAME does NOT match any regexes list 2) (the exclusions),
its name gets passed to the handler function.
3) The handler function. It can perform any action you want on the file whose name is given to it.
Some of the handler functions below merely report that the filename is suspicious, but do nothing else.
Another handler searches the file extensively for malicious snippets and reports each one found.
You could write a handler that automatically cleans the snippet out of the file,
or even deletes the file automatically. The handler can do anything.
*/
# ================================================================================
# 1) SUSPICIOUS FILENAMES.
# Files with these strings in their *names* will be reported as suspicious.
# There is currently no method provided to check for suspiciously named folders.
# ================================================================================
# FILENAMES TO MATCH
$FileMatchRegexes = array
(
# '/root/i',
# '/kit/i',
'/c(99|100)/i',
'/r57/i',
'/gifimg/i'
);
# AND FULLPATHS TO EXCLUDE FROM EXAMINATION
$FullpathExcludeRegexes = array
(
'#lookforbadguys\.php$#i'
);
# --------------------------------------------------------------------------------
# HANDLER FUNCTION - THIS IS THE ACTION PERFORMED ON A FILE WHOSE NAME IS A MATCH.
function badnames($filename)
{
echo CleanColorText($filename, 'blue') . " is a " . CleanColorText('suspicious file name', 'red') . ".
";
}
# --------------------------------------------------------------------------------
# THIS CODE ACTUALLY DOES THE SEARCH.
echo CleanColorText("Searching for files with suspicious names...", 'green') . "
";
FindAndProcessFiles($StartPath, $FileMatchRegexes, $FullpathExcludeRegexes, 'badnames');
# ================================================================================
# 2) WORDPRESS PHARMA HACK SUSPICIOUS FILENAMES.
# Files matching these names will be reported as possible pharma hack files.
# Regexes are based on the naming conventions described at
# http://www.pearsonified.com/2010/04/wordpress-pharma-hack.php
# ================================================================================
# FILENAMES TO MATCH
$FileMatchRegexes = array
(
'/^\..*(cache|bak|old)\.php/i', # HIDDEN FILES WITH PSEUDO-EXTENSIONS IN THE MIDDLE OF THE FILENAME
'/^db-.*\.php/i',
# Permit the standard WordPress files that start with class-, but flag all others as suspicious.
# The (?!) is called a negative lookahead assertion. It means "not followed by..."
'/^class-(?!snoopy|smtp|feed|pop3|IXR|phpmailer|json|simplepie|phpass|http|oembed|ftp-pure|wp-filesystem-ssh2|wp-filesystem-ftpsockets|ftp|wp-filesystem-ftpext|pclzip|wp-importer|wp-upgrader|wp-filesystem-base|ftp-sockets|wp-filesystem-direct)\.php/i'
);
# AND FULLPATHS TO EXCLUDE FROM EXAMINATION
$FullpathExcludeRegexes = array
(
'#lookforbadguys\.php$#i'
);
# --------------------------------------------------------------------------------
# HANDLER FUNCTION - THIS IS THE ACTION PERFORMED ON A FILE WHOSE NAME IS A MATCH.
function pharma($filename)
{
echo CleanColorText($filename, 'blue') . " is most likely a " . CleanColorText('pharma hack', 'red') . ".
";
}
# --------------------------------------------------------------------------------
# THIS CODE ACTUALLY DOES THE SEARCH.
echo "
" . CleanColorText("Searching for files with names related to Wordpress pharma hack...", 'green') . "
";
FindAndProcessFiles($StartPath, $FileMatchRegexes, $FullpathExcludeRegexes, 'pharma');
# ================================================================================
# 3) MALICIOUS CODE SNIPPETS.
# Search text files for snippets of malicious code and report all that are found.
# ================================================================================
# FILENAMES TO MATCH
# Ideally, this list should contain all common extensions of text files
# that can become hazardous when malicious text is injected into them.
$FileMatchRegexes = array
(
'/\.htaccess$/i',
'/\.php[45]?$/i',
'/\.html?$/i',
'/\.aspx?$/i',
'/\.inc$/i',
'/\.cfm$/i',
'/\.js$/i',
'/\.txt$/i',
'/\.css$/i'
);
# AND FULLPATHS TO EXCLUDE FROM EXAMINATION
$FullpathExcludeRegexes = array
(
'#lookforbadguys\.php$#i'
);
# --------------------------------------------------------------------------------
# HANDLER FUNCTION - THIS IS THE ACTION PERFORMED ON A FILE WHOSE NAME IS A MATCH.
function FindMaliciousCodeSnippets($filename)
{
if(!is_readable($filename))
{
echo "Warning: Unable to read " . CleanColorText($filename, 'blue') .
". Check it manually and check its access permissions.
";
return;
}
# READ THE FILE INTO A STRING, WITH LINE ENDS REMOVED AND WHITESPACE COMPRESSED.
$file = file_get_contents($filename);
$file = preg_replace('/\s+/', ' ', $file);
# The file is searched for each of these snippets of suspicious text.
# These are regular expressions with the required /DELIMITERS/ and with metachars escaped.
# /i at the end means case insensitive.
# PHP function names are case-insensitive.
# If your regex itself contains / chars, you can use a different
# char as a delimiter like this: '#delimited#i' to avoid confusion.
$SuspiciousSnippets = array
(
# POTENTIALLY SUSPICIOUS CODE
'/edoced_46esab/i',
'/passthru\s*\(/i',
'/shell_exec\s*\(/i',
'/document\.write\s*\(unescape\s*\(/i',
# THESE CAN GIVE MANY FALSE POSITIVES WHEN CHECKING WORDPRESS AND OTHER CMS.
# NONETHELESS, THEY CAN BE IMPORTANT TO FIND, ESPECIALLY BASE64_DECODE.
# THIS IS MUCH MORE SUSPICIOUS IF THE MATCHED TEXT CONTAINS THE EVAL() CODE.
'/(eval\s*\(.{0,40})?base64_decode\s*\(/i',
'/system\s*\(/i',
# PHP BACKTICK OPERATOR INVOKES SYSTEM FUNCTIONS, SAME AS system(),
# BUT IT IS ALSO A DATABASE,TABLE,FIELD DELIMITER IN SQL DATABASE QUERIES.
'/`[^`]+`/',
'/phpinfo\s*\(/i',
# THIS SET GENERATES MANY FALSE POSITIVES
# '/chmod\s*\(/i',
# '/mkdir\s*\(/i',
# '/fopen\s*\(/i',
# '/fclose\s*\(/i',
# '/readfile\s*\(/i',
# THESE WERE PREVIOUSLY SPECIAL CASES; NOW MOVED INTO THIS ARRAY.
'/RewriteRule\s/i', # SUSPICIOUS IF THE DESTINATION IS A DIFFERENT SITE OR SUSPICIOUS FILE.
'/AddHandler\s/i', # THIS CAN MAKE IMAGE OR OTHER FILES EXECUTABLE.
# JAVASCRIPT SNIPPETS WHOSE SRC= REFERENCES AN HTTP:// SOURCE OTHER THAN ONES KNOWN TO BE SAFE.
# EVEN WITH EXCEPTIONS, THIS CAN GIVE MANY FALSE POSITIVES.
'@