Script for detecting potentially vulnerable Log4j jars [CVE-2021-44228] on Windows Server

Update 2021-12-18 – This looks like a much more competent script for detecting this vulnerability and there is a python version for Linux: https://github.com/CERTCC/CVE-2021-44228_scanner

Updated 2021-12-17 – Script is v1.4 and looks for .war files now too

Original post below

Inspired by the one-liner here: https://gist.github.com/Neo23x0/e4c8b03ff8cdf1fa63b7d15db6e3860b#find-vulnerable-software-windows

gci 'C:\' -rec -force -include *.jar -ea 0 | foreach {select-string "JndiLookup.class" $_} | select -exp Path

I wrote a script to expand on the command, support Windows Server 2008 onward and to be more automated.

This script is basically the one liner with a bit of logic to get all the local fixed disks on a server and iterate through them all looking for Log4j jar file:

<# 
.Synopsis 
    Checks the local system for Log4Shell Vulnerability [CVE-2021-44228]
.DESCRIPTION 
    Gets a list of all volumes on the server, loops through searching each disk for Log4j stuff
    Using base search from https://gist.github.com/Neo23x0/e4c8b03ff8cdf1fa63b7d15db6e3860b#find-vulnerable-software-windows

    Version History
        1.0 - Initial release
        1.1 - Changed ErrorAction to "Continue" instead of stopping the script
        1.2 - Went back to SilentlyContinue, so much noise
        1.3 - Borrowed some improvements from @cedric2bx (https://gist.github.com/Neo23x0/e4c8b03ff8cdf1fa63b7d15db6e3860b#gistcomment-3995092)
                Replace attribute -Include by -Filter (prevent unauthorized access exception stopping scan)
                Remove duplicate path with Get-Unique cmdlet
        1.4 - Added .war support thanks to @djblazkowicz (https://gist.github.com/Neo23x0/e4c8b03ff8cdf1fa63b7d15db6e3860b#gistcomment-3998189)
.EXAMPLE 
    .\check_CVE-2021-44228.ps1
.NOTES 
    Created by Eric Schewe 2021-12-13
    Modified by Cedric BARBOTIN 2021-12-14
#> 

# Get Windows Version string
$windowsVersion = (Get-WmiObject -class Win32_OperatingSystem).Caption

# Server 2008 (R2)
if ($windowsVersion -like "*2008*") {

    $disks = [System.IO.DriveInfo]::getdrives() | Where-Object {$_.DriveType -eq "Fixed"}

}
# Everything else
else {

    $disks = Get-Volume | Where-Object {$_.DriveType -eq "Fixed"}

}

# I have no idea why I had to write it this way and why .Count didn't just work
$diskCount = $disks | Measure-Object | Select-Object Count -ExpandProperty Count

Write-Host -ForegroundColor Green "$(Get-Date -Format "yyyy-MM-dd H:mm:ss") - Starting the search of $($diskCount) disks"

foreach ($disk in $disks) {

    # One liner from https://gist.github.com/Neo23x0/e4c8b03ff8cdf1fa63b7d15db6e3860b#find-vulnerable-software-windows
    # gci 'C:\' -rec -force -include *.jar -ea 0 | foreach {select-string "JndiLookup.class" $_} | select -exp Path

    # Server 2008 (R2)
    if ($windowsVersion -like "*2008*") {

        Write-Host -ForegroundColor Yellow "  $(Get-Date -Format "yyyy-MM-dd H:mm:ss") - Checking $($disk.Name): - $($disk.VolumeLabel)"
        Get-ChildItem "$($disk.Name)" -Recurse -Force -Include @("*.jar","*.war") -ErrorAction SilentlyContinue | ForEach-Object { Select-String "JndiLookup.class" $_ } | Select-Object -ExpandProperty Path | Get-Unique

    }
    # Everything else
    else {

        Write-Host -ForegroundColor Yellow "  $(Get-Date -Format "yyyy-MM-dd H:mm:ss") - Checking $($disk.DriveLetter): - $($disk.VolumeLabel)"
        Get-ChildItem "$($disk.DriveLetter):\" -Recurse -Force -Include @("*.jar","*.war") -ErrorAction SilentlyContinue | ForEach-Object { Select-String "JndiLookup.class" $_ } | Select-Object -ExpandProperty Path | Get-Unique

    }

}

Write-Host -ForegroundColor Green "$(Get-Date -Format "yyyy-MM-dd H:mm:ss") - Done checking all drives"

Sample output with nothing found:

check_CVE-2021-44228.ps1 sample output

Sample output with something found:

check_CVE-2021-44228.ps1 sample output 2

Good luck everyone.

Script to sync Domain Controller SSL Certificates to a specific host

We have an application that uses LDAP over SSL to authenticate users via Active Directory. The server running the application is a member of the domain and has the domains Root CA installed in it’s local certificate store.

Technically the Root CA should be good enough for the server and any applications on it to trust the SSL certificates on our domain controllers because they are signed by that Root CA. Not the case for this application.

We have four Domain Controllers each with a different SSL certificate that expires yearly and each with a different expiry date. Exporting and importing these certificates manually is going to be a huge annoyance.

I wrote a PowerShell script to handle doing it automatically for us. This script is being run against 2012 R2 Domain controllers which is why I use the PowerShell Module exporting the certificates and the target is  2008 R2 which is why the import is handled via ‘certutil’. You could easily swap these out in the script to suite your needs.

# Domain Controller SSL Certificate syncing script
#
# Created by: Eric Schewe
# Created on: 2018-10-11
#
# Permission Requirements
# -----------------------------------------------------
# "Remote Management Users" in the domain that holds the DCs you're pulling the certificates from
# Local Admin on the destination server
# Login As Batch Job on what ever server you're running the script from unless you're running it as a local admin on the destination server
#
# Other requirepments
# -----------------------------------------------------
# A directory called C:\Temp must exist on all servers involved
#

# The domain we want to get DC certs from
$domainInfo = Get-ADDomain <FQDN OF YOUR DOMAIN>

# Server we're installing the certificates on
$destinationServer = "<FQDN OF THE DESTINATION SERVER>"

# For each Domain Controller in the domain do the following
foreach ($dc in $domainInfo.ReplicaDirectoryServers) {

    # Open a remote session to the DC
    Write-Host "Connecting to $($dc)"
    $sessionCertServer = New-PSSession -ComputerName $dc -EnableNetworkAccess

    # Find the certificates thumbprint that matches the DCs FQDN
    Write-Host "Getting cert list for $($dc)"
    $thumbPrint = Invoke-Command -Session $sessionCertServer -ScriptBlock {(Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object {$_.Subject -match "$($dc)"}).Thumbprint}

    # Debugging
    Write-Host "Dumping thumb prints from $($dc)"
    Write-Host $thumbPrint

    # Export the certificate on the remote DC, based on it's thumbprint
    Write-Host "Exporting $($thumbPrint) on $($dc)"
    Invoke-Command -Session $sessionCertServer -ScriptBlock {Get-ChildItem -Path Cert:\LocalMachine\My\$thumbPrint | Export-Certificate -FilePath "C:\Temp\$($args[0])-159969.crt" -Type CERT} -argumentlist $dc

    # Copy the exported certificate from the remote server to the local server
    Write-Host "Copying C:\Temp\$($dc)-159969.crt from $dc to C:\Temp locally"
    Copy-Item -FromSession $sessionCertServer -Path "C:\Temp\$($dc)-159969.crt" -Destination "C:\temp\"

    # Remove the exported certificate file on the remote server and close the session
    Write-Host "Cleaning up remote files and sessions"
    Invoke-Command -Session $sessionCertServer -ScriptBlock {Remove-Item -path "C:\Temp\$($args[0])-159969.crt"} -argumentlist $dc
    Remove-PSSession -Session $sessionCertServer

}

# Open a session to the server we're putting the certs on
$sessionDestinationServer = New-PSSession -ComputerName $destinationServer -EnableNetworkAccess

# Copy each 
foreach ($dc in $domainInfo.ReplicaDirectoryServers) {

    # Import the exported certificate file on the local server and then delete it
    Write-Host "Moving C:\Temp\$($dc)-159969.crt from local server to destination server"
    Copy-Item -ToSession $sessionDestinationServer -Path "C:\Temp\$($dc)-159969.crt" -Destination "C:\temp\"

    Write-Host "Importing certificate for $($dc) into destination server"
    Invoke-Command -Session $sessionDestinationServer -ScriptBlock {certutil -enterprise -f -v -AddStore "Root" "C:\Temp\$($args[0])-159969.crt"} -argumentlist $dc

    Write-Host "Deleting certificate files for $($dc)"
    Remove-Item -path "C:\Temp\$($dc)-159969.crt"
    Invoke-Command -Session $sessionDestinationServer -ScriptBlock {Remove-Item -path "C:\Temp\$($args[0])-159969.crt"} -argumentlist $dc

}

Remove-PSSession -Session $sessionDestinationServer

 

NetApp SnapManager for Exchange failing with VSS_E_WRITERERROR_RETRYABLE

Running into a problem with Exchange 2010, a FAS2240-4 and SnapManager for Exchange 7.1 where backups would randomly fail every now and then started failing consistently.

Our DFM server would send us an e-mail when the failure occurred that looked like this:

CLIENT APP ERROR Backup: SME Version 7.1: (111) on dora02 at Sun Sep 04 22:09:31 PDT 2016

The backup failure would also knock the databases offline and require us to re-sync them the next day.

Digging into the SME logs we found the following:

[22:10:42.635]  *****BACKUP DETAIL SUMMARY*****

 [22:10:42.635]  Backup group set #1: 

 [22:10:42.635]  Backup SG/DB [FK] Error: SnapManager detected the following Exchange writer error. Please retry SnapManager operation.
 VSS_E_WRITERERROR_RETRYABLE: The writer failed due to an error that might not occur if another snapshot copy is created.


 [22:10:42.635]  Backup SG/DB [LQ] Error: SnapManager detected the following Exchange writer error. Please retry SnapManager operation.
 VSS_E_WRITERERROR_RETRYABLE: The writer failed due to an error that might not occur if another snapshot copy is created.


 [22:10:42.635]  Backup SG/DB [RZ] Error: SnapManager detected the following Exchange writer error. Please retry SnapManager operation.
 VSS_E_WRITERERROR_RETRYABLE: The writer failed due to an error that might not occur if another snapshot copy is created.


 [22:10:42.635]  Backup SG/DB [AE] Error: SnapManager detected the following Exchange writer error. Please retry SnapManager operation.
 VSS_E_WRITERERROR_RETRYABLE: The writer failed due to an error that might not occur if another snapshot copy is created.


 [22:10:42.635]  Backup SG/DB [Public Folders (<SERVER>)] Error: SnapManager detected the following Exchange writer error. Please retry SnapManager operation.
 VSS_E_WRITERERROR_RETRYABLE: The writer failed due to an error that might not occur if another snapshot copy is created.




 [22:10:42.635]  ***SNAPMANAGER BACKUP JOB ENDED AT: [09-04-2016_22.10.42]

 [22:10:42.635]  Failed to backup storage groups/databases.

NetApp provides this page for what they call “Common VSS errors”: https://kb.netapp.com/support/index?page=content&id=1010785&locale=en_US

None of the suggestions there helped us.

In the end I found this forum post for a different product: https://community.emc.com/thread/168678?tstart=0 and applied the registry edits they suggested here: https://community.emc.com/message/705346#705346

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpWindowSize=256000
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\GlobalMaxTcpWindowSize=16777216
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\KeepAliveInterval=1000
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\KeepAliveTime=600000

and then rebooted our Exchange server running SME.

Since making the change roughly 20 days ago we haven’t had a single failed backup.

Error 1603 when upgrading vCenter 6.0u1 to 6.0u2

Recently ran across this one:

2016-06-22 10:23:19.878-07:00| vcsInstUtil-3634789| I: MonitorStatusFile: Other process terminated with 0, exiting
2016-06-22 10:23:19.878-07:00| vcsInstUtil-3634789| I: MonitorStatusFile: Process exited with a '0' exit code; no status monitoring so assuming success
2016-06-22 10:23:19.878-07:00| vcsInstUtil-3634789| I: MonitorStatusFile: called parse callback 0 times
2016-06-22 10:23:19.878-07:00| vcsInstUtil-3634789| I: MonitorStatusFile: No need to wait for process to complete
2016-06-22 10:23:19.878-07:00| vcsInstUtil-3634789| I: MonitorStatusFile: Process's job tree still hasn't terminated, waiting
2016-06-22 10:23:19.878-07:00| vcsInstUtil-3634789| I: MonitorStatusFile: Wait on process's job tree has completed: 0
2016-06-22 10:23:19.878-07:00| vcsInstUtil-3634789| I: Leaving function: MonitorStatusFile
2016-06-22 10:23:19.878-07:00| vcsInstUtil-3634789| E: LaunchProcAndMonitorStatus: Job still alive, terminating
2016-06-22 10:23:19.878-07:00| vcsInstUtil-3634789| I: Leaving function: LaunchProcAndMonitorStatus
2016-06-22 10:23:19.878-07:00| vcsInstUtil-3634789| I: RunFirstLastUpdateboot: Successfully ran boot script: "C:\Windows\system32\cmd.exe /S /C ""D:\VMware\vCenter Server\bin\run-updatebootrb-scripts.bat"""
2016-06-22 10:23:19.878-07:00| vcsInstUtil-3634789| I: Leaving function: VM_RunUpdateBoot
2016-06-22 10:23:20.065-07:00| vcsInstUtil-3634789| E: wWinMain: MSI result of install of "D:\Temp\VMware-VIMSetup-all-6.0.0-3634788\vCenter-Server\Packages\vcsservicemanager.msi" may have failed: 1603 (0x00000643)
2016-06-22 10:23:20.065-07:00| vcsInstUtil-3634789| E: LaunchPkgMgr: Operation on vcsservicemanager.msi appears to have failed: 1603 (0x00000643)
2016-06-22 10:23:20.065-07:00| vcsInstUtil-3634789| I: PitCA_MessageBox: Displaying message: "Installation of component VCSServiceManager failed with error code '1603'. Check the logs for more details."

 

The upgrade would get to the VCSServiceManager step, fail and back out. It then left our existing vCenter 6.0u1 installation unable to start.

I did all the standard things you’ll find on VMwares Support site (and recommended by the support rep I got a hold of):

2119768 Error code 1603 when upgrading to vCenter Server 6.0
2127519 Installing the VMware vCenter Server 6.0 fails with the vminst.log error: MSI result of install of “C:\vCenter-Server\Packages\vcsservicemanager.msi” may have failed : 1603
2137365 Upgrade of vCenter from 5.x to 6.0 fails with “Installation of component VCSServiceManager failed with error code ‘1603’. Check the logs for more details.”
2113068 Upgrading or installing VMware vCenter Server 6.0 fails with the vminst.log error: Error in accessing registry entry for DSN
2119169 Installing VMware vCenter Server 6.0 using a Microsoft SQL database fails with the error: An error occurred while starting service ‘invsvc’

None helped.

While waiting for my VMware Support rep to dig through the log files, on a hunch, I made the following changes:

  1. Checkmarked ‘IPv6’ in the network stack for the servers network card
  2. Re-ran the vCenter installer separately by right clicking it and ‘Running As Administrator’ (\VMware-VIMSetup-all-6.0.0-3634788\vCenter-Server\VMware-vCenter-Server.exe)

The installation then succeeded and we have a functioning vCenter again.

Two fun facts:

  1. The UAC is disabled on our server
  2. IPv6 was (and still is) disabled via the registry using these utilities even though I’ve now re-checked IPv6 in the network cards network stack

Our server is in a fairly unique configuration I suspect but hopefully this will help someone else.

Previous version of the Active Directory Replication Status Tool

Who liked using the Active Directory Replication Status Tool? I did.

Who thought it was a great, simple, straight forward tool that was far easier than interpreting the output of some command line tools and didn’t feel it needed to become a cloud service with a less intitive interface? I do.

Digging through a few of my servers I found the old installer for the Active Directory Replication Status Tool. The version you can install on your own servers and doesn’t appear to give an error about the installer being expired.

Download it here: https://dl.dropboxusercontent.com/u/22772464/adreplstatusInstaller.zip

I believe this is version 1.1 even though the splash page when launching it says it’s 1.0. It was the latest version you could download before Microsoft expired it here and told everyone to start using the cloud based SCOM solution they offer.

Please share it/mirror it for all to enjoy.

 

Update – 2016-04-05

Looks like Microsoft is trying to kill this tool. When you try the use the version I’ve linked above now it says it has also expired.

I’ve figured out a workaround. Download this handy tool and then do this:

runasdate settings

If anyone knows assembler and wants to try dissecting repl.exe to remove the date check I’ll happily link/host to their modified repl.exe.

I’ve seen a few comments on other sites about the saftey of getting this tool from a non-Microsoft source and this is the best I can provide to prove I have not altered the MSI file. If you check the hashes against the two download links below you’ll see they match files uploaded well before this blog post.

MSI File
MD5: d63ceaa4131f8dc64800d33ac3b242c7
SHA1: 1a117510e42d284199743c53722dd51690a93d59

http://www.herdprotect.com/adreplstatusinstaller.msi-1a117510e42d284199743c53722dd51690a93d59.aspx
https://malwr.com/analysis/Y2JlNDQ0YmM0MjM3NGY4MWJlOGJhOTkyMDNkZGQxZGI/

You can try the workaround I’ve mentioned above on the official download as well: https://www.microsoft.com/en-ca/download/details.aspx?id=30005

 

Update 2016-04-20

Good news everyone! Microsoft has brought back the stand-alone tool thanks to everyone who provided them feedback demanding it.

See: https://feedback.azure.com/forums/267889-operational-insights/suggestions/12293631-bring-back-the-on-prem-ad-replication-status-tool

The new, non-expiring download, can be found here: https://www.microsoft.com/en-us/download/details.aspx?id=30005

 

Update 2017-07-12

Looks like the tool is expiring again.

I was able to re-download, re-install from here: https://www.microsoft.com/en-us/download/details.aspx?id=30005

The tool worked again but now gives me a 24 day count down.

 

Update 2020-01-13

Microsoft might have finally killed this app. The latest version says the license is expired and the RunAsDate trick isn’t working for me anymore, at least not on Server 2019.

Looks like Microsoft posted a new version of the tool here: https://www.microsoft.com/en-us/download/details.aspx?id=30005 sadly it’s license is still expired.