How to detect and fix a hacked PHP website
Created
Reviewedbyfl

Recover a hacked PHP website. Detect the intrusion, clean the code, restore from backup. Notes from a hosting provider who has seen a few. This is the human-to-human edition.
Common patterns
Got pwned? It happens more often than you think. A hacked PHP website is rarely a targeted attack. Most of it is script kiddies prompt kiddies chasing a few bucks with automated tooling that hits known holes in unpatched software. Nobody picked you. You were next on the list.
What they do with the site:
- Phishing pages for banks and crypto wallets
- Crypto mining
- Fake web shops
- SEO spam, hidden links to shady sites
- Malware for your visitors
- A backdoor for later
- DDoS participation
Target systems
PHP websites are popular with hackers. Server-side rendering means they get to run code, and with weak isolation they may escalate from there. The systems we see hit most often:
- WordPress
- WordPress
- WordPress
- Craft CMS
- Laravel
- Others
Detect a hacked PHP website
Usually the website tells you itself, one way or the other:
- Performance goes down
- Errors (500, 504 …)
- Strange Google results
- Content on the site you did not put there
- Google blocklist warnings
- Phishing warning in the browser
- New users in the admin panel you don't remember creating
- Your hosting provider writes you an email
- A CVE for your CMS is all over the news
In our experience the average time to detection is about three months. Some notice on day one. Others snooze.
Implications
- Search ranking drops
- Cached search results full of spam
- Higher hosting costs, the miner is not free
Investigate
Read the access logs. Which files were hit, from which IPs, in what order. That alone often tells the story.
Fix a hacked PHP website
The fix depends on how deep they got in. The more you know about the attack, the easier the cleanup. Sometimes it helps to read up on recent breaches of the same software.
Is the hosting runtime compromised?
On a VPS the whole box can be lost. Many hosting providers, us included, run websites in a jail where escalating beyond the website owner is unlikely. If in doubt: take a fresh backup, rebuild the hosting resources, redeploy to a clean instance. Or reinstall the OS.
fortrabbit apps run in a tight jail. Getting out of it is hard.
Restore from backup
The preferred path, if there are recent backups you trust. Backups can be a local copy of the development environment, a hosted Git repo, or the backups of the hosting platform. For a classic LAMP stack that means code, runtime files like uploads, maybe build artifacts, and a database dump.
Restore means: redeploy the code, import the dump. Done. Almost, see aftermath.
Cleanup
No backups? Then it's manual work. Download everything to your local machine. It's faster there and mistakes are safe. Then grep. Your AI can help spotting obfuscated PHP, that is one of the things it is good at. Compare the CMS or framework core files against clean upstream versions to find the modified ones.
- Run
composer auditin Composer driven projects - Clean files
- Look deeply, backdoors are made to be missed
- Obfuscated code sandwiched between normal code
- The usual locations
- Files with odd timestamps
- Hidden files with names like
.htacces(missing s) - base64 blobs,
evalandassertscattered around
- Clean database
- Users and roles: any accounts you don't know?
- Posts, pages and options tables: injected links or iframes
- Serialized payloads hiding scripts
- Export to SQL and grep for the suspicious stuff
Example files
Here are some files from a recent Craft CMS CVE that we found to be affected.
.well-known/*
.widgets.php
accesson.php
autoload_classmap.php
cgi-bin/*
CoreCheck.php
craftt-api.php
envcraft.php
m.php
memberfuns.php
mn.php
mnb.php
wp-blogs.php
# Some files might be deeply hidden with existing folder structure like so:
assets/_120x78_crop_center-center_none/-vwugcm.php
assets/_240x122_crop_center-center_none/-gqpmnb.php
assets/_68x56_crop_center-center_none/-yuobgf.php
cpresources/4c4d6e37/d3-format/-rfihgs.php
cpresources/718fe862/mode/cypher/-nswipf.php
cpresources/718fe862/mode/swift/-oxtkip.php
cpresources/926d5982/js/captchas/-wtfbav.php
cpresources/d87ff9ec/-npcqfu.php
migrations/...
templates/...
vendor/...
Example code
Obfuscated code is meant to be unreadable for humans. It is usually encoded. Luckily the code of your CMS or framework is not, so the bad stuff stands out.
// Harmful code sometimes is hidden between other code.
<?php
error_reporting(0);
header('Content-Type: text/html; charset=utf-8');
$OooO0 = 'fgs1075';
date_default_timezone_set($O{35}.$O{22}.$O{12});
$OOooO="%31%73%65%71%71%69%75%69%6f%70%61%73%64%66%67%68%6a%6b%6c%7a%78%63%76%62%6e%6d%51%57%45%52%54%59%55%49%4f%50%41%53%44%46%47%48%4a%4b%4c%5a%58%43%56%42%4e%4d%5f%2d%22%3f%3e%20%3c%2e%2d%3d%3a%2f%31%32%33%30%36%35%34%38%37%39%27%3b%28%29%26%5e%24%5b%5d%5c%5c%25%7b%7d%21%2a%7c";
$O=urldecode($OOooO);
Aftermath
All malicious code and back doors gone? Now reset every credential that touched the site.
- Reset all access credentials
- Database passwords
- Admin user logins
- FTP passwords
- SSH keys
- API tokens
- ( Hosting control panel passwords )
- Get on a regular update schedule
- Remove unused plugins and themes
- Fix file permissions
- Have search engines re-index the site to get rid of the phishy results
- Google Search Console
- Bing webmaster tools
Appendix
Still reading? Here is the dessert.
Liability
Who is to blame for the damage? In most cases the website owner. We, as hosting provider, practice separation of concerns. We take care of the infrastructure and the OS layer. Clients are responsible for the code they install and write.
Security audits
We sometimes help clients with security audits. Many of the offerings out there are snake oil.
White hat hackers
White hat hackers can be useful to find real security issues.
Security plugins
Little experience, generally sceptical. Fewer plugins is the better security plugin. Use small, well maintained ones.
Forensics
You can try to find out how they got in and maybe even who. In most cases this leads nowhere. But it can be fun.
- Find the Telegram chat group ID where stolen credentials are sent to
- Find a generic email address
- Get the geo location of the origin IPs
- Check the bash history (unlikely, most hacks run through web shells)
Prevention
- Update software regularly
- Update software regularly
- Update software regularly
- Use a web application firewall
Most of the above we learned on client sites. Thanks for letting us look.