Before starting this write-up I have to thank Thomas from CERT-Bund for sharing some of the intelligence he has on this.
For the past weeks a spike has been seen in the amount of WordPress websites embedding iframes to exploit kits; more than just Fiesta has been seen. There are thousands of websites currently embedding the iframes, from what little data I have which is only some 3000~ websites it is most likely just a small section of it all.
When visiting one of the affected websites a user is greeted with some extra inject HTML before the tags on the website which consists of an iframe:
This iframe is a gate towards (in many case) the Fiesta exploit kit, for a detailed writeup of Fiesta you can read my previous article which goes through all the steps from redirect to exploitation: An In-depth analysis of the Fiesta Exploit Kit: An infection in 2015.
All the compromised websites are WordPress websites. This raises a question: “How did they get compromised with the HTML injection?”. WordPress itself has been quite stable for a while but the major problem with WordPress websites are the plug-ins that are installed.
In the case of this campaign the websites have all been compromised via a plug-in called “RevSlider” which already got in the new previously regarding its vulnerability:
Some administrators have also started to report on ‘strange’ things in a support thread on the WordPress support site: wp-admin page is white and blank. When you look at the screenshots the user added you can see that in fact it is the Fiesta exploit kit redirect active:
Investigation on one of the compromised sites shows the attackers performed the following steps:
- RevSlider was abused to add an extra Administrator account
- The attacker uploaded a script called ‘smart.php’
- Edited 3 files in the WordPress installation; 2 files inside other plugins were backdoored with a code execution backdoor and the WordPress ‘nav-menu.php’ file was modified
First we’ll have a look at the smart.php file uploaded by the attackers. When opening it you are greeted with a lot of non-ascii in a blob with at the end some PHP code:
When you indent and pretify the PHP code for a bit you can work out how the things actually functions:
First it checks if a specific variable is set in the cookie or POST data send to the PHP file. When the data is present it does some dissection on it (with the for loop) using the compressed blob. It uses the result of this for execution. The problem is that the blob is used for indexing on the POST data which we don’t have sadly.
Time to move on to the other files; 2 files had added backdoors at the top of the PHP code. Let’s open one of them up (these were files from other plugins), one of these files is part of SimplePie and was found in /wp-includes/SimplePie/Cache.php. Opening the file it is already really clear what they did (no obfuscation or hiding):
At line 1 it just starts with a plaintext/non-obfuscated backdoor. With the ’pass’ parameter and a combination of the ’p1’ or ’p2’ parameter the backdoor will either execute directory or first base64 decode it before executing. The ’pass’ parameter seems to be hardcoded and I’ve pixelated because it might actually be static across all the other hacked websites.
This exact same code is also present in /wp-includes/pomo/eentry.php as a ‘backup’ backdoor basically.
The third file that was modified was /wp-includes/nav-menu.php. The modification is a little bit harder to spot as its in the middle of the file inbetween some other PHP code:
The preg_replace function allows for a regular expression search and replace, the ’/e‘modifier actually makes it possible to evaluate the second argument as a PHP expression; meaning it executes the code in the second argument.
The second argument from the backdoored nav-menu.php file is a long string which comes down to:
When you decode and inflate the data blob you get the PHP script. The top part of it looks quite familair; its the same backdoor part we saw in the other files:
The second section becomes a bit more interesting, it builds up 2 variables, one to store the User-Agent used by the visiting clients and a URL:
The URL pattern takes a base64 encoded starting URL and appends the following data to the URL:
- Webserver domain name
- Client IP address
- Client User-Agent (Base64 encoded)
- Client Referer (Base64 encoded)
The full URL (without the domain, I pixelated a section of the base64 data):
/ordpm/v2/?export=7f53f8c6c730af6aeb52e66eb74d8507&url=50773&g=67&host=|compromised site|&ip=|client ip|&ua=|client user-agent|&ref=|client referer|
This client data is most likely used to make stats on the backend of this system.
In the third section a check if performed to do a couple of things:
- Make sure the ’echo’ variable isn’t set (this so it doesn’t inject the iframe multiple times)
- Make sure the client does have a User-Agent
- Make sure the client IP address doesn’t start with 74.125, this is a Google owned range; the full 126.96.36.199/16 in fact.
- Make sure the User-Agent is not one of the internet crawlers (Like Google, Bing, Yandex, etc)
An interesting thing to note is the commented checks present in the code. The old code used to also perform checks to see if the client had a referrer and if it was running Internet Explorer as a browser. The Internet Explorer part is interesting as the Fiesta exploit kit only works on Internet explorer as explained in my previous entry. The PHP code performing these checks:
The last section is where the interesting part happens; it injects the iframe HTML code:
First it makes sure CURL is available, then it builds up curl object to perform a request with. Next it formats a request based on the full URL constructed earlier (with the client IP, User-Agent etc). It performs the request and stores the returned data.
This return data is then decoded, its base64 encoded data, and printed to the page. This data is the iframe that is injected in the page, it comes from this backend after being requested by the webserver.
So to conclude; this is how the current campaign works:
- They compromise WordPress websites running the vulnerable RevSlider plugin
- When a client visits the website they inject HTML code obtained from the backend (The HTML is currently an iframe but it can be anything).
Some more examples of compromised sites (I’ve been tweeting a bunch of these sporadically of the past weeks):
Statistics & More information
The payloads that are dropped from the exploit kits are diverse. There are reports of Cryptowall 3.0 being dropped, some banking malware as well as ad fraud; it just depends who rents ’loads’ on these instances.
From the list of known compromised sites I was able to make some stats for TLD’s:
Besides that here are the affected country IP’s spread over the globe:
As you can see mostly the US is affected with hosted websites, the grey countries don’t host any affected websites. The top 10 countries:
- United States
- Great Britain
Keep in mind these numbers are incomplete; there are most likely a lot more websites.
CERT-Bund has been sharing the full list of currently known domains with other CERT teams. If you are a CERT and haven’t received the list contact CERT-Bund or email me, GPG ID: 0x7e6d96d628493171.
Exploit kit domains
The domains that have been seen are all hosted under dynamic DNS providers and have all been set to a short TTL. Just a small grab from a collection of the domains seen for the past week(s):
Mitigation & Prevention
In order to clean up a website affected by this a few steps have to be taken. However, the best thing to do here is to rebuild the site from a clean WordPress installation of course (keeping in mind to not install the same vulnerable plugin a second time of course).
Because the attacker adds an extra administrator account it is best to assume all credentials are compromised. Remove all accounts and create a brand new one without re-using any of the old username/password combinations.
Check all PHP files for modifications by comparing them to files from the official WordPress website (or own local copies if you are 100% sure they are unaffected). Any modified files should be replaced with the normal one.
Update the RevSlider plugin to the latest version. One thing to keep in mind is that certain versions of RevSlider that were embedded with WordPress themes cannot automatically update. Fix the vulnerable RevSlider plugin in these themes by installing this patch: Patch for Revolution Slider. Envato released a list of possible affected themes: List of Potentially Affected Themes
You are running a public website with a CMS that will have problems from time to time. Best is to keep up with the security updates in both the CMS platform as for the plugins, this should reduce the risk somewhat.
Another option is to run a static build from your WordPress website instead of a live (possibly vulnerable) one. There is a plugin that can do this: Really Static
You could also ask yourself if you really need a dynamic website. If you update content constantly you do but if you only update your website every few months consider a static webpage it saves you a lot of trouble.