Wordfence CLI Vulnerability Scan Bash Script for all Websites on a Plesk Server

Below I have compiled a script that scans all directories in the vhosts folder on a Plesk Obsidian web server using Wordfence CLI. It scans all the sites, generates a custom report as well as vulnerability report for each site. Once the script completes, it will send an email to the address specified in the script and attach the vulnerability csv for any site that has a vulnerability detected.

You will need to customize the script to fit your needs and your server.

I set my up to run as a scheduled task daily using the Plesk root account but you may need to use a different user.

To setup your script, connect to your server with root permissions via terminal and create a file named something like “wordfence-vuln-scan.sh”.

touch wordfence-vuln-scan.sh

Then make the script executable.

chmod +x wordfence-vuln-scan.sh

Now, open the script for editing.

nano wordfence-vuln-scan.sh

Copy and paste the following script into the editor. Be sure to customize the paths to fit your servers paths, etc.

#!/bin/bash
# Script for scaning all directories in the vhosts folder on a Plesk Obsidian web server using Wordfence CLI.
# It scans all the sites, generates a custom report as well as vulnerability report for each site.
# Once the script completes, it will send an email to the address specified in the script and attach the vulnerability csv for any site that has a vulnerability detected.
# https://nwdigital.cloud

# person to send scan results to
email="REPLACE_WITH_YOUR_EMAIL_ADDRESS"

# Log folder
logFolder="/home/wordfence-scans" # Use this or edit to your desired path

# Step 1: Create the directory if it doesn't exist
if [ ! -d "$logFolder" ]; then
  mkdir -p "$logFolder"
  #echo "Directory $logFolder created."
fi

# setup the log path
log=$logFolder/wordfence-scan.log

# Step 2: Create the file if it doesn't exist
if [ ! -f "$log" ]; then
  touch "$log"
  #echo "File $log created."
fi

# clear the previous log file data if any
> $log

ScanResults=()

Append() {
   tee -a $log
}

# Specify the directory for vhost files
directory="/var/www/vhosts"

ScanSite()
{
   wordfence vuln-scan --output-format csv --output-path $logFolder/$1/$1-scan.csv $directory/$1/httpdocs 2>&1 | tee -a $logFolder/wordfence-scan.log
   ScanResults+=(""$logFolder"/"$1"/"$1"-scan.csv")
}




# Initialize an array to hold the folder names
folders=()

exclude=(
    system
    default
    chroot
)

# Loop through the items in the directory
for item in "$directory"/*; do
  # Check if the item is a directory
  if [ -d "$item" ]; then
    # Add the directory name to the array
    if [ "$(basename "$item")" != "${exclude[0]}" ] && [ "$(basename "$item")" != "${exclude[1]}" ] && [ "$(basename "$item")" != "${exclude[2]}" ]; then
      folders+=("$(basename "$item")")
    fi
  fi
done

# Print the array of folder names
echo "Folders in $directory:"
for folder in "${folders[@]}"; do
  echo "$folder"
done

echo "<h3>Wordfence Scan Results For $HOSTNAME on `date +"%m-%d-%Y %H:%M:%S"`</h3>" | Append
echo "" | Append

for ((i = 0; i < ${#folders[@]}; ++i)); do
  echo "___________________________________________________________________________________________<br>" | Append
  echo "" | Append
  echo "<p><b>Scan Results for ${folders[$i]}</b></p>" | Append
  mkdir -p $logFolder/${folders[$i]}
  ScanSite "${folders[$i]}"
  echo "<br>" | Append
done

DIR="$(dirname "$(realpath "$0")")"
NAME="$(basename "$0")"

echo "<br>___________________________________________________________________________________________" | Append
echo "<p>Script location: $DIR/$NAME </p>" | Append
echo "WORDFENCE SCAN COMPLETED SUCCESSFULLY ON $HOSTNAME" | Append

# Check if the file exists
if [[ -f "$log" ]]; then
  # Perform search and replace, and overwrite the file
  sed -i "s/INFO/<br>INFO/g" "$log"
  sed -i "s/WARNING/<br>WARNING/g" "$log"
else
  echo "Error: File '$log' not found."
fi

# Attach any scan result csv files that have content or not empty
attach_args=()

for file in "${ScanResults[@]}"; do
   # Check if file exists and has content and add to attach_args
   if [ -s "$file" ]; then
       #echo "✅  File exists and is not empty. Adding to attachments array."
       attach_args+=("-A" "$file")
   fi
done

SendEmail() {
  mail_output=$(cat $log | mailx -A $log "${attach_args[@]}" --content-type="text/html" -s "Wordfence Scan Results for $HOSTNAME" $email)
}

SendEmail

# Check if the mail command was successful
if [ $? -eq 0 ]; then
    echo "Report emailed successfully to $email"
    #echo "Mail command output:"
    echo "$mail_output"
else
    echo "Failed to send mail."
    echo "Mail command output:"
    echo "$mail_output"
fi

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.