How to detect the Log4Shell vulnerability with Powershell

Recently I found a few solutions online that demonstrate how system administrators can detect the Log4Shell vulnerability with Powershell.

Example:

These scripts were great but I noticed they depended on Get-ChildItem to find .jar files on systems. As you may know, Get-ChildItem can be VERY slow to run. Especially when you are scanning entire drives for specific files. That’s when I decided to find an alternative that could run faster and use less resources. I first tried to use .Net but unfortunately that didn’t go anywhere because the EnumerationOptions class is not available to use with Powershell 5.0. Then I started searching Google for other options and someone on StackOverFlow recommended using RoboCopy without copying anything instead. Let’s just say I ended up canceling Get-ChildItem because it was still running after RoboCopy finished querying all of my drives for .jar files.

As you can see in the script, I also decided to not depend on a text file from GitHub that the other scripts were using (https://github.com/mubix/CVE-2021-44228-Log4Shell-Hashes/raw/main/sha256sums.txt). It’s great that it was grabbing the latest .txt file but I didn’t feel comfortable using a file that could possibly be compromised at a later time. Instead I encoded the text file and decoded it so the script can be 100% standalone without any external dependencies.

Update 12/17/2021 – Since I have received a few requests to add custom file hashes, I have updated the script so you can easily add additional file hashes that the script can query. In order to do this, you will need to add the file hashes to the $CustomFileHashes variable.

Example on how to add additional file hashes:

$CustomFileHashes = @(
"9da0f5ca7c8eab693d090ae759275b9db4ca5acdbcfe4a63d3871e0b17367463"
"006fc6623fbb961084243cfc327c885f3c57f2eba8ee05fbc4e93e5358778c85"
)

Well here is the script that you were waiting for. Hopefully it helps!

$CustomFileHashes = @(

)

Remove-Variable List,TotalResults -Force -ErrorAction SilentlyContinue
 
$Drives = (Get-PSDrive -PSProvider FileSystem | Where-Object { $_.Used -gt 0 }).Root
 
$List = ForEach($Drive in $Drives) {
  
    Robocopy $Drive 'Dest' *.jar /l /njh /njs /ndl /ns /nc /fp /e /xj
  
}
 
$EncodedHashes = "IyAyLlggdmVyc2lvbnMKCmJmNGY0MTQwMzI4MGMxYjExNTY1MGQ0NzBmOWIyNjBhNWM5MDQyYzA0ZDliY2MyYTZjYTUwNGE2NjM3OWIyZDYgIC4vYXBhY2hlLWxvZzRqLTIuMC1hbHBoYTItYmluL2xvZzRqLWNvcmUtMi4wLWFscGhhMi5qYXIKNThlOWY3MjA4MWVmZmY5YmRhYWJkODJlM2IzZWZlNWIxYjlmMTY2NmNlZmUyOGY0MjlhZDcxNzZhNmQ3NzBhZSAgLi9hcGFjaGUtbG9nNGotMi4wLWJldGExLWJpbi9sb2c0ai1jb3JlLTIuMC1iZXRhMS5qYXIKZWQyODVhZDVhYzZhOGNmMTM0NjFkNmMyODc0ZmRjZDNiZjY3MDAyODQ0ODMxZjY2ZTIxYzJkMGFkZGE0M2ZhNCAgLi9hcGFjaGUtbG9nNGotMi4wLWJldGEyLWJpbi9sb2c0ai1jb3JlLTIuMC1iZXRhMi5qYXIKZGJmODhjNjIzY2MyYWQ5OWQ4MmZhNGM1NzVmYjEwNWUyMDgzNDY1YTQ3Yjg0ZDY0ZTJlMWE2M2UxODNjMjc0ZSAgLi9hcGFjaGUtbG9nNGotMi4wLWJldGEzLWJpbi9sb2c0ai1jb3JlLTIuMC1iZXRhMy5qYXIKYTM4ZGRmZjFlNzk3YWRiMzlhMDg4NzY5MzJiYzI1MzhkNzcxZmY3ZGIyMzg4NWZiODgzZmVjNTI2YWZmNGZjOCAgLi9hcGFjaGUtbG9nNGotMi4wLWJldGE0LWJpbi9sb2c0ai1jb3JlLTIuMC1iZXRhNC5qYXIKN2Q4Njg0MTQ4OWFmZDEwOTc1NzZhNjQ5MDk0YWUxZWZiNzliMzE0N2NkMTYyYmEwMTk4NjFkZmFkNGU5NTczYiAgLi9hcGFjaGUtbG9nNGotMi4wLWJldGE1LWJpbi9sb2c0ai1jb3JlLTIuMC1iZXRhNS5qYXIKNGJmYjBkNTAyMmRjNDk5OTA4ZGE0NTk3ZjNlMTlmOWY2NGQzY2M5OGNlNzU2YTIyNDljNzIxNzlkM2Q3NWM0NyAgLi9hcGFjaGUtbG9nNGotMi4wLWJldGE2LWJpbi9sb2c0ai1jb3JlLTIuMC1iZXRhNi5qYXIKNDczZjE1YzA0MTIyZGFkODEwYzkxOWIyZjM0ODRkNDY1NjBmZDJkZDQ1NzNmNjY5NWQzODcxOTU4MTZiMDJhNiAgLi9hcGFjaGUtbG9nNGotMi4wLWJldGE3LWJpbi9sb2c0ai1jb3JlLTIuMC1iZXRhNy5qYXIKYjNmYWU0Zjg0ZDQzMDNjZGJhZDQ2OTY1NTRiNGU4ZDIzODFhZDNmYWY2ZTBjM2M4ZDJjZTYwYTQzODhjYWEwMiAgLi9hcGFjaGUtbG9nNGotMi4wLWJldGE4LWJpbi9sb2c0ai1jb3JlLTIuMC1iZXRhOC5qYXIKZGNkZTYwMzNiMjA1NDMzZDZlOTg1NWM5Mzc0MGY3OTg5NTFmYTNhM2YyNTIwMzVhNzY4ZDlmMzU2ZmRlODA2ZCAgLi9hcGFjaGUtbG9nNGotMi4wLWJldGE5LWJpbi9sb2c0ai1jb3JlLTIuMC1iZXRhOS5qYXIKODUzMzhmNjk0Yzg0NGM4YjY2ZDhhMWI5ODFiY2YzODYyN2Y5NTU3OTIwOWIyNjYyMTgyYTAwOWQ4NDllMWE0YyAgLi9hcGFjaGUtbG9nNGotMi4wLWJpbi9sb2c0ai1jb3JlLTIuMC5qYXIKZGIzOTA2ZWRhZDYwMDlkMTg4NmVjMWUyYTE5ODI0OWI2ZDk5ODIwYTM1NzVmOGVjODBjNmNlNTdmMDhkNTIxYSAgLi9hcGFjaGUtbG9nNGotMi4wLXJjMS1iaW4vbG9nNGotY29yZS0yLjAtcmMxLmphcgplYzQxMWEzNGZlZTQ5NjkyZjE5NmU0ZGMwYTkwNWIyNWQwNjY3ODI1OTA0ODYyZmRiYTE1M2RmNWU1MzE4M2UwICAuL2FwYWNoZS1sb2c0ai0yLjAtcmMyLWJpbi9sb2c0ai1jb3JlLTIuMC1yYzIuamFyCmEwMGE1NGUzZmI4Y2I4M2ZhYjM4Zjg3MTRmMjQwZWNjMTNhYjljNDkyNTg0YWE1NzFhZWM1ZmM3MWI0ODczMmQgIC4vYXBhY2hlLWxvZzRqLTIuMC4xLWJpbi9sb2c0ai1jb3JlLTIuMC4xLmphcgpjNTg0ZDEwMDA1OTFlZmEzOTEzODYyNjRlMGQ0M2VjMzVmNGRiYjE0NmNhZDkzOTBmNzMzNThkOWM4NGVlNzhkICAuL2FwYWNoZS1sb2c0ai0yLjAuMi1iaW4vbG9nNGotY29yZS0yLjAuMi5qYXIKOGJkYjY2Mjg0M2MxZjRiMTIwZmI0YzI1YTU2MzYwMDgwODU5MDBjZGY5OTQ3YjFkYWRiOWI2NzJlYTYxMzRkYyAgLi9hcGFjaGUtbG9nNGotMi4xLWJpbi9sb2c0ai1jb3JlLTIuMS5qYXIKYzgzMGNkZThmOTI5YzM1ZGFkNDJjYmRiNmIyODQ0N2RmNjljZWZmZTk5OTM3YmY0MjBkMzI0MjRkZjRkMDc2YSAgLi9hcGFjaGUtbG9nNGotMi4yLWJpbi9sb2c0ai1jb3JlLTIuMi5qYXIKNmFlM2IwY2I2NTdlMDUxZjk3ODM1YTY0MzJjMmIwZjUwYTY1MWIzNmI2ZDRhZjM5NWJiZTkwNjBiYjRlZjRiMiAgLi9hcGFjaGUtbG9nNGotMi4zLWJpbi9sb2c0ai1jb3JlLTIuMy5qYXIKNTM1ZTE5YmYxNGQ4Yzc2ZWMwMGE3ZTg0OTAyODdjYTJlMjU5N2NhZTJkZTViOGYxZjY1ZWI4MWVmMWMyYTRjNiAgLi9hcGFjaGUtbG9nNGotMi40LWJpbi9sb2c0ai1jb3JlLTIuNC5qYXIKNDJkZTM2ZTYxZDQ1NGFmZmY1ZTUwZTY5MzA5NjFjODViNTVkNjgxZTIzOTMxZWZkMjQ4ZmQ5YjliOTI5NzIzOSAgLi9hcGFjaGUtbG9nNGotMi40LjEtYmluL2xvZzRqLWNvcmUtMi40LjEuamFyCjRmNTNlNGQ1MmVmY2NjZGM0NDYwMTc0MjZjMTUwMDFiYjBmZTQ0NGM3YTZjZGM5OTY2Zjg3NDFjZjIxMGQ5OTcgIC4vYXBhY2hlLWxvZzRqLTIuNS1iaW4vbG9nNGotY29yZS0yLjUuamFyCmRmMDAyNzcwNDUzMzhjZWFhNmY3MGE3YjhlZWUxNzg3MTBiM2JhNTFlYWMyOGMxMTQyZWM4MDIxNTc0OTJkZTYgIC4vYXBhY2hlLWxvZzRqLTIuNi1iaW4vbG9nNGotY29yZS0yLjYuamFyCjI4NDMzNzM0YmQ5ZTMxMjFlMGEwYjc4MjM4ZDUxMzE4MzdiOWRiZTI2ZjFhOTMwYmM4NzJiYWQ0NGU2OGU0NGUgIC4vYXBhY2hlLWxvZzRqLTIuNi4xLWJpbi9sb2c0ai1jb3JlLTIuNi4xLmphcgpjZjY1ZjBkMzM2NDBmMmNkMGEwYjA2ZGQ4NmE1YzYzNTM5MzhjY2IyNWY0ZmZkMTQxMTZiNDg4NDE4MWUwMzkyICAuL2FwYWNoZS1sb2c0ai0yLjYuMi1iaW4vbG9nNGotY29yZS0yLjYuMi5qYXIKNWJiODRlMTEwZDVmMThjZWU0NzAyMWEwMjRkMzU4MjI3NjEyZGQ2ZGFjN2I5N2ZhNzgxZjg1YzZhZDNjY2VlNCAgLi9hcGFjaGUtbG9nNGotMi43LWJpbi9sb2c0ai1jb3JlLTIuNy5qYXIKY2NmMDJiYjkxOWUxYTQ0YjEzYjM2NmVhMWIyMDNmOTg3NzI2NTA0NzVmMmEwNmU5ZmFjNGIzYzk1N2E3YzNmYSAgLi9hcGFjaGUtbG9nNGotMi44LWJpbi9sb2c0ai1jb3JlLTIuOC5qYXIKODE1YTczZTIwZTkwYTQxMzY2MmVlZmU4NTk0NDE0Njg0ZGYzZDU3MjNlZGNkNzYwNzBlMWE1YWVlODY0NjE2ZSAgLi9hcGFjaGUtbG9nNGotMi44LjEtYmluL2xvZzRqLWNvcmUtMi44LjEuamFyCjEwZWYzMzExMTVjYmJkMThiNWJlM2YzNzYxZTA0NjUyM2Y5Yzk1YzEwMzQ4NDA4MmIxOGU2N2E3YzM2ZTU3MGMgIC4vYXBhY2hlLWxvZzRqLTIuOC4yLWJpbi9sb2c0ai1jb3JlLTIuOC4yLmphcgpkYzgxNWJlMjk5ZjgxYzE4MGFhOGQyOTI0ZjFiMDE1ZjJjNDY2ODZlODY2YmM0MTBlNzJkZTc1ZjdjZDQxYWFlICAuL2FwYWNoZS1sb2c0ai0yLjkuMC1iaW4vbG9nNGotY29yZS0yLjkuMC5qYXIKOTI3NWY1ZDU3NzA5ZTIyMDQ5MDBkM2RhZTI3MjdmNTkzMmY4NWQzODEzYWQzMWM5ZDM1MWRlZjAzZGQzZDAzZCAgLi9hcGFjaGUtbG9nNGotMi45LjEtYmluL2xvZzRqLWNvcmUtMi45LjEuamFyCmYzNWNjYzk5Nzg3OTdhODk1ZTViZWU1OGZhOGMzYjdhZDZkNWVlNTUzODZlOWU1MzJmMTQxZWU4ZWQyZTkzN2QgIC4vYXBhY2hlLWxvZzRqLTIuMTAuMC1iaW4vbG9nNGotY29yZS0yLjEwLjAuamFyCjUyNTY1MTdlNjIzN2I4ODhjNjVjODY5MWYyOTIxOWI2NjU4ZDgwMGMyM2U4MWQ1MTY3YzRhOGJiZDJhMGRhYTMgIC4vYXBhY2hlLWxvZzRqLTIuMTEuMC1iaW4vbG9nNGotY29yZS0yLjExLjAuamFyCmQ0NDg1MTc2YWVhNjdjYzg1ZjVjY2M0NWJiNjYxNjZmOGJmYzcxNWFlNGE2OTVmMGQ4NzBhMWY4ZDg0OGNjM2QgIC4vYXBhY2hlLWxvZzRqLTIuMTEuMS1iaW4vbG9nNGotY29yZS0yLjExLjEuamFyCjNmY2M0YzFmMmY4MDZhY2ZjMzk1MTQ0Yzk4YjhiYTJhODBmZTFiZjVlM2FkMzM5NzU4OGJiZDI2MTBhMzcxMDAgIC4vYXBhY2hlLWxvZzRqLTIuMTEuMi1iaW4vbG9nNGotY29yZS0yLjExLjIuamFyCjA1N2E0OGZlMzc4NTg2YjY5MTNkMjliNGIxMDE2MmI0YjUwNDUyNzdmMWJlNjZiN2EwMWZiN2UzMGJkMDVlZjMgIC4vYXBhY2hlLWxvZzRqLTIuMTIuMC1iaW4vbG9nNGotY29yZS0yLjEyLjAuamFyCjVkYmQ2YmIyMzgxYmY1NDU2M2VhMTViYzlmYmI2ZDcwOTRlYWY3MTg0ZTY5NzVjNTBmODk5NmY3N2JmYzNmMmMgIC4vYXBhY2hlLWxvZzRqLTIuMTIuMS1iaW4vbG9nNGotY29yZS0yLjEyLjEuamFyCmMzOWIwZWExNGU3NzY2NDQwYzU5ZTVhZTVmNDhhZGVlMDM4ZDliMWM3YTEzNzViMzc2ZTk2NmNhMTJjMjJjZDMgIC4vYXBhY2hlLWxvZzRqLTIuMTMuMC1iaW4vbG9nNGotY29yZS0yLjEzLjAuamFyCjZmMzhhMjU0ODJkODJjZDExOGM0MjU1ZjI1YjlkNzhkOTY4MjFkMjJiYWI0OThjZGNlOWNkYTdhNTYzY2E5OTIgIC4vYXBhY2hlLWxvZzRqLTIuMTMuMS1iaW4vbG9nNGotY29yZS0yLjEzLjEuamFyCjU0OTYyODM1OTkyZTMwMzkyOGFhOTA5NzMwY2UzYTUwZTMxMTA2OGMwOTYwYzcwOGU4MmFiNzY3MDFkYjVlNmIgIC4vYXBhY2hlLWxvZzRqLTIuMTMuMi1iaW4vbG9nNGotY29yZS0yLjEzLjIuamFyCmU1ZTliMGY4ZDcyZjRlN2I5MDIyYjdhODNjNjczMzM0ZDc5Njc5ODExOTFkMmQ5OGY5YzU3ZGM5N2I0Y2FhZTEgIC4vYXBhY2hlLWxvZzRqLTIuMTMuMy1iaW4vbG9nNGotY29yZS0yLjEzLjMuamFyCjY4ZDc5Mzk0MGMyOGRkZmY2NjcwYmU3MDM2OTBkZmRmOWU3NzMxNTk3MGM0MmM0YWY0MGNhNzI2MWE4NTcwZmEgIC4vYXBhY2hlLWxvZzRqLTIuMTQuMC1iaW4vbG9nNGotY29yZS0yLjE0LjAuamFyCjlkYTBmNWNhN2M4ZWFiNjkzZDA5MGFlNzU5Mjc1YjlkYjRjYTVhY2RiY2ZlNGE2M2QzODcxZTBiMTczNjc0NjMgIC4vYXBhY2hlLWxvZzRqLTIuMTQuMS1iaW4vbG9nNGotY29yZS0yLjE0LjEuamFyCjAwNmZjNjYyM2ZiYjk2MTA4NDI0M2NmYzMyN2M4ODVmM2M1N2YyZWJhOGVlMDVmYmM0ZTkzZTUzNTg3NzhjODUgIC4vbG9nNGotMi4wLWFscGhhMS9sb2c0ai1jb3JlLTIuMC1hbHBoYTEuamFy"
[System.Collections.Generic.List[string]]$FileHashes = -split [System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($EncodedHashes)) | Where-Object {$_.Length -eq 64 }
If($CustomFileHashes -ne $null) { $CustomFileHashes |  ForEach-Object { $FileHashes.Add("$_")} }

$TotalResults = ForEach($Item in $List.Where({$_}).Trim()) {
  
    If($Item.Length -gt 0) {
  
        $Hash = (Get-FileHash -Path $Item -Algorithm SHA256).Hash

            If($FileHashes -contains $Hash) {
  
                $Result = [PSCustomObject]@{
                    "Hostname" = $env:ComputerName
                    "File Hash" = $Hash
                    "File Name" = $Item
                }
  
                $Result
  
            }
  
    }
  
}
$TotalResults

11 Comments

  1. Not working on PS 4 or earlier

    Method invocation failed because [System.Collections.ArrayList] does not contain a method named ‘new’.

    • Jose Espitia

      Thanks for the heads up. I will add a note to the blog post that it is only compatible with Powershell 5.0 or above.

    • Jose Espitia

      You should try again. I made some modifications to the script and removed [System.Collections.ArrayList].

  2. maybe add a possibility to add more hashes to the hashlist. as i saw in our company that many vendors using log4j too but hashes are missing in your current variable
    br tom

    • Jose Espitia

      Great idea Tom! You were not the first to ask so I went ahead and updated the script so you can easily add additional file hashes. You just need to add them to the $CustomFileHashes variable 🙂

  3. how do you add hashes to the list? 2.15 is susceptible as well. I found the hash value but can’t seem to add it to the string value.

    • Jose Espitia

      Chris, you were not the first to ask so I went ahead and updated the script so you can easily add additional file hashes. You just need to add them to the $CustomFileHashes variable 🙂

  4. I ran your script manually on a client machine to test and see the result. The script ran for 10 minutes and returned no result. I guess there were no files found on the system.

  5. You may need to update the Get-Filehash command as it will not deal with long paths.

    If you prepend \\?\ to the $item then you can get the hash of long paths. Updated command bellow

    $Hash = (Get-FileHash -Path “\\?\$Item” -Algorithm SHA256).Hash

  6. Thanks for sharing this! How would you got about excluding certain folders? For instance, we have some that show up in the users folders that are really just synced Sharepoints, and this script makes OneDrive download all the .jar files.

    • Jose Espitia

      Mike, you could add /XD to the Robocopy command and add the directories afterwards.
      Example:
      Robocopy $Drive 'Dest' *.jar /l /njh /njs /ndl /ns /nc /fp /e /xj /xd "c:\your excluded folder"

Leave a Reply