#!/bin/bash # ===================================================================== # WordPress malware cleanup (xdav_00765e / wp-includes/functions.php) # Run: bash clean-wp.sh # ===================================================================== set -u SITE="/home/USERNAME/public_html" # <-- APNA WordPress ROOT PATH YAHAN DAALEIN NEW_ADMIN_PASS="" # optional: apne admin ka naya password daalein, khali = skip ADMIN_USER="" # optional: jis admin ka password badalna hai uska login name # --------------------------------------------------------------------- cd "$SITE" 2>/dev/null || { echo "ERROR: $SITE nahi mila"; exit 1; } [ -f wp-config.php ] || { echo "ERROR: yahan wp-config.php nahi hai, path galat hai"; exit 1; } STAMP=$(date +%F-%H%M) BK="$(dirname "$SITE")/infected-backup-$STAMP" REPORT="$(dirname "$SITE")/cleanup-report-$STAMP.txt" TMP=$(mktemp -d) mkdir -p "$BK" log() { echo -e "$1" | tee -a "$REPORT"; } WP="" if command -v wp >/dev/null 2>&1; then WP="wp --path=$SITE" [ "$(id -u)" = "0" ] && WP="$WP --allow-root" fi log "=== CLEANUP START $STAMP ===" log "Site: $SITE" # --------------------------------------------------------------------- # 1. EVIDENCE BACKUP (delete se pehle) # --------------------------------------------------------------------- log "\n[1] Infected files ka backup: $BK" cp -a wp-includes "$BK/wp-includes" 2>/dev/null cp -a wp-admin "$BK/wp-admin" 2>/dev/null cp -a wp-config.php "$BK/" 2>/dev/null cp -a .htaccess "$BK/" 2>/dev/null cp -a .user.ini "$BK/" 2>/dev/null # --------------------------------------------------------------------- # 2. INFECTION CHECK (replace se pehle) # --------------------------------------------------------------------- log "\n[2] Infection signature (core files):" grep -rIl "xdav_00765e" wp-includes wp-admin *.php 2>/dev/null | tee -a "$REPORT" # --------------------------------------------------------------------- # 3. FRESH WORDPRESS CORE DOWNLOAD (same version) # --------------------------------------------------------------------- VER=$(grep -oP "\\\$wp_version\s*=\s*'\K[^']+" wp-includes/version.php 2>/dev/null) log "\n[3] Detected WP version: ${VER:-unknown}" cd "$TMP" || exit 1 if [ -n "${VER:-}" ] && curl -fsSL -o wp.tar.gz "https://wordpress.org/wordpress-$VER.tar.gz"; then log "Downloaded wordpress-$VER" else log "Exact version nahi mila, latest download kar raha hoon" curl -fsSL -o wp.tar.gz "https://wordpress.org/latest.tar.gz" || { log "ERROR: download fail (server se wordpress.org block hai?)"; exit 1; } fi tar -xzf wp.tar.gz || { log "ERROR: extract fail"; exit 1; } cd "$SITE" || exit 1 # --------------------------------------------------------------------- # 4. CORE REPLACE (wp-content aur wp-config.php safe rahenge) # --------------------------------------------------------------------- log "\n[4] wp-admin aur wp-includes replace ho rahe hain" rm -rf wp-includes wp-admin cp -a "$TMP/wordpress/wp-includes" ./wp-includes cp -a "$TMP/wordpress/wp-admin" ./wp-admin log "Root core files replace ho rahi hain" for f in "$TMP"/wordpress/*.php; do base=$(basename "$f") [ "$base" = "wp-config-sample.php" ] && continue cp -f "$f" "./$base" done for f in license.txt readme.html; do [ -f "$TMP/wordpress/$f" ] && cp -f "$TMP/wordpress/$f" "./$f"; done log "\nRoot mein extra/anjaan PHP files (inhe check karein, backdoor ho sakti hain):" for f in ./*.php; do base=$(basename "$f") [ "$base" = "wp-config.php" ] && continue [ -f "$TMP/wordpress/$base" ] || log " SUSPICIOUS: $base" done # --------------------------------------------------------------------- # 5. wp-content SCAN (delete nahi karta, sirf report karta hai) # --------------------------------------------------------------------- log "\n[5] Malware scan (wp-content + root)" log "\n-- 'xdav_' signature:" grep -rIl "xdav_" . 2>/dev/null | grep -v "$BK" | tee -a "$REPORT" log "\n-- Obfuscated loader pattern (new Function / fromCharCode XOR / atob):" grep -rIlE "new Function\(|fromCharCode\([^)]*\^|eval\(atob\(|eval\(base64_decode|gzinflate\(base64_decode|str_rot13\(base64" wp-content *.php .htaccess 2>/dev/null | tee -a "$REPORT" log "\n-- uploads mein PHP files (nahi honi chahiye):" find wp-content/uploads -type f \( -name "*.php" -o -name "*.phtml" -o -name "*.php5" -o -name "*.phar" \) 2>/dev/null | tee -a "$REPORT" log "\n-- mu-plugins:" ls -la wp-content/mu-plugins 2>/dev/null | tee -a "$REPORT" log "\n-- drop-ins (wp-content ke root ki PHP files):" ls -la wp-content/*.php 2>/dev/null | tee -a "$REPORT" log "\n-- Pichhle 10 din mein modify hui PHP/JS files:" find . -type f \( -name "*.php" -o -name "*.js" \) -mtime -10 -not -path "./wp-content/cache/*" -not -path "./wp-content/uploads/*" -not -path "./wp-includes/*" -not -path "./wp-admin/*" 2>/dev/null | tee -a "$REPORT" log "\n-- auto_prepend / auto_append (php.ini, .user.ini, .htaccess):" grep -rn "auto_prepend_file\|auto_append_file" .htaccess .user.ini php.ini wp-admin/.user.ini 2>/dev/null | tee -a "$REPORT" log "\n-- .htaccess redirects:" grep -nE "RewriteCond.*(HTTP_REFERER|HTTP_USER_AGENT)|RewriteRule.*http" .htaccess 2>/dev/null | tee -a "$REPORT" log "\n-- Database mein injected script (WP-CLI):" if [ -n "$WP" ]; then $WP db query "SELECT option_name FROM $( $WP db prefix 2>/dev/null || echo wp_ )options WHERE option_value LIKE '%xdav_%' OR option_value LIKE '%new Function(%' OR option_value LIKE '%String.fromCharCode%';" 2>/dev/null | tee -a "$REPORT" $WP db query "SELECT ID, post_title FROM $( $WP db prefix 2>/dev/null || echo wp_ )posts WHERE post_content LIKE '%new Function(%' OR post_content LIKE '%String.fromCharCode(%' OR post_content LIKE '%xdav_%' LIMIT 50;" 2>/dev/null | tee -a "$REPORT" else log "wp-cli nahi hai, DB scan skip" fi # --------------------------------------------------------------------- # 6. wp-config.php HARDENING # --------------------------------------------------------------------- log "\n[6] wp-config.php hardening" if ! grep -q "DISALLOW_FILE_EDIT" wp-config.php; then sed -i "/That's all, stop editing/i define( 'DISALLOW_FILE_EDIT', true );" wp-config.php log "DISALLOW_FILE_EDIT add ho gaya" else log "DISALLOW_FILE_EDIT pehle se hai" fi # --------------------------------------------------------------------- # 7. WP-CLI TASKS # --------------------------------------------------------------------- if [ -n "$WP" ]; then log "\n[7] WP-CLI tasks" log "\n-- Core checksum verify:" $WP core verify-checksums 2>&1 | tee -a "$REPORT" log "\n-- Plugin checksum verify:" $WP plugin verify-checksums --all 2>&1 | tee -a "$REPORT" log "\n-- Security salts shuffle (sab sessions logout honge):" $WP config shuffle-salts 2>&1 | tee -a "$REPORT" log "\n-- Administrator users (anjaan user ho to delete karein):" $WP user list --role=administrator --fields=ID,user_login,user_email,user_registered 2>&1 | tee -a "$REPORT" if [ -n "$NEW_ADMIN_PASS" ] && [ -n "$ADMIN_USER" ]; then $WP user update "$ADMIN_USER" --user_pass="$NEW_ADMIN_PASS" 2>&1 | tee -a "$REPORT" fi log "\n-- Outdated plugins/themes:" $WP plugin list --update=available --fields=name,version,update_version 2>&1 | tee -a "$REPORT" $WP theme list --update=available --fields=name,version,update_version 2>&1 | tee -a "$REPORT" log "\n-- Cache flush:" $WP cache flush 2>&1 | tee -a "$REPORT" $WP transient delete --all 2>&1 | tee -a "$REPORT" $WP rewrite flush 2>&1 | tee -a "$REPORT" else log "\n[7] wp-cli installed nahi hai, ye steps skip hue (checksums, salts, users, cache)" fi # --------------------------------------------------------------------- # 8. PERMISSIONS # --------------------------------------------------------------------- log "\n[8] Permissions fix" find . -type d -exec chmod 755 {} \; 2>/dev/null find . -type f -exec chmod 644 {} \; 2>/dev/null chmod 600 wp-config.php 2>/dev/null # --------------------------------------------------------------------- # 9. FINAL VERIFY # --------------------------------------------------------------------- log "\n[9] FINAL CHECK" if grep -rq "xdav_00765e" wp-includes wp-admin 2>/dev/null; then log "FAIL: core mein ab bhi infection hai" else log "OK: wp-includes / wp-admin clean" fi php -l wp-includes/functions.php 2>&1 | tee -a "$REPORT" rm -rf "$TMP" log "\n=== DONE ===" log "Report file : $REPORT" log "Backup folder: $BK"