Find vulnerable WordPress plugin versions fast using PowerShell

Use PowerShell to find vulnerable WordPress plugins on your Windows webserver fast, because on a daily bases, new vulnerabilities are found in WordPress plugins and you can count on the fact you have customers using that vulnerable version of that particular plugin.
Published on Friday, 8 May 2020

Screenshot by Jan Reilink

On a daily bases, new vulnerabilities are found in WordPress plugins. And when you host thousands of WordPress sites, you can count on the fact you have some customers using that vulnerable version of that particular plugin. So you need to find those vulnerable versions on your servers fast. On Windows Server, PowerShell is a perfect tool for the job!

Of course you must have other security measures in place, like a web application firewall, good OS security, separation of users and roles, IIS application pools, and all that. But that doesn't prevent you from having a vulnerable file on your server. And when you do, you want to find that file.

This PowerShell script helps me and my coworkers. Whenever we are notified about about a (major) vulnerability, like Elementor Pro ([1]) for example, I fire up the PS snippet and it lists all websites using a vulnerable version of the particular plugin.

All you need to gather first is: the WordPress plugin file having the version number in it (elementor-pro.php), and the safe, patched version (2.9.4).

UPDATE: As of 4:22 PM UTC today, May 7 2020, Elementor has released version 2.9.4 of Elementor Pro. Our threat intelligence team has verified that this patches this vulnerability. We recommend updating to this version immediately.

https://www.wordfence.com/blog/2020/05/combined-attack-on-elementor-pro-and-ultimate-addons-for-elementor-puts-1-million-sites-at-risk/

find-vulnerable-wp-plugins.ps1

You can use the following PowerShell script as an example to search for and find vulnerable WordPress plugins. One plugin at a time.

<#

.SYNOPSIS
Search and find vulnerable WordPress plugins on your Windows Server NTFS file system fast.

.DESCRIPTION
The script searches for plugin files, in which the version number is looked up and compared to a known safe, patched version. Is the version found lower than the patched version, then the following information is printed:
  1. PSComputerName
  2. file (.FullName)
  3. the version number found

The search is limited to 5 levels deep. Increase this is necessary on line 55. The path searched is "z:\sites\www", change for your environment on line 55 as well.

.EXAMPLE
.\find-vulnerable-wp-plugins.ps1 elementor-pro.php 2.9.4
Searches for the file elementor-pro.php on all web servers, and prints the result if the version number is lower than 2.9.4.

.NOTES
- 

.LINK
-https://vevida.com-
-https://vevida.dev-
https://www.saotn.org

#>

[CmdletBinding()]
  Param(
    [Parameter(Mandatory = $true, Position = 0, HelpMessage="Plugin version file")]
    [string]$versionfile,
    [Parameter(Mandatory = $true, Position = 1, HelpMessage="What is the safe, patched, verson? Tip: if version 1.0.0 is vulnerable, but the plugin hasn't been updated yet, then fill out 1.0.1")]
    [string]$safeversion
  )

if($versionfile -notmatch "\.php$") {
    $versionfile += ".php"
}

$servers = (Get-ADComputer -Filter {(enabled -eq $True)} -SearchBase "OU=Computers,DC=example,DC=org").DNSHostName
Invoke-Command -ComputerName $servers -ScriptBlock {
  Try {
    foreach($file in (Get-ChildItem -Path "z:\sites\www" -Depth 5 -File -Filter $Using:versionfile -Recurse -ErrorAction Stop)) {
      $version = (Select-String "Version: " $file.FullName).line.Split("Version: ")[-1]
      if($version -notlike "${using:safeversion}") {
        [PSCustomObject]@{
          File = $file.fullname
          Version = $version
          Computername = $_.PSComputerName
        }
      }
    }
  }
  Catch {
  }
}  -ThrottleLimit $($servers.Count) |select-object pscomputername,file,version | ft

this code is not perfect, but works in my environment. Use at your own risk.

Using PowerShell cmdlets like Get-ChildItem and Select-String, all files are searched for matching pattern, in this case $Using:versionfile (thus elementor-pro.php). If a matching file is found, the version number is selected using Select-String and compared to our safe version. Is the selected version number lower than our safe version? Then it must be a vulnerable version and it's printed out.

The result is for example:

srv-01.example.com Z:\sites\www\example.net\www\wp-content\plugins\elementor-pro\elementor-pro.php     2.9.2
srv-01.example.com Z:\sites\www\example.net\www\archive\wp-content\plugins\elementor-pro\elementor-pro.php 2.9.3
srv-02.example.com Z:\sites\www\foobar.com\www\wp-content\plugins\elementor-pro\elementor-pro.php            2.9.3
srv-02.example.com Z:\sites\www\foobar.net\www\wp-content\plugins\elementor-pro\elementor-pro.php         2.9.3
srv-03.example.com Z:\sites\www\example.org\www\wp-content\plugins\elementor-pro\elementor-pro.php           2.9.3
srv-04.example.com Z:\sites\www\testsite-01.vwxyz\www\wp-content\plugins\elementor-pro\elementor-pro.php     2.9.2
srv-10.example.com Z:\sites\www\blahblah.blah\www\old\wp-content\plugins\elementor-pro\elementor-pro.php      2.8.4

Use FSRM File Screens to prevent the upload of vulnerable plugin files

Suppose the plugin developer hasn't released a patched version of the pluging yet. Then you don't want your users / customers to be able to upload this vulnerable plugin to even more websites, now do you?

And this is where File Server Resource Manager (FSRM) File Screens come in handy!

Use File Server Resource Manager (FSRM) File Screens to temporarily block the upload of known vulnerable plugin files. Unfortunately you cannot filter and block on a specific plugin version, but you can temporarily block the upload completely.

In my post Deny vulnerable WordPress plugins using Windows Server File Server Resource Manager's File Screens I show you how to deny the upload of WP-DB-Backup on Windows Server IIS. Use this to your advantage, cheers ! :)