← back to the workbench  ·  ler em português (PT-BR)
// project page

Elderward

A free, single-file PHP malware scanner and cleanup tool, aimed at compromised WordPress sites. It finds infections, removes known malware, and reads access logs for signs of how the attack happened.

released at WordCamp Brasil 2026PHP 5.6+single filesignature-based
visit elderward.space.fast ↗ source on GitHub ↗

what_it_is

Elderward is a variation of the Jetpack Cleanup Util, packaged so anyone can run it on their own host. It was publicly released during WordCamp Brasil 2026. You drop elderward.php on the server and run it from a shell, or over HTTP when there's no shell.

what_it_does

  • Checks files against known malware signatures and cleans them with atomic writes.
  • Reviews crontabs for known persistence patterns.
  • Scans access logs for known attack traffic, with optional correlation to files.
  • Compares WordPress core, plugins and themes against the official wordpress.org packages, with optional restore.
  • Quick checks for PHP in uploads, auto-prepend directives, mu-plugins and hidden PHP files.
  • Reports timestamp anomalies.
  • Prints findings as SEVERITY,TYPE,path,detail, or NDJSON with format=json.

try_it

Needs PHP 5.6 or newer (CLI preferred). The zlib extension is only needed to read rotated .gz logs. Start with a dry run:

preview, change nothing
php elderward.php dryrun=1
scan everything in a WordPress root
php elderward.php scanall=1 scandirectory=/path/to/wp-root
integrity check, dry-run restore
php elderward.php scanintegrity=1 restore=1 dryrun=1 scandirectory=/path/to/wp-root
all options
php elderward.php help=1

No shell? Set WEB_ACCESS_TOKEN in the file, upload it, and request it over HTTP:

HTTP mode
https://example.com/elderward.php?token=YOUR_TOKEN&dryrun=1

read_before_cleaning

  • Back up first, and use dryrun=1 to preview changes.
  • Detection is signature-based. A clean scan does not prove a site is clean.
  • Log findings include attack attempts, many of which failed. Treat them as leads, not proof of compromise.
  • Timestamp findings are heuristics and never trigger cleanup.
  • Restoring a file overwrites it and can destroy evidence. Set quarantinedir outside the webroot to keep copies.
  • Files larger than 2 MB are skipped.
  • After using HTTP mode, delete the file from the server.
  • A successful cleanup exits with code 3, the same as a HIGH finding.
NOTE TO SELF
Add sample output and a real changelog when I get to it. Tape stays on until then.