Created
December 2, 2025 15:54
-
-
Save daviddarke/cded25cd27e27265ac9ec8a3cac8bc6b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # | |
| # Scan a WordPress theme (or themes directory) for suspicious code. | |
| # | |
| # Usage examples: | |
| # # from WP root, scan ALL themes: | |
| # bash scan_wp_theme.sh wp-content/themes | |
| # | |
| # # scan a specific theme: | |
| # bash scan_wp_theme.sh wp-content/themes/twentytwentyfive | |
| # | |
| # # with absolute path: | |
| # bash scan_wp_theme.sh /var/www/html/wp-content/themes | |
| # | |
| THEME_DIR="${1:-wp-content/themes}" | |
| if [ ! -d "$THEME_DIR" ]; then | |
| echo "Directory not found: $THEME_DIR" >&2 | |
| exit 1 | |
| fi | |
| echo "Scanning theme directory: $THEME_DIR" | |
| echo | |
| ################################# | |
| # 1) List PHP files we will scan | |
| ################################# | |
| echo "=== PHP files found (for awareness) ===" | |
| find "$THEME_DIR" -type f -name "*.php" -print | |
| echo | |
| ########################################### | |
| # 2) Recently modified PHP files (top 30) | |
| ########################################### | |
| echo "=== Recently modified PHP files (top 30) ===" | |
| # Adjust -mtime if you only care about last N days, e.g. -mtime -7 for 7 days | |
| find "$THEME_DIR" -type f -name "*.php" -printf "%TY-%Tm-%Td %TH:%TM:%TS %p\n" \ | |
| | sort -r \ | |
| | head -n 30 | |
| echo | |
| ##################################################### | |
| # 3) Grep PHP for common malware / obfuscation signs | |
| ##################################################### | |
| echo "=== Searching PHP for suspicious patterns ===" | |
| # Common suspicious constructs seen in WP malware | |
| PATTERN_MALICIOUS=' | |
| (eval *\()| | |
| (assert *\()| | |
| (preg_replace *\(.*/e)| | |
| (create_function *\()| | |
| (base64_decode *\()| | |
| (gzinflate *\()| | |
| (str_rot13 *\()| | |
| (shell_exec *\()| | |
| (system *\()| | |
| (passthru *\()| | |
| (popen *\()| | |
| (proc_open *\()| | |
| (error_reporting *\(0\))| | |
| (@ini_set *\()| | |
| (@include *\()| | |
| (@require *\()| | |
| (\$\w+ *= *\$\{\$)| | |
| (GLOBALS\[\$\w+\])| | |
| (\\x[0-9a-fA-F]{2})| | |
| (base64_encode *\()| | |
| (goto +[a-zA-Z_]) | |
| ' | |
| # Compact whitespace in the regex (so the above is readable) | |
| PATTERN_MALICIOUS=$(echo "$PATTERN_MALICIOUS" | tr -d '\n') | |
| echo "--- Suspicious PHP function / pattern matches ---" | |
| find "$THEME_DIR" -type f -name "*.php" -print0 \ | |
| | xargs -0 -r grep -nE "$PATTERN_MALICIOUS" 2>/dev/null \ | |
| || echo "No suspicious patterns found (or none matched)." | |
| echo | |
| ################################################### | |
| # 4) PHP files containing URLs (possible callbacks) | |
| ################################################### | |
| echo "=== PHP files with embedded URLs (could be legit, but worth a look) ===" | |
| find "$THEME_DIR" -type f -name "*.php" -print0 \ | |
| | xargs -0 -r grep -nE "https?://[a-zA-Z0-9./_-]+" 2>/dev/null \ | |
| || echo "No URLs found in PHP files." | |
| echo | |
| ############################################### |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment