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:
- Authentication Compromise (stolen session cookies + compromised credentials) and
- 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.