Technology

Cleaning Up Hacked PHP Websites: Backdoors, FTP/SSH Scans and Safe Migration

If your PHP website is hacked, the most dangerous part is usually not the defaced homepage or the visible spam links. The real risk is the hidden backdoor that lets attackers come back anytime they want, even after you “clean” the obvious damage. In our day-to-day work at dchost.com, we regularly help customers recover from compromised PHP sites on shared hosting, VPS and dedicated servers. The pattern is always the same: the first cleanup looks successful, traffic and SEO seem normal again, and then a week later malicious files reappear from nowhere. The cause is almost always an undetected backdoor.

This article walks through a practical, no-drama process to clean hacked PHP websites properly. We will focus on how to detect backdoors, how to scan code over FTP or SSH, and when it is safer to migrate to a fresh hosting account or server instead of trying to patch a badly compromised environment. The steps apply to WordPress, Laravel, custom PHP apps and most other PHP-based systems.

Why Hacked PHP Sites Are Hard to Clean Properly

PHP malware rarely behaves like a single obvious file named “virus.php” sitting in your web root. Attackers usually:

  • Plant multiple small backdoors in different folders
  • Inject code into existing files (themes, plugins, libraries, index.php, configuration files)
  • Abuse writable directories (like uploads or cache) to store arbitrary PHP shells
  • Modify the database to inject spam links or malicious JavaScript

On top of that, most shared hosting and even many VPS setups have:

  • Weak file permissions (world-writable directories, 777 folders)
  • Outdated PHP versions and libraries
  • Multiple sites sharing the same user account

All of this makes a hacked PHP site a bit like an apartment with several hidden spare keys left under different doormats. You can change the main lock, but if the spare keys remain, intruders will keep coming back. That is why a proper cleanup combines:

  • Immediate containment and backups
  • Systematic search for backdoors in files and database
  • Security hardening of PHP, file permissions and web server
  • Often, migration to a fresh hosting account or VPS

First Response: Contain the Incident and Collect Evidence

Before touching files or deleting anything, take a methodical first-response approach. You want to:

1. Limit damage and stop automated abuse

  • Change all passwords related to the site: hosting panel, FTP/SFTP/SSH, database, CMS admin, and any deployment keys.
  • Enable maintenance mode or a temporary 503 page if possible, especially if the site is actively distributing malware or spam.
  • If you use a reverse proxy or CDN like Cloudflare, make sure basic WAF and rate limiting rules are enabled. Our article on Cloudflare security settings with WAF, rate limiting and bot protection shows practical rules we recommend.

2. Take full backups before cleaning

Even if the site is hacked, you must keep a snapshot of the compromised state for two reasons:

  • Forensic analysis later (where did the attack start?)
  • Ability to roll back specific changes if you remove something important by accident

At minimum, take:

  • A complete copy of all web files (public_html or application directory)
  • Database dumps for all related databases
  • Configuration files outside the web root (.env, config directories, etc.)

If your site is on cPanel, you can follow our full cPanel backup and restore guide to quickly capture a full account backup before you start cleaning. Longer term, implement a robust plan like the 3-2-1 backup strategy with automated backups on cPanel, Plesk and VPS so you always have clean restore points.

3. Write down basic incident details

Even a simple text document helps later when you review security:

  • When did you first notice the hack?
  • What symptoms appeared (defacement, redirects, spam emails, high CPU)?
  • Did your registrar, hosting provider or browser show phishing/malware warnings?
  • What software versions are you running (PHP, CMS, key plugins)?

These details help you narrow down which vulnerability was most likely exploited.

Detecting PHP Backdoors and Hidden Malware

Once you have backups, the main battle is discovering every backdoor. Attackers usually hide them in writable folders, obscure filenames, or inside legitimate files.

Typical backdoor patterns in PHP code

Although malware authors constantly obfuscate their code, most PHP backdoors still use a small set of risky functions and patterns, such as:

  • Dynamic execution: eval(), assert(), create_function(), preg_replace() with /e modifier.
  • System commands: system(), exec(), passthru(), shell_exec(), popen().
  • Obfuscation helpers: base64_decode(), gzinflate(), str_rot13(), nested multiple times.
  • Suspicious superglobal access: building PHP code from $_POST, $_GET, $_COOKIE, then passing it to eval or assert.
  • Random filenames and paths: small PHP files with random names inside uploads, cache or temporary directories.

Example of a simplified backdoor pattern (heavily simplified, real ones are more obfuscated):

<?php
if (isset($_POST['cmd'])) {
    eval(base64_decode($_POST['cmd']));
}
?>

Real-world malware usually wraps similar logic with obfuscation, huge useless string arrays, and confusing variable names to hide from quick inspection.

Searching for backdoors over SSH

If your hosting plan or VPS gives you SSH access, you have a huge advantage. You can scan the filesystem quickly using command-line tools. Some useful approaches:

1. Search for dangerous functions

From the site root directory:

grep -R "eval(" -n .
grep -R "base64_decode" -n .
grep -R "gzinflate" -n .
grep -R "shell_exec" -n .

Then review the results manually. Not every use of these functions is malicious, but in many CMS and frameworks they are rare and stand out. Focus on files that:

  • Appear in unexpected folders (for example, wp-includes/fonts/ containing PHP)
  • Have random-looking names (e.g. k9s8d.php)
  • Are very small yet contain heavy obfuscation and long encoded strings

2. List recently modified files

Attackers often touch many files in a short window. Look at the last few days or weeks:

find . -type f -mtime -7 -name "*.php" -ls

This lists PHP files changed in the last seven days. Compare the timeline against when you first noticed symptoms.

3. Use command-line malware scanners (if allowed)

On VPS and dedicated servers, you can install open-source antivirus or malware scanners to assist manual review. They are not perfect, but they catch many known signatures and suspicious patterns. Run them against the document root and uploads directories. Combine their findings with your own grep and diff analysis.

Scanning when you only have FTP access

Many shared hosting environments only offer FTP or SFTP access. You can still scan effectively with a few extra steps:

  1. Use SFTP instead of FTP if your account supports it. FTP sends credentials in clear text and is a frequent source of stolen passwords. We explain why this matters in our article on switching from FTP to SFTP for secure file transfer.
  2. Download a full copy of your site to a local machine dedicated for analysis (not your everyday laptop if possible).
  3. Scan locally with your desktop antivirus and any specialized web malware scanner you trust.
  4. Search the code with your local tools: text editor search, grep or IDE inspections for functions like eval, base64_decode, gzinflate, etc.
  5. Use diff tools to compare your downloaded code with a fresh copy of the same CMS or framework from the official source.

Even with only FTP, careful searching and comparison against clean source code will reveal most backdoors.

Cleaning and Hardening in Place vs Migrating to a New Hosting Account

One of the biggest decisions is whether to clean the website in its current hosting environment or move to a fresh account or server. We see both approaches work, but there are clear cases where migration is the safer option.

When it is relatively safe to clean in place

Consider staying on the current account if:

  • This is the first known compromise and the scope looks limited.
  • You have SSH access and can fully audit file permissions and logs.
  • Only a single site is hosted under that user, and there is no evidence of privilege escalation beyond the web user.
  • File permissions and ownership are sane (no world-writable web root, no 777 directories all over).

Even then, plan a full security review after cleaning: PHP version, CMS and plugin updates, file permissions, WAF and firewall rules.

When you should migrate to a fresh account or VPS

Migration is strongly recommended when:

  • Multiple sites under the same user are compromised.
  • There are signs of deeper intrusion (new system users, strange cron jobs, unusual SSH keys).
  • File permissions and ownership are a complete mess (lots of 777, mixed owners, leftover panel migrations).
  • You do not have SSH access or meaningful logs and you cannot fully trust the current environment.
  • The hosting account is overloaded or outdated, and you were planning to upgrade anyway.

In those cases, set up a fresh environment (new shared hosting account, VPS, dedicated server or colocation server at dchost.com) with hardened defaults, then carefully migrate only cleaned data. Our team handles this pattern often for customers whose sites suffered repeated compromises on older hosting setups.

Safe File-Level Cleanup: Step-by-Step

Whether you clean in place or before migrating, use a structured process for files. Random manual edits almost always miss something.

1. Build a clean baseline

For any CMS or framework (WordPress, Laravel, PrestaShop, custom frameworks), download a fresh, official copy of the same major version you are running. This gives you a baseline to compare against:

  • Core files that must match exactly
  • Default themes or skeleton app files
  • Standard directory structure

Then:

  • On SSH: use diff -r or similar tools to compare your live code with the clean baseline.
  • Over FTP: compare folders locally using a diff-capable file manager or IDE.

Any file present on your site but not in the baseline (outside known app-specific custom folders) is suspicious and should be reviewed.

2. Replace core and vendor files from trusted sources

As a rule of thumb, never try to clean core or vendor files by hand. Instead:

  • Delete the entire core directory (e.g. wp-admin, wp-includes for WordPress, or the vendor directory for Composer-based apps).
  • Upload or deploy a fresh copy from the official download or your version control repository.
  • Restore only configuration files (wp-config.php, .env, etc.) after carefully checking them for suspicious code.

For WordPress in particular, we go into more detail in our article on what to do if your WordPress site keeps getting hacked, but the same principles apply to most PHP applications.

3. Clean uploads, custom code and themes/plugins

Uploads folders are high-risk because they are usually writable by the web server. Ideally, they should contain only images, documents and other non-executable content.

  • List PHP files inside uploads and similar folders: any PHP file is suspicious and often malicious.
  • Delete or move out unknown PHP files, then test the application to ensure nothing critical relied on them.
  • Review custom code (themes, modules, custom libraries) line by line, or re-deploy from your version control repository if you have one.
  • Update or remove old plugins and modules. Many infections start via outdated extensions that are no longer maintained.

A good practice is to ensure uploads directories cannot execute PHP at all (for example, with .htaccess rules on Apache or location blocks on Nginx), which we often combine with other measures such as correct Linux file permissions like 644/755 on shared hosting and VPS.

Database Inspection and Cleanup

Even if all files are clean, attackers may have injected spam or scripts into the database. Typical signs include:

  • Strange content added to posts, products or pages (hidden links, iframes)
  • Unknown admin users or users with elevated roles
  • Malicious code in settings fields that get printed on every page

Steps:

  1. Backup the database again before editing.
  2. Search for suspicious content using SQL or your CMS admin:
SELECT * FROM posts_table WHERE content LIKE '%<iframe%';
SELECT * FROM posts_table WHERE content LIKE '%base64_decode%';
SELECT * FROM options_table WHERE option_value LIKE '%<script%';

Adjust table names to match your application. Look for base64 blobs, iframes to unknown domains, and JavaScript snippets that do not belong to your site.

  1. Review user accounts and remove or downgrade any suspicious admins.
  2. Check configuration tables for values that inject code into headers, footers or widgets.

For WordPress specifically, database bloat and strange options in wp_options can also hurt performance. Our guide on WordPress database optimization and cleaning up wp_options/autoload bloat shows how to safely inspect and tidy up the most sensitive tables.

Planning and Executing a Safe Migration

If you decide to migrate to a new hosting account, VPS, dedicated server or colocation setup, treat the move as both a cleanup and an upgrade opportunity. The goal is to leave all backdoors behind, not to copy them faithfully to a fresh server.

1. Prepare the new environment securely

On the new hosting or server:

2. Copy, scan and verify before DNS cutover

For a clean migration flow:

  1. Copy only what you trust from old hosting:
    • Fresh core/framework files from official sources or your Git repository
    • Carefully reviewed custom themes/modules
    • Uploads and media after scanning them for PHP and malware
    • Cleaned database dump
  2. Scan again on the new server using grep, your malware scanner and manual review. Do not skip this step; many reinfections we see come from missed backdoors that were migrated.
  3. Test the site using a hosts file override or temporary subdomain before switching your main domain. Verify logins, contact forms, checkout, and any custom integrations.
  4. Plan DNS change with reduced TTL for minimal downtime. Our article on TTL strategies for zero-downtime migrations explains how to make DNS propagation feel almost instant.

3. Post-migration security checklist

Once your domain points to the new environment:

  • Rotate all passwords again (CMS, database, panel, SFTP/SSH).
  • Remove any leftover test accounts or demo data.
  • Verify that directory listing is disabled and uploads directories cannot execute PHP.
  • Set up monitoring and alerts for uptime and unusual errors.
  • Confirm that old hosting credentials are revoked and, ideally, the old account is closed or wiped after you are sure the migration is stable.

Long-Term Hardening to Avoid Repeat Hacks

A cleaned site without hardening is almost guaranteed to be hacked again, often via the same vulnerability. Use the incident as a trigger to raise your baseline security:

  • Keep software updated: CMS, plugins, themes, frameworks, PHP, database server.
  • Review file permissions: ensure web files are typically 644 and directories 755, with minimal writable locations. Our article on Linux file permissions 644, 755 and 777 goes through safe defaults for shared hosting and VPS.
  • Segment sites: avoid hosting multiple unrelated sites under the same panel user if possible. A compromise in one app should not automatically expose another.
  • Use a WAF: either at the application level (ModSecurity with a modern ruleset) or via a CDN with WAF features.
  • Enforce strong authentication: long random passwords, 2FA where available, restricted admin URLs and IP-based limits for sensitive panels.
  • Monitor logs: regularly inspect web server logs for suspicious requests and unexpected HTTP status patterns.
  • Automate backups: daily off-site backups with versioning, and periodic restore tests.

For WordPress sites in particular, we have a practical checklist in our guide on WordPress security on shared hosting using plugins, WAF, 2FA and backups, but the main principles apply to most PHP applications.

Bringing Your Hacked PHP Site Back Under Control

Cleaning up a hacked PHP website is less about a single magic scanner and more about a disciplined process. First you contain the damage and preserve evidence. Then you methodically search for backdoors in files and databases using grep, diff, scanners and manual review. Where practical, you replace core and vendor code from trusted sources instead of editing by hand. If the environment itself is suspect or outdated, you migrate to a new, hardened hosting account or server, copying over only carefully cleaned data.

From our experience at dchost.com, the customers who recover cleanly and stay clean are those who treat a hack as a turning point. They invest in regular backups, controlled deployments, timely updates, safer file permissions and basic protections like WAF and security headers. You do not have to turn into a security engineer overnight, but you do need a clear, repeatable playbook. Use the steps in this article as your baseline, and if you host with us, our team can help you plan the practical side: from choosing the right shared hosting, VPS, dedicated or colocation setup to configuring backups, firewalls and monitoring in a way that keeps your PHP websites calm and under control.

Frequently Asked Questions

Common symptoms of a hacked PHP website include unexpected redirects to other domains, strange pop-ups or iframes, new admin users you did not create, sudden spikes in outgoing email or CPU usage, and search engine warnings about malware or phishing. You may also see unknown files or folders in your web root, or your hosting provider may notify you about abuse reports. If any of these appear, assume compromise and immediately change passwords, take full backups, and start investigating files and the database for malicious code and backdoors.

It depends on the depth of the compromise and the quality of your current environment. Cleaning in place is reasonable when this is a first-time, limited incident, file permissions look sane, and you have SSH access and usable logs. Migration to a fresh hosting account or VPS is safer when multiple sites are infected, permissions are chaotic, or there are signs of deeper intrusion (new system users, strange cron jobs). In that case, set up a hardened new environment, copy over only cleaned code, media and database, and leave all suspicious or unnecessary files behind.

If you only have FTP or SFTP, you can still perform an effective scan by pulling the site to a local machine. Download all files, then run your desktop antivirus and any web malware scanner you trust on that directory. Use your editor or command-line tools to search for suspicious PHP functions like eval, base64_decode, gzinflate and shell_exec, especially in unusual folders such as uploads or cache. Compare your files with a fresh copy of the same CMS or framework from the official source to identify unexpected or modified core files. Finally, review the database for injected iframes, scripts and unknown admin users.

After cleanup, focus on hardening and monitoring. Update your CMS, plugins, themes and PHP version to supported releases. Fix file permissions so that files are typically 644 and directories 755, with as few writable locations as possible. Disable PHP execution in uploads directories, and protect admin areas with strong passwords, 2FA where available, and IP-based limits or WAF rules. Configure a web application firewall and add modern HTTP security headers. Set up automated off-site backups and test restores regularly. Finally, keep an eye on web server logs and security alerts so that any new suspicious activity is caught early, before it becomes another full-scale incident.