Code Monkey home page Code Monkey logo

cve-2021-44228_scanner's Introduction

CVE-2021-44228_scanner

Applications that are vulnerable to the log4j CVE-2021-44228 issue may be detectable by scanning jar, war, and ear files to search for the presence of JndiLookup.class.

Depending on the platform that you are investigating, the PowerShell or the Python3 script may make more sense to run. In both cases, the optional argument is the top-level directory that you would like to use to begin your search.

Any file discovered is worth investigation to determine if the application using it is vulnerable. For any JndiLookup.class that is present, log4j commonly includes the version in the jar file name. For example, a hit on log4j-core-2.14.1.jar would be indicative of a vulnerable application. Alternatively, log4j-core-2.16.jar may also produce a hit because the JndiLookup code is still present in the 2.16 version of log4j, but it is disabled by default. See VU#930724 for more details.

Screenshots

For example, here is an invocation of the PowerShell version of the scanner: checkjndi.ps1 execution on c:\

Similarly, here is an invocation of the Python3 version: checkjndi.py execution on c:\

Finally, here is an invocation of the Bash version: checkjndi.sh execution on ~/in

Interpreting results

Note that the Bash and Python versions of this script will by design limit scans to a single filesystem. With the PowerShell version, locations to scan can be piped into the script to have control of what is checked. For example, to scan a list of paths conatined in a the file paths.txt:

get-content .\paths.txt | .\checkjndi.ps1

Let's look at the first hit on our Windows scan execution:

WARNING: C:\tmp\2.15\log4j-core-2.15.0.jar contains org/apache/logging/log4j/core/lookup/JndiLookup.class

Based on the jar name, this is a library from log4j 2.15. While this version of log4j fixes CVE-2021-44228, it still contained a flaw that is outlined as CVE-2021-45046. The impact of CVE-2021-45046 is a denial of service for only certain Java applications that use log4j 2.15. For Java applications that use log4j versions prior to 2.15 and that also fit the prerequisites for CVE-2021-45046 applying, the impact is RCE.

Let's look at the second hit:

C:\tmp\2.16\log4j-core-2.16.0.jar contains org/apache/logging/log4j/core/lookup/JndiLookup.class ** BUT APPEARS TO BE PATCHED **

This jar file contains a 2.16 version of log4j, which is not vulnerable to CVE-2021-44228. This result is reported for information purposes, which shows that a vendor has patched their product.

Let's look at the third hit:

WARNING: C:\tmp\ghidra_10.0_PUBLIC\Ghidra\Framework\Generic\lib\log4j-core-2.12.1.jar contains org/apache/logging/log4j/core/lookup/JndiLookup.class

Here we can see that Ghidra uses log4j version 2.12.1, and as such we should assume it to be vulnerable. And indeed, Ghidra versions before 10.1 are vulnerable to CVE-2021-44228.

You should investigate any hits reported by either of these scripts, and confirm that either the log4j version is indeed the fixed 2.16 version, or reach out to your software vendor to obtain a fixed version of the software. Alternatively, VU#930724 has information about how JndiLookup.class can be removed from vulnerable jar files.

Errors returned

The PowerShell version of the scanner has additional error reporting when files or directories cannot be investigated. In particular, any Unable to scan errors reporting UnauthorizedAccessException is indicative of a permission problem in accessing a directory and/or a file. Any Unable to scan errors reporting InvalidDataException is usually due to a corrupt archive.

cve-2021-44228_scanner's People

Contributors

grahampugh avatar jessiewestlake avatar jskiba99 avatar jsmartbnl avatar usbruce avatar wdormann avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cve-2021-44228_scanner's Issues

Getting Useless Output from Powershell Script

Running the powershell script on the entire C drive of some servers, and get an extremely long output of directories that were unable to be scanned. Is there a version of the script that only output the possibly vulnerable files that need to be reviewed, to avoid searching through thousands of lines of output just to find the one line of output actually needed?

PowerShell script finds nothing if access denied error occurs

As described in this reddit thread, Get-ChildItem can return nothing when an "Access is denied" error (System.UnauthorizedAccessException) occurs, despite -ErrorAction Ignore. I found that this happened on some systems when scanning a whole drive from the root directory.

The solution suggested by OPconfused, i.e. building the list of files manually, worked in my case. The "Access is denied" error is still shown, but the script proceeds to check the files that are found.

$jars = @();
Get-ChildItem -Path $topdir -File -Recurse -Force -Include "*.jar","*.war","*.ear","*.zip" -ErrorAction Ignore | % { $jars += $_ };

How to exclude a path

I recommend adding an option to exclude a path, for example: .\checkjindi.ps1 c:\ -skip c:\temp\

Detect ZLIB Compression & scan all ZLIB compressed files instead of just *.jar, *.ear, *.war, *.zip

Sequel to #4:

Theoretically relying on the file extension isn't reliable. Check this post by @DidierStevens:

https://isc.sans.edu/forums/diary/Recognizing+ZLIB+Compression/25182/

Unfortunately I couldn't quickly find a way to do this using only native powershell stuff (I'm sure it can be done, possibly via importing some .NET stuff, but that's not something rapidly figured out.), but there does exist a python option:

https://blog.didierstevens.com/2018/10/28/update-file-magic-py-version-0-0-4/

Recommendation for improvement to line 65

I'm not sure if it is really worthy to become an issue or not, but I gave it a shot.

Line 65 of checkjndi.py has a lot of endswiths to check for the four file extensions (.jar, .war, .ear, .zip). Python documentation on str.endswith says it accepts a tuple to look for as the suffix parameter instead of a single string.

So one str.endswith can be called and the code gets much more readable.

If this is not a worthy issue, please tell me and I will simply close it.

Difference in behavior python and sh script

Hello,

Thanks for sharing the tool. While testing it I noticed that python script fail silently on forder where it doesnt have read access. This behavior differ from the sh script version.

The sh script would be more usefull as it's not requiring python3 install but it seem to not scan the folder recursively in the same way as the python script (ex. scanning at root level).

Python version worked well the validation I needed, thank you again!

Eric

Powershell giving warning "-force not used"

I am not sure how to address this warning when I run the scanner. It is showing I am missing a parameter so it is not scanning hidden or system files. Where whould this parameter need to be included to make sure the scan is as complete as possible.

PS C:\WINDOWS\system32> (directory)\checkjndi.ps1
WARNING: -Force not used, will not scan System or Hidden files.

adding a look to find fixed drives.

<#
.Description
Scans filesystem for .jar, war, and ear files that contains log4j code that may be vulnerable to CVE-2021-44228
Supply a top-level directory to begin searching, or default to the current directory.
.PARAMETER Toplevel
Top-level directory to begin search for jar files.
.EXAMPLE
PS> .\checkjindi.ps1
Scan the current directory and subdirectory for jar files.
.EXAMPLE
PS> .\checkjindi.ps1 c:
Scan the entire c:\ drive for jar files.
.SYNOPSIS
Scans filesystem for .jar files that contains log4j code that may be vulnerable to CVE-2021-44228.
#>
param ([string]$toplevel = ".")

#Requires -Version 3.0

Add-Type -Assembly 'System.IO.Compression.FileSystem'

$global:foundvulnerable = $false

function Get-Files {
param (
[string]$topdir
)

$jars = @();
Get-ChildItem -Path $topdir -File -Recurse -Force -Include "*.jar","*.war","*.ear","*.zip","JndiLookup.class" -ErrorAction Ignore | % { $jars += $_ } | out-null

return $jars

}

function Process-JAR {
param (
[Object]$jarfile,
[String]$origfile = "",
[String]$subjarfile = ""
)
try {
$jar = [System.IO.Compression.ZipFile]::Open($jarfile, 'read');
}
catch {
return
}
[bool] $ispatched = 0;
[bool] $hasjndi = 0;
[string] $outputstring = "";

ForEach ($entry in $jar.Entries) {
    #Write-Output $entry.Name;
    if($entry.Name -like "*JndiLookup.class"){
        if ($origfile -eq "")
        {
            $hasjndi = 1;
            $outputstring = "$jarfile contains $entry";
        }
        else
        {
            $hasjndi = 1;
            $outputstring = "$origfile contains $subjarfile contains $entry";
        }
        $TempFile = [System.IO.Path]::GetTempFileName()
        try {
            [System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $TempFile, $true);
            if (Select-String -Path $TempFile -Pattern "JNDI is not supported"){
                $ispatched = 1;
            }
        }
        catch {}
        Remove-Item $TempFile;
    }
    elseif ($entry.Name -like "*MessagePatternConverter.class"){
        $TempFile = [System.IO.Path]::GetTempFileName()
        try {
            [System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $TempFile, $true);
            if (Select-String -Path $TempFile -Pattern "Message Lookups are no longer supported"){
                $ispatched = 1;
            }
        }
        catch {}
        Remove-Item $TempFile;
    }
    elseif (($entry.Name -like "*.jar") -or ($entry.Name -like "*.war") -or ($entry.Name -like "*.ear") -or ($entry.Name -like "*.zip")) {
        if ($origfile -eq "")
        {
            $origfile = $jarfile.FullName
        }
        $TempFile = [System.IO.Path]::GetTempFileName()
        try {
            [System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $TempFile, $true);
            Process-JAR $TempFile $origfile $entry.FullName;
        }
        catch{}
        Remove-Item $TempFile;

    }
}
$jar.Dispose();
if ($ispatched){
    $outputstring = $outputstring + " ** BUT APPEARS TO BE PATCHED **";
}
if ($hasjndi -and $ispatched){
    Write-Host $outputstring;
}
elseif ($hasjndi){
    $global:foundvulnerable = $true
    Write-Warning $outputstring;
}

}

$drives = Get-WmiObject -Class Win32_LogicalDisk | Select -Property DeviceID, DriveType | where {$_.DriveType -eq 3} | select DeviceID

$checkfiles = @()
foreach ($drive in $drives)
{

$topLevel = "$($drive.DeviceID)\"
$checkfiles += Get-Files $topLevel;   

}

ForEach ($checkfile In $checkfiles)
{
if ($checkfile.Name -eq "JndiLookup.class")
{
Write-Host "$checkfile IS JndiLookup.class"
}
else
{
Process-JAR $checkfile;
}
}

if ($global:foundvulnerable -eq $false)
{
"No vulnerable components found"
}

Scanner Crashes on Some Systems

When this line runs it crashes on some systems and won't continue the scan.

Get-ChildItem -Path $topdir -File -Recurse -Force:$Force -Include ".jar",".war",".ear",".zip","JndiLookup.class" -ErrorAction SilentlyContinue -ErrorVariable UnscannablePaths

If the process gets an “Get-ChildItem : Access to the path 'C:\ProgramData\Templates' is denied” error, it continues scanning

If the process gets an “Get-ChildItem : Access is denied” error, it crashes

To resolve the issue I changed the line to

Get-ChildItem -Path $topdir -File -Recurse -Force -ErrorAction SilentlyContinue -ErrorVariable UnscannablePaths | Where-Object {($.extension -eq ".jar") -or ($.extension -eq ".war") -or ($.extension -eq ".ear") -or ($.extension -eq ".zip") -or ($_.Name -eq "JndiLookup.class")}

After making the above change, I also had to change the following two lines.

OLD: Write-Host "$checkfile IS JndiLookup.class"
NEW: Write-Host "$($checkfile.FullName) IS JndiLookup.class"

OLD: Process-JAR $checkfile;
NEW: Process-JAR $checkfile.FullName;

Purpose of MessagePatternConverter.class Check

It seems that, in the PowerShell and Python scripts, if the MessagePatternConverter.class is found, it will check and mark the entry as patched if it finds the target text Message Lookups are no longer supported. I'm confused because that entry never outputs to the screen, whether it is marked as patched or not.

Can you explain the purpose of that check?

  • What is the intent if the MessagePatternConverter.class does contain Message Lookups are no longer supported?
  • What is the intent if the MessagePatternConverter.class does NOT contain Message Lookups are no longer supported?

checkjndi.py Does Not Report Skipped Directories

Although the README does indicate that "this script will by design limit scans to a single filesystem", it's not obvious that checkjndi.py skips directories that are mount points. In our case, we had vulnerable versions of log4j which were on separate partitions but those partitions were excluded from the scan and, as such, we were given false negatives. Only after commenting-out the "filter" line (we have very few NFS mounts) did we get a thorough scan which detected additional vulnerabilities. Recommend adding some output which indicates which directories are being skipped.

Move PoSh execution block to own function

$checkfiles = Get-Files $toplevel;
ForEach ($checkfile In $checkfiles) {
    if ($checkfile.Name -eq "JndiLookup.class")
    {
        Write-Warning "$checkfile *IS* JndiLookup.class"
    }
    else
    {
        Process-JAR $checkfile;
    }
}

imho, this whole block from the end of the file should be its own function & called at the end, instead of doing it directly.

Exclude directory

Hello,
First thank you for this script.
Second, how can I exclude a directory from the scan (I know it sounds controversial but it is a problem when the script downloads .zip files from one drive / google drive and can potentially jam your machine).

Hot to scan all drives in PS

How can I run the PS version and make it scan all drives without knowing in advance which drives exist and which not (for automation so I can scan all servers)?

Use Pester for development

@pester

(Wouldn't want it in the published version however, since that'd require importing non-built in modules which'd make deployment/distribution more difficult in restricted/controlled environments.)

Warning on DatabaseJndiLookup.class

When I execute the Powershell script on an application server in the lab:

powershell.exe -executionpolicy bypass -file .\checkjndi.ps1 -toplevel C:\ -Force

I'm receiving warnings on DatabaseJndiLookup.class which is not related to JndiLookup.class in log4j-core jar file. See examples below:

image

Set return code to non-zero if vulnerability found

The checkjndi.sh script sets a return code of 1 if the unzip program is not found. It should also set a non-zero return code if potential issues are found. Since there is already a flag whether a vulnerable component is found ($foundvulnerable) it would be easy to do so. It should also set a non-zero return code if JndiLookup.class is found.

How do I scan full system using .py or .sh script on my Ubuntu & MAC

Hi, I am new to Ubuntu and MAC. I ran the PowerShell script to find vulnerability on windows. There I mentioned all the Local Hard Drives partitions in a text file and ran the script. Now how do I do it in Linux and MAC machines? I need to scan all the partitions and files. Please provide me with the solution. Thanks in advance.

Does not detect exploded Jars or *.zip

Both exploded Jars and *.zip are reachable by Java.

(Don't want attackers just renaming WEB-INF/lib/log4j-core-2.1.0.jar to log4j-core-2.1.0.zip to foil scanners!)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.