A week of security logs from a WordPress site reveals four distinct attack patterns, each using a different technique, each trying to stay inconspicuous in a different way. One of them looked almost exactly like a legitimate search engine crawler. If you only glanced at the user-agent strings, you might have assumed it was Google doing its job.
It was not.
Pattern one: Technology fingerprinting across multiple stacks
The first pattern was not WordPress-specific at all, which is itself the point.
Three requests arrived in rapid succession from IPs on the same network block, all associated with an internet census organisation: a network that systematically scans the entire public internet to map what technology is running where. The requests covered an unusual range of targets simultaneously.
Some were WordPress-adjacent: readme files inside WordPress plugin directories. These reveal which plugins are installed and, critically, their version numbers. An attacker who knows you are running version 2.1 of a plugin with a known vulnerability in version 2.3 and below has found a potential entry point.
Others were entirely unrelated to WordPress: paths associated with Java web applications, a .cc file extension used by older ColdFusion applications, a Sitecore CMS path, a Telerik ASP.NET component endpoint, and an administrative console path.
The scanner was not assuming your stack. It was checking all of them at once. The response codes tell it which technologies are present and which are not. A 404 means that stack is absent. A 200 or 403 means something is there worth investigating further.
What this means for plugin management
Every WordPress plugin ships with a readme.txt file inside its directory. That file contains the plugin name, version, and changelog. Scanners request this file specifically because it is a reliable, structured source of version information.
A plugin you installed two years ago and stopped using is still there. Its readme file is still readable. If that version has a known vulnerability, the scanner now has a reason to probe further.
Removing unused plugins does not just reduce your attack surface in the abstract. It removes concrete, structured evidence that a vulnerable version of that plugin ever existed on your server.
Pattern two: Targeting a known vulnerable file uploader
The second pattern appeared three times across the week, from two different IPs using the same distinctive client signature. The user-agent string itself is flagged as malicious by security tools, so each request was blocked immediately.
The target was consistent across all three appearances: a file upload plugin that has a documented remote code execution vulnerability in older versions. The scanner was checking three different paths where that plugin’s files might be located, because different WordPress themes and custom configurations place plugin assets in different directories.
The technique is methodical. If path one returns a 404, try path two. If path two returns a 404, try path three. A 200 response on any of them confirms the plugin is present and the system is worth attacking further.
This pattern illustrates something worth understanding about how scanners work: they account for variation. They do not assume files are in the default location. They check the default location, the common alternatives, and the custom placements that different development teams use.
Pattern three: The one that looked like Google
This is the most instructive pattern in the week’s logs, and the one most likely to be misread by someone doing a quick review.
A single IP made a large number of requests in a short window. The user-agent strings on those requests identified the sender as Googlebot, Baiduspider, DeepSeekBot, YandexBot, and xAI’s search crawler, sometimes switching between them across consecutive requests.
Mixed into those requests were paths you would expect from a legitimate crawler: the sitemap, the blog index, individual posts, case study pages, comment feeds, a WordPress REST API endpoint.
Also in those requests, submitted with the same timing and from the same IP, were these paths:
/firebase.json/firebase-adminsdk.json/serviceAccountKey.json/credentials.json/keys.json/web.config
These are credential and configuration files. firebase-adminsdk.json and serviceAccountKey.json are Firebase service account keys: files that grant administrative access to a Firebase project, including its database, authentication system, and cloud storage. credentials.json and keys.json are common names for API credential files across multiple platforms. web.config is the IIS web server configuration file, which can contain database connection strings and application secrets.
None of these have any reason to be publicly accessible. But the scanner checks for them on every site it reaches, hidden inside what otherwise looks like routine crawler activity.
The tell
Legitimate search engine crawlers identify themselves honestly and can be verified. Google publishes the IP ranges its crawlers operate from. A request claiming to be Googlebot from an IP that does not belong to Google is not Googlebot.
Legitimate crawlers also do not request credential files. No search engine has any reason to request /firebase-adminsdk.json. Its presence in a crawl session alongside legitimate-looking requests is not a coincidence. It is the credential hunt using the cover of crawl traffic to avoid pattern-based detection.
The WordPress REST API probe in the same session was also deliberate. The endpoint /wp-json/wp/v2/pages/8 was checking whether unauthenticated access to page content through the REST API returns data that should be restricted.
Pattern four: Rotating user-agents on a PHP diagnostic sweep
The fourth pattern has appeared in previous logs from this site and repeated again this week. The same IP from the Netherlands ran a sweep of PHP diagnostic file variants across a subdomain, rotating between Windows, macOS, and Linux browser user-agent strings on each request.
The browser version in every rotating user-agent was Chrome 91: a release from 2021 that no real user runs in 2026. The rotation is designed to avoid fingerprint-based blocking. The outdated version is the tell.
Every request was blocked by banned URL rules before reaching the application.
The pattern connecting all four
Four different techniques, four different goals, but the same underlying logic: reduce the chance of detection by blending in.
The internet census scanner blends in by mixing WordPress targets with non-WordPress ones, making the traffic look like general internet mapping rather than targeted probing. The file uploader scanner blends in by using a common client signature across multiple paths, looking like routine software rather than targeted scanning. The spoofed crawler blends in by surrounding credential hunts with legitimate-looking crawl requests. The rotating user-agent scanner blends in by mimicking a real browser, just imperfectly.
Understanding the disguise is as important as understanding the technique. Security logs are not useful if the reader assumes that anything resembling normal traffic is normal traffic.
What these patterns change about defense
The credential file requests in pattern three reinforce a point made in the previous post in this series: Firebase service account keys, application credential files, and web server configuration files should never be inside the public web root. The scanner checks because sometimes they are. The defense is not a firewall rule alone. It is ensuring the files are not there to be found in the first place.
For plugin fingerprinting: disable readme file access for plugins you do not want publicly catalogued, and remove plugins you no longer use. The version information in those files has no value to legitimate users and material value to scanners.
For spoofed crawlers: verify bot identity at the network layer rather than trusting user-agent strings. Legitimate crawlers can be confirmed by reverse DNS lookup against their published IP ranges. A request claiming to be Googlebot from an unverified IP should be treated as an unverified request.
This is the fourth post in the website security series. The next post covers webshell and malware verification scans: what happens when attackers are not trying to break in but checking whether someone else already has.
More information on security
