Your site starts publishing posts you never wrote. Casino links, gambling pages, content nobody on your team touched. You clean it up and assume that's the end of it. Then visitors start telling you they can't reach the site at all. They land on a page asking them to prove they're human, and that page tells them to open Windows Terminal and paste in a command.
That was the call we got in July 2026.
We ran a MalCare scan on 20 July and it found seven infected files. The filenames had numbers in them that turned out to be dates, so we could read exactly when each file was written. 17 July at 20:30, then a second batch on 18 July at 07:37. Two waves, eleven hours apart. The attack was three days old.
We deleted all seven. The redirects kept happening.
Deleting them was the right call, incidentally. Running a scan and removing what it finds is what most people in this work would do first, and for most infections it's the entire job. This one was the exception.
The database told us why. Sitting in the user data were administrator records belonging to five accounts that no longer existed, every one of them dated March 2025. Sixteen months before the attack we'd been hired to fix. The site had never been cleaned before, so this wasn't left over from an old repair.
We'd been treating this as a three-day-old problem. It wasn't.
Most guides assume the day you noticed is close to the day it started, so they send you straight to cleanup. But cleanup destroys the evidence that tells you how far back this goes. And that one answer decides which backups you can trust, whether your other sites are affected, and whether your cleanup holds.
Work that out first.
How do you know your site is actually hacked?
Symptoms fall into two groups, and the split matters more than the list. There's what you see from inside your dashboard, and there's what everyone else sees. On a hacked site those are often completely different.
What you see from the inside
Posts or pages you never wrote, often about casinos, gambling or pharmacies
Users in your admin list you don't recognise
Your password stops working, and the reset email never arrives
Files with modification dates that make no sense
Plugins or theme files switched off, changed or missing
The site running slowly, or unexplained spikes in your hosting dashboard
An email from your host about malicious activity, or your account suspended
What everyone else sees
Visitors sent to spam, dating or phishing sites
A page asking visitors to prove they're human, which then tells them to run a command on their own computer
Pop-ups, injected ads or fake update prompts
A red browser warning reading "Deceptive site ahead"
Contact forms or checkout quietly breaking
A "This site may be hacked" label under your listings in Google
Traffic collapsing overnight, or surging from countries you don't serve, aimed at pages that don't exist
Customers getting spam sent from your own domain
The version everybody pictures, a homepage replaced with "Hacked by" and somebody's name, is now one of the rarest. Attacks that announce themselves get cleaned up. The ones that pay stay quiet.
That quiet is deliberate. Malware is often written to show itself only to certain visitors, based on their device, whether they're logged in, or where they came from. On our client's site only desktop visitors were redirected, so anyone on a phone saw a perfectly normal website, and so did anyone logged into WordPress. The person best placed to notice was the one person guaranteed not to.
So checking properly means leaving your own view. Open the site logged out, in a private window, on both a phone and a desktop. Then search Google for site:yourdomain.com and read what comes back, because spam pages show up there long before they show up anywhere you'd normally look.
If visitors are being told to open Windows Terminal, or to copy something and paste it into a box, that's a specific attack with its own playbook: ClickFix attack guide
What should you not do in the first hour?
Most of these are things a reasonable person would do, and some are recommended elsewhere. Each one costs you information you can't get back.
Do not update or reinstall everything first. This is the most common advice you'll find, and as a first move it's wrong. Replacing core files and running updates overwrites the dates that tell you when the site was changed and in what order.
Do not delete suspicious files as you find them. A bad file tells you when it was written and what was written alongside it. On our client's site the filenames carried the timing of the whole attack, and deleting them on sight would have taken that with them.
Do not stop at the first thing you find. Finding something feels like finding the problem. Serious attacks come in layers, and the visible layer is the one they can afford to lose.
Do not restore a backup yet. Restoring writes over the only copy of the evidence you have, and a backup taken after the infection puts the problem straight back.
Do not change passwords from the hacked site. Right instinct, wrong order. If the back door still works, the new passwords go straight to the attacker.
Do not ask Google to review the site. Asked while the site is still infected, the review gets rejected and leaves you worse off than before.
Each of these feels like progress and quietly removes information. The first hour isn't for fixing. It's for recording.
What to save before you touch anything
What you're making here isn't a backup. A backup exists so you can put the site back. This copy exists so you can read it, so make it, put it somewhere you won't touch, and never restore from it.
Save all of this before anything changes:
A full copy of the site files, with their dates intact
A copy of the database
Server access logs from your host, and the activity log from your security plugin if you run one
Screenshots of what visitors are seeing
Your Google Search Console security notices
Your current user list and hosting usage graphs
If you have an activity log, export it before anything else. It's the only record that says who did what and when, and it's the fastest route to the questions in the next section.
One detail decides whether any of this is useful. File dates are the backbone of the whole investigation and they're very easy to wipe out, because downloading files through some FTP programs resets every date to the time of the download. Zip the files on the server instead, using your host's file manager, and download the zip. The zip keeps the dates.
Then close the site to the public through your host or firewall rather than a maintenance plugin, since anything that writes files changes what you're trying to read. Change passwords last, from a device you trust: WordPress admin, hosting panel, FTP, database, and any email account tied to recovery.
How long has your site been hacked?
This is the question everything else depends on, and almost nobody asks it. Most advice assumes the hack is recent, because that's when you noticed. Noticing isn't the same as starting.
Security people call the gap dwell time: the stretch between someone getting in and anyone finding out. It's normally measured in months rather than days. That gap decides which backups are old enough to even consider, and whether the problem had time to spread. If you hold customer data, it also decides how long that data has been within reach.
Four places give you the answer, roughly in order of how much you can trust them.
The oldest changed file that shouldn't have changed. Sort by date and look at the far end, not the recent end. The recent end shows you the attack. The far end shows you the arrival.
User records in the database. Check the user table and the user settings table separately, because the two don't always agree, and where they disagree is itself information.
Scheduled tasks. Each one has a date and a job, and neither is hidden from you.
How far back your server logs go. Not evidence by itself, but it tells you how far back evidence can possibly exist.
On our client's site it was the second of these that changed the picture. Two things are worth being careful about there, because it's tempting to overstate both. The evidence proves the site carried a compromise for sixteen months with nobody noticing. It doesn't prove somebody was working inside it that whole time, and none of the five accounts showed any activity after that first burst. It also doesn't prove that whoever arrived in March 2025 is whoever attacked in July 2026, since lists of hacked sites get traded.
↗️
Need Help Cleaning Your Site?
Our security experts remove malware, fix vulnerabilities, and protect your site.
Get Free Security Check
What you find is the oldest evidence that survived, which isn't the same as the oldest event. Treat every date you recover as a ceiling, not a floor.
Is it one site, or your whole hosting account?
Owners ask whether their website was hacked. The more useful question is whether their hosting account was, because those have different answers and only one of them is fixed by cleaning a website.
Sites sharing one hosting account often share one set of files. Something that reaches the least important site reaches the most important one, and the old staging copy nobody has logged into in a year is the usual way in. Clean the site you care about and it gets reinfected from next door.
So look at every other WordPress install on the account, including staging copies, old subdomains and anything sitting in a folder you'd forgotten about. Then the hosting account's own user list, any FTP accounts you didn't create, and any scheduled tasks running at account level rather than inside WordPress.
The timeline feeds straight into this. Something three days old has had little chance to travel, while something sixteen months old has had every chance in the world.
Which of your backups are safe to restore?
Every guide tells you to restore a clean backup. Almost none tell you how to know which one is clean, and that's the whole difficulty.
A backup doesn't come with a label. What you have is a set of copies and a date on each, and the only thing that makes one worth considering is being older than the oldest evidence you found. Older than the evidence, not older than the day you noticed. Those two dates can be a year apart. Even then it's a candidate rather than a clean copy, and it needs checking somewhere that isn't the live site.
Then there's the problem most people hit. Many hosts keep daily backups for thirty days, and backup plugins often keep less. Set that against a compromise that started in March 2025 and the whole archive is useless, because every copy in it came from an already infected site.
Worth fixing for next time while it's fresh in your mind: when you choose a backup plugin, retention length is the setting that decides whether a backup can help you, not the feature list. Thirty days isn't much cover against something you might not notice for a year.
If nothing is old enough, restoring isn't the route. The choice becomes cleaning the current site properly, or rebuilding it and moving your content across deliberately rather than all at once. And restoring an old backup throws away everything since, including the real work. Orders, posts, form submissions, customer accounts. Sometimes that's the right trade, but it should be a decision rather than a surprise.
Where do you actually look?
Order matters more than coverage here, because the useful question is rarely where a file sits. It's why it's sitting there.
Start with files that can run code in places that should hold none. Your media library holds images and documents, and a .php file in the uploads folder has no reason to be there. Then compare rather than inspect: WordPress core, plugins and themes all have clean originals you can download, and a file that differs from its published version is a fact rather than a hunch. Then the database, looking for entries that are recent, entries that are huge, and entries holding script tags or scrambled blocks where there should be plain settings. Then scheduled tasks, because a hidden task that rebuilds deleted files is why some sites appear to reinfect themselves overnight.
Two things will save you time here. Searching for functions like eval or base64_decode and treating every hit as malicious gives you a long list and the wrong conclusion, because normal plugins use them constantly. And the database will hand you convincing false alarms, since content produced by page builders and embedded media can look alarming in raw form while being completely ordinary. On our client's site, a good part of the work was ruling that material out rather than finding more of it. Deleting it would have broken working pages and left the real problem sitting where it was.
You're looking for things that don't fit their surroundings.
Can you work out how they got in?
Every guide implies the way in is findable. Often it isn't, and guides that skip that leave people either inventing an answer or assuming they failed.
What you can genuinely check is short. Plugin and theme versions against published vulnerability records, to see whether anything had a known hole open at the time. Server logs around the earliest activity you confirmed, looking for repeated hits on login pages or successful requests to files that shouldn't be reachable. Upload paths, for anything that arrived through a form. And whether the hosting account itself was reached, which would make the site a symptom rather than the door.
Then the limits. Logs don't last. Most hosts keep weeks rather than years, so something dated sixteen months back has no surviving log evidence and no amount of effort brings it back.
Data from a firewall or security plugin installed after the infection shows you attacks that were blocked, not the one that worked. Say that plainly to yourself, because a dashboard full of blocked login attempts looks exactly like proof and isn't. Bots hammer login pages on every WordPress site continuously, so pointing at that and calling it the cause explains nothing that wouldn't be true anyway.
The reverse is the useful part. Had that firewall and its logging been running before the compromise, the record would still exist and this section would be a lot shorter. A security plugin doing login protection, two-factor and activity logging isn't there to find malware after the fact. It's there so a question like this one still has an answer.
When the answer isn't there, you close every path you can't rule out, because you can't close the one you never found. Patch everything, change everything, treat the account as reached rather than just the site, and remove software you aren't using.
How do you confirm the site is really clean?
Cleaning and confirming are different jobs, and the second gets skipped because the site looks fine by then. Looking fine is what the attack was built to do.
A scanner compares your site against patterns of things already known to be bad. That's useful, and it's why scanning is the right first move. It also can't answer the question people ask of it, because a report showing nothing means nothing matched, which isn't the same as nothing being there. Code written to avoid being recognised, files disguised as part of a normal plugin, and back doors that hide themselves from your plugin list are all built to survive exactly that comparison: a real incident where the visible infection was not the whole story
So confirmation is a period rather than a moment. Give it days rather than hours, because plenty of malware is written to stay quiet after a cleanup and come back once attention moves on. Something that reappears on day four was never removed on day one.
During that time, check from outside your own view, for the same reason the symptoms were invisible from inside it. Load the site logged out on more than one device, run the site: search again and watch whether spam pages drop out of Google, and watch your server logs for requests to pages that shouldn't exist, because that's somebody testing whether their way back still works. Then check that what you fixed has stayed fixed: the user list, the uploads folder, scheduled tasks, the files you replaced. File integrity monitoring and alerts on new admin accounts do this watching for you, which matters because attention fades and the malware is written to wait for exactly that.
Anything reappearing there means something was missed rather than something new arriving. That's what reinfection almost always is: not a fresh break-in, but the one piece that survived doing exactly what it was installed to do. Hidden web shells and why they survive cleanup.
If Google flagged your site, the notice is in Search Console under Security Issues, and it often lists example URLs worth reading, because they sometimes point at parts of the site you hadn't reached. Ask for the review after the work, not during it. The warning usually clears within days of a successful review, while spam pages already in the index take longer, since those clear as Google recrawls. Getting rankings back is a separate matter with its own timeline rankings impact.
A quiet week is good evidence, though it isn't proof.
When should you bring in help?
Plenty of hacked sites can be handled by their owners. The honest signs that yours isn't one of them:
It has been cleaned before and the problem came back
The compromise is old enough that the evidence has outlived the logs
More than one site sits on the account, or the account itself looks reached
The database has been changed and you can't tell which changes were yours
Google has flagged the site and your business depends on that traffic
Customer data was within reach, and somebody needs to establish for how long
You have cleaned it and can't tell whether it worked
None of these are really about technical difficulty. Each one is a question about something you can't see, and the cost of a wrong answer is another compromise on a site you've already told everyone is fixed.
If all of this sounds like a lot of work to do before you're allowed to fix anything, that's a fair objection. It isn't a separate project. Copying the files, exporting the logs and reading four dates is an hour, and it's an hour that decides whether the cleanup after it is worth doing at all.
On this job we quoted for what the symptoms suggested, and the real work was considerably larger, because the visible attack was three days old and the compromise was not. Anyone quoting confidently before investigating is quoting on the same assumption we did.
The redirects on that site stopped the day we deleted seven files. That was never the question. The question was what had been sitting in the database since March 2025, and no scan was ever going to ask it.
If you need someone to fix them in the right order. That's the work we do, contact we us.