log4j-tools: CVE-2021-44228 poses a serious threat to a wide range of Java-based applications

Overview

log4j-tools

Quick links

Click to find:

Inclusions of log4j2 in compiled code Calls to log4j2 in compiled code Calls to log4j2 in source code

Overview

CVE-2021-44228 poses a serious threat to a wide range of Java-based applications. The important questions a developer may ask in this context are:

1. Does my code include log4j2?

Does the released code include log4j2? Which version of the library is included there? Answering these questions may not be immediate due to two factors:

  1. Transitive dependencies: while log4j2 may not be in the direct dependency list of the project, it may be used indirectly by some other dependency.

  2. The code of this library may not appear directly as a separate file (i.e., log4j2-core-2.xx.0.jar), but rather be bundled in some other code jar file.

JFrog is releasing a tool to help resolve this problem: scan_jndimanager_versions. The tool looks for the class code of JndiManager (regardless of containing .jar file names and content of pom.xml files), which is required for the vulnerability to be exploitable, and checks whether its version is fixed one (i.e., 2.15 or above) by testing for existence of an indicative string. Both Python and Java implementations are included.

2. Where does my code use log4j2?

The question is relevant for the cases where the developer would like to verify if the calls to log4j2 in the codebase may pass potentially attacker-controlled data. While the safest way to fix the vulnerability, as discussed in the advisories, is to apply the appropriate patches and global flags, controlling for and verifying the potential impact under assumption of unpatched log4j2 may be valuable in many situations. In order to address this problem JFrog is releasing two scripts:

  1. scan_log4j2_calls_src.py, which locates calls to log4j2 logging functions (info, log, error etc.) with non-constant arguments in .java source files and reports the findings on the level of source file and line
  2. scan_log4j2_calls_jar.py, which locates the calls to logging functions in compiled .jars, and reports the findings as class name and method names in which each call appears.

Usage instructions

scan_jndimanager_versions.py

The tool requires python3, without additional dependencies.

Usage
python scan_jndimanager_versions.py root-folder

The tool will scan root_folder recursively for .jar and .war files; in each located file the tool looks for a *log4j/core/net/JndiManager.class code (recursively in each .jar file). If the code is located, and does not contain allowedJndiProtocols string constant (added in 2.15), the file as reported as containing a vulnerable implementation if JndiManager.


scan_jndimanager_versions.jar

The tool requires java runtime, without additional dependencies. It can be recompiled from the provided source.

Usage
java -jar scan_jndimanager_versions.jar root-folder

The tool will scan root_folder recursively for .jar and .war files; in each located file the tool looks for a *log4j/core/net/JndiManager.class code. If the code is located, and does not contain allowedJndiProtocols string constant (added in 2.15), the file as reported as containing a vulnerable implementation if JndiManager.


scan_log4j_calls_jar.py

The tool requires python 3 and the following 3rd party libraries: jawa, tqdm, easyargs, colorama

Dependencies installation
pip install -r requirements.txt
Usage

The default use case:

python scan_log4j_calls_jar.py root-folder

will recursively scan all .jar files in root-folder, for each printing out locations (class name and method name) of calls to info/warn/error/log/debug /trace/fatal methods of log4j2.Logger.

The tool may be configured for additional use cases using the following command line flags.

Flag Default value Use
--class_regex org/apache/logging/log4j/Logger Regular expression for required class name
--method_regex (info|warn|error|log|debug|trace|fatal) Regular expression for required method name
--quickmatch_string log4j Pre-condition for file analysis: .jar files not containing the specified string will be ignored
--class_existence Not set When not set, look for calls to class::method as specified by regexes. When set, --method_regex is ignored, and the tool will look for existence of classes specified by --class_regex in the jar.
--no_quickmatch Not set When set, the value of --quickmatch_string is ignored and all jar files are analyzed

For example,

python scan_log4j_calls_jar.py --class_regex ".*JndiManager$" --class_existence --no_quickmatch root-folder

Will scan all .jar files (even if they do have no mentions of log4j2) for the existence of a class ending with JndiManager.


scan_log4j_calls_src.py

The tool requires python 3 and the following 3rd party libraries: javalang, tqdm, easyargs, colorama

Dependencies installation
pip install -r requirements.txt
Usage

The default use case:

python scan_log4j_calls_src.py root-folder

will recursively scan all .java files in root-folder, for each printing out the locations (file name and corresponding code lines) of calls to log4j2 logging methods.

The tool may be configured for additional use cases using the following command line flags:

Flag Default value Use
--class_regex org/apache/logging/log4j/Logger Regular expression for required class name
--method_regex (info|warn|error|log|debug|trace|fatal) Regular expression for required method name

Compiling scan_jndimanager_versions.jar from source

cd scan_jndimanager_versions
gradle build
cp build/libs/scan_jndimanager_versions.jar ..
Comments
  • Add an option to hide errors

    Add an option to hide errors

    Running scan_log4j_versions.py against the root directory generates tonnes of output for unopened files.

    /usr/bin/python3 scan_log4j_versions.py /
    Scanning /
    snap/core18/2246/usr/share/doc/apparmor/changelog.Debian.gz: file could not be opened successfully
    [Errno 2] No such file or directory: '/snap/core18/2246/usr/share/doc/bash/README.md.bash_completion.gz'
    snap/core18/2246/usr/share/doc/bash/changelog.Debian.gz: file could not be opened successfully
    snap/core18/2246/usr/share/doc/bash-completion/changelog.Debian.gz: file could not be opened successfully
    snap/core18/2246/usr/share/doc/bsdutils/changelog.Debian.gz: file could not be opened successfully
    snap/core18/2246/usr/share/doc/bzip2/changelog.Debian.gz: file could not be opened successfully
    snap/core18/2246/usr/share/doc/cloud-guest-utils/changelog.Debian.gz: file could not be opened successfully
    snap/core18/2246/usr/share/doc/cloud-init/changelog.Debian.gz: file could not be opened successfully
    snap/core18/2246/usr/share/doc/coreutils/changelog.Debian.gz: file could not be opened successfully
    snap/core18/2246/usr/share/doc/dash/changelog.Debian.gz: file could not be opened successfully
    ...
    

    Please add an option to hide/disable errors on output.

    opened by kaipee 8
  • False alerts detected?

    False alerts detected?

    Script scan_log4j_calls_jar.py provided next output:

    BOOT-INF/lib/commons-logging-1.2.jar
    
    Class: org/apache/commons/logging/impl/Log4JLogger
    Vulnerable call | Methods
    ----------------+---------
    log             | error, debug, trace, warn, fatal, info
    
    Processing .jar file:
    BOOT-INF/lib/jboss-logging-3.4.1.Final.jar
    
    Class: org/jboss/logging/Log4jLogger
    Vulnerable call | Methods
    ----------------+---------
    log             | doLogf, doLog
    
    Processing .jar file:
    BOOT-INF/lib/spring-boot-2.4.3.jar
    
    Class: org/springframework/boot/logging/log4j2/ColorConverter
    Vulnerable call | Methods
    ----------------+---------
    error           | newInstance
    

    I've found those methods in project dependencies, but we don't have log4j-core.jar anywhere in our project (checked the source code and deployed app.jar).
    I've asked dev to check, and they said it is a false positive.

    Now i'm not sure is app vulnerable or i'm doing something wrong?

    opened by moivica 5
  • Account for zlib.error and UnicodeDecodeError

    Account for zlib.error and UnicodeDecodeError

    The scan_log4j_versions.py may profit from additional exception catching (there may be more) as neither catching zlib.error nor UnicodeDecodeError ends the scan runs rather prematurely.

    Example 1/2 - fun with invalid unicode in filenames

    # ...
      File "/some/place/jfrog-log4j-tools/scan_log4j_versions.py", line 126, in zip_file
        with ZipFile(file) as jarfile:
      File "/another/place/.pyenv/versions/3.9.6/lib/python3.9/zipfile.py", line 1257, in __init__
        self._RealGetContents()
      File "/another/place/.pyenv/versions/3.9.6/lib/python3.9/zipfile.py", line 1359, in _RealGetContents
        filename = filename.decode('utf-8')
    UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa2 in position 12: invalid start byte
    

    Example 2/2 - zlib.error (is off-exception hierarchy)

    # ...
      File "/some/place/jfrog-log4j-tools/scan_log4j_versions.py", line 173, in tar_file
        with tar_open(fileobj=file) as tarfile:
      File "/another/place/.pyenv/versions/3.9.6/lib/python3.9/tarfile.py", line 1611, in open
        return func(name, "r", fileobj, **kwargs)
      File "/another/place/.pyenv/versions/3.9.6/lib/python3.9/tarfile.py", line 1682, in gzopen
        t = cls.taropen(name, mode, fileobj, **kwargs)
      File "/another/place/.pyenv/versions/3.9.6/lib/python3.9/tarfile.py", line 1659, in taropen
        return cls(name, mode, fileobj, **kwargs)
      File "/another/place/.pyenv/versions/3.9.6/lib/python3.9/tarfile.py", line 1522, in __init__
        self.firstmember = self.next()
      File "/another/place/.pyenv/versions/3.9.6/lib/python3.9/tarfile.py", line 2327, in next
        tarinfo = self.tarinfo.fromtarfile(self)
      File "/another/place/.pyenv/versions/3.9.6/lib/python3.9/tarfile.py", line 1112, in fromtarfile
        buf = tarfile.fileobj.read(BLOCKSIZE)
      File "/another/place/.pyenv/versions/3.9.6/lib/python3.9/gzip.py", line 300, in read
        return self._buffer.read(size)
      File "/another/place/.pyenv/versions/3.9.6/lib/python3.9/_compression.py", line 68, in readinto
        data = self.read(len(byte_view))
      File "/another/place/.pyenv/versions/3.9.6/lib/python3.9/gzip.py", line 495, in read
        uncompress = self._decompressor.decompress(buf, size)
    zlib.error: Error -3 while decompressing data: invalid distance too far back
    
    opened by sthagen 5
  • scan_log4j_versions.py dependency for dataclasses with python3.6

    scan_log4j_versions.py dependency for dataclasses with python3.6

    Hi,

    Thanks for the tools. scan_log4j_versions.py The tool requires Python 3, without additional dependencies.

    python3.6 still seems to have additional dependencies like dataclasses Also, is it possible to exclude some subdirectory paths in the argument

    python3 scan_log4j_versions.py /usr

    Traceback (most recent call last): File "scan_log4j_versions.py", line 3, in from dataclasses import dataclass ModuleNotFoundError: No module named 'dataclasses'

    opened by danilansible 4
  • elasticsearch-sql-cli-7.16.1.jar mentioned as vunerable, but shoud be the fixed version

    elasticsearch-sql-cli-7.16.1.jar mentioned as vunerable, but shoud be the fixed version

    https://www.elastic.co/guide/en/elasticsearch/reference/current/release-notes-7.16.1.html

    Enhancementsedit Infra/Logging Disable JNDI lookups via the log4j2.formatMsgNoLookups system property #81622 Patch log4j jar to remove the JndiLookup class from the classpath #81629

    scan results :

    SonarQube\sonarqube-8.9.5\elasticsearch\bin\elasticsearch-sql-cli-7.16.1.jar: vulnerable JndiManager found SonarQube\sonarqube-8.9.5\elasticsearch\lib\elasticsearch-log4j-7.16.1.jar: vulnerable JndiManager found

    opened by svbrburgman 3
  • RuntimeError from scan_log4j_versions.py in case of encrypted zip

    RuntimeError from scan_log4j_versions.py in case of encrypted zip

    $ python3.6 scan_log4j_versions.py /
    Traceback (most recent call last):
      File "scan_log4j_versions.py", line 227, in <module>
        run_scanner(root_dir, set(exclude_dirs))
      File "scan_log4j_versions.py", line 181, in run_scanner
        test_file(file, rel_path)
      File "scan_log4j_versions.py", line 127, in test_file
        next_file = jarfile.open(file_name, "r")
      File "/usr/lib/python3.6/zipfile.py", line 1429, in open
        "required for extraction" % name)
    RuntimeError: File 'boot/classworlds-1.1.jar' is encrypted, password required for extraction
    

    The error is from a test file in apache-commons-compress: https://gitbox.apache.org/repos/asf?p=commons-compress.git;a=blob;f=src/test/resources/password-encrypted.zip;h=939029cd68c2969df268bc7eec63900c0f1a7196;hb=HEAD

    I think the scanner can report such errors and continue on scanning other files?

    opened by yan12125 2
  • Getting ValueError: invalid magic number

    Getting ValueError: invalid magic number

    Hi, Thanks for providing this library to check log4j vulnerability.

    I am trying to scan the log4j file with pattern matching but I am getting following error.

    `(log4env) C:\Log4Env\log4j-tools>python scan_log4j_calls_jar.py --class_regex ".*JndiManager$" --class_existence --no_quickmatch ..\MyJavaProject Looking for presence of classes: .*JndiManager$ Scanning folder for .jar files Walking ..\MyJavaProject... 40%|████████████████████████████████ | 198/494 [00:45<01:07, 4.36it/s] Traceback (most recent call last): File "C:\Log4Env\python38\log4env\lib\site-packages\jawa\classloader.py", line 142, in load r = self.class_cache.pop(path) KeyError: 'COM/ibm/db2os390/sqlj/custom/DB2SQLJCustomizer'

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last): File "scan_log4j_calls_jar.py", line 250, in run_scanner() File "C:\Log4Env\python38\log4env\lib\site-packages\easyargs\decorators.py", line 17, in decorated return parsers.handle_parser(parser) File "C:\Log4Env\python38\log4env\lib\site-packages\easyargs\parsers.py", line 16, in handle_parser return function(**args) File "scan_log4j_calls_jar.py", line 242, in run_scanner xref_analysis = XrefAnalysis(filename, class_regex, method_regex) File "scan_log4j_calls_jar.py", line 89, in init self.methods, self.callers = self.traverse(self.class_loader) File "scan_log4j_calls_jar.py", line 124, in traverse classloader[class_name] File "C:\Log4Env\python38\log4env\lib\site-packages\jawa\classloader.py", line 53, in getitem return self.load(path) File "C:\Log4Env\python38\log4env\lib\site-packages\jawa\classloader.py", line 145, in load r = self.klass(source) File "C:\Log4Env\python38\log4env\lib\site-packages\jawa\cf.py", line 94, in init self._from_io(source) File "C:\Log4Env\python38\log4env\lib\site-packages\jawa\cf.py", line 150, in _from_io raise ValueError('invalid magic number') ValueError: invalid magic number`

    Please help

    opened by sidnaik03 2
  • scan_log4j_versions.py syntax error with python 3.4.10

    scan_log4j_versions.py syntax error with python 3.4.10

    Hi again,

    on another system(with python version 3.4.10), maybe a simple syntax glitch

    python3 scan_log4j_versions.py /usr

    File "scan_log4j_versions.py", line 80 f"Warning: {filename} contains multiple copies of {classname}; result may be invalid" ^ SyntaxError: invalid syntax

    opened by danilansible 1
  • Also scan ear and sar files and nested war, sar and ear files

    Also scan ear and sar files and nested war, sar and ear files

    1. Java also has two lesser known archive files: ear and sar. Especially ear files are known to contain (many) nested jar, war and sar files. Although sar files are rarely encountered nowadays. Although ear files are deployed in application servers that bring their own logging libraries, Log4j could be used by an application. So it would be prudent to scan these as well.

    2. On a long running scan I encountered a FileNotFoundError, so a catch was added to prevent the scan from aborting

    3. Some friendly output was added for when an incorrect path was passed to the script

    More on ear files: https://en.wikipedia.org/wiki/EAR_(file_format)

    opened by GijsCalis 0
  • refactor/missing-python-library-in-requirements

    refactor/missing-python-library-in-requirements

    Missing Python lib in requirements

    Traceback (most recent call last):
      File "scan_log4j_versions.py", line 3, in <module>
        from dataclasses import dataclass
    ModuleNotFoundError: No module named 'dataclasses'
    
    opened by dignajar 0
Owner
JFrog Ltd.
JFrog Ltd.
Simple Python 3 script to detect the "Log4j" Java library vulnerability (CVE-2021-44228) for a list of URL with multithreading

log4j-detect Simple Python 3 script to detect the "Log4j" Java library vulnerability (CVE-2021-44228) for a list of URL with multithreading The script

Víctor García 187 Jan 3, 2023
Simple Python 3 script to detect the "Log4j" Java library vulnerability (CVE-2021-44228) for a list of URL with multithreading

log4j-detect Simple Python 3 script to detect the "Log4j" Java library vulnerability (CVE-2021-44228) for a list of URL with multithreading The script

Wade 1 Dec 15, 2021
ProxyLogon Full Exploit Chain PoC (CVE-2021–26855, CVE-2021–26857, CVE-2021–26858, CVE-2021–27065)

ExProlog ProxyLogon Full Exploit Chain PoC (CVE-2021–26855, CVE-2021–26857, CVE-2021–26858, CVE-2021–27065) Usage: exprolog.py [OPTIONS] ExProlog -

Herwono W. Wijaya 130 Dec 15, 2022
Tools for investigating Log4j CVE-2021-44228

Log4jTools Tools for investigating Log4j CVE-2021-44228 FetchPayload.py (Get java payload from ldap path provided in JNDI lookup). Example command: Re

MalwareTech 91 Dec 29, 2022
Find vulnerable Log4j2 versions on disk and also inside Java Archive Files (Log4Shell CVE-2021-44228)

log4j-finder A Python3 script to scan the filesystem to find Log4j2 that is vulnerable to Log4Shell (CVE-2021-44228) It scans recursively both on disk

Fox-IT 431 Dec 22, 2022
Northwave Log4j CVE-2021-44228 checker

Northwave Log4j CVE-2021-44228 checker Friday 10 December 2021 a new Proof-of-Concept 1 addressing a Remote code Execution (RCE) vulnerability in the

Northwave 125 Dec 9, 2022
Python script that sends CVE-2021-44228 log4j payload requests to url list

scan4log4j Python script that sends CVE-2021-44228 log4j payload requests to url list [VERY BETA] using Supply your url list to urls.txt Put your payl

elyesa 5 Nov 9, 2022
A proof-of-concept exploit for Log4j RCE Unauthenticated (CVE-2021-44228)

CVE-2021-44228 – Log4j RCE Unauthenticated About This is a proof-of-concept exploit for Log4j RCE Unauthenticated (CVE-2021-44228). This vulnerability

Pedro Havay 20 Nov 11, 2022
Mass Check Vulnerable Log4j CVE-2021-44228

Log4j-CVE-2021-44228 Mass Check Vulnerable Log4j CVE-2021-44228 Introduction Actually I just checked via Vulnerable Application from https://github.co

Justakazh 6 Dec 28, 2022
Providing DevOps and security teams script to identify cloud workloads that may be vulnerable to the Log4j vulnerability(CVE-2021-44228) in their AWS account.

We are providing DevOps and security teams script to identify cloud workloads that may be vulnerable to the Log4j vulnerability(CVE-2021-44228) in their AWS account. The script enables security teams to identify external-facing AWS assets by running the exploit on them, and thus be able to map them and quickly patch them

Mitiga 13 Jan 4, 2022
Log4j command generator: Generate commands for CVE-2021-44228

Log4j command generator Generate commands for CVE-2021-44228. Description The vulnerability exists due to the Log4j processor's handling of log messag

null 1 Jan 3, 2022
Scans for Log4j versions effected by CVE-2021-44228

check_mkExtension to check for log4j2 CVE-2021-44228 This Plugin wraps around logpresso/CVE-2021-44228-Scanner (Apache License 2.0) How it works Run i

inett GmbH 4 Jun 30, 2022
A scanner and a proof of sample exploit for log4j RCE CVE-2021-44228

1.Create a Sample Vulnerable Application . 2.Start a netcat listner . 3.Run the exploit . 5.Use jdk1.8.0_20 for better results . Exploit-db - https://

Isuru Umayanga 7 Aug 6, 2022
An automated header extensive scanner for detecting log4j RCE CVE-2021-44228

log4j An automated header extensive scanner for detecting log4j RCE CVE-2021-44228 Usage $ python3 log4j.py -l urls.txt --dns-log REPLACE_THIS.dnslog.

null 2 Dec 16, 2021
A script to search, scrape and scan for Apache Log4j CVE-2021-44228 affected files using Google dorks

Log4j dork scanner This is an auto script to search, scrape and scan for Apache Log4j CVE-2021-44228 affected files using Google dorks. Installation:

Jagar 5 Dec 27, 2022
open detection and scanning tool for discovering and fuzzing for Log4J RCE CVE-2021-44228 vulnerability

CVE-2021-44228-log4jVulnScanner-metasploit open detection and scanning tool for discovering and fuzzing for Log4J RCE CVE-2021-44228 vulnerability pre

Taroballz 7 Nov 9, 2022
CVE-2021-44228 log4j 2.x rce漏洞检测工具

#1 使用说明 CVE-2021-44228 log4j 2.x rce漏洞检测工具,对目标链接发起get请求并利用dnslog探测是否有回显 $ python3 log4j-scan.py -h

CoCo ainrm- 4 Jan 13, 2022
PortSwigger Burp Plugin for the Log4j (CVE-2021-44228)

yLog4j This is Y-Sec's @PortSwigger Burp Plugin for the Log4j CVE-2021-44228 vulnerability. The focus of yLog4j is to support mass-scanning of the Log

Y-Security 1 Jan 31, 2022
HatSploit collection of generic payloads designed to provide a wide range of attacks without having to spend time writing new ones.

HatSploit collection of generic payloads designed to provide a wide range of attacks without having to spend time writing new ones.

EntySec 5 May 10, 2022