How to Clean Malware from a Hacked Website (Non-WordPress)

Errors & Troubleshooting | Updated July 2026

If your Joomla, Drupal, custom PHP, or plain HTML site on Ultra Web Hosting has been hacked, this guide walks you through cleaning it up the right way. It covers how to confirm the site is actually compromised, how to find and remove the malware, how to close the hole the attacker used, and how to get your domain off Google Safe Browsing and other blacklists. This is the non-WordPress companion to our WordPress cleanup guide; if you run WordPress, use article 478 instead.

The Safest Path

Restore a Clean Backup, Then Patch

Cleaning an infection by hand is error-prone because a single missed backdoor puts you right back where you started. If you have a backup from before the site was compromised, restoring it and then patching the vulnerability is faster and far more reliable than hunting every injected line. We keep account backups you can restore, and you can keep your own in-account backups too.

  • Restore a known-clean copy taken before the infection date
  • Apply all pending CMS, extension, and plugin updates immediately
  • Change all passwords before bringing the site back online

01. How to Tell Your Site Is Compromised

Sometimes a hack is obvious: the homepage is replaced with a defacement page. More often it is quiet, because the attacker wants to keep using your account. Here are the signs, from loudest to most subtle.

  • Browser malware warnings. Chrome, Firefox, or Safari shows a red "Deceptive site ahead" or "The site ahead contains malware" screen to your visitors.
  • Blacklist or Safe Browsing flag. Your domain gets flagged by Google Safe Browsing, and search results show a "This site may be hacked" label under your listing.
  • Spam sent from your account. You get a notice from us about outbound spam, your mail starts bouncing, or your domain lands on a spam blacklist.
  • Unknown files. Files you did not create appear in your document root, often with random names or names that mimic real ones (for example wp-conflg.php, lang.php, or xml.php in a folder that has no business holding PHP).
  • Defaced pages. Your homepage or an inner page is replaced with an attacker's message.
  • Redirects to sketchy sites. Visitors, especially those arriving from Google or on mobile, get bounced to pharma, gambling, or scam pages while you see the normal site.
  • Sudden resource spikes. CPU, memory, or bandwidth jumps for no reason you can explain, because your account is being used to send mail or attack other sites.
  • Injected scripts in your pages. View source on a page and you find <script> or <iframe> tags pointing at domains you have never heard of, usually near the top or very bottom of the HTML.
Note

Seeing a redirect only from mobile or only from Google, but never when you type the URL directly, is a classic conditional-redirect infection. The malicious code reads the visitor's user agent or referrer and only fires for the traffic the attacker wants. Do not assume the site is fine just because it loads normally for you.

02. First Steps: Do Not Panic, But Act

A compromised site is a fixable problem, but the order you do things in matters. Move deliberately.

  1. Take a full backup of the current, infected state first. This is your evidence and your safety net. If a cleanup step goes wrong, or you later need to see how the attacker got in, you will want this snapshot. Download a full backup from cPanel or copy the document root and export the database before you change anything.
  2. Change all passwords immediately. Not just the CMS admin. Change your cPanel password, every FTP account, the database user password, and every application admin login. If the attacker has your cPanel or FTP credentials, cleaning files is pointless because they will re-upload within hours. See article 309 for password strength and two-factor principles, and turn on two-factor authentication wherever it is offered (our 2FA guide covers setup).
  3. Check who else has access. Look for FTP accounts, cPanel sub-users, and application admin accounts you did not create, and remove them.
This Part Is Non-Negotiable

Changing every password and fixing the entry point (Section 09) are not optional steps you can come back to later. If you clean the files but leave the stolen credentials valid or the vulnerable script in place, reinfection is not a risk, it is a certainty. Most sites that get "hacked again a week later" were never actually secured, only cleaned.

03. Take the Site Offline While You Clean

While the site is infected it may be serving malware to visitors, sending spam, or redirecting your customers. Take it out of circulation before you start cleaning so you are not spreading the problem or getting re-flagged mid-cleanup.

  1. Put up a maintenance page. The simplest approach is a temporary index.html that says the site is under maintenance, moved aside from your real files. For a CMS, use its built-in maintenance or offline mode.
  2. Or restrict access to your own IP. If you need the live site reachable while you work, block everyone except your own address in .htaccess so visitors are not exposed.
  3. Do not simply delete everything yet. You still need the infected files for diagnosis. Move them aside or lock access rather than wiping until you know what you are dealing with.
Tip

A quick way to restrict a site to just your own IP while cleaning is a short .htaccess block at the document root:

Require ip 203.0.113.45

Replace the address with your own. Remember to remove this block when you bring the site back online, or legitimate visitors will get a 403.

04. Identify the Infection

Now find what was changed. You are looking for files the attacker added or modified. There are a few reliable tells.

  • Recently modified files. Sort your files by modification date. Anything changed around the time the problem started, that you did not change yourself, is suspect.
  • Unfamiliar .php files. A .php file in an uploads, images, or cache directory is almost always a backdoor. Those folders hold media and generated files, not code.
  • Obfuscated code. Backdoors hide behind functions that run text as code or decode packed strings. The usual suspects are eval, base64_decode, gzinflate, str_rot13, assert, and preg_replace with the /e modifier.
  • Injected script and iframe tags. In HTML and inside PHP that outputs HTML, look for <script> and <iframe> tags pointing at unfamiliar domains.
  • .htaccess redirects. A rewritten .htaccess that sends visitors elsewhere based on their user agent or referrer.
  • Unknown cron jobs. A scheduled task that re-downloads the payload after you clean it.

These are the patterns to grep for. Seeing any of them inside your own files is a strong signal, though note that legitimate software occasionally uses base64_decode, so read the surrounding code before deleting.

eval(
base64_decode(
gzinflate(
gzuncompress(
str_rot13(
assert(
preg_replace( ... /e
system(
shell_exec(
passthru(
exec(
create_function(
$_POST[
$_GET[
$_REQUEST[
FilesMan
c99
r57
<iframe
document.write(unescape(
A Long Base64 Blob Is a Backdoor Until Proven Otherwise

If you open a file and the top is a single enormous line of eval(base64_decode(...)) or a wall of packed characters, that is a webshell. Legitimate code is readable. Do not try to decode and understand every shell; note the filename, confirm you did not write it, and remove it.

05. Search Efficiently for the Malware

Clicking through folders by hand does not scale. Use search, either the cPanel File Manager search or, much faster, the command line over SSH if your plan includes it.

With SSH (grep)

From your document root, search recursively for the red-flag function names. This finds the files that contain them and the line they are on:

cd ~/public_html
grep -rEn "eval\(|base64_decode\(|gzinflate\(|str_rot13\(|shell_exec\(|assert\(" . --include="*.php"

Find every PHP file changed in the last, say, seven days, which is the fastest way to spot recently planted files:

find ~/public_html -name "*.php" -mtime -7 -printf "%TY-%Tm-%Td %p\n" | sort

And look for stray PHP files in directories that should only hold media:

find ~/public_html/images ~/public_html/uploads -name "*.php" 2>/dev/null

With cPanel File Manager

No SSH? The File Manager has a Search box (top right). Set it to search all files, and look for the same tokens one at a time: base64_decode, eval(, gzinflate. You can also sort any folder by Last Modified to surface recently changed files. It is slower than grep but it works on any plan.

Tip

Compare against a known-good copy. If you have a clean backup or a fresh download of the same CMS version, a file comparison (diff) between the two instantly highlights every changed and added file. This turns a needle-in-a-haystack search into a short list.

06. Clean or Replace the Files

How you clean depends on what kind of site it is.

For a CMS (Joomla, Drupal, and similar)

  1. Replace the core with fresh files. Download the exact same version from the official project site (getjoomla or joomla.org for Joomla, drupal.org for Drupal). Delete the existing core directories and replace them with the clean copies. This wipes any core files the attacker modified in one move.
  2. Do not overwrite your configuration or user content. Keep your configuration.php (Joomla) or settings.php (Drupal), your database, and your genuine uploads. Replace code, not your data.
  3. Remove unknown extensions. Review installed components, modules, plugins, and themes. Anything you did not install, or any nulled or pirated extension, comes out. Nulled extensions are a leading infection source.
  4. Update everything to the current release once the core is clean, so you are not reinstalling the same vulnerable version.

For static or custom PHP sites

  1. Restore known-good files from a clean backup where you have one. This is the reliable path.
  2. Remove injected code by hand where you do not. Strip the injected <script> and <iframe> tags from your HTML and PHP, and delete any backdoor files you found in Section 04. Work from your evidence list so you do not miss any.
  3. Delete, do not just empty, the backdoor files. A zero-byte file left behind can still be a marker the attacker checks for.
Risky

Clean in Place

Editing infected files by hand and deleting backdoors one by one. Works, but it is easy to miss a single hidden shell, and one survivor re-infects everything.

  • No clean backup required
  • Keeps recent content changes
  • High chance of leaving a backdoor behind

07. Check the Database for Injected Content

Attackers do not only touch files. On database-driven sites they inject into the database too, so a file-only cleanup leaves the infection alive. Open phpMyAdmin from cPanel and check.

  1. Look for admin users you did not create. In your CMS users table, any account with administrator privileges that you do not recognize is a backdoor account. Delete it.
  2. Search content tables for injected markup. Use the phpMyAdmin Search tab, or SQL, to look through articles, posts, and configuration for <script, <iframe, and unfamiliar external domains.
  3. Check for spam rows. Look for bulk pharma, gambling, or SEO-spam content injected into your tables, and remove it.
  4. Review settings tables for altered site URLs, template overrides, or custom header and footer fields where injected scripts love to hide.
Note

Export the database before you edit it, and change the database user password (Section 02) once you are done. If the attacker had your DB credentials, they can rewrite the database as fast as you clean it.

08. Check .htaccess, Cron Jobs, and Email for Persistence

A good attacker plants more than one way back in. After the obvious files are clean, sweep these persistence spots or the site quietly reinfects itself.

  1. .htaccess files. Check the document root and every subfolder. Look for RewriteRule lines that redirect based on user agent or referrer, php_value auto_prepend_file directives that force-load a backdoor into every request, and AddType lines that make images execute as PHP. There is often more than one poisoned .htaccess.
  2. Cron jobs. In cPanel, open Cron Jobs and review every entry. A task that runs wget, curl, or a stray PHP file on a schedule is there to re-download the payload after you remove it. Delete anything you did not set up.
  3. Email accounts and forwarders. Check for email accounts and forwarders you did not create, which attackers add to send spam or catch password resets. Remove them and check your account's outbound mail queue.
  4. Scheduled tasks inside the CMS. Some platforms have their own scheduler. Review it for tasks you did not create.
The auto_prepend_file Trap

A single line like php_value auto_prepend_file /home/user/public_html/.cache.php in .htaccess silently loads a backdoor before every PHP request on the site, even after you have deleted every other shell. If your site keeps reinfecting after a thorough file cleanup, this is a prime suspect. Check every .htaccess.

09. Find and Fix the Entry Point

This is the step that decides whether the cleanup holds. The attacker got in through a specific door. Find it and close it, or they walk right back through.

  • Outdated software. An out-of-date CMS core, or an old vulnerable extension, plugin, or module, is the most common entry point by a wide margin. Update everything to current, and remove anything you no longer use.
  • Weak or reused passwords. A guessable or previously-leaked admin, FTP, or cPanel password. This is why Section 02 exists. See article 309 for building strong credentials.
  • A vulnerable custom script. An upload form with no validation, a contact script that writes files, or an old third-party library with a known hole. Review anything that accepts input or writes to disk.
  • Nulled or pirated extensions. Pirated commercial extensions frequently ship with a backdoor baked in. If you are running any, that is very likely your door.

Your access logs help pinpoint the door. Look in cPanel's Raw Access or Metrics for POST requests to unusual URLs around the time of infection, repeated hits on a login or upload endpoint, and requests to any backdoor file you found. That request pattern often names the vulnerability for you. For blocking the reconnaissance and brute-force traffic that precedes most of these hacks, see article 81 on firewall and security protection.

Tip

If you genuinely cannot find the entry point, treat outdated software and weak credentials as the default cause: update every component to its current version, rotate every password, and remove unused extensions and scripts. That closes the overwhelming majority of doors even when the logs are inconclusive.

10. After Cleanup: Harden and Request Delisting

The infection is gone and the hole is closed. Now make the site harder to hit again, confirm it is clean, and get your reputation restored.

  1. Update everything, again. Confirm the CMS core, all extensions, and any libraries are on their current release. Set a reminder to keep them current, because staying patched is what prevents the next one.
  2. Harden the site. Apply the hardening principles in article 309: strong unique passwords, two-factor authentication on every admin and cPanel login, least-privilege file permissions, and disabling any admin features you do not use. Make sure your site is served over HTTPS, and if it is not yet, article 68 covers SSL and HTTPS setup.
  3. Scan again. Re-run your search from Sections 04 and 05 to confirm nothing came back. We run server-side scanning on our shared platform and will flag anything we catch on your account.
  4. Request review and delisting. If Google Safe Browsing flagged your domain, request a review in Google Search Console once the site is verified clean. If you landed on a mail blacklist, use that blacklist's own delisting request form. Delisting only sticks if the site is genuinely clean, so do this last.
Running WordPress Instead?

This guide is for Joomla, Drupal, custom PHP, and static sites. If your site is WordPress, follow article 478 for the WordPress-specific cleanup, and secure it afterward with our "Securing WordPress with Wordfence or Solid Security" guide. Our WordPress security hardening article 309 covers the password and two-factor principles that apply to any platform.

Not Sure You Got It All?

A missed backdoor is the difference between a cleanup that holds and one that fails in a week. We run server-side scanning and can advise on what we are seeing on your account. For a deep or repeated infection, a professional cleanup is money well spent. Open a ticket and tell us the domain and what you have found so far.

Open a Support Ticket

Quick Recap: Cleaning a Hacked Site

If you take away six things from this guide, take these:

  1. Back up the infected state for evidence, then change every password: cPanel, FTP, database, and admin.
  2. Take the site offline or restrict it to your own IP so you are not serving malware while you clean.
  3. Find the malware by searching for obfuscated code, stray PHP files, and recently modified files.
  4. Clean or replace files, and where you can, restore a clean pre-infection backup instead of cleaning by hand.
  5. Sweep the database, .htaccess, cron jobs, and email for injected content and hidden persistence.
  6. Fix the entry point and harden the site, then scan again and request delisting. This is the step that stops it happening again.

Last updated July 2026 · Browse all Errors and Troubleshooting articles

  • 0 Users Found This Useful

Was this answer helpful?

Related Articles

403 Error on POST

Errors & Troubleshooting | Updated 2026 A 403 Forbidden error on POST requests (form...

There Has Been a Critical Error on This Website

Errors & Troubleshooting | Updated March 2026 "There has been a critical error on this...

Error 500 - Internal Server Error

Errors & Troubleshooting | Updated March 2026 A 500 Internal Server Error means something...

Error: SoftException in Application(dot)cpp:303 UID of script is small than min_uid

Errors & Troubleshooting | Updated 2026 The "SoftException in Application.cpp: UID of...

Error 406 unacceptable

Errors & Troubleshooting | Updated 2026 A 406 "Not Acceptable" error means the server...



Save 30% on web hosting - Use coupon code Hosting30