Restore From Backup, Then Find How They Got in

Expert professional cleaning a hacked site.

I remember sitting in my home office at 3:00 AM, staring at a terminal screen while the blue light burned my eyes, trying to figure out why a client’s site was redirecting every single visitor to a gambling portal in Eastern Europe. Most people think cleaning a hacked site requires some kind of digital wizardry or a high-priced cybersecurity firm that charges by the minute. They think it’s a sophisticated, targeted strike by a nation-state actor. It isn’t. Usually, it’s just a lazy, unpatched plugin or a directory with permissions set so wide a toddler could walk through them.

I’m not going to sell you on expensive, proprietary tools or complex forensic software that you don’t need. My goal here is to give you the practical, unvarnished truth about how to actually scrub the filth out of your file system and stop the bleeding. We are going to talk about the boring, manual work—the stuff that actually works—so you can get your site back online without paying for capacity you aren’t using or falling victim to the same hole next week.

Identifying Malicious Code in the Boring Messy Files

Identifying Malicious Code in the Boring Messy Files

When you finally get into the file manager or SSH into the server, don’t expect to see a file named `virus.exe`. That’s not how this works. Instead, you’re looking for things that look slightly off. I always start by looking at the file modification timestamps. If you haven’t touched your theme files in six months, but suddenly fifty files in `/wp-includes/` show a timestamp from three hours ago, you’ve found your problem. This is the core of identifying malicious code: it’s usually hiding in plain sight, disguised as a legitimate core file or tucked away in a directory that should be empty.

You’ll often find long, nonsensical strings of characters—what we call obfuscated code—mashed into the top of a standard PHP file. It looks like someone spilled alphabet soup over your configuration. During a server-side infection cleanup, I’ve learned to look for functions like `eval()`, `base64_decode()`, or `gzinflate()`. When these are used in a way that doesn’t make sense for your specific setup, they are almost certainly trying to execute a payload. It’s messy, it’s tedious, and it’s exactly why you need to keep your file permissions tight.

The Real Malware Removal Process for Tired Sysadmins

The Real Malware Removal Process for Tired Sysadmins

Look, I’ve been paged at 3:00 AM for this more times than I care to admit, and the biggest mistake people make is trying to play whack-a-mole with individual files. You delete one suspicious script, and ten minutes later, another one pops up in a different directory. That’s because you haven’t actually completed a proper malware removal process; you’ve just trimmed the weeds while leaving the roots intact. If you aren’t doing a full server-side infection cleanup, you’re just wasting your time and your sleep.

The only way to do this right without losing your mind is to go back to a known clean state. If you have a backup from before the breach—and I mean a tested backup, not just a zip file sitting in a folder—use it. Wipe the directory, reinstall the core files, and then carefully migrate your database and media. It’s tedious, but it’s the only way to ensure you aren’t just moving the infection from one folder to another. Once the dust settles, your next priority isn’t just getting back online; it’s wordpress security hardening so you don’t end up right back here next week.

The Post-Cleanup Checklist: Because Getting Hit Once is a Warning, Not a Cure

  • Stop looking for the “virus” and start looking for the hole. If you clean the files but don’t patch the outdated plugin or the weak admin password that let them in, you’re just wasting your Saturday cleaning the same mess again next week.
  • Audit your database, not just your files. I’ve seen plenty of people scrub their wp-content folder clean only to have the site redirect to a gambling site because a malicious script was tucked away in a single row in the wp_options table.
  • Force a global password reset for every single user on the site. Don’t just change yours. If they scraped your user list, they have the targets; make them work for it by forcing everyone—including the “subscriber” accounts you forgot existed—to reset.
  • Check your cron jobs and scheduled tasks. Hackers love to hide a little piece of logic in your server’s task scheduler that reaches out, grabs a fresh payload, and re-infects your clean files while you’re sleeping.
  • Verify your backups actually work before you celebrate. There is nothing more demoralizing than thinking you’ve secured the site, only to realize your “automated” backup system has been backing up empty, corrupted files for the last three months.

The Bottom Line

Stop looking for a digital mastermind; most hacks are just the result of a neglected plugin or a directory with permissions set way too loosely.

Cleaning the files is only half the battle—if you don’t find the entry point, you’re just resetting the timer until the next infection.

A clean site is useless without a tested backup, so stop assuming your automated cron job is actually saving anything useful.

The Cleanup is Only Half the Battle

The Cleanup is Only Half the Battle.

Look, cleaning the site is just the triage phase. You’ve scrubbed the malicious scripts, replaced the corrupted core files, and hopefully found that one rogue plugin that acted as the front door for the attacker. But if you just walk away now, you’re essentially leaving your front door unlocked and hoping for the best. You have to verify your backups, tighten your file permissions, and—this is the part everyone skips—actually test your restoration process. If you haven’t checked your backups lately, you don’t actually have backups; you just have a false sense of security that will disappear the next time things go sideways.

Getting hacked feels like a massive setback, but try not to let it derail you. In my experience, these incidents are usually just expensive lessons in digital hygiene. Don’t view this as a failure of your intelligence, but as a signal that your current systems have outgrown their setup. Use this momentum to build something more resilient. Set up your monitoring, automate your updates, and start treating your site like the critical infrastructure it is. It’s not about being unhackable—nothing is—it’s about being too much of a headache to bother with and having the preparedness to bounce back before the damage becomes permanent.

Frequently Asked Questions

How do I know if the hacker is still in my system after I've deleted the suspicious files?

If you think you’re clean but you aren’t, you’re probably just playing whack-a-mole. Check your file integrity against a known good backup, but more importantly, watch your outbound traffic and cron jobs. If you see weird spikes in CPU or unexpected scripts running at 3 AM, they’re still there. They’ve likely tucked a backdoor into a legitimate core file or a plugin you haven’t touched in months. Don’t trust a “clean” scan blindly.

Is it actually worth trying to clean the existing files, or should I just wipe the server and restore from a clean backup?

If you have a verified, clean backup from before the infection, wipe the server. Period. Don’t waste your weekend playing detective with a thousand messy files, hoping you caught every single backdoor. Hackers love hiding tiny, one-line scripts in deep directories that you’ll almost certainly miss. If you can’t trust the file system, don’t try to patch it. Nuke it, restore the clean version, and then fix the vulnerability that let them in.

What's the fastest way to check if my database has been injected with malicious scripts alongside the file changes?

Don’t waste time scanning every single row manually. The fastest way is to search for common injection patterns—like “, `eval(`, or `base64_decode`—directly in your database using a tool like phpMyAdmin or a CLI command. If you’re using WordPress, check your `wp_options` and `wp_posts` tables first. That’s where the junk usually hides. If you find a weird string of gibberish where a simple text description should be, you’ve found your culprit.

About Otieno Mbatha

Most hosting problems are not exotic. They are an expired certificate, a full disk, or a backup nobody tested. I write about the boring things because the boring things are what break.