https://github.com/adityaarsharma/wordpress-malware-removal
AI-powered WordPress malware removal & deep scanner (Claude Code / MCP skill). Finds SEO-spam cloaking, the Japanese keyword hack, redirect malware, web-shells, backdoors & database injections that Wordfence/MalCare/Sucuri miss. Quarantine-first, no false positives.
https://github.com/adityaarsharma/wordpress-malware-removal
claude claude-code incident-response japanese-keyword-hack malware-detection malware-removal malware-scanner mcp php security-tools seo-spam website-security wordpress wordpress-plugin wordpress-security
Last synced: 2 days ago
JSON representation
AI-powered WordPress malware removal & deep scanner (Claude Code / MCP skill). Finds SEO-spam cloaking, the Japanese keyword hack, redirect malware, web-shells, backdoors & database injections that Wordfence/MalCare/Sucuri miss. Quarantine-first, no false positives.
- Host: GitHub
- URL: https://github.com/adityaarsharma/wordpress-malware-removal
- Owner: adityaarsharma
- License: gpl-2.0
- Created: 2026-07-02T06:08:53.000Z (13 days ago)
- Default Branch: main
- Last Pushed: 2026-07-02T07:30:59.000Z (13 days ago)
- Last Synced: 2026-07-02T08:24:03.033Z (13 days ago)
- Topics: claude, claude-code, incident-response, japanese-keyword-hack, malware-detection, malware-removal, malware-scanner, mcp, php, security-tools, seo-spam, website-security, wordpress, wordpress-plugin, wordpress-security
- Language: Python
- Size: 119 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# WordPress Malware Removal
### Audit, clean, and harden a WordPress site — end to end, with an AI agent.
[](https://github.com/adityaarsharma/wordpress-malware-removal/actions/workflows/ci.yml)
[](LICENSE)
[](#works-with-your-ai-agent)
[](#standalone-scripts)
[](#contributing)
[](https://github.com/adityaarsharma/wordpress-malware-removal/stargazers)
Three things every WordPress owner needs, in one open-source tool:
- **Audit** — how hackable is your site *right now*? A read-only security posture score (vulnerable plugins, exposure, code risk, hardening state) with a ranked fix list.
- **Remove** — if it's already hacked, clean it — including the **hidden** stuff scanners miss (cloaking, web-root backdoors, database injections), safely, and find out how they got in.
- **Harden** — lock the doors so it doesn't happen again (2FA, permissions, REST/XML-RPC, and more) — applied safely, reversible.
It looks at your site the way **Google and an attacker** do — not just the way a browser does — cleans **safely** (it won't touch a thing until *you've* taken a backup, nothing deleted blind, auto-rollback if a change breaks the site), and always tells you **how they got in**.
**Free · open-source (AGPL-3.0) · runs with any AI coding agent — Claude Code, Cursor, Codex, or any MCP client.**
---
## Install (30 seconds)
```bash
git clone https://github.com/adityaarsharma/wordpress-malware-removal.git
cd wordpress-malware-removal
./install.sh # installs all three skills into ~/.claude/skills
```
Options: `./install.sh --dir PATH` (custom skills dir for Codex/Cursor/other), `--skill wp-hardening`
(install one), `--list` (preview), `--uninstall`. Re-run any time to update. Helper scripts need Python
3.8+ and have **zero third-party dependencies**.
This installs **three self-contained, gateway-agnostic skills** — each runs over any SSH+WP-CLI or any
WordPress MCP (SproutOS recommended):
| Skill | Ask it | What it does |
|---|---|---|
| **wp-security-audit** | "How hackable is this site?" | Read-only A–F posture score: vulns + code + exposure + ranked fixes. Touches nothing. |
| **wp-malware-removal** | "This site is hacked — clean it" | 12-layer forensic scan → verify → quarantine-first removal → prove clean → entry vector. |
| **wp-hardening** | "Lock the doors" | Idempotent, reversible hardening — auto-applies safe fixes, asks before risky ones. |
---
## Table of contents
- [Install](#install-30-seconds)
- [What it does](#what-it-does)
- [Works with your AI agent](#works-with-your-ai-agent)
- [How it compares](#how-it-compares)
- [How to use it](#how-to-use-it)
- [Keeping it updated](#keeping-it-updated)
- [How it works (the 12-layer scan)](#how-it-works)
- [Connecting your site (gateways)](#connecting-your-site)
- [What it detects (38 families)](#what-it-detects)
- [Standalone scripts](#standalone-scripts)
- [How it cleans safely](#how-it-cleans-safely)
- [Documentation](#documentation)
- [FAQ](#faq)
- [A real example](#a-real-example)
- [Contributing](#contributing)
- [License](#license)
---
## What it does — three modes
| Mode | When | What it does |
|---|---|---|
| **Audit** | "Am I safe?" | Read-only posture check → an **A–F score** + ranked fixes. Cross-checks your plugins/themes against **known vulnerabilities**, tests **exposure** (REST user-leaks, XML-RPC, public `debug.log`, security headers…), audits **risky code**, and reports **hardening state**. Weighted so credential hygiene (**2FA**) counts most — stolen logins are the #1 real breach vector. |
| **Remove** | "I'm hacked" | Deep-cleans malware — including the **hidden** stuff scanners miss: SEO-spam **cloaking**, the **Japanese keyword hack**, redirect malware, web-shells, and backdoors. Backs up first, **quarantines instead of deleting**, auto-rolls-back if a change breaks the site, and reconstructs **how the attacker got in**. |
| **Harden** | "Lock it down" | Applies hardening **safely** — the reversible, low-risk fixes automatically (file permissions, disable file editing, security headers, block PHP in uploads), and **asks before** anything that could break a plugin (XML-RPC off, REST restriction, 2FA enforcement). |
Not sure which you need? Run **Audit** first — it tells you whether to Remove, Harden, or relax.
---
## Works with your AI agent
Not just Claude. This is designed to be **agent-agnostic**:
- **The Python scripts run on their own** — no AI needed. Scan, detect cloaking, verify core integrity, and check vulnerabilities straight from your terminal.
- **The cleanup methodology works with any capable AI coding agent** — Claude Code, Cursor, Codex, or anything that can read a project and run commands. Point your agent at this repo and ask it to scan or clean.
- **It connects to your site over MCP** (an open standard) or SSH — so any MCP-compatible client can drive it. [SproutOS](https://github.com/posimyth/sproutos) is the recommended gateway (no SSH needed).
- **Claude Code gets the tightest fit** — it loads this as a native skill, so a plain "scan my site" just works.
One tool, your choice of agent. Nothing here is locked to a single vendor.
---
## How it compares
These are all good tools that do different things. The table describes each one's **publicly documented approach** — it's a comparison of design, not a claim that any product is better or worse. Run this **alongside** your existing security plugin; a second, independent look never hurts.
| | Manual cleaning | Wordfence | MalCare | Sucuri | This tool |
|---|---|---|---|---|---|
| **What it is** | Do-it-yourself | Security plugin | Plugin + cloud | Plugin + remote service | AI agent / Claude skill |
| **Where it works** | You, on the server | Inside WordPress | Synced copy on its cloud | Remote scan + cloud firewall | Over a connection or SSH — whole server |
| **How it finds malware** | Your own inspection | Signature matching | Behavioral signals | Signatures + remote checks | Reads each file in context |
| **Looks at** | Wherever you look | WordPress files & DB | WordPress files & DB | Public pages + files (with agent) | Whole server, DB, logs, users |
| **Checks pages as Googlebot**
(spam shown only to Google) | Only if you know to | Scans files, not a crawler fetch | Scans files on its cloud | Remote scanner reads public pages | Yes — as Googlebot & at the origin |
| **Scans outside `wp-content`** | If you check there | WordPress-focused | WordPress-focused | Public URLs; server scan via agent | Yes — web root and above |
| **Explains how the site was hacked** | Only if you dig through logs | Live traffic / login logging | Activity-log add-on | Post-hack analysis (paid) | Built-in log forensics + free vuln check |
| **Reduces false alarms** | Depends on your skill | Pattern rules | Signal scoring | Signature rules | Reads each file before flagging |
| **Risk of breaking the site** | High — easy to delete the wrong file | Low–medium | Low | Low | Low — backup, quarantine, auto-rollback |
| **Skill required** | High | Low | Low | Low | Low — the AI drives it |
| **Undo / rollback** | Your own backups | Manual restore | Restore from backup | Restore from backup | Quarantine + automatic rollback |
| **Open source** | n/a | Free plugin is GPL | Plugin GPL; engine proprietary | Plugin GPL; platform proprietary | Fully open (AGPL-3.0) |
| **Price** | Your time | Freemium | Freemium | Paid platform (free remote scan) | Free |
Comparison of each option's publicly documented approach as of 2026, for orientation only — not a claim that any product is better or worse, and features change often, so please check current versions. Product names are trademarks of their respective owners. These tools are complementary; running an independent second scan is always sensible.
**What this tool adds on top:** it checks your pages **as a search engine** (to catch spam shown only to Google), scans **outside** `wp-content` (web root and above), removes threats **quarantine-first** with an automatic health check, and explains **how the site was hacked**.
---
## How to use it
**Step 1 — Get it.**
```bash
git clone https://github.com/adityaarsharma/wordpress-malware-removal.git
```
**Step 2 — Point your agent at it.**
- **Claude Code** (native skill): `ln -s "$(pwd)/wordpress-malware-removal" ~/.claude/skills/wordpress-malware-removal`
- **Cursor / Codex / other agents**: open the folder in your agent and tell it to follow `SKILL.md`.
- **No agent**: run the [scripts](#standalone-scripts) directly.
**Step 3 — Connect your site** (see [gateways](#connecting-your-site)) — SproutOS (no SSH) or SSH.
**Step 4 — Just ask** (or run the scripts):
> *"Scan example.com for malware"*
> *"My site shows gambling spam in Google — clean it"*
> *"Remove the Japanese keyword hack"*
> *"How was this site hacked?"*
Optional: find the entry point with the free Wordfence vulnerability feed
The free [Wordfence Intelligence](https://www.wordfence.com/threat-intel/) feed (free account, no usage cap, commercial use allowed) lets the tool cross-check your installed plugins/themes against known vulnerabilities to find the likely way in.
```bash
export WORDFENCE_API_KEY=your_free_key
```
This is optional — the core malware detection works without it. Setup details: [references/wordfence-integration.md](references/wordfence-integration.md).
---
## Keeping it updated
New malware appears constantly, so the detection is built to grow.
- **Update the tool:** `git pull` — you get the latest detection patterns and fixes.
- **Vulnerability data updates itself:** the Wordfence feed refreshes automatically (force it with `python3 scripts/wordfence_client.py --refresh`).
- **Add your own patterns:** the signature list ([`scripts/signatures.json`](scripts/signatures.json)) is easy to extend, and a built-in test corpus + CI make sure a new pattern catches real malware without flagging clean code. Full guide: [references/growing-the-database.md](references/growing-the-database.md).
Contributions welcome — [open a PR or an issue](#contributing).
---
## How it works
The 12-layer forensic scan — click to expand
Every scan runs these layers (each degrades gracefully to the access you actually have). Full commands per layer: [references/detection-playbook.md](references/detection-playbook.md).
| # | Layer | What it checks |
|---|---|---|
| 1 | **External cloaking** | Fetches pages as Googlebot vs a browser (and at the origin behind your CDN) to catch spam shown only to search engines |
| 2 | **Web-root sweep** | Files/folders outside `wp-content` — where a lot of malware hides |
| 3 | **Core integrity** | Modified or extra WordPress core files |
| 4 | **Plugin/theme integrity** | Nulled/hidden plugins, injected code, fake plugins, unauthenticated REST routes |
| 5 | **Uploads** | Executable PHP where it shouldn't be |
| 6 | **mu-plugins & drop-ins** | `db.php`, `object-cache.php`, must-use plugins that load on every request |
| 7 | **Web-shells & backdoors** | File managers and tiny auto-login backdoors |
| 8 | **Obfuscation** | `eval(base64…)`, packed/encoded code |
| 9 | **Database** | Injection in posts, options, users, redirects, and log tables |
| 10 | **Persistence** | Cron, `.htaccess`, PHP prepend, stream-wrappers, server-level backdoors |
| 11 | **Users & sessions** | Unexpected admins, rogue application passwords |
| 12 | **Log forensics** | Reconstructs the attack timeline and finds the entry point + attacker IP |
Flow:
```
Scan (12 layers) -> verify each finding in context (reduce false alarms) -> back up ->
quarantine -> health-check + rollback -> re-check as Googlebot -> harden -> report
```
How it decides what's malware (the no-false-alarm step)
It never deletes on a pattern match alone. For every suspicious item it:
1. **Reads the actual file/row in context** and decides, like an engineer, whether it's malicious or legitimate (a minified library, a code-snippet plugin, an AMP handler, etc.).
2. **Classifies** it as *confirmed*, *needs a human*, or *false alarm*. Only *confirmed* items are removed.
3. **When unsure, it flags for review** instead of deleting. A file it leaves for you is recoverable; a wrongly deleted file that breaks your site is not.
---
## Connecting your site
Three ways to connect (SproutOS recommended, none required)
| Gateway | Needs | Best for |
|---|---|---|
| **[SproutOS](https://github.com/posimyth/sproutos)** *(recommended)* | An Application Password | No SSH — connects right inside WordPress |
| Any other WordPress MCP | The MCP connected | If you already run one |
| **SSH + WP-CLI** | Shell access | Most complete access |
SproutOS turns any WordPress site into an MCP server over an Application Password — no SSH needed. It's a **doorway, not a dependency**. Command mapping for each gateway: [references/mcp-gateways.md](references/mcp-gateways.md).
---
## What it detects
38 malware families — click to expand
SEO-spam cloaking · the Japanese keyword hack · pharma & gambling spam · redirect malware · web-shells · auto-login backdoors · uploader scripts · PHP stream-wrapper payloads hidden in images · fake "core function" loaders that rebuild from the database · unauthenticated REST-route backdoors · PHP object injection · `wp-config.php` injection · malicious `.htaccess` rules and `DirectoryIndex` hijacks · `?g=` query-string spam · malicious cron jobs · unexpected admin accounts · rogue application passwords · card skimmers · cryptominers · SSH-key backdoors · files disguised as images · core-filename typosquats · double-extension shells · injected sitemaps · server-level persistence · and more.
Full, explained list: [references/signature-library.md](references/signature-library.md) · the deep-dive on each family and how it hides: [references/malware-families.md](references/malware-families.md).
---
## Standalone scripts
Run the engine directly — zero dependencies, stock Python 3
You don't need Claude to use the core scripts:
```bash
# 1. Check for spam shown only to search engines, across your whole sitemap
python3 scripts/cloaking_diff.py --sitemap https://example.com/sitemap.xml --origin-ip 1.2.3.4
# 2. Deep-scan a WordPress folder for the 38 malware families
python3 scripts/scan_patterns.py /path/to/wordpress --since 2026-06-14 --json findings.json
# 3. Check installed plugins/themes against known vulnerabilities (free Wordfence feed)
python3 scripts/wordfence_client.py --installed installed.json
```
| Script | Mode | What it does |
|---|---|---|
| `scripts/cloaking_diff.py` | Clean | Detects cloaking (bot vs browser, origin vs CDN, JS-redirect) |
| `scripts/scan_patterns.py` | Clean | Pattern-scans a WordPress tree for malware candidates |
| `scripts/safety_gate.py` | Remove/Harden | Refuses to act until *you* register a fresh backup → quarantine (never deletes) → auto-rollback |
| `scripts/reinstall_clean.py` | Remove | Verifies core/plugins against official checksums; reinstalls from clean source |
| `scripts/harden_actions.py` | Harden | 20 idempotent, reversible hardening actions (SAFE/RISKY/MANUAL); sentinel-wrapped, per-action rollback |
| `scripts/hardening_audit.py` | Audit | Read-only config/exposure check (REST user-enum, XML-RPC, debug.log, headers…) |
| `scripts/code_auditor.py` | Audit | Audits plugin/theme/custom code for vulnerabilities (SQLi, XSS, CSRF, access control…) |
| `scripts/wordfence_client.py` | Audit | Matches installed versions against known CVEs |
| `scripts/posture_score.py` | Audit | Aggregates findings into an A–F security score + ranked fixes |
| `scripts/signatures.json` / `audit_rules.json` | — | The malware + code-audit pattern databases |
---
## How it cleans safely
The "don't break the site" protocol
- **Requires a fresh backup before it will touch anything** — *you* (or your host) take the backup; the tool does **not** create it for you. It then **refuses to delete anything until that backup is registered** and is under 24h old (enforced in code by `safety_gate.py`, not just a guideline). Read-only **Audit / Review never touch the site**, so they need no backup — the reminder is only for a destructive clean.
- For malware injected into **real WordPress/plugin files**, it **replaces them from the official clean source** (`reinstall_clean.py`) instead of risky hand-editing.
- **Moves** standalone bad files to a quarantine folder — it doesn't delete them.
- **Checks the site still loads** after every change; if a change breaks something, it restores the file automatically.
- **Asks you before anything permanent.**
- **Re-checks as Googlebot** to confirm the spam is actually gone.
It aims to remove every infection it finds and leave the site working. No scanner can promise a site is *permanently* clean against future or unknown attacks, so it's honest about that: it lists anything it couldn't fully check and suggests a follow-up scan a day or two later to catch anything that tries to come back. Full protocol: [references/remediation-playbook.md](references/remediation-playbook.md).
---
## Documentation
All guides — click to expand
| Document | What's inside |
|---|---|
| [SKILL.md](SKILL.md) | Suite router — points to the three skills |
| [skills/wp-security-audit/SKILL.md](skills/wp-security-audit/SKILL.md) | The read-only audit methodology (A–F posture) |
| [skills/wp-malware-removal/SKILL.md](skills/wp-malware-removal/SKILL.md) | The 12-layer clean methodology |
| [skills/wp-hardening/SKILL.md](skills/wp-hardening/SKILL.md) | The safe/reversible hardening methodology |
| [ROADMAP.md](ROADMAP.md) | What's shipped and what's next |
| [SPEC.md](SPEC.md) | Product & security specification |
| [docs/research-2026-07-wp-security.md](docs/research-2026-07-wp-security.md) | Sourced research behind detection, hardening & audit |
| [references/gateway.md](references/gateway.md) | Reaching the site over SproutOS / any WP MCP / SSH+WP-CLI |
| [references/detection-playbook.md](references/detection-playbook.md) | Every layer's commands, per gateway |
| [references/remediation-playbook.md](references/remediation-playbook.md) | Safe removal: backup → quarantine → verify → rollback |
| [references/hardening.md](references/hardening.md) | The SAFE/RISKY/MANUAL hardening control reference |
| [references/cloaking-detection.md](references/cloaking-detection.md) | The bot-vs-browser method in depth |
| [references/malware-families.md](references/malware-families.md) | The malware families + 2026 threat landscape |
| [references/signature-library.md](references/signature-library.md) | Human-readable signature list |
| [references/edge-cases.md](references/edge-cases.md) | Multisite, custom prefixes, reinfection, safeguards |
| [references/mcp-gateways.md](references/mcp-gateways.md) | Connecting via SproutOS / other MCP / SSH |
| [references/wordfence-integration.md](references/wordfence-integration.md) | Free Wordfence feed setup |
| [references/growing-the-database.md](references/growing-the-database.md) | How to grow the vulnerability + attack-pattern coverage |
| [references/incident-case-study.md](references/incident-case-study.md) | A real hack, start to finish |
---
## FAQ
How do I remove the Japanese keyword hack?
Connect the tool to your site and say *"remove the Japanese keyword hack."* It looks for the spam pages that appear only to search engines, rogue sitemaps, `.htaccess` tricks, and database injections, cleans them safely, and re-checks as Googlebot to confirm they're gone.
My WordPress site redirects visitors to spam. Can it help?
Yes — it looks for redirect code in `.htaccess`, the database, theme files, and injected JavaScript, including redirects that only trigger on mobile or for search engines.
My scanner says the site is clean, but Google flags it. Why?
Some infections (called *cloaking*) show spam only to search engines and clean content to everyone else — including scanners. This tool checks your pages *as Googlebot*, which is how it can spot that kind of infection.
Does it work without SSH?
Yes. Connect [SproutOS](https://github.com/posimyth/sproutos) (over an Application Password) and it runs without shell access.
Will it break my site?
It's designed not to: it backs up first, quarantines instead of deleting, and checks the site after every step, restoring anything that causes a problem.
---
## A real example
A hidden gambling-spam infection a normal scan didn't catch
A live WordPress site was infected with gambling spam that **only appeared in Google search results** — the site looked completely normal to visitors and to the security scanner that was active on it. The malware was hiding in folders **outside** `wp-content`, plus a tiny backdoor file that kept letting the attacker back in.
This tool is built to find exactly that kind of hidden infection. The full, step-by-step write-up is included as a worked example and regression test: [references/incident-case-study.md](references/incident-case-study.md).
---
## Contributing
New detection patterns are always welcome
Malware changes constantly. The pattern list ([`scripts/signatures.json`](scripts/signatures.json)) is easy to extend — add a family, add a safeguard against false alarms, and open a PR. Found something it missed? [Open an issue](https://github.com/adityaarsharma/wordpress-malware-removal/issues) with a sanitized sample.
**If this helped you, a star helps others find it.**
---
## Works well alongside
[Wordfence](https://www.wordfence.com/), [MalCare](https://www.malcare.com/), and [Sucuri](https://sucuri.net/) are well-known WordPress security tools; running an independent second scan is always sensible. This project uses [SproutOS](https://github.com/posimyth/sproutos) as its recommended gateway and the free [Wordfence Intelligence](https://www.wordfence.com/threat-intel/) vulnerability feed.
## License
[AGPL-3.0-or-later](LICENSE). Strong copyleft: you're free to use, modify, and self-host it, but if you run a **modified** version as a network service, you must share your source. This keeps hosted derivatives open.
---