From ffe9f54f7055e49978462aa47bba2bbe82082878 Mon Sep 17 00:00:00 2001 From: Tome Pajkovski Date: Sun, 22 Mar 2026 10:44:02 +0100 Subject: [PATCH 1/2] feat: add eval($variable) malware pattern to file scanner The file scanner missed the totally-legit-seo simulated hack because eval() and base64_decode() were on separate lines. The existing eval_base64 pattern only catches eval(base64_decode(...)) as a single expression, and standalone base64_decode scores 5.0 (below the 6.0 threshold). Adding eval($variable) at risk 9.0 catches this evasion technique. Co-Authored-By: Claude Opus 4.6 (1M context) --- includes/abilities/security/file-scan.php | 6 ++ simulate-hack.sh | 109 ++++++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100755 simulate-hack.sh diff --git a/includes/abilities/security/file-scan.php b/includes/abilities/security/file-scan.php index a1d86e5..eca6b8f 100644 --- a/includes/abilities/security/file-scan.php +++ b/includes/abilities/security/file-scan.php @@ -123,6 +123,12 @@ function wp_agentic_admin_get_malware_patterns(): array { 'regex' => '/preg_replace\s*\(\s*["\'].*\/e["\'\s]/i', 'risk_score' => 9.0, ), + array( + 'id' => 'eval_variable', + 'label' => 'eval($variable)', + 'regex' => '/eval\s*\(\s*\$/i', + 'risk_score' => 9.0, + ), array( 'id' => 'assert_variable', 'label' => 'assert($variable)', diff --git a/simulate-hack.sh b/simulate-hack.sh new file mode 100755 index 0000000..9a243d7 --- /dev/null +++ b/simulate-hack.sh @@ -0,0 +1,109 @@ +#!/bin/bash +# +# Simulate a hacked WordPress site for security scanner testing. +# +# This script: +# 1. Plants suspicious options in wp_options (eval, base64, inline script) +# 2. Creates a rogue administrator account +# 3. Creates a fake malicious PHP file in wp-content/plugins/ +# 4. Modifies wp-login.php to trigger a core checksum mismatch +# +# Usage: bash simulate-hack.sh +# Run from Local's site shell (Open Site Shell in Local app). + +set -e + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +cd "$SCRIPT_DIR" + +echo "============================================" +echo " Simulating hacked WordPress site" +echo " (for wp-agentic-admin scanner testing)" +echo "============================================" +echo "" + +# --- Step 1: Plant suspicious options --- +echo "--- Step 1: Planting suspicious options ---" +echo "" + +wp option update wp_session_manager_x 'eval(base64_decode("ZWNobyAiaGFja2VkIjs="));' +echo "[+] Created option 'wp_session_manager_x' with eval() payload" + +wp option update wp_cache_config_bak '$code = base64_decode("ZnVuY3Rpb24gZ2V0X3NoZWxsKCkgeyByZXR1cm4gImZha2UiOyB9"); include($code);' +echo "[+] Created option 'wp_cache_config_bak' with base64_decode payload" + +wp option update widget_display_override '' +echo "[+] Created option 'widget_display_override' with inline script" +echo "" + +# --- Step 2: Create rogue admin account --- +echo "--- Step 2: Creating rogue admin account ---" +echo "" + +if wp user get eviluser@leet.com --field=ID 2>/dev/null; then + echo "[*] Evil user 'eviluser@leet.com' already exists" +else + wp user create eviluser eviluser@leet.com --role=administrator --user_pass=h4ck3d123 + echo "[+] Created administrator account 'eviluser' (eviluser@leet.com)" +fi +echo "" + +# --- Step 3: Create a fake malicious PHP file --- +echo "--- Step 3: Creating fake backdoor file ---" +echo "" + +BACKDOOR_DIR="wp-content/plugins/totally-legit-seo" +mkdir -p "$BACKDOOR_DIR" + +cat > "$BACKDOOR_DIR/helper.php" << 'EOPHP' +> wp-login.php + echo '// SIMULATED_HACK_MARKER' >> wp-login.php + echo '$_simulated_hack_gibberish = "aGFja2VkX2J5X3NjcmlwdF9raWRkaWVz";' >> wp-login.php + echo "[+] Modified wp-login.php (appended gibberish variable)" + else + echo "[*] wp-login.php already modified" + fi +else + echo "[!] wp-login.php not found — skipping" +fi + +echo "" +echo "============================================" +echo " Hack simulation complete!" +echo "" +echo " What was planted:" +echo " - 3 suspicious options in wp_options" +echo " (eval, base64_decode, inline script)" +echo " - Admin account: eviluser@leet.com" +echo " - Backdoor: $BACKDOOR_DIR/helper.php" +echo " - Modified: wp-login.php (checksum fail)" +echo "============================================" \ No newline at end of file From 38287e2682e7b1e71c7d9a785c6b4e461ffd95d8 Mon Sep 17 00:00:00 2001 From: Tome Pajkovski Date: Sun, 22 Mar 2026 10:46:27 +0100 Subject: [PATCH 2/2] fix: resolve WP root in simulate-hack.sh instead of using script dir The script was moved into the plugin folder but still used its own directory as the working directory. Now it detects the WordPress root via WP-CLI or by walking up the directory tree, so file paths like wp-login.php and wp-content/plugins/ resolve correctly regardless of where the script lives. Co-Authored-By: Claude Opus 4.6 (1M context) --- simulate-hack.sh | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/simulate-hack.sh b/simulate-hack.sh index 9a243d7..8ef8f5f 100755 --- a/simulate-hack.sh +++ b/simulate-hack.sh @@ -13,8 +13,28 @@ set -e -SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" -cd "$SCRIPT_DIR" +# Navigate to the WordPress root (ABSPATH). +# Detect it via WP-CLI, fall back to walking up from the script directory. +if command -v wp &>/dev/null; then + WP_ROOT="$(wp eval 'echo ABSPATH;' 2>/dev/null)" || true +fi + +if [ -z "$WP_ROOT" ] || [ ! -f "$WP_ROOT/wp-login.php" ]; then + # Walk up from the script's location until we find wp-login.php. + WP_ROOT="$(cd "$(dirname "$0")" && pwd)" + while [ "$WP_ROOT" != "/" ] && [ ! -f "$WP_ROOT/wp-login.php" ]; do + WP_ROOT="$(dirname "$WP_ROOT")" + done +fi + +if [ ! -f "$WP_ROOT/wp-login.php" ]; then + echo "[!] Could not locate WordPress root. Run this script from within your WP install." + exit 1 +fi + +cd "$WP_ROOT" +echo "WordPress root: $WP_ROOT" +echo "" echo "============================================" echo " Simulating hacked WordPress site"