The Real Attack Vector Responsible for 60% of Hacked WordPress Sites in 2023

Introduction 


WordPress Security is full of myths that have no basis in reality or data.

A particularly pervasive one is the unsubstantiated claim that “95% of WordPress hacks are due to outdated plugins or themes.

If that’s the case, then during times of no current zero-day exploits, or the lack of major vulnerable plugins and themes, no sites should be getting hacked, right?

Well, our data says otherwise.

Much of what we’re going to say here is going against popular “opinions”.

 

We’ll show you, based on 851+ billion log entries (851,023,697,544 to be exact), that WordPress websites are getting hacked at scale through authentication credential compromises and NOT through plugin or theme vulnerabilities.

 

How we collect data & why it matters

 

As of January 1, 2023, we were watching 4,320,455 websites with our Freemium Plan (to be renamed “Watching” soon). That started growing significantly throughout 2023 as we were making various strategic partnerships.

 

Collectively, one of our server clusters receives streams of 20 million log lines per second for analysis and cataloging – and we utilize multiple clusters.

 

We monitor file changes (additions, modifications, removals), log files (access logs, etc.), database changes, system processes and all outgoing traffic from a server.

 

All of these events are captured at the operating system level, so it can’t be tampered with, unlike plugin-based Malware Scanning.

 

It’s crucial to mention that we collect raw, non-aggregated data (logs).

This allows us to perform root cause analysis AFTER a website was found to be hacked and determine precisely WHAT the initial entry point was.

Since we collect (large amounts) of non-aggregated data, we’re able to find answers to questions that are impossible to foresee ahead of time.

Our root cause analysis is fundamentally different to what popular plugin-based services are capable of doing.They simply don’t have access to all of the “real” data!

Plugins only collect pre-determined metrics, for example, the number of observed failed login attempts or the observed amount of attempted SQL-Injection.

Collecting pre-aggregated metrics is not useless, but it significantly limits insights into what’s really happening.

If all you’re measuring is “Blocked Attacks” you’ll not be able to correctly answer retrospective questions such as “How are WordPress sites getting hacked” because you’re not even collecting the necessary data points.

To give a hyperbolic example:

Assume that a plugin only measures the number of times it sees suspicious shell commands (RCE) in any request parameter.

This would lead you to believe that 100% of WordPress sites are hacked through remote code execution, since it’s the only data that you’re measuring.

For this reason, various vendors usually make bold claims that 95% of WordPress sites are hacked through plugin vulnerability. They simply don’t collect the proper data points.

Furthermore, without OS-level root-cause analysis, it’s impossible to know if an attempted exploit would even lead to a successful hack.

There are some attacks that are reported as blocked by plugin firewalls that are not even WordPress specific and would have never been successful. This skews the data and the gathered insights.

Whenever you hear claims such as “X Billion Attacks blocked last month”, remember that a large amount of them would have never succeeded anyway.

 

For this research, when our system found an infected website, it worked backwards to find the initial point of entry. This is fundamentally different from methods used by others, and is actually superior. This strategy allows us to accurately collect the data points required for this research. 

 

The three types of WordPress Hacks

 

There are three statistically relevant types of WordPress hacks that can be summarized into two overarching categories.

 

In our data, we can clearly distinguish between:

 

  1. Authentication Compromise (stolen session cookies + compromised credentials) and
  2. Exploited Plugin/Theme/Core Vulnerabilities

 

Furthermore, we can detect the difference between compromised credentials (username/password) and stolen session/authentication cookie.

 

We’ll briefly explain each type below.

 

Stolen Session Cookies (Authentication compromise)

 

An attacker directly steals the WordPress authentication/session cookies after a user logged in. This can happen at the local device. The user might have a virus/infostealer on their local device that steals the authentication cookie.


This is also commonly referred to as a “Pass the cookie” attack and is particularly nasty since it bypasses all types of authentication protection such as multi factor authentication or passkeys without requiring the username or user ID.

 

If we see that stolen session cookies were used, our analyzers backtrack to see if anyone has logged in with that user in the past 48 hours and then also the last 2 weeks (“Remember me” was checked, which does not expire a session cookie for 2 weeks, 14 days).

 

Our research has seen instances where after the hackers have a valid session cookie, they will automatically refresh the session cookie by temporarily accessing the site, requiring authentication, within that expiration period, thus extending the expiration of the session cookie for another 48 hour or 14 days.

 

This backtracking consumes huge amounts of resources, but is necessary to get to the facts. Facts are all we’re interested in, not bold, baseless claims. 😉

 

 

The above access log shows an attacker probing the validity of a stolen session cookie.

 

The “green” IP address’s only request was straight to the user-edit.php file, without any previous attempts at authentication. It receives a 302 response and then gets redirected to the /wp-login.php file. Furthermore, the user agent (highlighted in yellow) is an extremely outdated Chrome version.

It’s safe to assume an attacker was using an expired cookie, since they were redirected to the wp-login.php page. It’s believed hackers are smart enough not to try going directly to a file they know requires authentication. They are professionals at their craft.

 

Compromised Username/Password Credentials (Authentication compromise)

 

Passwords are either guessed/brute-forced or stolen.

 

The way we determine stolen username and password versus brute-force (guessed), is historical data, when available.

 

When an attempt is made to log in, or many attempts, it’s typically from a variety of IP addresses. We might see a cluster of 2 to 3 attempts from the same IP address, but that is rare.

 

A typical brute-force or dictionary attack will try a large variety of usernames and passwords. Sometimes there’s evidence of user enumeration to see which ones are valid. Then they try their myriad of passwords with those usernames to see if any of them work. If one works, we see the successful login in the logs. 

The items highlighted in yellow are the Chrome version as a substring of the user-agent. The items in green are the IP addresses. User-agent is important as you can see from this actual snippet at the time of these log entries, the current version of Chrome was 119. These are severely outdated and even though the user-agent is something that can be spoofed, quite often it’s the result of an old tool the hackers are using. So this can be accurately blocked.

 

In the case of a dictionary attack, we’ll see something similar to the above image – Many failed logins, then suddenly a successful login will occur:

 

Hackers know about Fail2ban so they use a distributed attack from many, many different IP addresses. We’ve seen some attacks that, over the course of 48 hours, never once use the same IP address in over 1,000 attacks.

 

Stolen credentials could be the result of a password stealing trojan (an info-stealer) on a local device used to log in to the WordPress dashboard, or the user uses the same email address and password across many sites and one of them was compromised in a large-scale breach.

 

Since we also monitor the database, we know the email addresses of the WordPress users, and we check those against haveibeenpwned.com’s database. Frequently we see an admin’s email address has been breached (listed in haveibeenpwned.com) and then further investigation proves that the user has the same password in many online accounts. A big “no-no”.

 

Plugin, Theme & Core vulnerabilities

 

We always know all the installed plugins & themes that are installed on a website, and we track this information over time & correlate it with vulnerability databases such as the WordFence Threat Intelligence API.

 

We are able to see when plugins were first announced to have vulnerabilities, and then watch the traffic searching for those plugins from what we consider to be suspicious sources.

 

By further analyzing the logs we can see during the time a plugin/theme/core vulnerability was first announced and suspicious traffic to that plugin/theme/core across all the sites being watched and that either files were changed/added or suspicious data in the database was added.

 

Meaning, we can clearly tie the presence of a vulnerability to a potential exploit of the vulnerability.

 

Collected Data points

 

In our data, summarized below, we break out the numbers for successful breaches due to stolen session cookies, successful brute-force attacks and attacks on plugins and themes and WordPress core.

It’s important to remember that the failed attempts for all categories are orders of magnitude higher than the successful attempts. We already touched on this topic in the “How we collect data” section.

 

We will show the following data points:

 

  • Number of websites watched at the start of each month: Self explanatory.
    • Number of websites watched at the end of each month: Self explanatory.
    • New infections detected with newly watched sites: Of the new sites added to our services, this number were already infected.
  • New infections detected on all watched sites: The above number plus the sites under our Watching service already. Remember, the freemium Watching Plan doesn’t provide protection.
  • Monthly number of successful attempts to use stolen session cookies: These used session cookies successfully, but provided other signs of malicious activity, such as file modifications or database changes.
  • Monthly number of successful attempts to use stolen login credentials: Either a previous brute force attempt was successful, or the hackers had stolen the login credentials some other way (local virus, easily guessed, etc.)
    • Monthly number of successful authentication compromises: This is the total number of combined stolen session cookies and stolen login credentials.
  • Monthly new core/plugin/theme vulnerabilities announced: Data gathered from Wordfence’s Threat Intelligence Reports.
  • Monthly number of sites exploited due to core/plugin/theme vulnerabilities: Observed traffic to newly announced exploitable plugins/themes/core.

 

Our Findings

 

Below, we’ll talk about the most interesting findings using easy to understand graphics. The raw, month over month data can be obtained at the bottom of the page.

 

Yearly Distribution of Hack Root Causes in 2023

 


 

 

 

 

 

 

 

 

In 2023, the analysis of hacked WordPress sites reveals that Stolen Session Cookies were the predominant root cause, contributing toapproximately 60% of all incidents. This figure significantly exceeds the proportion of hacks due to exploited vulnerabilities, which, contrary to common belief, only account for about half as many incidents.

Within the category of exploited vulnerabilities, the majority of hacks are attributable to vulnerabilities in plugins.

Furthermore, Compromised Login Credentials, though not as prevalent as the other two categories, still represent a notable portion of the total hacks, indicating that traditional methods of unauthorized access remain a significant concern. 

Month over Month Distribution of Hack Root Causes

 

 

 

 

 

 

 

 

 

 

 

The month-over-month data shows that session hijacking is typically the most common hack root cause, except when a zero-day vulnerability is mass-exploited.



The data shows that exploited vulnerabilities have a much higher fluctuation than stolen session cookies. This is because attackers mostly only bother (mass) exploiting the highest critical vulnerabilities, and only if the plugin has a high installation number.

Stolen Session Cookies have less fluctuation. A stolen session cookie has a much higher chance of leading to a successful site takeover and a significantly lower detection. If a cookie is not expired yet (2 days by default, 14 days for “remember me”) the likelihood of “success” is almost 100% since WordPress Core has no protection mechanism against session hijacking.

 

Our research has seen instances where a security plugin reports an admin-level user logging in from a specific IP address, but the plugin enables hackers to spoof the IP address, so the admin login looks legit. It gets reported through the security plugin, but with a spoofed IP address it could look legitimate to the website owner and therefore, allowed.

Furthermore, every WordPress site is theoretically exposed to session hijacking, while at a given point in time, only a fraction of sites are running a vulnerable plugin that might be mass-exploited.

 

 

Month over Month data

 

 

January:

 

Number of websites watched at the start of the month: 4,320,455 websites

Number of websites watched at the end of the month: 4,877,978

New infected sites detected with newly watched sites: 73,477

New infections detected on all watched sites: 102,437

Monthly number of successful attempts to use stolen session cookies: 67,731

Monthly number of successful attempts to use stolen login credentials: 21,390

Monthly number of successful authentication compromises: 89,121 (87% of total)

Monthly new plugin vulnerabilities published: 453

Monthly number of sites exploited due to core/plugin/theme vulnerabilities: 13,316

 

A major vulnerability in January was in YITH WooCommerce Giftcards Premium, which was actually disclosed in November 2022 but still being exploited in January 2023.

 

 

February:

 

Number of websites watched at the start of the month: 4,877,978 sites

Number of websites watched at the end of the month: 5,091,021 sites

New infected sites detected on newly watched sites: 6,391

New infections detected on all watched sites: 66,183

Monthly number of successful attempts to use stolen session cookies: 40,728

Monthly number of successful attempts to use stolen login credentials: 11,127

Monthly number of successful authentication compromises: 51,855 (78.35% of total)

Monthly new plugin vulnerabilities published: 457

Monthly number of sites exploited due to core/plugin/theme vulnerabilities: 14,328

 

 

March:

 

Number of websites watched at the start of the month: 5,091,021 sites

Number of websites watched at the end of the month: 5,512,386 sites

New infected sites detected on newly watched sites: 12,935

New infections detected on all watched sites: 77,173

Monthly number of successful attempts to use stolen session cookies: 31,916

Monthly number of successful attempts to use stolen login credentials: 7,882

Monthly number of successful authentication compromises: 39,798 (51.56% of total)

Monthly new plugin vulnerabilities published: 392

Monthly number of sites exploited due to plugin vulnerabilities: 37,375

 

 

April:

 

Number of websites watched at the start of the month: 5,512,386 sites

Number of websites watched at the end of the month: 5,822,311 sites

New infected sites detected on newly watched sites: 6,818

New infections detected on all watched sites: 221,247

Monthly number of successful attempts to use stolen session cookies: 73,652

Monthly number of successful attempts to use stolen login credentials: 8,877

Monthly number of successful authentication compromises: 82,529 (37.3% of total)

Monthly new core/plugin/theme vulnerabilities published: 410

Monthly number of sites exploited due to core/plugin/theme vulnerabilities: 138,718

 

In April, we saw a big spike in the vulnerability category due to this Elementor vulnerability that was disclosed in the end of March 2023. 

 

 

May:

 

Number of websites watched at the start of the month: 5,822,311 sites

Number of websites watched at the end of the month: 5,923,895 sites

New infected sites detected on newly watched sites: 62,200

New infections detected on all watched sites: 103,178

Monthly number of successful attempts to use stolen session cookies: 67,335

Monthly number of successful attempts to use stolen login credentials: 1,762

Monthly number of successful authentication compromises: 69,097 (66.96% of total)

Monthly new plugin vulnerabilities published: 445

Monthly number of sites exploited due to plugin vulnerabilities: 34,081

 

In May and July, the spike in the vulnerability category did further increase due to this vulnerability in the Essential Elementor Add-ons plugin.

 

 

June:

 

Number of websites watched at the start of the month: 5,923,895 sites

Number of websites watched at the end of the month: 6,233,264 sites

New infected sites detected on newly watched sites: 34,871

New infections detected on all watched sites: 46,074

Monthly number of successful attempts to use stolen session cookies: 13,110

Monthly number of successful attempts to use stolen login credentials: 14,035

Monthly number of successful authentication compromises: 27,145 (58.91% of total)

Monthly new core/plugin/theme vulnerabilities published: 321

Monthly number of sites exploited due to core/plugin/theme vulnerabilities: 18,929

 

June has historically always been a month with very little hacked sites. Yes, hacking has seasonality.

 

 

July:

 

Number of websites watched at the start of the month: 6,233,264 sites

Number of websites watched at the end of the month: 6,290,127 sites

New infected sites detected on newly watched sites: 966

New infections detected on all watched sites: 122,140

Monthly number of successful attempts to use stolen session cookies: 33,110

Monthly number of successful attempts to use stolen login credentials: 16,385

Monthly number of successful authentication compromises: 60,255 (49.33% of total)

Monthly new plugin vulnerabilities published: 288

Monthly number of sites exploited due to plugin vulnerabilities: 61,885

 

 

August:

 

Number of websites watched at the start of the month: 6,290,127 sites

Number of websites watched at the end of the month: 6,502,883 sites

New infected sites detected on newly watched sites: 5,744

New infections detected on all watched sites: 138,620

Monthly number of successful attempts to use stolen session cookies: 105,767

Monthly number of successful attempts to use stolen login credentials: 11,332

Monthly number of successful authentication compromises: 117,099 

Monthly new plugin vulnerabilities published: 267

Monthly number of sites exploited due to plugin vulnerabilities: 21,521

 

 

September:

 

Number of websites watched at the start of the month: 6,502,883 sites

Number of websites watched at the end of the month: 6,907,664 sites

New infected sites detected on newly watched sites: 7,241

New infections detected on all watched sites: 130,112

Monthly number of successful attempts to use stolen session cookies: 71,112

Monthly number of successful attempts to use stolen login credentials: 9,182

Monthly number of successful authentication compromises: 80,294 

Monthly new core/plugin/theme vulnerabilities published: 330

Monthly number of sites exploited due to core/plugin/theme vulnerabilities: 49,818

 

 

October:

 

Number of websites watched at the start of the month:  6,907,664 sites

Number of websites watched at the end of the month: 7,425,138 sites

New infected sites detected on newly watched sites: 13,276

New infections detected on all watched sites: 113,887

Monthly number of successful attempts to use stolen session cookies: 71,656

Monthly number of successful attempts to use stolen login credentials: 10,011

Monthly number of successful authentication compromises: 81,667 

Monthly new core/plugin/theme vulnerabilities published: 479

Monthly number of sites exploited due to core/plugin/theme vulnerabilities: 32,220

 

 

November:

 

Number of websites watched at the start of the month: 7,425,138 sites

Number of websites watched at the end of the month: 7,909,613 sites

New infected sites detected on newly watched sites: 9,541

New infections detected on all watched sites: 177,894

Monthly number of successful attempts to use stolen session cookies: 114,533

Monthly number of successful attempts to use stolen login credentials: 1,739

Monthly number of successful authentication compromises: 116,272 

Monthly new core/plugin/theme vulnerabilities published: 553

Monthly number of sites exploited due to core/plugin/theme vulnerabilities: 61,622

 

 

December:

 

Number of websites watched at the start of the month: 7,909,613 sites

Number of websites watched at the end of the month: 9,499,094 total sites

New infected sites detected on newly watched sites: 97,990

New infections detected on all watched sites: 263,436

Monthly number of successful attempts to use stolen session cookies: 401,397

Monthly number of successful attempts to use stolen login credentials: 17,991

Monthly number of successful authentication compromises: 419,388 

Monthly new core/plugin/theme vulnerabilities published: 176

Monthly number of sites exploited due to core/plugin/theme vulnerabilities: 116,362

Conclusion 

 

So what?

 

What does this data teach you? What can you learn from this?

 

Data analysis for the sake of analyzing data is pointless. Like running a race, you need to know where the finish line is. 

 

Our goal in this data analysis was to see what methods cybercriminals are actually using to infect WordPress websites. However, in answering that question the effectiveness of current strategies at preventing malware infections was discovered. 

 

Obviously the need for early detection is critical. When we onboard a server, a full scan and analysis is performed. This covers the files, the database and all processes for all sites on that server. Over the course of this year (2023) we saw 331,450 infected sites during our onboarding process. A surprising number of them had been infected over 1 week (58,998 – 17.8%), 9.89% (32,780) were infected longer than 2 weeks and 11.32% (37,520) were infected longer than one month. 

 

It appears that the previous methods of early detection were ineffective. Part of our service provides notification to the server/hosting provider of an obvious indication of compromise for a specified IP address. Due to the outgoing traffic being monitored on the network layer, it’s impossible to determine which site on a server is sending the offending traffic so all sites must be investigated. We also track how long it takes for the server to stop with the offending traffic, meaning the infection was remediated or the server was just shut-down or all sites were moved to a different server. 

 

Note: The ranking details of which server/hosting provider was fastest will not be released as our fight is not with server/hosting providers but with hackers.

 

It’s our belief that virtual patching is highly effective, as seen by the low numbers of successful breaches focused on exploiting vulnerabilities in core/plugin/themes. Why would hackers go after a target with a low chance of being successful? They certainly would not risk exposure for a tactic with an extremely low chance of success. Cybercriminals are very intelligent and focused on current strategies. As mentioned above, they already have many strategies in place to avoid being blocked by Fail2Ban.

 

Again, without providing detailed numbers, the three most found successful strategies for preventing infection were:  Patchstack, Wordfence and Imunify360. Those specific details will not be released because we are not here to fight with any of them or to cause any chest beating. They are doing their jobs and quite well enough that hackers have shifted their focus to compromised authentication while waiting for the next zero-day vulnerability.

 

It appears that the competition of the bounty programs between Patchstack and Wordfence is reaping great benefits for the masses.

 

While many services provide virtual patching combined with malware detection/removal, it became apparent their virtual patching was far more efficient than the malware detection services.

 

Readers must realize the importance of virtual patching as a necessary layer in a defense in depth strategy, while also accepting that virtual patching alone is insufficient in the war against cyber crime.

 

The above data proves beyond a reasonable doubt that the hackers have already shifted their focus to compromising authentication credentials, whether that be session cookies or username and passwords. 

 

What can you do?

 

Something as simple as logging out after every admin session can prevent successful session hijacking, but bad habits are hard to break. 2FA and passkeys, like SolidWP offers, provides sufficient protection against compromised username and password, and while that tactic is only a small portion of successful attacks, it remains a critical component in the defense in depth strategy.

 

Always remember to create a new user account for every admin. Yes, you’ll have to delete the account when they’re no longer active, but it makes it much easier to determine who’s session cookie was stolen, or who’s username and password has been compromised.

 

A more all-inclusive service such as Fortress from Snicco nullifies both session hijacking and username/password compromises.

 

Reach out to them to discuss your options.

 

More power is required in order to achieve that peace of mind sought after by website owners.

 

The data not presented here, but apparent to us, is that blocking certain ranges of IP addresses is very efficient at blocking generic attacks. Why would an IP address from GoDaddy want to login to your WordPress site? Seriously, if you have a use-case for that please let me know. What about IP addresses from Bluehost, etc…

 

What about IP addresses from Vultr or Digital Ocean, or… You might have a use-case there if you’re using a WordPress management system to connect to all of your servers, but that can always be placed on an “allowed” list to bypass blocking.

 

Recently, some security plugins have been boasting about blocking millions of IP addresses. Further investigation shows they’re using CrowdStrike’s database. While that might be useful, unless you’re blocking at the network layer, you’re going to be consuming large amounts of server resources to accomplish this. Security plugins cannot block at the network layer.

 

Implementing user-agent blocking is also highly recommended and very efficient. This needs to be expanded more than what 7G provides. A future blog post will show exactly how to accomplish that. It’s easier than you might think.

 

Blocking ranges of IP addresses and strategically blocking user-agents satisfies the need for more generic security and provides that peace of mind. These methods block the traffic before it attacks the application. Blocking IP ranges can block SSH attacks, MySQL attacks (port 3306), SQL injection, cross-site scripting, etc. Not all of these attacks can be blocked, but as hackers are primarily using servers for their attacks, it is highly effective.

 

Keep in mind that our services remediate your malware on our servers. We don’t consume your server resources. Our log analysis is performed on our servers. Our database monitoring is on our servers.