#!/usr/bin/env bash
# wp-persistence-check.sh, survey every WordPress persistence layer for anomalies.
# Source: https://techearl.com/wordpress-malware-persistence-mechanisms
# Site:   https://techearl.com/
# Reports candidates; does NOT modify or delete.
#
# Usage:
#   ./wp-persistence-check.sh /path/to/wordpress
#
# Requires: wp-cli (for the WordPress-level checks), bash, find, grep.

set -e
WP_ROOT="${1:-$PWD}"
WEB_USER="$(stat -c '%U' "$WP_ROOT/wp-config.php" 2>/dev/null || stat -f '%Su' "$WP_ROOT/wp-config.php")"

echo "=========================================="
echo "  WordPress Persistence Check"
echo "  Root:     $WP_ROOT"
echo "  Web user: $WEB_USER"
echo "=========================================="

echo
echo "--- 1. Server cron for $WEB_USER ---"
sudo -u "$WEB_USER" crontab -l 2>/dev/null || echo "  (no crontab for $WEB_USER)"
echo "--- system-wide cron ---"
sudo ls -la /etc/cron.d/ /etc/cron.daily/ /etc/cron.hourly/ 2>/dev/null | head -20

echo
echo "--- 2. auto_prepend_file in .htaccess ---"
find "$WP_ROOT" -name '.htaccess' -exec grep -lE 'auto_(pre|ap)pend_file' {} \;

echo
echo "--- 3. wp-config.php anomalies ---"
grep -nE '@?(include|require)|eval\(|base64_decode|gzinflate|preg_replace.*/e' "$WP_ROOT/wp-config.php" || echo "  (clean)"
grep -nE "define\s*\(\s*['\"]WP_(CONTENT|PLUGIN)_DIR" "$WP_ROOT/wp-config.php" || echo "  (no WP_CONTENT_DIR override)"

echo
echo "--- 4. mu-plugins contents ---"
ls -la "$WP_ROOT/wp-content/mu-plugins/" 2>/dev/null || echo "  (mu-plugins absent, normal)"

echo
echo "--- 5. drop-ins ---"
for dropin in advanced-cache.php object-cache.php db.php sunrise.php; do
  if [ -f "$WP_ROOT/wp-content/$dropin" ]; then
    echo "  PRESENT: wp-content/$dropin"
  fi
done

echo
echo "--- 6. Big autoloaded wp_options rows ---"
wp option list --autoload=on --format=csv --fields=option_name,size_bytes \
  --path="$WP_ROOT" --allow-root 2>/dev/null \
  | sort -t, -k 2 -n -r | head -15

echo
echo "--- 7. WP-Cron events (look for unrecognized hooks) ---"
wp cron event list --format=table --fields=hook,next_run_relative \
  --path="$WP_ROOT" --allow-root 2>/dev/null | head -30

echo
echo "--- 8. Core checksum verification ---"
wp core verify-checksums --path="$WP_ROOT" --allow-root 2>&1 | head -20

echo
echo "--- 9. REST API routes (unfamiliar namespaces are suspicious) ---"
wp rest endpoint list --format=csv --fields=route --path="$WP_ROOT" --allow-root 2>/dev/null \
  | awk -F/ '{print "/"$2"/"$3}' | sort -u

echo
echo "--- 10. Shell startup files for $WEB_USER ---"
WEB_HOME=$(getent passwd "$WEB_USER" | cut -d: -f6)
sudo grep -lE 'base64|eval|exec.*-a|defunct|watchdogd' \
  "$WEB_HOME/.bashrc" "$WEB_HOME/.bash_profile" "$WEB_HOME/.profile" "$WEB_HOME/.zshrc" 2>/dev/null \
  || echo "  (no suspicious patterns in shell startup files)"

echo
echo "--- 11. Resident processes for $WEB_USER ---"
ps -u "$WEB_USER" -o pid,etime,comm,args 2>/dev/null | head -40
echo "  ^ anything in [brackets] owned by a non-root user is suspicious"

echo
echo "--- 12. Stashed binaries in user home ---"
sudo find "$WEB_HOME" -type f \( -name 'defunct' -o -name 'defunct.dat' -o -name '.htop' \) 2>/dev/null
sudo ls -la "$WEB_HOME/.config/htop/" 2>/dev/null || true

echo
echo "=========================================="
echo "  Review each section. Anything you can't"
echo "  attribute to a legitimate plugin or theme"
echo "  is a candidate for removal."
echo "=========================================="
