diff --git a/CVE-2021-44228_log4j-core/CVE-2021-44228.sh b/CVE-2021-44228_log4j-core/CVE-2021-44228.sh
new file mode 100755
index 0000000..7562488
--- /dev/null
+++ b/CVE-2021-44228_log4j-core/CVE-2021-44228.sh
@@ -0,0 +1,1539 @@
+#!/bin/bash
+
+# Copyright (c) 2021 Red Hat, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+VERSION="1.0"
+
+# Warning! Be sure to download the latest version of this script from its primary source:
+
+BULLETIN="https://access.redhat.com/security/vulnerabilities/RHSB-2021-009"
+
+# DO NOT blindly trust any internet sources and NEVER do `curl something | bash`!
+
+# exit on empty variables
+set -u
+
+# exit on non-zero status (together with 'set -u', empty variables make the non-zero status propagate out of a subshell)
+set -e
+
+# dotglob: match hidden files/dirs, but not . and ..
+# nullglob: if there's no glob match, do not resolve the glob to the nonexistent file name "*"
+# extglob: allow globs like !(0) that are like * but ignore files named '0'
+shopt -s dotglob nullglob extglob
+
+
+
+# NOTE about file creation and deletion safety and the auditing thereof
+# ---------------------------------------------------------------------
+#
+# Creating and deleting files & directories is sensitive and can cause damage
+# if done on the wrong path. This script modifies files and directories only
+# through vetted code paths. It is easy to review the basic claims even
+# without auditing the more advanced redundant checks:
+#
+# * User-supplied paths are saved into global variables scan_path, tmp_path,
+# audit_scan_path, and audit_tmp_path.
+#
+# * These paths are ensured to be canonical in basic_args().
+# (That means, absolute paths that can't have symlinks in the path.)
+#
+# * The variables scan_path, tmp_path, audit_scan_path, audit_tmp_path
+# are never modified, except for being set once in basic_args().
+#
+# * The variables scan_path and tmp_path are read many times in the script,
+# so for the purpose of making security audits easier, the variables
+# audit_scan_path and audit_tmp_path are used only in 'rm' operations.
+#
+# * All 'rm' operation are of a similar form and are surrounded by similar
+# sanity checks.
+#
+# * There are no other 'rm' operations, nor anything even slightly similar,
+# like 'mv'.
+#
+# * The variable audit_scan_path is never read, because that is exactly in
+# accordance with these claims.
+#
+# * Any files/directories deleted by this script are strictly temporary
+# files/directories created by this script inside user-provided $tmp_path.
+#
+# * Before each 'rm' operation, audit_tmp_path is checked to be non-empty and
+# identical to tmp_path.
+#
+# * Additionally, unassigned variables make the script exit immediately, due
+# to the 'set -u' and 'set -e' setting.
+#
+# * Before each file / directory creation or modification operation, the path
+# is checked to be inside tmp_path.
+#
+# * Before each file / directory read operation, the path is checked to be
+# inside tmp_path or scan_path.
+#
+# * These claims are checkable by anyone with moderate Bash proficiency and a
+# basic text editor with string search capability.
+#
+# * Everyone is welcome to perform a thorough review to see there are no
+# other avenues for malicious 'rm'.
+
+
+set_default_values() {
+ # Sets default global variable values.
+ #
+ # Side effects:
+ # Sets global variables.
+
+ RED=""
+ GREEN=""
+ BOLD=""
+ RESET=""
+ num_before="n1"
+ num_after="n2"
+ POM_PATH="META-INF/maven/org.apache.logging.log4j/log4j-core/pom.xml"
+ vulnerable=0
+ result=0
+ queue_position=0
+ queue_length=0
+ queue_length_check=0
+ running_kernel=""
+ scan_path="/dev/null"
+ tmp_path="/dev/null"
+ print_progress=1
+
+ readonly queue="CVE_2021_44228_queue"
+ readonly catalog="CVE_2021_44228_catalog"
+ readonly decompressed="CVE_2021_44228_decompressed"
+ readonly parents="CVE_2021_44228_parents"
+ readonly backtrack="CVE_2021_44228_backtrack"
+ readonly detections="CVE_2021_44228_detections"
+ readonly report="report"
+}
+
+
+print_help() {
+ echo "Usage: $( basename "$0" ) [-n | --no-colors] [-d | --debug] [--no-progress] --scan SCANPATH --tmp TMPPATH"
+ echo
+ echo "* SCANPATH will be recursively searched for vulnerable log4j-core jar files,"
+ echo " unpacking zip and jar files along the way. Symbolic links are not followed."
+ echo " Only local filesystem paths are supported."
+ echo
+ echo "* TMPPATH must be a writable empty directory. After the script finishes, it"
+ echo " will contain the subdirectory 'report' with .txt files, each containing"
+ echo " path to a vulnerable log4j-core jar file. There must be enough available"
+ echo " space in TMPPATH, roughly 30 times the size of SCANPATH, otherwise the"
+ echo " result will be incomplete."
+ echo
+ echo "* Both paths must be canonical (absolute). Relative paths and paths that"
+ echo " traverse through symlinks are not supported. TMPPATH must not be inside"
+ echo " SCANPATH."
+}
+
+
+print_debug() {
+ # Prints selected variables when debugging is enabled.
+ if (( debug )); then
+ echo
+ variables=( running_kernel vulnerable result scan_path tmp_path num_before num_after queue_position queue_length queue_length_check )
+ for variable in "${variables[@]}"; do
+ echo "$variable = *${!variable}*"
+ done
+ echo
+ fi
+}
+
+
+basic_args() {
+ # Parses basic commandline arguments and sets basic environment.
+ #
+ # Args:
+ # parameters - an array of commandline arguments
+ #
+ # Side effects:
+ # Exits if --help parameters is used, or if provided arguments are not valid
+ # Sets COLOR constants and variables debug, scan_path, tmp_path, audit_scan_path, audit_tmp_path
+
+ local parameters=( "$@" )
+
+ RED="\\033[1;31m"
+ GREEN="\\033[1;32m"
+ BOLD="\\033[1m"
+ RESET="\\033[0m"
+
+ local processing_scanpath=0
+ local processing_tmppath=0
+ local found_scanpath=0
+ local found_tmppath=0
+ local scanpath=""
+ local tmppath=""
+
+ debug=0
+
+ for parameter in "${parameters[@]}"; do
+ if (( ! processing_scanpath && ! processing_tmppath )) && [[ "$parameter" == "-h" || "$parameter" == "--help" ]]; then
+ print_help
+ print_debug
+ exit 1
+ elif (( ! processing_scanpath && ! processing_tmppath )) && [[ "$parameter" == "-n" || "$parameter" == "--no-colors" ]]; then
+ RED=""
+ GREEN=""
+ BOLD=""
+ RESET=""
+ elif (( ! processing_scanpath && ! processing_tmppath )) && [[ "$parameter" == "-d" || "$parameter" == "--debug" ]]; then
+ debug=1
+ elif (( ! processing_scanpath && ! processing_tmppath )) && [[ "$parameter" == "--no-progress" ]]; then
+ print_progress=0
+ elif (( ! processing_scanpath && ! processing_tmppath )) && [[ "$parameter" == "--scan" ]]; then
+ processing_scanpath=1
+ elif (( ! processing_scanpath && ! processing_tmppath )) && [[ "$parameter" == "--tmp" ]]; then
+ processing_tmppath=1
+ elif (( processing_scanpath )); then
+ scanpath="$parameter"
+ found_scanpath=1
+ processing_scanpath=0
+ elif (( processing_tmppath )); then
+ tmppath="$parameter"
+ found_tmppath=1
+ processing_tmppath=0
+ fi
+ done
+
+ if (( ! found_scanpath || ! found_tmppath )); then
+ print_help
+ print_debug
+ exit 1
+ fi
+
+ if [[ ! -d "$scanpath" ]]; then
+ echo "SCANPATH doesn't exist or is not a directory."
+ echo
+ print_help
+ print_debug
+ exit 1
+ fi
+
+ if [[ ! -d "$tmppath" ]]; then
+ echo "TMPPATH doesn't exist or is not a directory."
+ echo
+ print_help
+ print_debug
+ exit 1
+ fi
+
+ # canonicalize path (strip trailing /, convert to absolute, follow symlink)
+ scan_path="$( readlink -f "$scanpath" )"
+ tmp_path="$( readlink -f "$tmppath" )"
+
+ # strip trailing /
+ scanpath="${scanpath%/}"
+ tmppath="${tmppath%/}"
+
+ # * Make sure the paths are canonical.
+ # * Make sure the resolved paths are not empty strings (since they exist, they can't be empty, as long as the provided and canonicalized paths are equal).
+ if [[ "$scan_path" != "$scanpath" ]] ; then
+ echo "SCANPATH is not a canonical path. Please use absolute paths, for example /opt/something/something. Exiting."
+ echo
+ print_help
+ print_debug
+ exit 1
+ fi
+
+ if [[ "$tmp_path" != "$tmppath" ]] ; then
+ echo "TMPPATH is not a canonical path. Please use absolute paths, for example /tmp/something/something. Make sure the path is not a symlink. Exiting."
+ echo
+ print_help
+ print_debug
+ exit 1
+ fi
+
+ local len_scanpath="${#scanpath}"
+ local len_tmppath="${#tmppath}"
+
+ if (( len_tmppath > len_scanpath )) ; then
+ local prefix_of_tmppath="${tmppath:0:$len_scanpath}"
+ if [[ "$prefix_of_tmppath" == "$scanpath" ]] ; then
+ local char_after_prefix="${tmppath:$len_scanpath:1}"
+ if [[ "$char_after_prefix" == "/" ]] ; then
+ echo "TMPPATH must not be a subdirectory of SCANPATH. Exiting."
+ echo
+ print_help
+ print_debug
+ exit 1
+ fi
+ fi
+ fi
+
+ audit_tmp_path="$tmp_path"
+ audit_scan_path="$scan_path"
+
+ readonly tmp_path
+ readonly scan_path
+ readonly audit_tmp_path
+
+ # Unused on purpose. See the NOTE at the beginning.
+ # shellcheck disable=SC2034
+ readonly audit_scan_path
+}
+
+
+basic_reqs() {
+ # Prints common disclaimer and checks basic requirements.
+ #
+ # Args:
+ # CVE - string printed in the disclaimer
+ #
+ # Side effects:
+ # Exits when a command is not available
+
+ local CVE="$1"
+
+ # Disclaimer
+ echo
+ echo -e "${BOLD}This script (v$VERSION) is primarily designed to detect $CVE on supported"
+ echo -e "Red Hat Enterprise Linux 6-8 systems."
+ echo -e "Result may be inaccurate for other systems."
+ echo -e "Result may be inaccurate for affected log4j-core jar files other than those found"
+ echo -e "in the two listed maven repositories as of 2021-12-13 and between versions"
+ echo -e "2.0(.*) inclusive and 2.14.* inclusive:"
+ echo -e "* https://maven.repository.redhat.com/ga/org/apache/logging/log4j/log4j-core/"
+ echo -e "* https://repo1.maven.org/maven2/org/apache/logging/log4j/log4j-core/${RESET}"
+
+ echo "Symbolic links are not followed. Only local filesystem paths are supported."
+ echo
+
+ # * readlink is required to canonicalize paths; it's installed by default on supported RHEL versions (coreutils)
+ # * file is required to recognize zip/jar files; it's installed by default on supported RHEL versions (file)
+ # * unzip is required to unpack zip/jar files; it's installed by default on RHEL 6 and 8, but not on 7 (unzip)
+ # * stat is required to calculate file size; it's installed by default on supported RHEL versions (coreutils)
+ # * sha256sum is required to deduplicate and catalog temporary files; it's installed by default on supported RHEL versions (coreutils)
+ # * basename is required to deduplicate and catalog temporary files; it's installed by default on supported RHEL versions (coreutils)
+ # * cat is required to deduplicate and catalog temporary files; it's installed by default on supported RHEL versions (coreutils)
+ # * grep is required to deduplicate and catalog temporary files; it's installed by default on supported RHEL versions (grep)
+ # * uname is required for debug output; it's installed by default on supported RHEL versions (coreutils)
+ # * pwd is required during algorithm processing; it's installed by default on supported RHEL versions (coreutils)
+ # * /bin/rm is required during algorithm processing and to clean temporary files at the end of execution; it's installed by default on supported RHEL versions (coreutils)
+ for required_command in readlink file unzip stat sha256sum basename cat grep uname pwd /bin/rm ; do
+ if ! command -v "$required_command" &> /dev/null; then
+ echo "'$required_command' command is required, but not installed. Exiting."
+ if [[ "$required_command" == "unzip" ]] ; then
+ # Be extra nice because a lot of systems are going to hit this.
+ echo "Please run 'yum install unzip' before running this script."
+ fi
+ print_debug
+ exit 1
+ fi
+ done
+}
+
+
+err_inaccessible() {
+ # Prints an error message. Prints debug information if configured to do so.
+ #
+ # Side effects:
+ # Exits.
+
+ echo "The provided temporary directory is not accessible or can't be created. Please provide an empty and accessible temporary directory."
+ echo
+ print_help
+ print_debug
+ exit 1
+}
+
+
+err_nonempty() {
+ # Prints an error message. Prints debug information if configured to do so.
+ #
+ # Side effects:
+ # Exits.
+
+ echo "The provided temporary directory is not empty. Please provide an empty temporary directory."
+ echo
+ print_help
+ print_debug
+ exit 1
+}
+
+
+err_internal_path_validation() {
+ # Prints an error message. Prints debug information if configured to do so.
+ #
+ # Side effects:
+ # Exits.
+
+ # We realize this is not helpful, but printing the string that triggered the check might itself be unsafe.
+ # This should never happen, as long as sha256sum behaves as expected, and as long as TMPPATH and SCANPATH are not externally modified.
+ echo "An error occurred during internal file path validation. Please make sure only a single instance of the script runs and that TMPPATH nor SCANPATH is modified while the script runs."
+ print_debug
+ exit 3
+}
+
+is_subpath() {
+ # Checks that the following is true:
+ # 1. The supplied base path ($1) is a subpath of the supplied proposed path ($2). That means:
+ # a. The supplied base path is not longer than the supplied proposed path.
+ # b. The supplied base path is a substring (starting at the beginning) of the supplied proposed path.
+ # c. After that substring, there is a slash in the supplied proposed path.
+ # (I.e. if $1 is /opt/something and $2 /opt/somethingelse, an error is produced.)
+ # 2. Both paths are canonical.
+ # a. base path is canonical
+ # a. proposed path is canonical
+ # 3. There are no /../ parts in the paths.
+ # a. base path
+ # a. proposed path
+ # 4. There are no symlinks in the paths.
+ # a. base path
+ # a. proposed path
+ #
+ # Args:
+ # base_path_is - the base path
+ # proposed_path_is - the proposed path to check whether it's a subpath
+ #
+ # Side effects:
+ # Exits, if there's an issue.
+
+ local base_path_is="$1"
+ local proposed_path_is="$2"
+
+ local len_base_path_is="${#base_path_is}"
+ local len_proposed_path_is="${#proposed_path_is}"
+
+ # This is for human review purposes. These checks correspond with the function's docstring.
+ local check_1_a=0
+ local check_1_b=0
+ local check_1_c=0
+ local check_2_a=0
+ local check_2_b=0
+ local check_3_a=0
+ local check_3_b=0
+ local check_4_a=0
+ local check_4_b=0
+
+ # A subpath can't be shorter! (If both are canonical.)
+ if (( len_base_path_is > len_proposed_path_is )) ; then
+ err_internal_path_validation # exit 3
+ else
+ check_1_a=1
+ fi
+
+ local prefix_of_proposed_is="${proposed_path_is:0:$len_base_path_is}"
+
+ # The "base" path must be the exact prefix of the "proposed" path
+ if [[ "$prefix_of_proposed_is" != "$base_path_is" ]] ; then
+ err_internal_path_validation # exit 3
+ else
+ check_1_b=1
+ fi
+
+ local char_after_prefix_of_proposed_is="${proposed_path_is:$len_base_path_is:1}"
+
+ # After that prefix, there must be a /
+ if [[ "$char_after_prefix_of_proposed_is" != "/" ]] ; then
+ err_internal_path_validation # exit 3
+ else
+ check_1_c=1
+ fi
+
+ # Both supplied paths must be canonical. This eliminates symlinks and things like /../
+
+ if [[ "$( readlink -f "$base_path_is" )" != "$base_path_is" ]] ; then
+ err_internal_path_validation # exit 3
+ else
+ check_2_a=1
+ check_3_a=1
+ check_4_a=1
+ fi
+
+ if [[ "$( readlink -f "$proposed_path_is" )" != "$proposed_path_is" ]] ; then
+ err_internal_path_validation # exit 3
+ else
+ check_2_b=1
+ check_3_b=1
+ check_4_b=1
+ fi
+
+ if (( check_1_a && check_1_b && check_1_c && check_2_a && check_2_b && check_3_a && check_3_b && check_4_a && check_4_b )) ; then
+ return 0
+ else
+ err_internal_path_validation # exit 3
+ fi
+}
+
+
+validate_path_tmp() {
+ # Checks that the $proposed_path_vpt is a subpath of $base_path_vpt and
+ # that both are subpaths of $tmp_path.
+ #
+ # Args:
+ # base_path_vpt - the base path we deem as generally safe for manipulation
+ # proposed_path_vpt - the proposed path to check for issues
+ #
+ # Side effects:
+ # Exits, if there's an issue.
+
+ local base_path_vpt="$1"
+ local proposed_path_vpt="$2"
+
+ # The supplied base path must be a subpath of $tmp_path, which we treat as trusted (absolute canonical user-supplied path),
+ # or it must be identical to $tmp_path
+ if [[ "$base_path_vpt" != "$tmp_path" ]] ; then
+ is_subpath "$tmp_path" "$base_path_vpt"
+ fi
+
+ # The supplied proposed path must be a subpath of the supplied base path
+ is_subpath "$base_path_vpt" "$proposed_path_vpt"
+
+ # Note that is_subpath calls "exit 3" if any of the claims are not true / if any of the checks fail
+}
+
+
+validate_path_scan() {
+ # Checks that the $proposed_path_vps is a subpath of $base_path_vps and
+ # that both are subpaths of $scan_path.
+ #
+ # Args:
+ # base_path_vps - the base path we deem as generally safe for manipulation
+ # proposed_path_vps - the proposed path to check for issues
+ #
+ # Side effects:
+ # Exits, if there's an issue.
+
+ local base_path_vps="$1"
+ local proposed_path_vps="$2"
+
+ # The supplied base path must be a subpath of $scan_path, which we treat as trusted (absolute canonical user-supplied path),
+ # or it must be identical to $scan_path
+ if [[ "$base_path_vps" != "$scan_path" ]] ; then
+ is_subpath "$scan_path" "$base_path_vps"
+ fi
+
+ # The supplied proposed path must be a subpath of the supplied base path
+ is_subpath "$base_path_vps" "$proposed_path_vps"
+
+ # Note that is_subpath calls "exit 3" if any of the claims are not true / if any of the checks fail
+}
+
+
+safe_mkdir_parents() {
+ # Creates $newdir under $tmp_path/$parents.
+ #
+ # Args:
+ # newdir - directory to create under $tmp_path/$parents
+ #
+ # Side effects:
+ # Exits, if there's an issue, such as $newdir being outside $tmp_path/$parents.
+
+ local newdir="$1"
+
+ # Note that the '-p' argument makes mkdir not complain if the directory already exists.
+
+ # Yes, $tmp_path/$parents == $tmp_path/CVE_2021_44228_parents, but the point of using the second expression is to very clearly show where the new dir is being created
+ validate_path_tmp "$tmp_path/$parents" "$tmp_path/CVE_2021_44228_parents/$newdir"
+ mkdir -p "$tmp_path/$parents/$newdir"
+}
+
+
+safe_mkdir_decompressed() {
+ # Creates $newdir under $tmp_path/$decompressed.
+ #
+ # Args:
+ # newdir - directory to create under $tmp_path/$decompressed
+ #
+ # Side effects:
+ # Exits, if there's an issue, such as $newdir being outside $tmp_path/$decompressed.
+
+ local newdir="$1"
+
+ # Yes, $tmp_path/$decompressed == $tmp_path/CVE_2021_44228_decompressed, but the point of using the second expression is to very clearly show where the new dir is being created
+ validate_path_tmp "$tmp_path/$decompressed" "$tmp_path/CVE_2021_44228_decompressed/$newdir"
+ mkdir "$tmp_path/$decompressed/$newdir"
+}
+
+
+safe_mkdir_backtrack() {
+ # Creates $newdir under $tmp_path/$backtrack.
+ #
+ # Args:
+ # newdir - directory to create under $tmp_path/$backtrack
+ #
+ # Side effects:
+ # Exits, if there's an issue, such as $newdir being outside $tmp_path/$backtrack.
+
+ local newdir="$1"
+
+ # Note that the '-p' argument makes mkdir not complain if the directory already exists.
+
+ # Yes, $tmp_path/$backtrack == $tmp_path/CVE_2021_44228_backtrack, but the point of using the second expression is to very clearly show where the new dir is being created
+ validate_path_tmp "$tmp_path/$backtrack" "$tmp_path/CVE_2021_44228_backtrack/$newdir"
+ mkdir -p "$tmp_path/$backtrack/$newdir"
+}
+
+
+safe_echo_parents() {
+ # Does 'echo $str > $tmp_path/$parents/$dst'.
+ #
+ # Args:
+ # str - string to be echoed into a file
+ # dst - file path where to save the string
+ #
+ # Side effects:
+ # Exits, if there's an issue, such as $dst being outside $tmp_path/$parents.
+
+ local str="$1"
+ local dst="$2"
+
+ # Yes, $tmp_path/$parents == $tmp_path/CVE_2021_44228_parents, but the point of using the second expression is to very clearly show where the new dir is being created
+ validate_path_tmp "$tmp_path/$parents" "$tmp_path/CVE_2021_44228_parents/$dst"
+ echo "$str" > "$tmp_path/$parents/$dst"
+}
+
+
+safe_echo_backtrack() {
+ # Does 'echo $str > $tmp_path/$backtrack/$dst'.
+ #
+ # Args:
+ # str - string to be echoed into a file
+ # dst - file path where to save the string
+ #
+ # Side effects:
+ # Exits, if there's an issue, such as $dst being outside $tmp_path/$backtrack.
+
+ local str="$1"
+ local dst="$2"
+
+ # Yes, $tmp_path/$backtrack == $tmp_path/CVE_2021_44228_backtrack, but the point of using the second expression is to very clearly show where the new dir is being created
+ validate_path_tmp "$tmp_path/$backtrack" "$tmp_path/CVE_2021_44228_backtrack/$dst"
+ echo "$str" > "$tmp_path/$backtrack/$dst"
+}
+
+
+safe_echo_report() {
+ # Does 'echo $str > $tmp_path/$report/$dst'.
+ #
+ # Args:
+ # str - string to be echoed into a file
+ # dst - file path where to save the string
+ #
+ # Side effects:
+ # Exits, if there's an issue, such as $dst being outside $tmp_path/$report.
+
+ local str="$1"
+ local dst="$2"
+
+ # Yes, $tmp_path/$report == $tmp_path/report, but the point of using the second expression is to very clearly show where the new dir is being created
+ validate_path_tmp "$tmp_path/$report" "$tmp_path/report/$dst"
+ echo "$str" > "$tmp_path/report/$dst"
+}
+
+
+validate_path_inside_scan_or_tmp() {
+ # Checks that $src is a subpath of $scan_path or of $tmp_path.
+ #
+ # Args:
+ # src - path to be validated
+ #
+ # Side effects:
+ # Exits, if there's an issue, or if the answer is "no".
+
+ local src="$1"
+ local len_src="${#src}"
+ local scan_path_with_slash="$scan_path/"
+ local len_scan_path="${#scan_path_with_slash}"
+
+ local probably_inside_scan_path=0
+
+ if (( len_src > len_scan_path )) ; then
+ local src_prefix="${src:0:$len_scan_path}"
+ if [[ "$src_prefix" == "$scan_path_with_slash" ]] ; then
+ probably_inside_scan_path=1
+ fi
+ fi
+
+ # Forbid reading from anywhere else than inside scan_path or tmp_path
+ if (( probably_inside_scan_path )) ; then
+ validate_path_scan "$scan_path" "$src"
+ else
+ validate_path_tmp "$tmp_path" "$src"
+ fi
+}
+
+
+safe_cp_queue() {
+ # Does 'cp $src $tmp_path/$queue/$dst'. Checks that $src is a subpath of $scan_path or
+ # $tmp_path and checks that '$tmp_path/$queue/$dst' doesn't get outside of $tmp_path/$queue.
+ #
+ # Args:
+ # src
+ # dst
+ #
+ # Side effects:
+ # Exits, if there's an issue.
+
+ local src="$1"
+ local dst="$2"
+
+ # Forbid reading from anywhere else than inside scan_path or tmp_path
+ validate_path_inside_scan_or_tmp "$src"
+
+ # Yes, $tmp_path/$queue == $tmp_path/CVE_2021_44228_queue, but the point of using the second expression is to very clearly show where the new dir is being created
+ validate_path_tmp "$tmp_path/$queue" "$tmp_path/CVE_2021_44228_queue/$dst"
+
+ if [[ ! -f "$src" ]] ; then
+ err_internal_path_validation
+ fi
+
+ cp "$src" "$tmp_path/$queue/$dst"
+}
+
+
+safe_sha256_sum_from_string() {
+ # Returns a sha256hash of the string in the argument $src.
+ #
+ # Args:
+ # src - the string to be hashed
+ #
+ # Side effects:
+ # Exits, if there's an issue, such as invalid sha256sum output.
+
+ local src="$1"
+ local hash
+ hash="$( echo "$src" | sha256sum )"
+ hash="${hash%% *}"
+ if [[ $hash =~ ^[01-9a-f]{64}$ ]] ; then
+ echo "$hash"
+ else
+ echo "There's a file that makes sha256sum output non-standard. This is highly suspicious. Aborting." >&2
+ exit 3
+ fi
+}
+
+
+safe_sha256_sum_from_file() {
+ # Returns a sha256hash of the file in the path $src. Checks that $src is a
+ # subpath of $scan_path or $tmp_path.
+ #
+ # Args:
+ # src - the file to be hashed
+ #
+ # Side effects:
+ # Exits, if there's an issue, such as invalid sha256sum output, or $src
+ # outside of allowed paths.
+
+ local src="$1"
+
+ # Forbid reading from anywhere else than inside scan_path or tmp_path
+ validate_path_inside_scan_or_tmp "$src"
+
+ if [[ ! -f "$src" ]] ; then
+ err_internal_path_validation
+ fi
+
+ local hash
+ hash="$( sha256sum "$src" )"
+ hash="${hash%% *}"
+
+ if [[ $hash =~ ^[01-9a-f]{64}$ ]] ; then
+ echo "$hash"
+ else
+ echo "There's a file that makes sha256sum output non-standard. This is highly suspicious. Aborting." >&2
+ exit 3
+ fi
+}
+
+
+safe_cat_parents() {
+ # Does 'cat $tmp_path/$parents/$src'.
+ #
+ # Args:
+ # src - file to read and return via stdout, located under $tmp_path/$parents
+ #
+ # Side effects:
+ # Exits, if there's an issue, such as $src pointint outside of allowed
+ # path, or $src not existing.
+
+ local src="$1"
+
+ # Yes, $tmp_path/$parents == $tmp_path/CVE_2021_44228_parents, but the point of using the second expression is to very clearly show where the new dir is being created
+ validate_path_tmp "$tmp_path/$parents" "$tmp_path/CVE_2021_44228_parents/$src"
+
+ if [[ ! -f "$tmp_path/$parents/$src" ]] ; then
+ err_internal_path_validation
+ fi
+
+ cat "$tmp_path/$parents/$src"
+}
+
+
+safe_cat_backtrack() {
+ # Does 'cat $tmp_path/$backtrack/$src'.
+ #
+ # Args:
+ # src - file to read and return via stdout, located under $tmp_path/$backtrack
+ #
+ # Side effects:
+ # Exits, if there's an issue, such as $src pointint outside of allowed
+ # path, or $src not existing.
+
+ local src="$1"
+
+ # Yes, $tmp_path/$backtrack == $tmp_path/CVE_2021_44228_backtrack, but the point of using the second expression is to very clearly show where the new dir is being created
+ validate_path_tmp "$tmp_path/$backtrack" "$tmp_path/CVE_2021_44228_backtrack/$src"
+
+ if [[ ! -f "$tmp_path/$backtrack/$src" ]] ; then
+ err_internal_path_validation
+ fi
+
+ cat "$tmp_path/$backtrack/$src"
+}
+
+
+safe_rm_rf_backtrack() {
+ # Does 'rm -rf $tmp_path/$backtrack/$dir_to_delete'. Checks that $dir_to_delete is a subpath of $tmp_path/$backtrack.
+ #
+ # Args:
+ # dir_to_delete - the directory to recursively delete, under $tmp_path/$backtrack
+ #
+ # Side effects:
+ # Exits, if there's an issue, such as $dir_to_delete outside of allowed
+ # path, not existing, or containing .. or /
+
+ local dir_to_delete="$1"
+
+ # Yes, $tmp_path/$backtrack == $tmp_path/CVE_2021_44228_backtrack, but the point of using the second expression is to very clearly show where the new dir is being created
+ validate_path_tmp "$tmp_path/$backtrack" "$tmp_path/CVE_2021_44228_backtrack/$dir_to_delete"
+
+ if [[ ! -d "$tmp_path/$backtrack/$dir_to_delete" ]] ; then
+ err_internal_path_validation
+ fi
+
+ # The checks are technically redundant, but make auditing easier.
+ if [[ -d "$tmp_path/$backtrack/$dir_to_delete" && ! -L "$tmp_path/$backtrack/$dir_to_delete" ]] ; then
+ if [[ "$dir_to_delete" != *..* && "$dir_to_delete" != */* ]] ; then
+ if [[ "$tmp_path/$backtrack/$dir_to_delete" == "$audit_tmp_path/$backtrack/$dir_to_delete" ]] ; then
+ # Note that "${var:?}" fails on purpose if $var is null or unset (empty). See https://github.com/koalaman/shellcheck/wiki/SC2115
+ ( cd -- "${audit_tmp_path:?}" && /bin/rm -rf --one-file-system -- "${backtrack:?}/${dir_to_delete:?}" ; )
+ fi
+ fi
+ fi
+}
+
+
+safe_touch_catalog() {
+ # Creates or 'touch'es a file $newfile under $tmp_path/$catalog.
+ #
+ # Args:
+ # newfile - file to create or 'touch' under $tmp_path/$catalog
+ #
+ # Side effects:
+ # Exits, if there's an issue, such as the resulting path being outside
+ # $tmp_path/$catalog.
+
+ local newfile="$1"
+
+ # Yes, $tmp_path/$catalog == $tmp_path/CVE_2021_44228_catalog, but the point of using the second expression is to very clearly show where the new dir is being created
+ validate_path_tmp "$tmp_path/$catalog" "$tmp_path/CVE_2021_44228_catalog/$newfile"
+
+ touch "$tmp_path/$catalog/$newfile"
+}
+
+
+safe_touch_detections() {
+ # Creates or 'touch'es a file $newfile under $tmp_path/$detections.
+ #
+ # Args:
+ # newfile - file to create or 'touch' under $tmp_path/$detections
+ #
+ # Side effects:
+ # Exits, if there's an issue, such as the resulting path being outside
+ # $tmp_path/$detections.
+
+ local newfile="$1"
+
+ # Yes, $tmp_path/$detections == $tmp_path/CVE_2021_44228_detections, but the point of using the second expression is to very clearly show where the new dir is being created
+ validate_path_tmp "$tmp_path/$detections" "$tmp_path/CVE_2021_44228_detections/$newfile"
+
+ touch "$tmp_path/$detections/$newfile"
+}
+
+
+get_queue_length() {
+ # Returns the number of files under $tmp_path/$queue.
+
+ local queue_files_for_counting=( "$tmp_path/$queue"/q-*-* )
+ local num="${#queue_files_for_counting[@]}"
+ echo "$num"
+}
+
+
+prepare_directories() {
+ # Prepares temporary and result report directories under tmp_path for the
+ # detection algorithm's operation.
+ #
+ # Side effects:
+ # Exits, if there's an issue, such as non-writable tmp_path.
+ (
+ cd "$tmp_path" || err_inaccessible
+
+ local are_there_files=(*)
+ if (( "${#are_there_files[@]}" != 0 )) ; then
+ err_nonempty
+ fi
+ )
+
+ validate_path_tmp "$tmp_path" "$tmp_path/$queue"
+ validate_path_tmp "$tmp_path" "$tmp_path/$catalog"
+ validate_path_tmp "$tmp_path" "$tmp_path/$decompressed"
+ validate_path_tmp "$tmp_path" "$tmp_path/$parents"
+ validate_path_tmp "$tmp_path" "$tmp_path/$backtrack"
+ validate_path_tmp "$tmp_path" "$tmp_path/$detections"
+ validate_path_tmp "$tmp_path" "$tmp_path/$report"
+
+ mkdir "$tmp_path/$queue" || err_inaccessible
+ mkdir "$tmp_path/$catalog" || err_inaccessible
+ mkdir "$tmp_path/$decompressed" || err_inaccessible
+ mkdir "$tmp_path/$parents" || err_inaccessible
+ mkdir "$tmp_path/$backtrack" || err_inaccessible
+ mkdir "$tmp_path/$detections" || err_inaccessible
+ mkdir "$tmp_path/$report" || err_inaccessible
+}
+
+
+delete_directories() {
+ # Deletion is a sensitive operation. The checks here are painfully redundant.
+ # This is to make it clear to reviewers that it is not possible for files
+ # outside user-specified TMPPATH to get deleted. See the NOTE at the beginning
+ # for more details.
+
+ # All of these must turn non-zero for deletion to occur.
+ local ok_tmp_path=0
+ local ok_queue=0
+ local ok_catalog=0
+ local ok_decompressed=0
+ local ok_parents=0
+ local ok_backtrack=0
+ local ok_detections=0
+ local ok_report=0
+
+ local check_queue
+ local check_catalog
+ local check_decompressed
+ local check_parents
+ local check_backtrack
+ local check_detections
+ local check_report
+
+ # All these paths should already be canonical, so let's canonicalize them again to check again.
+ check_queue="$( readlink -f "$tmp_path/$queue" || exit 1 )"
+ check_catalog="$( readlink -f "$tmp_path/$catalog" || exit 1 )"
+ check_decompressed="$( readlink -f "$tmp_path/$decompressed" || exit 1 )"
+ check_parents="$( readlink -f "$tmp_path/$parents" || exit 1 )"
+ check_backtrack="$( readlink -f "$tmp_path/$backtrack" || exit 1 )"
+ check_detections="$( readlink -f "$tmp_path/$detections" || exit 1 )"
+ check_report="$( readlink -f "$tmp_path/$report" || exit 1 )"
+
+ # Making sure tmp_path didn't get emptied somewhere.
+ # Making sure the temporary directory contains the right number of items.
+ if [[ "$tmp_path" != "" ]] && [[ -d "$tmp_path" && ! -L "$tmp_path" ]] ; then
+ local num_of_entries=0
+ local tmp_path_problem=0
+ local entry
+ for entry in "$tmp_path"/* ; do
+ num_of_entries="$(( num_of_entries + 1 ))"
+ if ! [[ "$entry" == "$tmp_path/$queue" || "$entry" == "$tmp_path/$catalog" || "$entry" == "$tmp_path/$decompressed" || "$entry" == "$tmp_path/$parents" || "$entry" == "$tmp_path/$backtrack" || "$entry" == "$tmp_path/$detections" || "$entry" == "$tmp_path/$report" ]] ; then
+ tmp_path_problem=1
+ fi
+ done
+ if (( num_of_entries == 7 && !tmp_path_problem )) ; then
+ ok_tmp_path=1
+ fi
+ fi
+
+ # Making sure the variables didn't get changed somehow.
+ # The directory existence checks ensure that even if a single directory is missing, nothing gets deleted.
+ if [[ "$check_queue" == "$tmp_path/$queue" ]] && [[ "$check_queue" == "$tmp_path/CVE_2021_44228_queue" ]] ; then
+ if [[ -d "$check_queue" && ! -L "$check_queue" ]] ; then
+ ok_queue=1
+ fi
+ fi
+
+ # By the way, note that all the temporary files have strings that are unlikely to occur in normal operations. Even if tmp_path resolved to something malicious and evaded all checks, only the final subdirectories with the peculiar strings would be deleted.
+ if [[ "$check_catalog" == "$tmp_path/$catalog" ]] && [[ "$check_catalog" == "$tmp_path/CVE_2021_44228_catalog" ]] ; then
+ if [[ -d "$check_catalog" && ! -L "$check_catalog" ]] ; then
+ ok_catalog=1
+ fi
+ fi
+
+ if [[ "$check_decompressed" == "$tmp_path/$decompressed" ]] && [[ "$check_decompressed" == "$tmp_path/CVE_2021_44228_decompressed" ]] ; then
+ if [[ -d "$check_decompressed" && ! -L "$check_decompressed" ]] ; then
+ ok_decompressed=1
+ fi
+ fi
+
+ if [[ "$check_parents" == "$tmp_path/$parents" ]] && [[ "$check_parents" == "$tmp_path/CVE_2021_44228_parents" ]] ; then
+ if [[ -d "$check_parents" && ! -L "$check_parents" ]] ; then
+ ok_parents=1
+ fi
+ fi
+
+ if [[ "$check_backtrack" == "$tmp_path/$backtrack" ]] && [[ "$check_backtrack" == "$tmp_path/CVE_2021_44228_backtrack" ]] ; then
+ if [[ -d "$check_backtrack" && ! -L "$check_backtrack" ]] ; then
+ ok_backtrack=1
+ fi
+ fi
+
+ if [[ "$check_detections" == "$tmp_path/$detections" ]] && [[ "$check_detections" == "$tmp_path/CVE_2021_44228_detections" ]] ; then
+ if [[ -d "$check_detections" && ! -L "$check_detections" ]] ; then
+ ok_detections=1
+ fi
+ fi
+
+ if [[ "$check_report" == "$tmp_path/$report" ]] && [[ "$check_report" == "$tmp_path/report" ]] ; then
+ if [[ -d "$check_report" && ! -L "$check_report" ]] ; then
+ ok_report=1
+ fi
+ fi
+
+ if (( ok_tmp_path && ok_queue && ok_catalog && ok_decompressed && ok_parents && ok_backtrack && ok_detections && ok_report )) ; then
+
+ # The checks are technically redundant, but make auditing easier.
+ # Note that "${var:?}" fails on purpose if $var is null or unset (empty). See https://github.com/koalaman/shellcheck/wiki/SC2115
+
+ if [[ "$tmp_path/$queue" == "$audit_tmp_path/$queue" ]] ; then
+ ( cd -- "${audit_tmp_path:?}" && /bin/rm -rf --one-file-system -- "${queue:?}" ; )
+ fi
+
+ if [[ "$tmp_path/$catalog" == "$audit_tmp_path/$catalog" ]] ; then
+ ( cd -- "${audit_tmp_path:?}" && /bin/rm -rf --one-file-system -- "${catalog:?}" ; )
+ fi
+
+ if [[ "$tmp_path/$decompressed" == "$audit_tmp_path/$decompressed" ]] ; then
+ ( cd -- "${audit_tmp_path:?}" && /bin/rm -rf --one-file-system -- "${decompressed:?}" ; )
+ fi
+
+ if [[ "$tmp_path/$parents" == "$audit_tmp_path/$parents" ]] ; then
+ ( cd -- "${audit_tmp_path:?}" && /bin/rm -rf --one-file-system -- "${parents:?}" ; )
+ fi
+
+ if [[ "$tmp_path/$backtrack" == "$audit_tmp_path/$backtrack" ]] ; then
+ ( cd -- "${audit_tmp_path:?}" && /bin/rm -rf --one-file-system -- "${backtrack:?}" ; )
+ fi
+
+ if [[ "$tmp_path/$detections" == "$audit_tmp_path/$detections" ]] ; then
+ ( cd -- "${audit_tmp_path:?}" && /bin/rm -rf --one-file-system -- "${detections:?}" ; )
+ fi
+
+ # Note that $report is not deleted, because it contains output for the user.
+ fi
+}
+
+
+is_zip() {
+ # Returns exit code 0 if $file_to_check is a jar/zip file. Returns non-zero
+ # exit code if it doesn't exist or is not a jar/zip file.
+ #
+ # Args:
+ # file_to_check
+ #
+ # Side effects:
+ # Exits, if $file_to_check is outside of allowed paths ($scan_path or
+ # $tmp_path).
+
+ local file_to_check="$1"
+
+ if [[ -f "$file_to_check" && ! -L "$file_to_check" ]] ; then
+ validate_path_inside_scan_or_tmp "$( pwd )/$file_to_check"
+ file -b "$file_to_check" | grep -q -E '^(Java archive data)|(Zip archive data)'
+ else
+ return 1
+ fi
+}
+
+
+# Even though this is not correct general-purpose XML processing, it works for all known log4j-core version 2 releases.
+is_log4j() {
+ # Returns exit code 0 if $file_to_check is a log4j jar file. Returns non-zero
+ # exit code if it doesn't exist or is not a log4j jar file.
+ #
+ # Args:
+ # file_to_check
+ #
+ # Side effects:
+ # Exits, if $file_to_check is outside of allowed paths ($scan_path or
+ # $tmp_path).
+
+ local file_to_check="$1"
+
+ local parent_il
+ if [[ -d "$file_to_check" && ! -L "$file_to_check" ]] ; then
+ (
+ cd "$file_to_check" && {
+ # Forbid reading from anywhere else than inside scan_path or tmp_path
+ validate_path_inside_scan_or_tmp "$( pwd )"
+
+ if [[ -f "$POM_PATH" && ! -L "$POM_PATH" ]] ; then
+ validate_path_tmp "$tmp_path/$decompressed" "$( pwd )/$POM_PATH"
+ parent_il="$( grep -A5 -F "" "$POM_PATH" | grep -B5 -F "" )"
+ if { echo "$parent_il" | grep -q -F 'org.apache.logging.log4j' ; } ; then
+ if { echo "$parent_il" | grep -q -F 'log4j' ; } ; then
+ return 0
+ fi
+ fi
+ fi
+ }
+ return 1
+ )
+ fi
+}
+
+
+is_vulnerable() {
+ # Returns exit code 0 if $file_to_check is a log4j jar file with version
+ # 2.0-<2.15, except for 2.12.2. Returns non-zero exit code if it doesn't
+ # exist or the answer is "no"
+ #
+ # Args:
+ # file_to_check
+ #
+ # Side effects:
+ # Exits, if $file_to_check is outside of allowed paths ($scan_path or
+ # $tmp_path).
+
+ local file_to_check="$1"
+
+ local parent_iv
+ local version
+ local minor
+
+ if [[ -d "$file_to_check" && ! -L "$file_to_check" ]] ; then
+ (
+ cd "$file_to_check" && {
+ # Forbid reading from anywhere else than inside scan_path or tmp_path
+ validate_path_inside_scan_or_tmp "$( pwd )"
+
+ if [[ -f "$POM_PATH" && ! -L "$POM_PATH" ]] ; then
+ validate_path_tmp "$tmp_path/$decompressed" "$( pwd )/$POM_PATH"
+ parent_iv="$( grep -A5 -F "" "$POM_PATH" | grep -B5 -F "" )"
+ if { echo "$parent_iv" | grep -q -F 'org.apache.logging.log4j' ; } ; then
+ if { echo "$parent_iv" | grep -q -F 'log4j' ; } ; then
+ version="$( echo "$parent_iv" | grep -o -E '2\..*' | grep -o -E '2[^<]*' )"
+ if [[ "$version" == "" ]] ; then
+ # Not vulnerable, because this is not version 2.
+ return 1
+ fi
+ minor="${version##2.}"
+ minor="${minor%%-*}"
+ minor="${minor%%.*}"
+ if (( minor < 15 && minor >= 0 )) ; then
+ # vulnerable are those between earliest 2.0 and lower than 2.15 (not including 2.15), except for 2.12.2
+ if [[ "$version" != "2.12.2" ]] ; then
+ return 0
+ fi
+ fi
+ fi
+ fi
+ fi
+ }
+ return 1
+ )
+ fi
+}
+
+
+save_relationship() {
+ # Saves information about a relationship of two files and the path fragment
+ # that leads from one to the other. This information is saved under $tmp_path/$parents.
+ #
+ # Args:
+ # pch - parent content hash
+ # cch - child content hash
+ # pf - path fragment (relative path of child under parent)
+ # hpf - hash of the path fragment
+ #
+ # Side effects:
+ # Exits, if using any of $pch, $cch or $hpf would result in a path
+ # outside of $tmp_path/$parents.
+
+ local pch="$1"
+ local cch="$2"
+ local pf="$3"
+ local hpf="$4"
+
+ validate_path_tmp "$tmp_path/$parents" "$tmp_path/$parents/$cch"
+ safe_mkdir_parents "$cch"
+
+ validate_path_tmp "$tmp_path/$parents/$cch" "$tmp_path/$parents/$cch/$pch"
+ safe_mkdir_parents "$cch/$pch"
+
+ validate_path_tmp "$tmp_path/$parents/$cch/$pch" "$tmp_path/$parents/$cch/$pch/$hpf"
+ validate_path_tmp "$tmp_path/$parents" "$tmp_path/$parents/$cch/$pch/$hpf"
+ safe_echo_parents "$pf" "$cch/$pch/$hpf"
+}
+
+
+catalog_dir() {
+ # Iterates over the specified $dir_to_catalog and processes regular files
+ # (by calling catalog_file) and directories (recursively calling itself).
+ # Passes $path_fragment and $parent_content_hash to the recursively-called
+ # functions.
+ #
+ # Args:
+ # dir_to_catalog - dir to be cataloged
+ # path_fragment - path fragment from parent file
+ # parent_content_hash - hash of the parent file contents
+ #
+ # Side effects:
+ # Exits, if $dir_to_catalog is outside of $scan_path or $tmp_path.
+
+ local dir_to_catalog="$1"
+ local path_fragment="$2"
+ local parent_content_hash="$3"
+
+ if [[ -d "$dir_to_catalog" && ! -L "$dir_to_catalog" ]] ; then
+ (
+ cd "$dir_to_catalog" && {
+ # Forbid reading from anywhere else than inside scan_path or tmp_path
+ if [[ "$dir_to_catalog" != "$scan_path" ]] ; then
+ validate_path_inside_scan_or_tmp "$( pwd )"
+ fi
+
+ for fn in * ; do
+ if [[ -f "$fn" && ! -L "$fn" ]] ; then
+ catalog_file "$fn" "$path_fragment/$fn" "$parent_content_hash"
+ elif [[ -d "$fn" && ! -L "$fn" ]] ; then
+ catalog_dir "$fn" "$path_fragment/$fn" "$parent_content_hash"
+ fi
+ done
+ }
+ )
+ fi
+}
+
+
+catalog_file() {
+ # Briefly analyzes the file, decides whether to queue it for extraction,
+ # finds already-processed duplicates, and records the file's relationship
+ # information (parent, path fragment).
+ #
+ # Args:
+ # file_to_catalog - file to be cataloged
+ # path_fragment - path fragment from parent file
+ # parent_content_hash - hash of the parent file contents
+ #
+ # Side effects:
+ # Exits, if $file_to_catalog is outside of $scan_path or $tmp_path, or
+ # if unexpected things happen (reading/writing outside of approved
+ # paths or hashing not working as expected).
+
+ local file_to_catalog="$1"
+ local path_fragment="$2"
+ local parent_content_hash="$3"
+
+ local size
+ local hash
+ local path_fragment_hash
+
+ # Forbid reading from anywhere else than inside scan_path or tmp_path
+ validate_path_inside_scan_or_tmp "$( pwd )/$file_to_catalog"
+ size="$( stat -c%s "$file_to_catalog" )"
+
+ # smallest known log4j-core is 375010 bytes, smallest known non-alpha is 702665 bytes, so 300k leaves us with a cushion in case there are other builds out there
+ if (( size > 300000 )) ; then
+ if is_zip "$file_to_catalog" ; then
+
+ if (( print_progress )) ; then
+ # $queue_length might be out-of-date, but it's not an essential feature
+ echo "[ $queue_position / $( get_queue_length ) ] Cataloging file ${file_to_catalog:0:60}..."
+ fi
+
+ hash="$( safe_sha256_sum_from_file "$( pwd )/$file_to_catalog" )"
+ path_fragment_hash="$( safe_sha256_sum_from_string "$path_fragment" )"
+ if [[ -f "$tmp_path/$catalog/$hash" ]] ; then
+ # Already processed, so just record the new path
+ # Args of save_relationship:
+ # 1 - parent content hash
+ # 2 - child content hash
+ # 3 - path fragment from parent to child
+ # 4 - hash of path fragment from parent to child
+ save_relationship "$parent_content_hash" "$hash" "$path_fragment" "$path_fragment_hash"
+ else
+ # This is being run in a subshell, so we don't see current global variables, nor is there write access to them, but it's possible to update them, just for this subshell.
+ queue_length="$( get_queue_length )"
+ queue_length="$(( queue_length + 1 ))"
+ safe_cp_queue "$( pwd )/$file_to_catalog" "q-${queue_length}-$hash"
+ safe_touch_catalog "$hash"
+ # Args of save_relationship:
+ # 1 - parent content hash
+ # 2 - child content hash
+ # 3 - path fragment from parent to child
+ # 4 - hash of path fragment from parent to child
+ save_relationship "$parent_content_hash" "$hash" "$path_fragment" "$path_fragment_hash"
+ fi
+ fi
+ fi
+}
+
+
+unpack_cataloged_recatalog() {
+ # Processes queued files by extracting them and iterating over their
+ # contents, adding new found files into the queue.
+ # Detects affected log4j jar files among the queued files (even nested).
+ #
+ # Side effects:
+ # * Uses significant disk space, depending on the original contents of
+ # $scan_path, which was loaded into $tmp_path before this function is
+ # run.
+ # * Exits, if any file operation happens outside of $tmp_path, or if
+ # any path to be used is found to be non-canonical (e.g. containing
+ # symlinks). Exits if any of the operations do not pass their
+ # individual validations.
+
+ local queued_path
+ local cataloged_hash_ucr
+
+ queue_length="$( get_queue_length )"
+ while (( queue_position < queue_length )) ; do
+ queue_position="$(( queue_position + 1 ))"
+ queue_length="$( get_queue_length )"
+ if (( queue_length_check <= queue_length )) ; then
+ queue_length_check="$queue_length"
+ else
+ echo "An external modification occurred in $tmp_path/$queue"
+ echo
+ err_internal_path_validation
+ fi
+
+ for queued_path in "$tmp_path/$queue/q-$queue_position-"* ; do
+ :
+ # just using the for loop to resolve the glob
+ done
+
+ if [[ ! -f "$queued_path" ]] ; then
+ continue
+ fi
+
+ validate_path_tmp "$tmp_path/$queue" "$queued_path"
+
+ cataloged_hash_ucr="$( basename "$queued_path" )"
+ cataloged_hash_ucr="${cataloged_hash_ucr#q-${queue_position}-}"
+ if [[ "$queued_path" != "$tmp_path/$queue/q-$queue_position-$cataloged_hash_ucr" ]] ; then
+ echo "An external modification occurred in $tmp_path/$queue"
+ echo
+ err_internal_path_validation
+ fi
+
+ validate_path_tmp "$tmp_path/$decompressed" "$tmp_path/$decompressed/$cataloged_hash_ucr"
+
+ if [[ -d "$tmp_path/$decompressed/$cataloged_hash_ucr" ]] ; then
+ # Already processed. This shouldn't happen, unless someone else adds new files here. Please, don't do that.
+ : #skip
+ else
+
+ if (( print_progress )) ; then
+ echo "[ $queue_position / $queue_length ] Extracting file..."
+ fi
+
+ safe_mkdir_decompressed "$cataloged_hash_ucr"
+ (
+ unzip -qq "$queued_path" -d "$tmp_path/$decompressed/$cataloged_hash_ucr" >/dev/null 2>&1 || true
+ )
+
+ if is_log4j "$tmp_path/$decompressed/$cataloged_hash_ucr" ; then
+ if is_vulnerable "$tmp_path/$decompressed/$cataloged_hash_ucr" ; then
+ validate_path_tmp "$tmp_path/$detections" "$tmp_path/$detections/$cataloged_hash_ucr"
+ safe_touch_detections "$cataloged_hash_ucr"
+ fi
+ fi
+
+ # Args of catalog_dir:
+ # 1 - dir to be cataloged
+ # 2 - path fragment from parent
+ # 3 - parent content hash
+ catalog_dir "$tmp_path/$decompressed/$cataloged_hash_ucr" "" "$cataloged_hash_ucr"
+ fi
+ done
+}
+
+
+produce_report() {
+ # Assembles recorded file relationships, path fragments, and log4j
+ # detections into full paths of detected affected log4j jar files, and
+ # saves these paths into .txt files in $tmp_path/$report.
+ #
+ # Side effects:
+ # Exits, if any file operation happens outside of $tmp_path, or if
+ # any path to be used is found to be non-canonical (e.g. containing
+ # symlinks). Exits if any of the operations do not pass their
+ # individual validations.
+
+ local detection_note_pr
+ local cataloged_hash_pr
+ local immediate_parent_pr
+ local immediate_parent_cataloged_hash_pr
+ local immediate_parent_pathfragment_path_pr
+ local immediate_parent_pathfragment_fn_pr
+ local immediate_parent_pathfragment_pr
+ local immediate_parent_pathfragment_hash_pr
+ local parent_pr
+ local parent_cataloged_hash_pr
+ local grandparent_pr
+ local grandparent_pathfragment_path_pr
+ local parent_pathfragment_path_pr
+ local detection_path_pr
+ local grandparent_cataloged_hash_pr
+ local grandparent_pathfragment_fn_pr
+ local grandparent_pathfragment_pr
+ local parent_pathfragment_fn_pr
+ local parent_pathfragment_pr
+ local assembled_grandparent_pathfragment_pr
+ local assembled_grandparent_pathfragment_hash_pr
+ local relevant_ls_pr
+ local num_relevant_ls_pr
+ local detection_path_basename_pr
+ local report_filename_pr
+ local detection_path_pathfragment_pr
+
+ # Record all leaf file path fragments (like "/log4j.jar") and all the parents that include these vulnerable files
+ for detection_note_pr in "$tmp_path/$detections"/* ; do
+ cataloged_hash_pr="$( basename "$detection_note_pr" )"
+ validate_path_tmp "$tmp_path/$detections" "$tmp_path/$detections/$cataloged_hash_pr"
+ validate_path_tmp "$tmp_path/$parents" "$tmp_path/$parents/$cataloged_hash_pr"
+ for immediate_parent_pr in "$tmp_path/$parents/$cataloged_hash_pr"/* ; do
+ immediate_parent_cataloged_hash_pr="$( basename "$immediate_parent_pr" )"
+ validate_path_tmp "$tmp_path/$parents/$cataloged_hash_pr" "$tmp_path/$parents/$cataloged_hash_pr/$immediate_parent_cataloged_hash_pr"
+ validate_path_tmp "$tmp_path/$parents/$cataloged_hash_pr" "$immediate_parent_pr"
+ for immediate_parent_pathfragment_path_pr in "$immediate_parent_pr"/* ; do
+ validate_path_tmp "$tmp_path/$parents/$cataloged_hash_pr/$immediate_parent_cataloged_hash_pr" "$immediate_parent_pathfragment_path_pr"
+ immediate_parent_pathfragment_fn_pr="$( basename "$immediate_parent_pathfragment_path_pr" )"
+ validate_path_tmp "$tmp_path/$parents/$cataloged_hash_pr/$immediate_parent_cataloged_hash_pr" "$tmp_path/$parents/$cataloged_hash_pr/$immediate_parent_cataloged_hash_pr/$immediate_parent_pathfragment_fn_pr"
+ immediate_parent_pathfragment_pr="$( safe_cat_parents "$cataloged_hash_pr/$immediate_parent_cataloged_hash_pr/$immediate_parent_pathfragment_fn_pr" )"
+ immediate_parent_pathfragment_hash_pr="$( safe_sha256_sum_from_string "$immediate_parent_pathfragment_pr" )"
+ validate_path_tmp "$tmp_path/$backtrack" "$tmp_path/$backtrack/$immediate_parent_cataloged_hash_pr"
+ safe_mkdir_backtrack "$immediate_parent_cataloged_hash_pr"
+ validate_path_tmp "$tmp_path/$backtrack/$immediate_parent_cataloged_hash_pr" "$tmp_path/$backtrack/$immediate_parent_cataloged_hash_pr/$immediate_parent_pathfragment_hash_pr"
+ safe_echo_backtrack "$immediate_parent_pathfragment_pr" "$immediate_parent_cataloged_hash_pr/$immediate_parent_pathfragment_hash_pr"
+ done
+ done
+ done
+
+ relevant_ls_pr=( "$tmp_path/$backtrack"/!(0) )
+ num_relevant_ls_pr="${#relevant_ls_pr[@]}"
+
+ # Resolve the paths one layer at a time
+ while (( num_relevant_ls_pr > 0 )) ; do
+ # One of them should be "0" - the scan_path.
+ # If there's sth else, it's yet-unresolved path fragments.
+ for parent_pr in "$tmp_path/$backtrack"/* ; do
+ parent_cataloged_hash_pr="$( basename "$parent_pr" )"
+ if [[ "$parent_cataloged_hash_pr" == "0" ]] ; then
+ continue
+ fi
+ for grandparent_pr in "$tmp_path/$parents/$parent_cataloged_hash_pr"/* ; do
+ grandparent_cataloged_hash_pr="$( basename "$grandparent_pr" )"
+ for grandparent_pathfragment_path_pr in "$grandparent_pr"/* ; do
+ validate_path_tmp "$tmp_path/$parents/$parent_cataloged_hash_pr/$grandparent_cataloged_hash_pr" "$grandparent_pathfragment_path_pr"
+ grandparent_pathfragment_fn_pr="$( basename "$grandparent_pathfragment_path_pr" )"
+ validate_path_tmp "$tmp_path/$parents/$parent_cataloged_hash_pr/$grandparent_cataloged_hash_pr" "$tmp_path/$parents/$parent_cataloged_hash_pr/$grandparent_cataloged_hash_pr/$grandparent_pathfragment_fn_pr"
+ grandparent_pathfragment_pr="$( safe_cat_parents "$parent_cataloged_hash_pr/$grandparent_cataloged_hash_pr/$grandparent_pathfragment_fn_pr" )"
+ for parent_pathfragment_path_pr in "$parent_pr"/* ; do
+ validate_path_tmp "$tmp_path/$backtrack" "$parent_pathfragment_path_pr"
+ parent_pathfragment_fn_pr="$( basename "$parent_pathfragment_path_pr" )"
+ validate_path_tmp "$tmp_path/$backtrack" "$tmp_path/$backtrack/$parent_cataloged_hash_pr/$parent_pathfragment_fn_pr"
+ parent_pathfragment_pr="$( safe_cat_backtrack "$parent_cataloged_hash_pr/$parent_pathfragment_fn_pr" )"
+ # Double slash to signify an archive (one of the slashes is already at the beginning of $parent_pathfragment_pr)
+ assembled_grandparent_pathfragment_pr="$grandparent_pathfragment_pr/$parent_pathfragment_pr"
+ assembled_grandparent_pathfragment_hash_pr="$( safe_sha256_sum_from_string "$assembled_grandparent_pathfragment_pr" )"
+ validate_path_tmp "$tmp_path/$backtrack" "$tmp_path/$backtrack/$grandparent_cataloged_hash_pr"
+ safe_mkdir_backtrack "$grandparent_cataloged_hash_pr"
+ validate_path_tmp "$tmp_path/$backtrack/$grandparent_cataloged_hash_pr" "$tmp_path/$backtrack/$grandparent_cataloged_hash_pr/$assembled_grandparent_pathfragment_hash_pr"
+ safe_echo_backtrack "$assembled_grandparent_pathfragment_pr" "$grandparent_cataloged_hash_pr/$assembled_grandparent_pathfragment_hash_pr"
+ done
+ done
+ done
+ validate_path_tmp "$tmp_path/$backtrack" "$tmp_path/$backtrack/$parent_cataloged_hash_pr"
+ safe_rm_rf_backtrack "$parent_cataloged_hash_pr"
+ done
+
+ relevant_ls_pr=( "$tmp_path/$backtrack"/!(0) )
+ num_relevant_ls_pr="${#relevant_ls_pr[@]}"
+
+ done
+
+ # Copy and rename the files into "report"
+ for detection_path_pr in "$tmp_path/$backtrack"/0/* ; do
+ detection_path_basename_pr="$( basename "$detection_path_pr" )"
+ report_filename_pr="vuln_log4j2_path_${detection_path_basename_pr:0:16}.txt"
+ validate_path_tmp "$tmp_path/$backtrack" "$detection_path_pr"
+ validate_path_tmp "$tmp_path/$backtrack" "$tmp_path/$backtrack/0/$detection_path_basename_pr"
+ detection_path_pathfragment_pr="$( safe_cat_backtrack "0/$detection_path_basename_pr" )"
+ validate_path_tmp "$tmp_path/$report" "$tmp_path/$report/$report_filename_pr"
+ safe_echo_report "${scan_path}${detection_path_pathfragment_pr}" "$report_filename_pr"
+ vulnerable="$(( vulnerable + 1 ))"
+ done
+
+ if (( vulnerable )); then
+ result=2
+ fi
+}
+
+
+if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
+ set_default_values
+ if [[ "$#" == "0" ]] ; then
+ # A sufficiently old Bash (such as in RHEL6) treats "$@" as an error if 'set -ue' and $#==0.
+ basic_args --help
+ else
+ basic_args "$@"
+ fi
+ basic_reqs "CVE-2021-44228"
+
+ # This variable is referenced indirectly, and this warning is marked to produce a false positive in that scenario.
+ # shellcheck disable=SC2034
+ running_kernel=$( uname -r )
+
+ prepare_directories
+
+ # Args of catalog_dir:
+ # 1 - dir to be cataloged
+ # 2 - path fragment from parent
+ # 3 - parent content hash
+ catalog_dir "$scan_path" "" "0"
+
+ while [[ "$num_before" != "$num_after" ]] ; do
+ num_before="$num_after"
+ unpack_cataloged_recatalog
+ catalog_files_for_counting_num=( "$tmp_path/$catalog"/* )
+ num_after=${#catalog_files_for_counting_num[@]}
+ done
+
+ produce_report
+
+ delete_directories
+
+ echo "Finished scanning of the specified directory"
+ echo "$scan_path"
+ echo
+
+ if (( vulnerable )); then
+ echo -e "${RED}The specified directory ${BOLD}contains vulnerable${RESET}${RED} log4j-core jar files.${RESET}"
+ echo "* $vulnerable files were identified."
+ echo "* Paths of the identified files can be found in .txt files in the directory"
+ echo " $tmp_path/$report"
+ echo "* To print all these paths, you can run the following command in the 'report' directory:"
+ echo " cat vuln_log4j2_path_*.txt"
+ echo "* The paths may show paths inside zip/jar archive files, signified by a double slash //."
+
+ else
+ echo -e "${GREEN}The specified directory ${BOLD}does not${RESET}${GREEN} contain vulnerable log4j-core jar files.${RESET}"
+ fi
+
+ echo
+ echo "Please note that vulnerability is determined based on the version only."
+ echo "This script doesn't detect any mitigations."
+ echo
+ echo -e "Follow $BULLETIN for advice."
+
+ print_debug
+
+ exit "$result"
+fi
diff --git a/CVE-2021-44228_log4j-core/approved_rm_blocks.txt b/CVE-2021-44228_log4j-core/approved_rm_blocks.txt
new file mode 100644
index 0000000..c547a65
--- /dev/null
+++ b/CVE-2021-44228_log4j-core/approved_rm_blocks.txt
@@ -0,0 +1,40 @@
+ for required_command in readlink file unzip stat sha256sum basename cat grep uname pwd /bin/rm ; do
+ if ! command -v "$required_command" &> /dev/null; then
+ echo "'$required_command' command is required, but not installed. Exiting."
+ if [[ "$required_command" == "unzip" ]] ; then
+--
+ if [[ -d "$tmp_path/$backtrack/$dir_to_delete" && ! -L "$tmp_path/$backtrack/$dir_to_delete" ]] ; then
+ if [[ "$dir_to_delete" != *..* && "$dir_to_delete" != */* ]] ; then
+ if [[ "$tmp_path/$backtrack/$dir_to_delete" == "$audit_tmp_path/$backtrack/$dir_to_delete" ]] ; then
+ ( cd -- "${audit_tmp_path:?}" && /bin/rm -rf --one-file-system -- "${backtrack:?}/${dir_to_delete:?}" ; )
+ fi
+ fi
+ fi
+--
+
+
+ if [[ "$tmp_path/$queue" == "$audit_tmp_path/$queue" ]] ; then
+ ( cd -- "${audit_tmp_path:?}" && /bin/rm -rf --one-file-system -- "${queue:?}" ; )
+ fi
+
+ if [[ "$tmp_path/$catalog" == "$audit_tmp_path/$catalog" ]] ; then
+ ( cd -- "${audit_tmp_path:?}" && /bin/rm -rf --one-file-system -- "${catalog:?}" ; )
+ fi
+
+ if [[ "$tmp_path/$decompressed" == "$audit_tmp_path/$decompressed" ]] ; then
+ ( cd -- "${audit_tmp_path:?}" && /bin/rm -rf --one-file-system -- "${decompressed:?}" ; )
+ fi
+
+ if [[ "$tmp_path/$parents" == "$audit_tmp_path/$parents" ]] ; then
+ ( cd -- "${audit_tmp_path:?}" && /bin/rm -rf --one-file-system -- "${parents:?}" ; )
+ fi
+
+ if [[ "$tmp_path/$backtrack" == "$audit_tmp_path/$backtrack" ]] ; then
+ ( cd -- "${audit_tmp_path:?}" && /bin/rm -rf --one-file-system -- "${backtrack:?}" ; )
+ fi
+
+ if [[ "$tmp_path/$detections" == "$audit_tmp_path/$detections" ]] ; then
+ ( cd -- "${audit_tmp_path:?}" && /bin/rm -rf --one-file-system -- "${detections:?}" ; )
+ fi
+
+
diff --git a/CVE-2021-44228_log4j-core/approved_rm_lines.txt b/CVE-2021-44228_log4j-core/approved_rm_lines.txt
new file mode 100644
index 0000000..a4fe454
--- /dev/null
+++ b/CVE-2021-44228_log4j-core/approved_rm_lines.txt
@@ -0,0 +1,8 @@
+for required_command in readlink file unzip stat sha256sum basename cat grep uname pwd /bin/rm ; do
+( cd -- "${audit_tmp_path:?}" && /bin/rm -rf --one-file-system -- "${backtrack:?}/${dir_to_delete:?}" ; )
+( cd -- "${audit_tmp_path:?}" && /bin/rm -rf --one-file-system -- "${queue:?}" ; )
+( cd -- "${audit_tmp_path:?}" && /bin/rm -rf --one-file-system -- "${catalog:?}" ; )
+( cd -- "${audit_tmp_path:?}" && /bin/rm -rf --one-file-system -- "${decompressed:?}" ; )
+( cd -- "${audit_tmp_path:?}" && /bin/rm -rf --one-file-system -- "${parents:?}" ; )
+( cd -- "${audit_tmp_path:?}" && /bin/rm -rf --one-file-system -- "${backtrack:?}" ; )
+( cd -- "${audit_tmp_path:?}" && /bin/rm -rf --one-file-system -- "${detections:?}" ; )
diff --git a/CVE-2021-44228_log4j-core/fake_jars.tar.gz b/CVE-2021-44228_log4j-core/fake_jars.tar.gz
new file mode 100644
index 0000000..1ed582f
Binary files /dev/null and b/CVE-2021-44228_log4j-core/fake_jars.tar.gz differ
diff --git a/CVE-2021-44228_log4j-core/fake_jars_delete.sh b/CVE-2021-44228_log4j-core/fake_jars_delete.sh
new file mode 100755
index 0000000..d0f861e
--- /dev/null
+++ b/CVE-2021-44228_log4j-core/fake_jars_delete.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+
+rm -rf fake_jars_vuln
+rm -rf fake_jars_nonvuln
+rm -rf fake_jar_test_battery_*
+rm -rf tmp-fake-log4j-core
diff --git a/CVE-2021-44228_log4j-core/fake_jars_generate.sh b/CVE-2021-44228_log4j-core/fake_jars_generate.sh
new file mode 100755
index 0000000..7b10cca
--- /dev/null
+++ b/CVE-2021-44228_log4j-core/fake_jars_generate.sh
@@ -0,0 +1,178 @@
+#!/bin/bash
+
+vuln_vers=(
+ '2.0-alpha1'
+ '2.0-alpha2'
+ '2.0-beta1'
+ '2.0-beta2'
+ '2.0-beta3'
+ '2.0-beta4'
+ '2.0-beta5'
+ '2.0-beta6'
+ '2.0-beta7'
+ '2.0-beta8'
+ '2.0-beta9'
+ '2.0-rc1'
+ '2.0-rc2'
+ '2.0'
+ '2.0.1'
+ '2.0.2'
+ '2.1'
+ '2.2'
+ '2.3'
+ '2.4'
+ '2.4.1'
+ '2.5'
+ '2.6'
+ '2.6.1'
+ '2.6.2'
+ '2.7'
+ '2.8'
+ '2.8.1'
+ '2.8.2'
+ '2.9.0'
+ '2.9.1'
+ '2.10.0'
+ '2.11.0'
+ '2.11.1'
+ '2.11.2'
+ '2.12.0'
+ '2.12.1'
+ '2.13.0'
+ '2.13.1'
+ '2.13.2'
+ '2.13.3'
+ '2.14.0'
+ '2.14.1'
+ '2.2.0.redhat-1'
+ '2.2.0.redhat-2'
+ '2.5.0.redhat-1'
+ '2.5.0.redhat-2'
+ '2.5.0.redhat-3'
+ '2.8.0.redhat-1'
+ '2.8.2.redhat-1'
+ '2.8.2.redhat-002'
+ '2.11.1.redhat-00001'
+ '2.11.2.redhat-00002'
+ '2.13.1.redhat-00001'
+ '2.13.2.redhat-00001'
+ '2.13.2.redhat-00002'
+ '2.13.3.redhat-00001'
+ '2.13.3.redhat-00002'
+ '2.13.3.redhat-00003'
+ '2.14.0.redhat-00002'
+ '2.14.0.redhat-00004'
+)
+
+non_vuln_vers=(
+ '1.2.3'
+ '2.12.2' # https://logging.apache.org/log4j/log4j-2.12.1/
+ '2.15.0'
+ '2.16.0'
+ '2.123.456'
+)
+
+POM_PATH="META-INF/maven/org.apache.logging.log4j/log4j-core/pom.xml"
+POM_DIR="META-INF/maven/org.apache.logging.log4j/log4j-core"
+
+rm -rf fake_jars_vuln
+rm -rf fake_jars_nonvuln
+
+mkdir -p fake_jars_vuln
+mkdir -p fake_jars_nonvuln
+
+for ver in "${vuln_vers[@]}" ; do
+ (
+ rm -rf tmp-fake-log4j-core
+ mkdir tmp-fake-log4j-core
+ cd tmp-fake-log4j-core || { echo "that's weird" ; exit 1 ; }
+ mkdir -p "$POM_DIR"
+ echo "
+ ...something something something something...
+ 4.0.0
+
+ org.apache.logging.log4j
+ log4j
+ $ver
+ ../
+
+ ...something something something something...
+ " > "$POM_PATH"
+ dd if=/dev/zero of=filler bs=1024 count=301
+ zip -0 -r ../fake_jars_vuln/log4j-core-"$ver".zip META-INF filler
+ cd ..
+ rm -rf tmp-fake-log4j-core
+ )
+done
+
+
+for ver in "${non_vuln_vers[@]}" ; do
+ (
+ rm -rf tmp-fake-log4j-core
+ mkdir tmp-fake-log4j-core
+ cd tmp-fake-log4j-core || { echo "that's weird" ; exit 1 ; }
+ mkdir -p "$POM_DIR"
+ echo "
+ ...something something something something...
+ 4.0.0
+
+ org.apache.logging.log4j
+ log4j
+ $ver
+ ../
+
+ ...something something something something...
+ " > "$POM_PATH"
+ dd if=/dev/zero of=filler bs=1024 count=301
+ zip -0 -r ../fake_jars_nonvuln/log4j-core-"$ver".zip META-INF filler
+ rm -rf tmp-fake-log4j-core
+ )
+done
+
+rm -rf fake_jar_test_battery_*
+
+# expected 61 detections
+mkdir -p fake_jar_test_battery_1
+cp -R fake_jars_vuln fake_jars_nonvuln fake_jar_test_battery_1/
+
+# expected 0 detections
+mkdir -p fake_jar_test_battery_2
+cp -R fake_jars_nonvuln fake_jar_test_battery_2/
+
+# expected 61 detections
+mkdir -p fake_jar_test_battery_3
+zip -0 -r fake_jar_test_battery_3/zip.jar fake_jar_test_battery_1 fake_jar_test_battery_2
+
+# expected 183 detections
+mkdir -p fake_jar_test_battery_4
+zip -0 -r fake_jar_test_battery_4/zip.zip fake_jar_test_battery_1 fake_jar_test_battery_2 fake_jar_test_battery_3
+cp -R fake_jars_vuln fake_jars_nonvuln fake_jar_test_battery_4/
+
+
+# expected 1 detection
+mkdir -p fake_jar_test_battery_smoke_1
+cp -R fake_jars_vuln/log4j-core-2.0.zip fake_jars_nonvuln/log4j-core-2.16.0.zip fake_jar_test_battery_smoke_1/
+
+# expected 0 detections
+mkdir -p fake_jar_test_battery_smoke_2
+cp -R fake_jars_nonvuln/log4j-core-2.16.0.zip fake_jar_test_battery_smoke_2/
+
+# expected 1 detection
+mkdir -p fake_jar_test_battery_smoke_3
+zip -0 -r fake_jar_test_battery_smoke_3/zip.jar fake_jar_test_battery_smoke_1 fake_jar_test_battery_smoke_2
+
+# expected 3 detections
+mkdir -p fake_jar_test_battery_smoke_4
+zip -0 -r fake_jar_test_battery_smoke_4/zip.zip fake_jar_test_battery_smoke_1 fake_jar_test_battery_smoke_2 fake_jar_test_battery_smoke_3
+cp -R fake_jars_vuln/log4j-core-2.0.zip fake_jars_nonvuln/log4j-core-2.16.0.zip fake_jar_test_battery_smoke_4/
+
+# expected 4 detections
+mkdir -p fake_jar_test_battery_smoke_5/f4
+mkdir -p fake_jar_test_battery_smoke_5/f3
+mkdir -p fake_jar_test_battery_smoke_5/f2
+mkdir -p fake_jar_test_battery_smoke_5/f1
+cp -R fake_jars_vuln/log4j-core-2.0.zip fake_jar_test_battery_smoke_5/f4/
+zip -0 -r fake_jar_test_battery_smoke_5/f3/zipf3.jar fake_jar_test_battery_smoke_5/f4
+zip -0 -r fake_jar_test_battery_smoke_5/f2/zipf2.zip fake_jar_test_battery_smoke_5/f3
+zip -0 -r fake_jar_test_battery_smoke_5/f1/zipf1.jar fake_jar_test_battery_smoke_5/f2
+
diff --git a/CVE-2021-44228_log4j-core/fake_jars_pack.sh b/CVE-2021-44228_log4j-core/fake_jars_pack.sh
new file mode 100644
index 0000000..c783511
--- /dev/null
+++ b/CVE-2021-44228_log4j-core/fake_jars_pack.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+rm -rf fake_jars.tar.gz
+tar -czf fake_jars.tar.gz fake_jars_vuln fake_jars_nonvuln fake_jar_test_battery_* tmp-fake-log4j-core
diff --git a/CVE-2021-44228_log4j-core/fake_jars_unpack.sh b/CVE-2021-44228_log4j-core/fake_jars_unpack.sh
new file mode 100644
index 0000000..58cc209
--- /dev/null
+++ b/CVE-2021-44228_log4j-core/fake_jars_unpack.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+
+rm -rf fake_jars_vuln
+rm -rf fake_jars_nonvuln
+rm -rf fake_jar_test_battery_*
+rm -rf tmp-fake-log4j-core
+tar -xf fake_jars.tar.gz
+
+
diff --git a/CVE-2021-44228_log4j-core/results_fake_jar_test_battery_1.sha b/CVE-2021-44228_log4j-core/results_fake_jar_test_battery_1.sha
new file mode 100644
index 0000000..e0ecd9f
--- /dev/null
+++ b/CVE-2021-44228_log4j-core/results_fake_jar_test_battery_1.sha
@@ -0,0 +1,61 @@
+e4010634e316a1554ea4ca3471f33aaf01941a3ba16639941ed5db0a2afa003e test_integration_tmp/report/vuln_log4j2_path_03d02af5ca3463db.txt
+9403b04d3c650cc74051d2b082a165bb812922de79f0e5c43aa432e2031e74a9 test_integration_tmp/report/vuln_log4j2_path_06052543def5c5e0.txt
+0f0c93a2f217fee14cab668771ad8f60c420d6e671b378aeb49f504b2413b4f3 test_integration_tmp/report/vuln_log4j2_path_0f6d03e02acbfd82.txt
+4ddfb93efcc1dc56ffde84503bf7d0f3d7fe12de869c519fedf0cf60d920bb99 test_integration_tmp/report/vuln_log4j2_path_15c75160235e9e75.txt
+013b2494a25c1ef1046774c600f0c782fed58173297512c2a3f537f89bdfd4fe test_integration_tmp/report/vuln_log4j2_path_1629699373150cc6.txt
+a3d6f9dc77219e1a170f0b4481ad67514234b0f0cc2ecc9a665d13de4020b92a test_integration_tmp/report/vuln_log4j2_path_1baf2940680d24f3.txt
+ca0bf3a6e11f8835b13c5a0eba9a5858867abc4d0d1da10e815fb31a70489253 test_integration_tmp/report/vuln_log4j2_path_1e96c1a3cf3f46a4.txt
+943401649027b07d96b7e2be614aad0af277e6fa906540263b4d5c0ab185264b test_integration_tmp/report/vuln_log4j2_path_218f52359b313788.txt
+050741e1bdf2f42c016bbebad96e5d6d915743e35060a729c3ea95db445fdfe4 test_integration_tmp/report/vuln_log4j2_path_2f56422fd3d8dce8.txt
+b19c32499e6dd4b4254280748075a7e946480fe86c14b1f1f09cf67ee3b5ef36 test_integration_tmp/report/vuln_log4j2_path_3173abb3d87e0143.txt
+cf74e2986dc6cbb1f57fbfe7fcbe20a895dd1dad9d5a9ec646735da7bb027359 test_integration_tmp/report/vuln_log4j2_path_31b18655c74fc76d.txt
+8a7ba7e5c04e041cde76931c6298b8011a73d5df5cb3f0a61adbef6664266803 test_integration_tmp/report/vuln_log4j2_path_36ae989cdac58048.txt
+e2fb9ecdc834759a42a4cf5f7c677ab372b610d738242fc263c43335fc3f2758 test_integration_tmp/report/vuln_log4j2_path_3730483e8ca86796.txt
+c13a7586a3a80b5a60914744107afafa7c0187239f058c6f246ec0f21f80cadd test_integration_tmp/report/vuln_log4j2_path_3b5a82c4a542e870.txt
+d90808fd8c1cbd79d2e9422bdab3df5df4b9850be5a9c8be9f9eb5115a1f0fa5 test_integration_tmp/report/vuln_log4j2_path_416cddc9d02c4f0e.txt
+c6d998e1aaa5ec923814085fe3a46ea548ba2f7bd46051c995aecd467612c551 test_integration_tmp/report/vuln_log4j2_path_4199fc439eaa2219.txt
+1d15903b18a5df938c0e51d4715cc36687a6418a360f0d81da192238d0156e15 test_integration_tmp/report/vuln_log4j2_path_497f584f64b76668.txt
+c0863e5c6fcb79d191afd305a43eda04bcf357740f09f2beaf23323c4e8fc37c test_integration_tmp/report/vuln_log4j2_path_4a38d79ab2774a73.txt
+fe85f4a57b0ca5d746b4054be52df007a13080ecf9026e8aa5d1f0071748f488 test_integration_tmp/report/vuln_log4j2_path_4f05e15b2ee3c8cc.txt
+21b3f3aec1ca5b35c5f8f536828d0e2bc6b9ae8dfb86a70adb98b765f2da2a3c test_integration_tmp/report/vuln_log4j2_path_50db5a23389dd871.txt
+103c5b40a4f20a7c179bedeae969850dbc1c0ae2b68013db9c50c07996173341 test_integration_tmp/report/vuln_log4j2_path_5b399762512f00f2.txt
+23e62a44e896895cdff2ab12e95295062602ed197e7f51bd4d7f89af4fe4bed2 test_integration_tmp/report/vuln_log4j2_path_5c51d74d9ce5b560.txt
+3ec577a72e23c9c71be655dcd22cc2d1ad8408d6b35eedff6619b776f90e2a03 test_integration_tmp/report/vuln_log4j2_path_5d37198fdeb5913b.txt
+b09df72eb582a77ad45b80b7753cc75df9bbf0aad7dc62f3b10ec57ec25bddb1 test_integration_tmp/report/vuln_log4j2_path_6518f3b41fe30d03.txt
+9d5d71a72fe7edde2e04c04c76d3b952820c0dc8e4358fd2eb1698efa44e2bbc test_integration_tmp/report/vuln_log4j2_path_67358eb916ba4c7c.txt
+86fbfa5ac7f8ecf1bc6f1141895971dcb57e729753cadb922f98d1adb2750e7c test_integration_tmp/report/vuln_log4j2_path_72a499598d17f518.txt
+8e81b90a214cc1d051fa0e95f4dccc94a7f7743689dda27c882cf8efac7b5033 test_integration_tmp/report/vuln_log4j2_path_72b5f9768db0cbde.txt
+f07dea7b2793c631ea1d49d542023215f3fe61dee6531e12a5f8dc77de0a3e62 test_integration_tmp/report/vuln_log4j2_path_762b9b0702762234.txt
+a13ee0e7eb116b2de7d294b5b7776faea5e8fc5cbab6218f68fc2cf5924e5f21 test_integration_tmp/report/vuln_log4j2_path_78d1468f497b477b.txt
+2469dbb61172dff21e38e7667db91eb7e889556bcad2d269a58edd5bf20c43a4 test_integration_tmp/report/vuln_log4j2_path_7932639ab36530f6.txt
+63ff8db556e583f7dbf62a13474f4cf15c0aa5079065f7e60edbd2e3a9cb06a8 test_integration_tmp/report/vuln_log4j2_path_7b63d09989c0f0b8.txt
+1cc3720afc11e72e22519ccea2822c69cb5b2b33ffe350d093569a2615bc7e73 test_integration_tmp/report/vuln_log4j2_path_7f651fe744e64b71.txt
+b196c56db4bdc9110b3fbb2514d9e06f6e72dc0380a61d619748bb6e35f73cdd test_integration_tmp/report/vuln_log4j2_path_80f06ae3b14925ab.txt
+f91280ed3887d49348ecb64d36fbafec41851b387121722a9a43b63737ce029d test_integration_tmp/report/vuln_log4j2_path_83b0e061a7ccc02c.txt
+61bc6b39577f2ff8c6e59e484c80a4b29dc94a142d0cb690706df49e71f05d22 test_integration_tmp/report/vuln_log4j2_path_86d8ff4d2b52ff8e.txt
+1522eb9df0aa86c4bf244dec8975cb37b01ac3a7495dfb5ada02d789568a16a5 test_integration_tmp/report/vuln_log4j2_path_86dca1be59d79980.txt
+4715f0755ae040b615b58e25d969b0c3d29faa5e5e7af457dbec10eea79142af test_integration_tmp/report/vuln_log4j2_path_87e9a37f23339f66.txt
+6dee1bcf301a790cc3245304aa6d0df389a0f61f1776417f929c9856f61c04f6 test_integration_tmp/report/vuln_log4j2_path_8a34f1c004b491db.txt
+bc63c42b8ae7e2e4fdfa6b0191728b28a77ac180e097cdf3cc14e8744859bc94 test_integration_tmp/report/vuln_log4j2_path_8ec4166d6abc0fbe.txt
+ceef4101403805f155b627467083573ca080a9145563592e1f665d3dae039ea7 test_integration_tmp/report/vuln_log4j2_path_9a0000fdb130634f.txt
+d701e0e16a5cd5f2b8270567a0d7c94016994097bb1d12885ba6c2d7e0e3631c test_integration_tmp/report/vuln_log4j2_path_9a83ecac5ade892f.txt
+fcbb4fc625ae04a24d93e1e809feefabfced0576c25a2458b3f54743c2babfa6 test_integration_tmp/report/vuln_log4j2_path_9edd0055a00fe1b1.txt
+e1b74687ec15ac57b779598bd5fd876c9450b489f79dd2553a7834d6d98abfca test_integration_tmp/report/vuln_log4j2_path_9f47287993299f57.txt
+4174d1c68155dbb5e2675d7b0591efd2513e8fde5de895dc6c5b2013d1bf12e2 test_integration_tmp/report/vuln_log4j2_path_a25acb22b5eb60a8.txt
+5bf063964693efac0437f9cedca912ac2dbb64bbc269622fedc090edb6f4c8d4 test_integration_tmp/report/vuln_log4j2_path_b1694fb370a46f39.txt
+37ebf033f6805dec60b6a41de32b0735f259a7e52aec3e82d83adbd6cfd6fa29 test_integration_tmp/report/vuln_log4j2_path_b41ee82fac4095e9.txt
+59e5665b2b8bfd3db22f05b35e88a2f8caded663aff940c62f08eaddb7a32743 test_integration_tmp/report/vuln_log4j2_path_be4b249b79da102b.txt
+34f0495126d3ce1887f15795f3c462fbb0652ca4e06ddaea55d44ea05890ae11 test_integration_tmp/report/vuln_log4j2_path_c6f627890822e4be.txt
+0921c2ef2cacdb2e6e476ed62609edfeb12188e67f23ef7618e4ed5c80fc8deb test_integration_tmp/report/vuln_log4j2_path_cba05cf9d483daa3.txt
+9c9329780bcdf1c088208ee951a189ff09b2e9d335717cdf52edc4f4e76be7c0 test_integration_tmp/report/vuln_log4j2_path_cbbcb336f66fff4a.txt
+005ff6a90db6f489af523e38a26fe928a9825f992fd57f8982880a9b5ea9b315 test_integration_tmp/report/vuln_log4j2_path_d4d3ce0b5c3edbce.txt
+47f57b0af319043b39cc100c18dce5317acaaea3ecca58622c3044961d022872 test_integration_tmp/report/vuln_log4j2_path_d8dcb3917a45f774.txt
+a53481f6b182845834f341e87ec02ed41ebc62a6005d34d4b3e5176d28dfaa51 test_integration_tmp/report/vuln_log4j2_path_e16cb82391de2363.txt
+ae5c0fb63341e826a86b0a3d455b413287d702220271bf9f2752ccf2d30bb233 test_integration_tmp/report/vuln_log4j2_path_e7363321894a469d.txt
+c1f16ea0f351b0069b1b7c7357ba91190f7506108b2e122ceeaf86bf5c72396b test_integration_tmp/report/vuln_log4j2_path_f022e40757fba59f.txt
+c6238349c66b73e3b7ba179eecd06e280b4b82adb5eb1eed531cac58f314649f test_integration_tmp/report/vuln_log4j2_path_f0eca2fa460e05bb.txt
+fad3b053df631eab30157c54a6c5ed29dcc5d6552954b9b14fb0c206bc6c0eaa test_integration_tmp/report/vuln_log4j2_path_f4ea9cd194b9db27.txt
+038772db0bebf4adc4f68f4466e21903866413bdc80e39e8668951e2dbe070ff test_integration_tmp/report/vuln_log4j2_path_f67de04669e623a8.txt
+621183b989dc50f087f55253737c9849fa7b284c23c915fded7da9ea93fe6997 test_integration_tmp/report/vuln_log4j2_path_f8fcbf11cd975697.txt
+609d69db3d3cc91dd9f3a9740aff53f33a0d4a87f37ea1d6d61b614077681d93 test_integration_tmp/report/vuln_log4j2_path_fa1b2818366b66f3.txt
+9b8315b37c2b6b2a6834a745602cec9fea9a82329a09d2cf5cdf8048499af1aa test_integration_tmp/report/vuln_log4j2_path_fca1f67c85ea077d.txt
diff --git a/CVE-2021-44228_log4j-core/results_fake_jar_test_battery_3.sha b/CVE-2021-44228_log4j-core/results_fake_jar_test_battery_3.sha
new file mode 100644
index 0000000..4035172
--- /dev/null
+++ b/CVE-2021-44228_log4j-core/results_fake_jar_test_battery_3.sha
@@ -0,0 +1,61 @@
+cb76d749d08c4c3594ef818e0005d35b1c1a74af138d75ffb00172dd42fc2a00 test_integration_tmp/report/vuln_log4j2_path_078b31befe799158.txt
+ff8f5aaae4660295d2a7d73b99644848ef968602001de3a759dc47749057f3de test_integration_tmp/report/vuln_log4j2_path_0bfd3cb06c9930a3.txt
+e47c9a0e662bea753c7e5284695850466362eda860b46e9c0f56147dbf4f0349 test_integration_tmp/report/vuln_log4j2_path_175f6432902cf96f.txt
+f5fefbd22de3d1e230aafe6afed5a6c5165015423cd2765693cf13f5dcb07bb6 test_integration_tmp/report/vuln_log4j2_path_1925007801fb47b2.txt
+d4458af049bbf10a627b996cecb06c53a7ad34d8e168c2acc4190290441eb417 test_integration_tmp/report/vuln_log4j2_path_19c42c1d8bccd2ce.txt
+06fdbbd65c22983136de877002ea3ee05bb52f1a641d70f2d178c24e3acc3679 test_integration_tmp/report/vuln_log4j2_path_2029753b76a9c2e2.txt
+b3037aee6fbb2f0a1450625253dd4cb4abf6291ae908929171f597518b43675f test_integration_tmp/report/vuln_log4j2_path_20ca3b4103fe1bb2.txt
+4022f1859968e51f5fb6c46a3c36f68fad028912b3f8bdff0d67f69220544d54 test_integration_tmp/report/vuln_log4j2_path_226c471fcf952936.txt
+b267751202c4179f0c36a6e5641e013a275fb4fcea90f385fc51d4dedc773bcb test_integration_tmp/report/vuln_log4j2_path_23c780cc04e29385.txt
+169d988d87cd374426284054b29c36413480bda882818f004d0eba824732affe test_integration_tmp/report/vuln_log4j2_path_28550436ad91336a.txt
+678fba0079d746d268038018092430c3f8b622d857ababe523d4720add84ce18 test_integration_tmp/report/vuln_log4j2_path_2b57a153bdf97ff5.txt
+a0471112f8713c706962c035ab7e7bf50a5985533f4d3eb468413f5e11c9bf1f test_integration_tmp/report/vuln_log4j2_path_3135ddcaa893463f.txt
+fe055266876efbd7cb15765c93453b0c0b358d7cd88a2f528d83b1cfce3ceb5a test_integration_tmp/report/vuln_log4j2_path_36f001fbe019caa5.txt
+9b1d8a89c5a9ca220afdc1f02eb440e326fef64e5125ebecf9d8a3368b79f99f test_integration_tmp/report/vuln_log4j2_path_3c3479b13a3b2e0b.txt
+57149a614b33006e9dc24e79e85367196ad64a098f308aa47c3b1af6d37bd5bf test_integration_tmp/report/vuln_log4j2_path_3ccf8005a10e59cf.txt
+1f81879d1a32f75d6a7e294a238e591e997795dd00291f484ec1919070c14906 test_integration_tmp/report/vuln_log4j2_path_4cf1bf8744cc7a82.txt
+1e053b083c5e01bc9aa0d48f21fbbbd734cfb9c03023c5f40152be2fa4c7e9f8 test_integration_tmp/report/vuln_log4j2_path_4de28a2b7bafa38a.txt
+d05417a98f80fa3979c712d414db612e4f9c1b54305a5e036787ecea16fc8686 test_integration_tmp/report/vuln_log4j2_path_530e78f387897ff8.txt
+da2be58813497282121eae84079ae16fd0fc1c29554035175f05035b821be1fb test_integration_tmp/report/vuln_log4j2_path_59f7ce02963f0333.txt
+c221b1f74ddde3ebd32ed9e9a5e4ab2a8752aa44e70088abdc9ee6c994e8560d test_integration_tmp/report/vuln_log4j2_path_6469e4d6571aa2d6.txt
+eeb9bd3672a1cd9475b3261c41ec65e930905f07f29a6fa2b71da9f6e54a27cd test_integration_tmp/report/vuln_log4j2_path_65bc4f30424bd050.txt
+c98b4e3edb015b92369873bcbe75b1f3e385394fa4e56fcd6fe1c1144c6899ea test_integration_tmp/report/vuln_log4j2_path_66ec4d9da47a5f03.txt
+e2177348187064e6435e1506bb2a2b46ae85c2c04d6f61808e854013b6d62709 test_integration_tmp/report/vuln_log4j2_path_699c53bc61415907.txt
+669896288845c7a6b8ad759e3f7b56a49744e688beeacf618c4487ae1bb283a7 test_integration_tmp/report/vuln_log4j2_path_6e40ff3990aee8d1.txt
+fc941f17df8cbe0fae17805df3ca3384c43262a8d55c96f02abdeae7ec3e3f2f test_integration_tmp/report/vuln_log4j2_path_74e5b220aca350ca.txt
+0e584d029a79eacdddb0ad38017451d3b845c08ad6680714da3d0b8bb69e1548 test_integration_tmp/report/vuln_log4j2_path_7538665f9cca952b.txt
+204fc7ad806905574941bdc411ce5c9518d4cce49b63bcef3437e5975acc27e0 test_integration_tmp/report/vuln_log4j2_path_763b32acea5e7c84.txt
+dd516bff7b157b17ea02e73a4e84fd17025eac276e66539a390ff276aac6de0d test_integration_tmp/report/vuln_log4j2_path_797a5eb9bb6aeb4a.txt
+25053c177529818a39226ea67ad628de9cd3180ea560fb45e01e662b5a7d8d68 test_integration_tmp/report/vuln_log4j2_path_7fa374a2857f8ddb.txt
+1e16e879e4ca55870ce9bbc93fae69e89c11f2f2d9d982ddb0624f63767fb9d4 test_integration_tmp/report/vuln_log4j2_path_7fdae5cbcc3aa103.txt
+9ce7c32c87dd849db4cf4d3db4997a4cd8f67685afc5215f474a53c2b789c5fe test_integration_tmp/report/vuln_log4j2_path_8129a3709aa28f75.txt
+df4bc96adee95edd8bf0d1c725826a147a81f408d9f3f2a936ed245af71df8b9 test_integration_tmp/report/vuln_log4j2_path_8637a020ee3b4d42.txt
+200d8659072aea3f752f562f5e0b80c29d27bad191eae9f1aeed9d3cbd0705f7 test_integration_tmp/report/vuln_log4j2_path_86abf5253c0c8b9c.txt
+7395aae1e5662891e8827f4f069f687a62cc525514779ecbc4825ebb994e7a6f test_integration_tmp/report/vuln_log4j2_path_91e586378bad80bf.txt
+ced5275366c456a3f219e64434540d8140acfc736894b322493b77201ef16a10 test_integration_tmp/report/vuln_log4j2_path_99455f2669c78eaa.txt
+090f71e909a2a4381714843186a82f06280b81fbe473b8d1fa1659e68962b7d7 test_integration_tmp/report/vuln_log4j2_path_9ab5abfd9e3dc7da.txt
+62f617b44ac9ce74d428905bd12e7b175907b1e3bf648b146bd8c3a0a5006013 test_integration_tmp/report/vuln_log4j2_path_a6a31abf99f90c54.txt
+922887a189f1edcd998e9685fb7da2a5d0226ff3da549925207e23d67407e70d test_integration_tmp/report/vuln_log4j2_path_a9ab18e2ee726112.txt
+aeeb22c77d04f38b495f4b953729af5148d91af76364197085c6fb69cb8fec55 test_integration_tmp/report/vuln_log4j2_path_af43831ace3bc957.txt
+dbbac97101d0075a1d9e658052108227160112c112c0cce9458d7f13546e4381 test_integration_tmp/report/vuln_log4j2_path_b872b8e3ccc4883b.txt
+542331c7bd4d7c59dbe76fb65ead3ae6fc76a4ec59efbc9965a5c32635cff2ec test_integration_tmp/report/vuln_log4j2_path_b8bffec1525be5c9.txt
+1c84c8da67bd46d1b3bc48355a0e761d6a7ed777ba03e332ddf0bb7ec495e9e7 test_integration_tmp/report/vuln_log4j2_path_bc791e4f2da41d7a.txt
+b427f38257eca07eb48e622a05bc3c1bc1397c9f6ff43c4b30002e9932064d5f test_integration_tmp/report/vuln_log4j2_path_c85c4bfbdc028e1d.txt
+3bd1c5a90a79bfa6a9b6906b5458b97a3e78345cdbf6a616f1f398d06bad201c test_integration_tmp/report/vuln_log4j2_path_c8bd536fe6bbb4e8.txt
+d8669f5b3de894de2204b9e789e24e0ad353ed08a83c350fb000222d0bb23c94 test_integration_tmp/report/vuln_log4j2_path_d6d58352fbce9699.txt
+7b6ef455115553e0871e5d0c86cdf9b7a63a53623a3009c299241d96a0fedb6b test_integration_tmp/report/vuln_log4j2_path_da63b7757a1d67e3.txt
+b9614dcaaae4449d28159754ad706704c146ef4dd01fda9232df19f3e7c67e0c test_integration_tmp/report/vuln_log4j2_path_dc89e9f0776b21a9.txt
+afcf6233b9c4958d5f2756b4c27e3c3714a54fa9dbc0ec53431b84d8305d191a test_integration_tmp/report/vuln_log4j2_path_e19a8cd1ed011d95.txt
+bc06699f7cbe8dbe0237618898f4501bd04337143cc810e8608c542f79698d90 test_integration_tmp/report/vuln_log4j2_path_e41c49e970f5b193.txt
+ac93fe7de2cfceb94ccae21089b8bdf1cf8b08cb697660b71570abf4f689f2f1 test_integration_tmp/report/vuln_log4j2_path_e5c519b2ffa01d2a.txt
+ea4e726090fe3e8d360d2e198f9053fa26099ef6d3749d03a0089ea6b7268457 test_integration_tmp/report/vuln_log4j2_path_e66dc6ea655f2990.txt
+49dfbfb44e77e20e5152b9aa414ffb2cfb9293571f7690511480272d4a2f0676 test_integration_tmp/report/vuln_log4j2_path_eaa2f21c55ee3626.txt
+fe67e0eafcb81df6edda8d3c05662fc3398b7fe3203a8b5dd5bee10343b669e5 test_integration_tmp/report/vuln_log4j2_path_ecfa3c1d191121da.txt
+1d061d9f72f45513d8d3a2072b768770a2cb6e67d55bd15beecaca9baf5b5bb5 test_integration_tmp/report/vuln_log4j2_path_f05e25ccda4824fa.txt
+9cfe76edc94bf516ac0394bea7d6bfc560c7d986cc6850ed01857c749c3ff8d3 test_integration_tmp/report/vuln_log4j2_path_f1a175ff192a3c14.txt
+824879b65f19a9be0f86c384f11710148696f4846571b6ac2df3695d7408b0a2 test_integration_tmp/report/vuln_log4j2_path_f1b4d00c89ad358a.txt
+685c15c88c0fcebca333d98773f55b06bb1ff27a0f2fb1db94eea30cc15f4c24 test_integration_tmp/report/vuln_log4j2_path_f290633c3577001b.txt
+ae0d48fccf98a661cc027cae85dd9dae2e348f2f8bf1e469e920cc7fbeaa2521 test_integration_tmp/report/vuln_log4j2_path_f4153c2f8616b47e.txt
+b12e5ed2551e8ddaafb0828ab8e5a9576ae5896631ebd0775c197accf9ee832a test_integration_tmp/report/vuln_log4j2_path_f4613d6cafca1172.txt
+6e607ee2c294bedf95502d3746c1cb9555172eb8d72cc009fcd490a256f8bcd6 test_integration_tmp/report/vuln_log4j2_path_f62e7a687bb0b967.txt
+42c1342bbe9def56392738a1adb01c0f9c25e1344b2bfdc347cbaa1e3a086e91 test_integration_tmp/report/vuln_log4j2_path_f9658cbfc394a47e.txt
diff --git a/CVE-2021-44228_log4j-core/results_fake_jar_test_battery_4.sha b/CVE-2021-44228_log4j-core/results_fake_jar_test_battery_4.sha
new file mode 100644
index 0000000..7caaee0
--- /dev/null
+++ b/CVE-2021-44228_log4j-core/results_fake_jar_test_battery_4.sha
@@ -0,0 +1,183 @@
+5e0bd7f83ecd7c0161ff38c6a2c109db7ae369d53455aadc860fbd2ae3360803 test_integration_tmp/report/vuln_log4j2_path_02224a78efeb81ba.txt
+d337014bd09b7efa3f1c2320f1b00ac13a55a315953ef4eb8ea063ac85314c87 test_integration_tmp/report/vuln_log4j2_path_03d02af5ca3463db.txt
+258f9e68366f2a9f1243573cfcb411701ff1475b51bb02db3454517e8f5da034 test_integration_tmp/report/vuln_log4j2_path_04a4698450becdd4.txt
+ab4fcb99d49dcdb44eec3c0c97379dafc6714d8bb7d3b01a5858645874653566 test_integration_tmp/report/vuln_log4j2_path_06052543def5c5e0.txt
+972e9927903117910872fd7639ea4a99f5c5cb5b5cdd0c129639204c4043d64e test_integration_tmp/report/vuln_log4j2_path_0ca0b63c8a8a16d1.txt
+8f972ace1217ee3ce68db6dd1b0f411a21f796a37e11bff34a496d0996ebe103 test_integration_tmp/report/vuln_log4j2_path_0dd60a54e18cbc0c.txt
+2879b6ebe2996b6ef686c1c60f6f13c06506a91d76b1b27a77302071c0ab0513 test_integration_tmp/report/vuln_log4j2_path_0deda5331167837e.txt
+289eed02ee4659158f1fa7a5774f36366106e30bc93c7403666be5238a93a0cc test_integration_tmp/report/vuln_log4j2_path_0f6d03e02acbfd82.txt
+a3fa2b91167eadb3096601256c2bc1ce39c6ba4471b4c9a2e833c77f8a2ccea3 test_integration_tmp/report/vuln_log4j2_path_1236dd854b033015.txt
+ff62a20bdc3011d8469d871293030201d86712f1c1d73a8224a0bb37f132f516 test_integration_tmp/report/vuln_log4j2_path_15c75160235e9e75.txt
+b5baef6e4f571c418e5cc28007d8e37768e865dc5c356377d5e089d31e14560c test_integration_tmp/report/vuln_log4j2_path_1629699373150cc6.txt
+0d2daf47b833cbb1c4e4728e7f7f1ea3b639d1a304d0aea9409d7034f3467135 test_integration_tmp/report/vuln_log4j2_path_17d80943e9cc0b04.txt
+424cc012845bb93fa5b979c4e3d42ceddeb98aa0f19e5b345620d2069bc9fc3e test_integration_tmp/report/vuln_log4j2_path_1804194e86a1ae43.txt
+cdd2f5243a70a8299624f906a22d0c18146df0e283c4fff9181dd29bd6941c68 test_integration_tmp/report/vuln_log4j2_path_18866c329f9c63d2.txt
+a1d184fa0d3cf2e791149f0cf8a9ff5fde23161ef584b8318edc12718d2ec565 test_integration_tmp/report/vuln_log4j2_path_1a22d1bf2598b6fe.txt
+d7813ae599b4115eeeba4c79b87cede416c0bbcefb51f9fff6fb91f9cabc73ff test_integration_tmp/report/vuln_log4j2_path_1a49a5414c60948a.txt
+39fce40976b2beb0405022200e8f19ed9544ac34de8aff8e7a4ac4c61e64571f test_integration_tmp/report/vuln_log4j2_path_1b28b799e5b26ce1.txt
+85b0e40c7a894dd356ad1a349bfb961aed171fa49305566a4faceb834ba01eb7 test_integration_tmp/report/vuln_log4j2_path_1baf2940680d24f3.txt
+f6598aea04328b12c27c077dac99467424faa0c6f0eef7686bb5da69b785dfab test_integration_tmp/report/vuln_log4j2_path_1d51e08e8d973c40.txt
+c437b1b7e29ab507b22dd7c31c1c993644f546da0c4fa23091c656c56162aa6c test_integration_tmp/report/vuln_log4j2_path_1df499e1c63870b9.txt
+51c2c0167798462ca5b78cac3fb505ac153bd308581e5c7f9498dfcfc1b70c6c test_integration_tmp/report/vuln_log4j2_path_1e96c1a3cf3f46a4.txt
+7549fce93eee75babc1c7fb3f7c47a37ae9bbcd9d8f098d7b72219e07dcd7bbc test_integration_tmp/report/vuln_log4j2_path_1f84f22abab3a72c.txt
+bc3b9b1dba16f8bbda63c7eff3d2286c77997f410d82902b9f3e811d03177809 test_integration_tmp/report/vuln_log4j2_path_20512208b37f960b.txt
+83f906780af12b57b752b9f364fa69d2bd7f98b96dd08efeab2c2c0ccbf40dd1 test_integration_tmp/report/vuln_log4j2_path_20d5dfacfadba614.txt
+1ee2fb47e5baa1651ff503ff29f38bdab67a18b5b3ebdeac96295d8b102967ba test_integration_tmp/report/vuln_log4j2_path_218f52359b313788.txt
+a0ca2e43cf1d5cba5386e1fcd8bfd48b2784108e5bbd6e984b542ee7ec07c13b test_integration_tmp/report/vuln_log4j2_path_2441b0c65aee481c.txt
+870587e3c63dfaebdc4c782bc003a3dceae8959198259079552b09b3a65c0e4d test_integration_tmp/report/vuln_log4j2_path_25239825d507da69.txt
+69c8ca1bbe2da56e650a4e02a17ca2f1316766b50cf4db82d839759862dd03d4 test_integration_tmp/report/vuln_log4j2_path_2b9ab8ef78158784.txt
+7bb8627e46885e62453bea354e65f1c4fff528d9ae470f95fabfe069f6731f7f test_integration_tmp/report/vuln_log4j2_path_2f53c69f9940fb15.txt
+9072d71c84b7666d9d0977b1911bd029c65a209bb75affd299dbf8d620362707 test_integration_tmp/report/vuln_log4j2_path_2f56422fd3d8dce8.txt
+de8d3bfad49f01852941edb1a24b30d401c4f28a32ef0939890f27fbc27f3e72 test_integration_tmp/report/vuln_log4j2_path_30043dea0f3fd604.txt
+bdfaeca30427e652a3ccebba6ab638ef05e2aca3ca3fd647baacd36fb9506fda test_integration_tmp/report/vuln_log4j2_path_315a07a538d79165.txt
+036a0e03215e5edc139d75d09af3f0365265ce15a5ee66b8625d7760f61f2eb3 test_integration_tmp/report/vuln_log4j2_path_3173abb3d87e0143.txt
+212ba79cf5833d590b57d1467cbe0bf2ebfbb6828f869e27c999190f2d8ea784 test_integration_tmp/report/vuln_log4j2_path_31b18655c74fc76d.txt
+9a907c393106186f1e4561e60b88549a1d3042cc1a15e779696b00c08dce9f05 test_integration_tmp/report/vuln_log4j2_path_337e6b4b658500c8.txt
+8d331e9dae4dc66b19f6a9e7c46cc0f97463bc583a4caa7810c096e55f0a2b98 test_integration_tmp/report/vuln_log4j2_path_339972242baaa04f.txt
+2fdf5535c37cb331a95ca08cbb5a8ff32e1a6d2659b2ccb75cd9ae803438faef test_integration_tmp/report/vuln_log4j2_path_3412875fc43c6cea.txt
+c86c04413cda59fe76ee531ff26916a473562d4b8aaa38bdfac00fbe5ddc06ce test_integration_tmp/report/vuln_log4j2_path_36ae989cdac58048.txt
+8b1c80636bb0f2096d07a7359ed33844b836267004e0b9b04c5f6521563fa077 test_integration_tmp/report/vuln_log4j2_path_36f6c080c8bd2b2b.txt
+f5aed0b91c0f1dd2fbc393e77ca0e307d1feacfc95ffa1759453f40b104d3e59 test_integration_tmp/report/vuln_log4j2_path_3730483e8ca86796.txt
+fff0cd504e9bf41ae842c36be81d38cd2d175c23adba7abdf3d20eaa5c3c09de test_integration_tmp/report/vuln_log4j2_path_3825e4f345852d57.txt
+05c63c7184eda9ba7aa42e1be5b76276cc672a5c9829f37b3f6aaea520a6408b test_integration_tmp/report/vuln_log4j2_path_3a99edbc1cc7e4c5.txt
+28f3f7e1e1a84a42d786be6c382450b9bf36e9c189053004a4af92fc0e8d9043 test_integration_tmp/report/vuln_log4j2_path_3b5a82c4a542e870.txt
+4c7df138e4f868deedc15888a9197caf7210bc21e56a5efbe7ab9087669cebfd test_integration_tmp/report/vuln_log4j2_path_3bedaf8d7b20fe62.txt
+e9e51d99fbc8162b245a93c70e1372042b8e78d711f91a7104c4effdfddd5067 test_integration_tmp/report/vuln_log4j2_path_3c7e9b286d6d2aee.txt
+b73b03127eb059117c3659ee50f19c05c41c15a881123bffa56743708f8b7811 test_integration_tmp/report/vuln_log4j2_path_3e11c9a1fe1a98cc.txt
+9e4abd5c7865d835441ae6a6b16e274852be9bf35049aa56ae3ee10c1cc91cc3 test_integration_tmp/report/vuln_log4j2_path_3fd488643cae2fe4.txt
+c6eb6881c3646e6c65f514384fdfe535f365c2fe061988ab4ea294c9656ea0c1 test_integration_tmp/report/vuln_log4j2_path_416cddc9d02c4f0e.txt
+3b851968c47062fa2d049bc3f5b7752ddf64cc1097f0986e234b2ad9c110207c test_integration_tmp/report/vuln_log4j2_path_4199fc439eaa2219.txt
+3472a6acccc4f4f8b4736aa6350233b628ee6e7e4e4f80cad8716e4e25c0cc10 test_integration_tmp/report/vuln_log4j2_path_42ff6344f29207e0.txt
+994b790a258d4080b6352c62b0e2e98ed10680036a592ab675b30f047908c112 test_integration_tmp/report/vuln_log4j2_path_43035a8e5bfcff7f.txt
+f2e3c70ecba5069d0c1071a40f2a23449555105d935531cc135f2c067d57ae66 test_integration_tmp/report/vuln_log4j2_path_43543852e88a8401.txt
+fa62f9bf009078fbcd20a6b618e8f6f928d22fd8a6532abb4244ebb921df1445 test_integration_tmp/report/vuln_log4j2_path_4568ea894ad3c4ce.txt
+c9018538ce085e9c22ae945529a67bd3eaf1ed71657ab66c96229b53b8288953 test_integration_tmp/report/vuln_log4j2_path_497f584f64b76668.txt
+24216ac6bd9f171abe977e6154bca5ecf9da52b39bd8ceb8916afa8d2eeaba91 test_integration_tmp/report/vuln_log4j2_path_49fa93e6c83e23ec.txt
+7a8d886e35f3f443d01ced563d5a119f8d5995dfe63b1535aefa714dbd2d92fc test_integration_tmp/report/vuln_log4j2_path_4a38d79ab2774a73.txt
+3ef92c1ded241f1422753ec4a77211365e5d33cc2d7e090fca3347ddbab8d6a8 test_integration_tmp/report/vuln_log4j2_path_4d2ea18c98642de5.txt
+5c186beb155bbcebea60751b5258b4901877ec1879fdc05ea5df1fe04a15ba73 test_integration_tmp/report/vuln_log4j2_path_4f05e15b2ee3c8cc.txt
+5705b064b7f96d72975b9d9eed9ff35d9714b61e918aec2460430031d2f10edc test_integration_tmp/report/vuln_log4j2_path_4f52c6a58f5bc533.txt
+6115038851bad9e5c661f3bdd68d58d3ebbb2ab615cb505e10bb75486ff0dc65 test_integration_tmp/report/vuln_log4j2_path_50293d973dc91221.txt
+d2b592e8f1e31462b5af98b8d6a4ff2319e553c0bc761888063be35a11afb1f1 test_integration_tmp/report/vuln_log4j2_path_50db5a23389dd871.txt
+60dc9f1ce0a144193ff39d4c13e5163ab3867363cc26c8d79a3435d7ba466912 test_integration_tmp/report/vuln_log4j2_path_53880da6a61cb0bb.txt
+9cb32baeed1a1d89402a616e22462b762b7159bc65c32da19b8a8be9123e79aa test_integration_tmp/report/vuln_log4j2_path_545b75c47893a9ad.txt
+deee3e1897abe295d6e0302ad340d4cad3957466f3002944cad45e0a2af0962b test_integration_tmp/report/vuln_log4j2_path_545deea45bdea2ab.txt
+ff2222f14c510fc2b001e562a883bd82e70130c1a7ec17a2fe641d51b2458f61 test_integration_tmp/report/vuln_log4j2_path_5b399762512f00f2.txt
+c3a670cfc0ae900d6b9d49c1c5993010d90893991363488307f01c213501a6da test_integration_tmp/report/vuln_log4j2_path_5c51d74d9ce5b560.txt
+10dd3b581b0b2c57973f17fcd8085df2935dde80df9483bde7f98036cadb0f28 test_integration_tmp/report/vuln_log4j2_path_5ce516ddbb769bdc.txt
+295fb942c6c24e7cdd71a1d85a25d1a9b55737d441342ac0e6834e277d5bf896 test_integration_tmp/report/vuln_log4j2_path_5cf966d53ec13d50.txt
+c06caebb7dfe71e0ac55d13c50b19153822bbfd8e2afc3fa53a638bfd03a449e test_integration_tmp/report/vuln_log4j2_path_5d37198fdeb5913b.txt
+dd75f0d6862f5358b13fd2acd851857867a99a0d0b3afdd643938449c7f842e6 test_integration_tmp/report/vuln_log4j2_path_6120b0a607515f47.txt
+45bebc7c3dad92c90edd9130d9df78736c116ccd23118a710d72b4d00c92401e test_integration_tmp/report/vuln_log4j2_path_6509a34550fb0556.txt
+e50707622922ec5f0d2e535e1de77243a13253b5a8530cc45d2cc4fa9b4d13d5 test_integration_tmp/report/vuln_log4j2_path_6518f3b41fe30d03.txt
+bc0605cd77fd2b7dce182804ab36a60e78d66801176b4b1284f414534cb13938 test_integration_tmp/report/vuln_log4j2_path_66f95869b074ba47.txt
+087539ccfabaa2bb14cbdd2aee2b88da3889c6dad189764f575284e887d6d056 test_integration_tmp/report/vuln_log4j2_path_67358eb916ba4c7c.txt
+41bcf77e67b788215d806c6f458e49f58ad1069d01e289f22b72a2a18d0d3d1e test_integration_tmp/report/vuln_log4j2_path_67ba8a9663789b10.txt
+a1281dcc2f043da670f6afbab451127dff757418bb6ee59e9bb55b1d51106ee5 test_integration_tmp/report/vuln_log4j2_path_6cc3b5435cf089e4.txt
+145802ffa0ec621443ab189711865c415a85fe91dfcaab04e3fe90248120eb20 test_integration_tmp/report/vuln_log4j2_path_6eb7831ddafa6b06.txt
+9ae08e9b959c0ad7243035ab444f6f9d04e0725a250d9dbd275c59a7625ce70f test_integration_tmp/report/vuln_log4j2_path_6ecc3cc65e4adb06.txt
+c65d1512915e1e522fb93cfa05ed887dd96f19d209d438de1f4b113adc08b6b9 test_integration_tmp/report/vuln_log4j2_path_6f31bef3034c24e2.txt
+0c23f3d62ac9e423e1beb4af9a8cd3f645cecdf5911b3d2a645dfefbc7ad775b test_integration_tmp/report/vuln_log4j2_path_714c5ee354e9523b.txt
+968d7f0b6801d3e018ae447cd31f4e138f64087df492655d21fac2d06674a785 test_integration_tmp/report/vuln_log4j2_path_71d6ad741c71e545.txt
+7de8273a738af4a0566f5c469cc09cb163a99fad0f84b3e58447b23abece4cf8 test_integration_tmp/report/vuln_log4j2_path_72a499598d17f518.txt
+b8b60f7266abd5f4018165c294524c0c853c0b54b9d41ce0d4d0aa2d05dd963d test_integration_tmp/report/vuln_log4j2_path_72b5f9768db0cbde.txt
+9d3d6f004c69f21f9e63020f9c5b74b7779de5d29881bd48932d922d22ff300f test_integration_tmp/report/vuln_log4j2_path_7346d19dae1efcc8.txt
+00579a810d9d90a5db0882ed42ed29f2d8cfce542f4fd65c154b03dbe4d2c666 test_integration_tmp/report/vuln_log4j2_path_736547c0fc4339dd.txt
+a93d006dfd581bfc77d2f11bdcf4d7f27e3c4bc48e3b98fbd340f515575c49d9 test_integration_tmp/report/vuln_log4j2_path_762b9b0702762234.txt
+b282420fa6e91b6a9d030ade5cbec7a637b63aa5b3a62f124c8d06c719b02bf3 test_integration_tmp/report/vuln_log4j2_path_78d1468f497b477b.txt
+55e708918d502130ba4d7e9521713b5c54c58e2b3901ab81d5f998c015008cdf test_integration_tmp/report/vuln_log4j2_path_7932639ab36530f6.txt
+fab8b1c6b57dd35616f9f423a4a18a0214e9c6800f3dbce3d52053d8f3491f93 test_integration_tmp/report/vuln_log4j2_path_7a6cd42bb3ac2d4f.txt
+43ad0e42d45a4e6a7813c280bf7227f50c76d8e05e1a318d53b63a9d14af8916 test_integration_tmp/report/vuln_log4j2_path_7ae6781f7231886f.txt
+9103cb4bc5a5ddca435e50423603a5058cd9f34bc1b6319621b9b1ac86a63583 test_integration_tmp/report/vuln_log4j2_path_7b63d09989c0f0b8.txt
+0e1f5875ce0b0e2dafe8f9a2c7a21fa41b8b8cb9ec80dc09fad6360502941280 test_integration_tmp/report/vuln_log4j2_path_7c5f633dd45555d5.txt
+b765b8d124671ac2ee6cbb8582eca6b0b9b7ed7090a931af7841249b275c871f test_integration_tmp/report/vuln_log4j2_path_7f651fe744e64b71.txt
+c504717a4d839aef9ac390c74f5a63bccafd61b16605cc72c86c9c402ff5d7c6 test_integration_tmp/report/vuln_log4j2_path_80f06ae3b14925ab.txt
+e004672f9e3b50ec8310482eb578f09861471aee0c1d9e4951c4f30cdbb4f3f3 test_integration_tmp/report/vuln_log4j2_path_82a80cf18dddafa2.txt
+e8a77f4aad6f43320396ca48e3a4fedd3f4372333650a1aec5c5ee3d34d1c9aa test_integration_tmp/report/vuln_log4j2_path_83b0e061a7ccc02c.txt
+10200ba2d9f676b74e76b205608ed9a5688bd83d94974441daebad4c780f5ce5 test_integration_tmp/report/vuln_log4j2_path_85bb13959a1480f8.txt
+0a06ae94fd6344e0a209c30440e995f8bdaea040f9f58f195b41e67ce73c38d6 test_integration_tmp/report/vuln_log4j2_path_860859dd9a89fd09.txt
+c69c52af5602862b84f2dafb69d806d49ad6352b7d700fdb7bcaae945a8cae88 test_integration_tmp/report/vuln_log4j2_path_866a2723524967c3.txt
+25bab6d1e67a7fc67055eec0b6603117e023c5cf0022934f4219c5c176c0a0c8 test_integration_tmp/report/vuln_log4j2_path_86d8ff4d2b52ff8e.txt
+3d19d7e1dbfe4e7bd60850c0c6efb19c3e0039c16b6c7cc6c01c078715f1a2a7 test_integration_tmp/report/vuln_log4j2_path_86dca1be59d79980.txt
+a6caba039badc245b1226b170f103b6a7b1c4f8c061d0abadf388571f521e534 test_integration_tmp/report/vuln_log4j2_path_87e9a37f23339f66.txt
+8a32d7caa54a70a700529727ffeca8a96aaf4965e155f548cc641be77cd4889d test_integration_tmp/report/vuln_log4j2_path_899dc671f8679beb.txt
+0f831f75067e40c323f103e677135fe97930810d664c38fefc142b895b21be1c test_integration_tmp/report/vuln_log4j2_path_8a34f1c004b491db.txt
+1b0949812619992b39510d4802abc996e1641229c048cff7637ea1b5aca7348b test_integration_tmp/report/vuln_log4j2_path_8ec4166d6abc0fbe.txt
+eaa2368fc856af375ea1099a0b25b308294d3ce35ad57ac75a5c42ec21f4814a test_integration_tmp/report/vuln_log4j2_path_8ef967e3b46f9113.txt
+448b3cb98aee402bf79afce9e8c73e32137cbe94f4af0e287e5d9ecde89710d6 test_integration_tmp/report/vuln_log4j2_path_938862c7c15b06eb.txt
+76680f1cda224914a1d3810e9caaadccdf89611128fc17028550eee9f27abbc0 test_integration_tmp/report/vuln_log4j2_path_946923090a497ce5.txt
+ac8195bc70092e71f06154918a575faf753956a2a8ef90ec42bdbfd28453ef39 test_integration_tmp/report/vuln_log4j2_path_948db28bdc1125e5.txt
+4ee2a576d569f32e78453d1f56627fce3889aee201fe36868d385680603de8a9 test_integration_tmp/report/vuln_log4j2_path_9a0000fdb130634f.txt
+a601c83e23c25cc8aefc996069518fd80cd301e054dc9c34164191fa82463016 test_integration_tmp/report/vuln_log4j2_path_9a4fb0be9222227b.txt
+21e434ed2ca852092c43da1d11ac6b016fd13559fabf51f61f34033b932b2a84 test_integration_tmp/report/vuln_log4j2_path_9a83ecac5ade892f.txt
+7113d9d52d956e0c188e1ff9f78c9f8a56a8a5186887aa07fd757ede624cfe25 test_integration_tmp/report/vuln_log4j2_path_9c2d3edd7632b5a9.txt
+c0d9c7ff47bbc53ec738880510af886bfdcc53067a422c2576620f656bd7584a test_integration_tmp/report/vuln_log4j2_path_9e155474857bdddb.txt
+13970cd87ee131793191e04218e98506e0734231fa3dce56be481cdd0a325fda test_integration_tmp/report/vuln_log4j2_path_9edd0055a00fe1b1.txt
+0929774e9f3934eb9f2989cdfb6bb2d9f501258ca9d9aaf88bbd14c6bc77be98 test_integration_tmp/report/vuln_log4j2_path_9f47287993299f57.txt
+70a692d2549b23bf9ec8ec245522dcf2977592215249887701b419498b09a85d test_integration_tmp/report/vuln_log4j2_path_a25a0f90651fe5bc.txt
+157188a754be1baf1ba930a629d3e8fbd65a9510929e0ecd749147ae1d7dcf0f test_integration_tmp/report/vuln_log4j2_path_a25acb22b5eb60a8.txt
+bd1229686376aa471366c19be247cdfb8804c53cf9e176397c20b0632c4d4e34 test_integration_tmp/report/vuln_log4j2_path_a32e23ad382abf04.txt
+4cff46e07b2ab4c03e8a28ced1a7d63ad027c6f6d79ba224834ff4709a47fd67 test_integration_tmp/report/vuln_log4j2_path_a380b2a628f1dda5.txt
+e69e97759e14df49f05c1bff2d100912af1afbf526365f562e2f13a913f84d9e test_integration_tmp/report/vuln_log4j2_path_a488ea471d57b03a.txt
+4afd42c26c156cd9457eed7abc0e04eae0ebb3f375db20bf2d037ddb8921e133 test_integration_tmp/report/vuln_log4j2_path_a4de21f1ba8d91c9.txt
+740e2f15b54e48cf8cfedbaa0b7d96c782713f0b70f3513b4d596c72b3b4380c test_integration_tmp/report/vuln_log4j2_path_a538bc2e8d26a36c.txt
+4ea001151ed801a48336692665f1c2e3626672057c74eeaf4ed3bf959f864f68 test_integration_tmp/report/vuln_log4j2_path_a74fd972f8e2b340.txt
+71643c499cec0782d972776d8adcd0759fcd7999769809da88f4122709be5833 test_integration_tmp/report/vuln_log4j2_path_a865a19275457f59.txt
+4343db3ca1bfde74bc641ff9ef345a67ce31bfa1a87d69c926d4c54163ab9877 test_integration_tmp/report/vuln_log4j2_path_aad83b1c7d458b94.txt
+80cb7c01ae2573f0425d9c174a25884f917ae2d811724ef04f74bf9b28233d81 test_integration_tmp/report/vuln_log4j2_path_ad396ce51b77cb57.txt
+c211d430cfbef0738b200fa6e6dead08f38f938d291f8516ca97a303a641bd4c test_integration_tmp/report/vuln_log4j2_path_ad53880741f1a8d1.txt
+d3632a04e15b6ab3637459dbf755fd171bb2e2a8a5cf86a35489e2cdf9efc3db test_integration_tmp/report/vuln_log4j2_path_b076f060e6983b80.txt
+d1790a0909fdd3eda1ae96c832b41373e44e84e1bac5175768a732d9fbae5bde test_integration_tmp/report/vuln_log4j2_path_b162e9d972ff44d1.txt
+2d60477d037dd094e32fcd74e84527931c2ae5555fa87e9985f5001dc3deda4f test_integration_tmp/report/vuln_log4j2_path_b1694fb370a46f39.txt
+cb2f9b775f0c31ec0cf643406910cc89a7f06f19c62485ac1f08f297db648d6f test_integration_tmp/report/vuln_log4j2_path_b296ed8c0cdf22e3.txt
+5036fad3881818e941b2f8c7f2af3bbf93735c8e94e8b3305915aea23d7259a0 test_integration_tmp/report/vuln_log4j2_path_b41ee82fac4095e9.txt
+0c3fb5a4c9b633b53176990c5eccc1ff459b3a724ccf3c12239ba0e8b20c2fb1 test_integration_tmp/report/vuln_log4j2_path_b66ab814952d2b67.txt
+0f2e17a9e173ef6d6f403cafd03892dfb7bd378645dc27db02aa793cf1fa3f4e test_integration_tmp/report/vuln_log4j2_path_b6852a06bd2dc755.txt
+bfef7fe770eebc923c492b09f64e9c2350fe6b1dca7d3e4e7890fb8ae428c7a1 test_integration_tmp/report/vuln_log4j2_path_b9ec0178f0f2a169.txt
+ae4f586f0e1467ee2d258c468b2f7ebebbd7f4cb8bd0a2ec853b06b0e222423f test_integration_tmp/report/vuln_log4j2_path_ba2206b8ab412441.txt
+cc8f313431e72182d15218655ea3fe831051a0710b0ac0ee89e2cba48a5060ff test_integration_tmp/report/vuln_log4j2_path_be4b249b79da102b.txt
+e4c9d0bfffcabb70c2650ef997f2c311392a6825d3d146c19122100230614b6d test_integration_tmp/report/vuln_log4j2_path_be8dfb405a6271c0.txt
+35e2cca96402f2ee92e02c49393e67864f29935b380d68bfcc80f062a8700363 test_integration_tmp/report/vuln_log4j2_path_c619efcad728785f.txt
+dff4cdcb37c2d651a93cf126005e3e93631c8bbc913eb7d49e7c558a05442c52 test_integration_tmp/report/vuln_log4j2_path_c6f627890822e4be.txt
+61d2b1899ee47fff77e0981543e11fac57e00b86c2bd8b4f8de71a441bca7c2a test_integration_tmp/report/vuln_log4j2_path_ca8611af231263cf.txt
+3392054548e15ab8a10ef89c4b3b3bc6ca0e5a946164ca99459dd6f0b136db34 test_integration_tmp/report/vuln_log4j2_path_cba05cf9d483daa3.txt
+3e9a749e54daab15e25128526bc3c675366208ba7a05ac8cbb374f456167c108 test_integration_tmp/report/vuln_log4j2_path_cbbcb336f66fff4a.txt
+21dbf9221384ae846fb3ddbb58159427fceed6311dba9e98e56d85f303f894d6 test_integration_tmp/report/vuln_log4j2_path_cd9f20fafc0643e7.txt
+f803dae1cafc16f680502474bc841aaeb733a5bc64538deaad65a5d8318efdb7 test_integration_tmp/report/vuln_log4j2_path_ce70900dfd0cec68.txt
+f4cdb75dddba187e09f6dbd72e96c6119a5be497a5c79d106081ba05ced0ee39 test_integration_tmp/report/vuln_log4j2_path_ce90ab6ccf4c6916.txt
+21d35bdd74a8e8fd512d83ef6e79ca9bfe1e656aaed8c424a9f8002eb54447e9 test_integration_tmp/report/vuln_log4j2_path_d0cb45884636a46b.txt
+50471b7038be8d5a26dc1a0233e4e1e6801f2e1be9d0a1e0d791dd0351203288 test_integration_tmp/report/vuln_log4j2_path_d12ef35f6aa6ee8d.txt
+9df3c6980ce7a770c9488bc91dd737fc1074830ce4cc23377b583884d336516e test_integration_tmp/report/vuln_log4j2_path_d2c0867c3a5b8e40.txt
+befa8225a7bacc191f1e3472ad2b79265536da5943438a58f6e2c0558645aac1 test_integration_tmp/report/vuln_log4j2_path_d4a094e6ecb486c4.txt
+0599002a3f79795fda3d823d0b0a88e5eef58ab7d28a2d310dda2f3de4b3d827 test_integration_tmp/report/vuln_log4j2_path_d4d3ce0b5c3edbce.txt
+7703fb149278e600edc498c26e2976fe7508cdd1cc60298a7b23b89363a8ea3e test_integration_tmp/report/vuln_log4j2_path_d7b067d8b211d636.txt
+31ab1f7804090eec0061d18099d8fcec28b0ff5e236212be79fc87b23b2823a0 test_integration_tmp/report/vuln_log4j2_path_d8dcb3917a45f774.txt
+dbb680726b9fa86ce00b451fecf83b2e81b7796e42314cbdab2b3fe8a65d3b82 test_integration_tmp/report/vuln_log4j2_path_da754f14b2e31b8e.txt
+96f074a0d9f231bcc61c923a7b9d27631cd736ed95eb8b0246858b83f906abed test_integration_tmp/report/vuln_log4j2_path_dc84d24dac5a5d0f.txt
+831d9f4397322b3f02fc301d5de224ff07d6a6fbc6abb46a9f13539cbfe147b6 test_integration_tmp/report/vuln_log4j2_path_dd23c4c229b20772.txt
+5b06f368f6a01fd690618e30e11e6959e12a9f443256326c68559532ca75620a test_integration_tmp/report/vuln_log4j2_path_de96302dc92685df.txt
+a32d05e7e057f685ea13686740853c17116756c07cbad715ebd8b06d4049809c test_integration_tmp/report/vuln_log4j2_path_e06d8a752c6fbc3d.txt
+ddc882d8d5e66f8e55b3b992b0abb7eca7064dc75cda440acfc35f57e973678e test_integration_tmp/report/vuln_log4j2_path_e16cb82391de2363.txt
+dfb94dbd703516a2b4b55fb5c71259bb0198c5d002ca4dc5bc8114fc4b84ef24 test_integration_tmp/report/vuln_log4j2_path_e2c1896dddbb8040.txt
+84b9c82ca8144fee426d07d953fbd067bae9699fa708a1b7c3f2599385d99ac8 test_integration_tmp/report/vuln_log4j2_path_e7363321894a469d.txt
+681b2556535ff9db103cadfef717d56a5120454ad170d4f6f2a8994c8e782a8e test_integration_tmp/report/vuln_log4j2_path_e95b5c5eb88a4812.txt
+b6e670764fcd7fb9cc9e68e7c78f147057e5b2e55902daee44a02f9e6b801db5 test_integration_tmp/report/vuln_log4j2_path_e9ba656439affe60.txt
+124f5364cbe644601d1a1e8375a5fe4d8a8098b10782ac3e343b32f368ce7abc test_integration_tmp/report/vuln_log4j2_path_ea003d18ee4b100d.txt
+d313e8a39e0cb01ca9c399e4dd51cea8a73bf61d617f206800787544bd54d22e test_integration_tmp/report/vuln_log4j2_path_ebf12df7ca8d0f12.txt
+793829ae9e8f3b02cc260b7edb1fd712b439c7440a273fe99991e0e2c606ade1 test_integration_tmp/report/vuln_log4j2_path_ee8d42a478ed7597.txt
+4a13fd8825ac3f31ad8fb4fd60d93712a70f851bf5dd6140e2153c2396a7f07d test_integration_tmp/report/vuln_log4j2_path_f022e40757fba59f.txt
+f2be4adff9904a1f5e0bf7a0c5aa4ca7e61844449955e31c4f9fd277faf14e8b test_integration_tmp/report/vuln_log4j2_path_f0eca2fa460e05bb.txt
+f4b2cf43c439cb3394c85acf5b5f5838f71a77560774e3290c4d3d0f4c3661d4 test_integration_tmp/report/vuln_log4j2_path_f177678adc002e10.txt
+aa946a43d66117309baf976088ca952e4ac1ebbef9b674e24b41e33c668cbe4c test_integration_tmp/report/vuln_log4j2_path_f2fdaf1b0986d4d9.txt
+232d9b77b278ca4352439bc15132e76b49d11fefd52dc92350822253222edc18 test_integration_tmp/report/vuln_log4j2_path_f4ea9cd194b9db27.txt
+93d7981bbdc50ee269108131f45a82e54616338e9bec1474ee5f1a0ee2cf4b1b test_integration_tmp/report/vuln_log4j2_path_f67de04669e623a8.txt
+c5d4fa2be305476f7c8bd9a1fd02d893e18a0a350a4e3226b75673269b6998b4 test_integration_tmp/report/vuln_log4j2_path_f693a814ea7fb33e.txt
+737b3a2077fd2cf269191323112ee7157710e482ae3f3a65b49d4d10ef25dd7f test_integration_tmp/report/vuln_log4j2_path_f7ded6a45c7b3bce.txt
+2bb8a54e0a126f5fb37687d1fd03cec4689b80d26e3c641ef5e502f3b8beb877 test_integration_tmp/report/vuln_log4j2_path_f8fcbf11cd975697.txt
+8276dbbc20541ead251ec361f97b42343027de28088318b6d8ed2fc31be7abe3 test_integration_tmp/report/vuln_log4j2_path_fa1b2818366b66f3.txt
+faed9dbbead3cb732d53bc6127ac6f684292005778f3c2e0b6c7133a4b507517 test_integration_tmp/report/vuln_log4j2_path_fb9091fc9a8eeecb.txt
+df369fc0f4f002bcdbaadf794c4f0cf4a5651caf5f5d4e18386ae4fef9596d15 test_integration_tmp/report/vuln_log4j2_path_fca1f67c85ea077d.txt
+dab348c5ab81cbaf76ed4429e0b801136d29f424fb2c461077f3337e7b436c60 test_integration_tmp/report/vuln_log4j2_path_fcf370fe158cf299.txt
+1b4adc45734ec6582a808779689cb39143dbcd6b41751255fafc064eb277137a test_integration_tmp/report/vuln_log4j2_path_fdfbd0d53db91bb3.txt
+108e9ecfe637967828ab357d7cafd2b6553ef784ca1769326aaf8729aa694886 test_integration_tmp/report/vuln_log4j2_path_fe3e65a5c04c2043.txt
+07822f26962c5afda65e66c076527bdcdafb15df78bba896a52f7b5b2f932884 test_integration_tmp/report/vuln_log4j2_path_ffe7f47bc3a2d6db.txt
diff --git a/CVE-2021-44228_log4j-core/results_fake_jar_test_battery_smoke_1.sha b/CVE-2021-44228_log4j-core/results_fake_jar_test_battery_smoke_1.sha
new file mode 100644
index 0000000..7a23f40
--- /dev/null
+++ b/CVE-2021-44228_log4j-core/results_fake_jar_test_battery_smoke_1.sha
@@ -0,0 +1 @@
+0b3a83f34f16b66ba5ff576c4055811204f2bf390fcf167132fad7c2b21329ff test_integration_tmp/report/vuln_log4j2_path_75f04e8a7f45fd56.txt
diff --git a/CVE-2021-44228_log4j-core/results_fake_jar_test_battery_smoke_3.sha b/CVE-2021-44228_log4j-core/results_fake_jar_test_battery_smoke_3.sha
new file mode 100644
index 0000000..969e876
--- /dev/null
+++ b/CVE-2021-44228_log4j-core/results_fake_jar_test_battery_smoke_3.sha
@@ -0,0 +1 @@
+5b1a4d4f7fe070def9efbb23d46bee520c3137bb070df0e33f1ea176a2291243 test_integration_tmp/report/vuln_log4j2_path_87429c51877b6257.txt
diff --git a/CVE-2021-44228_log4j-core/results_fake_jar_test_battery_smoke_4.sha b/CVE-2021-44228_log4j-core/results_fake_jar_test_battery_smoke_4.sha
new file mode 100644
index 0000000..049aa9d
--- /dev/null
+++ b/CVE-2021-44228_log4j-core/results_fake_jar_test_battery_smoke_4.sha
@@ -0,0 +1,3 @@
+cad059ef975494b7f6ea29adadd8581e9cd2dad37aeac24107e45d7d33ba2811 test_integration_tmp/report/vuln_log4j2_path_124b49541f9b3fe7.txt
+b0ffb53909805bf96c7661a065807bca0335f55ced65269391cf803f1ff1509d test_integration_tmp/report/vuln_log4j2_path_75f04e8a7f45fd56.txt
+b949956d97025a7055e59ce8b8382da00d28959e2b4fe2ef4b661edbea35a307 test_integration_tmp/report/vuln_log4j2_path_c91e90ba2e4a8c69.txt
diff --git a/CVE-2021-44228_log4j-core/results_fake_jar_test_battery_smoke_5.sha b/CVE-2021-44228_log4j-core/results_fake_jar_test_battery_smoke_5.sha
new file mode 100644
index 0000000..2ea8d31
--- /dev/null
+++ b/CVE-2021-44228_log4j-core/results_fake_jar_test_battery_smoke_5.sha
@@ -0,0 +1,4 @@
+f9fa556be6c4ee135cff000e9edc8376d6bec09a694f87ca713b2598b8054d62 test_integration_tmp/report/vuln_log4j2_path_6ae490fca20e40df.txt
+5b5aeb098f8eae782f05c02e8dd0c43840aee477cec25b1305290153e3486faa test_integration_tmp/report/vuln_log4j2_path_813c96c1559d181e.txt
+85fa4f7f1a4e591d059e558d6f6025beb08e3c01efae4243351641f83dcf52d7 test_integration_tmp/report/vuln_log4j2_path_9682866f06d88e59.txt
+d7b928b7769c86c2452a1708415f67027cf27bf1af9d54d14401992e2738be07 test_integration_tmp/report/vuln_log4j2_path_adea06a02694d6e0.txt
diff --git a/CVE-2021-44228_log4j-core/results_fake_jars_vuln.sha b/CVE-2021-44228_log4j-core/results_fake_jars_vuln.sha
new file mode 100644
index 0000000..5dc6a9e
--- /dev/null
+++ b/CVE-2021-44228_log4j-core/results_fake_jars_vuln.sha
@@ -0,0 +1,61 @@
+da256140287e98a8927984d101181b9a478338da773193b3953c439ef138151a test_integration_tmp/report/vuln_log4j2_path_09fd6faeb7c0741d.txt
+58e286c44cc74bfc796637584447934e1cdae18d82a008ca2b0a36e7988dc5f1 test_integration_tmp/report/vuln_log4j2_path_0b42f76865bb20b5.txt
+1b0737a8cbc2e51ff28b66915f946ac6faaf33843ddecabb0d9eccb52f81485b test_integration_tmp/report/vuln_log4j2_path_0b7a60470ac40155.txt
+325abe2b329d72fe7cfe36c0c79c4ec6806181b74ce20644944805563069377d test_integration_tmp/report/vuln_log4j2_path_1207b2c233dfd444.txt
+2d9e4bab5cb821417854433be3b77b069235051e66deb69f163259538c0124b8 test_integration_tmp/report/vuln_log4j2_path_15d1deb972a196b8.txt
+511b3f4c3e77220459ba91915835ac8c1ab71d1c7c0eabaa3e4e05c80f0f27ef test_integration_tmp/report/vuln_log4j2_path_15e2bd6adaf71e83.txt
+2e8195eebd40167b380fe8e5fcbc71f28c1d8022208b19489811f2b8f528436a test_integration_tmp/report/vuln_log4j2_path_205f188038e91a7e.txt
+46aa57a00ea02ac1a83535aa26eefaedbdcd81bc1e5fa2a455f351f8397f14ce test_integration_tmp/report/vuln_log4j2_path_23a931883633bb18.txt
+c63a4a1864d62e670f5e92551552f8db3ccc549cf32305edc8985ce9677803d7 test_integration_tmp/report/vuln_log4j2_path_25eca9e05e664fcd.txt
+51479eedfeb89ed4ef31816b55d4234e6ef79b01e78c002dc670fb652a3d6990 test_integration_tmp/report/vuln_log4j2_path_2f615c5b5cad372e.txt
+3ccd7755c608afa7d047107494e8643ab9f8ae9350f51c016540e4df7f12cc94 test_integration_tmp/report/vuln_log4j2_path_30f032f1645bb8b3.txt
+a3c942926522ddf18c11a1e3accf78d16d22bbe0319ac61e67ca4aaaa5a726a4 test_integration_tmp/report/vuln_log4j2_path_39013d146b5115a4.txt
+d965859fd2483cfa531394d5a1ad5912e424f18aa10c6506108fc78871268043 test_integration_tmp/report/vuln_log4j2_path_3a9eff456f5d120f.txt
+60317bffbd55f0bda6edb07bc04481188362c1bde3506991983228164cd07a4b test_integration_tmp/report/vuln_log4j2_path_45ab91fc386729b0.txt
+4707e5af15889b35e68fca6b41adaf91d6d0afdbf2370cfa18cfd4ecbd35ebdb test_integration_tmp/report/vuln_log4j2_path_4bc216bc37e9970d.txt
+0e72a4fad83a42f52bd7ca2645a70407afd2c89994c5e34a5aec68f3bfa40898 test_integration_tmp/report/vuln_log4j2_path_5e153b7de9e9a1b3.txt
+b71eb1e86a1668bae4ae82789b226c7780ea2dbad0b4a29603ca692e1482479b test_integration_tmp/report/vuln_log4j2_path_610e36537200dc10.txt
+a98317615e641fed5158efba815eae150c70b43bbff4a28a3dc3934d9df4e098 test_integration_tmp/report/vuln_log4j2_path_620746f26924b937.txt
+5f11e0715014f06d679c2cd2c96c627d1c3b5902ecee7e73593d723206d1f591 test_integration_tmp/report/vuln_log4j2_path_63a13cb9f31b09c0.txt
+970a0860459727674a09d02a6bbc93b44a7766ace8b39acae68d49ad58580177 test_integration_tmp/report/vuln_log4j2_path_6a4f04e4dbdc625b.txt
+600bda8c0391942a81c5c84c747adce300667eedf55d991ebe6377740abbf313 test_integration_tmp/report/vuln_log4j2_path_71b4010d4b14b865.txt
+5dee486bb1d58663025fd87338be4f6a8f1707196c8e010f5e4820aa6b1e4a46 test_integration_tmp/report/vuln_log4j2_path_73e6144a32f6a8d7.txt
+1a3e927347a0103f7c0db8b11d4ff3fe87e22a235366177d90af970a912c19db test_integration_tmp/report/vuln_log4j2_path_75f04e8a7f45fd56.txt
+fe116740fc9c6c8c8300a1b50003c543572ac7ac6400c7bc58dd263dde1c5a96 test_integration_tmp/report/vuln_log4j2_path_77f10f87c95a2260.txt
+d5b0827f2d49417d9841427784b0c6696a33bb84e964d7d7fc4d4f692fc81a28 test_integration_tmp/report/vuln_log4j2_path_804ec50463638863.txt
+fabc88940889500ff9913c4b36647d5b53c8e04fb3e11a56408e094e4601bed4 test_integration_tmp/report/vuln_log4j2_path_81ac1319d82122e6.txt
+d257de23c610ab978e19c001b29d45b1a6570b3d06be234d7468bc59ca87c0a5 test_integration_tmp/report/vuln_log4j2_path_8425a776b98e6157.txt
+bcd5aba5ca1afae6a2b0c992879ec73c920897ef9b031bc79a322540244880ce test_integration_tmp/report/vuln_log4j2_path_85130bcc7ffd5dd0.txt
+5836caf711422de4bdc7ed70f327b213ebaa1e64ab5cf3690c6aea31a4353e0c test_integration_tmp/report/vuln_log4j2_path_862db021053d59bf.txt
+fb3cd902fb81e6176cc227f6faa4eb35cf7ad6b3098cd051c83ff9b131ae70cb test_integration_tmp/report/vuln_log4j2_path_88bf7e563b920a08.txt
+7a0a0d73efe588a3f72129f06acb2bab3816e56f9d99a8a09762e665279af00d test_integration_tmp/report/vuln_log4j2_path_89cef381bdbd3535.txt
+c8a85646e926040eba4a7b809963b0aeac3f0cb60e4c300a0cd5627f1fe321b1 test_integration_tmp/report/vuln_log4j2_path_9021348842156aeb.txt
+dc12b5337f2c0fbe4a713984f8faf3eac8408e7bdcab397e04f280103ad4b049 test_integration_tmp/report/vuln_log4j2_path_98b7de550bd8c62f.txt
+f929ee1f0bc50ddd4732c8ff657b93f26550a350f26eea64de2852dca3e84f72 test_integration_tmp/report/vuln_log4j2_path_9bc00e7506a468e3.txt
+008e842f0524e9fd927951464ebe6834e27b6f28fa78b145df9958610c8b650e test_integration_tmp/report/vuln_log4j2_path_9d2bfbf5208adea3.txt
+c869c87b49d84c94ebbfcad3b01eb576b7d8d5f8b57a539b9fcfec2b42530f78 test_integration_tmp/report/vuln_log4j2_path_9de238923fafbeb4.txt
+cc208d1d2729f706a65c48654f86fdfddeb9eaf1cb44fa036a5a631b068ac2dd test_integration_tmp/report/vuln_log4j2_path_a0a6642fc05f0f39.txt
+1c181faf800aeef3edf79861f6b812daf245f36bd05302d48dca6640f2117033 test_integration_tmp/report/vuln_log4j2_path_a1ba7fbd1a917457.txt
+e7323763767ae0e1c07f7c089d652f550c991c1270060a49ca479f02eead144b test_integration_tmp/report/vuln_log4j2_path_a570eece577e02ba.txt
+05f7c195d7f55391c461d1a99b94b33a505131e47ad90127657ec5f63dd65e5a test_integration_tmp/report/vuln_log4j2_path_a5715cbd36156a15.txt
+5d8447d07908ac8844844cd518eea7a268f4fa17976852905e387cbb72117e9f test_integration_tmp/report/vuln_log4j2_path_a9cc80eebb3a7c42.txt
+e54b4aaee93462776c8821ba7f3396ed39068ed4e2e7c0d7da0671fe88eac2e9 test_integration_tmp/report/vuln_log4j2_path_ad736f8f4b44b0e2.txt
+58c0ecf77012578f1b472f643715dad592e84c1a63c7aa294981024a9be3ec6d test_integration_tmp/report/vuln_log4j2_path_b8ac4e934e0e3f86.txt
+f0eeb2319dc00221f35dff38325ae22a98a328fbc58417883b7c1c0c86d1c013 test_integration_tmp/report/vuln_log4j2_path_bfef383edea0974f.txt
+c1076bf9201c971fdd64dcf51d2db58ec3dd53e15971dbbc0ff5ef8e05976afc test_integration_tmp/report/vuln_log4j2_path_d2fba0c6a7f46e45.txt
+bdea668ac23d455d67124c5db5681b7e33ffbc6dde32d7928e7c4cb85ecd341f test_integration_tmp/report/vuln_log4j2_path_d998dd4816b5eb85.txt
+617d01718ddbb0ccddabfe210bb4c34da98e0c0e2f65f7313e381b738f20a644 test_integration_tmp/report/vuln_log4j2_path_da3d47772bd8b054.txt
+8e73ebae5a50a3bf9872f37d8d56d5c0ba5d305d307e49a371e3b5de8c460c06 test_integration_tmp/report/vuln_log4j2_path_de0fce47038e3286.txt
+4e447581e76e5227e452396b3d4a3b352fcef6bb4a972337d5500f8587a4bc73 test_integration_tmp/report/vuln_log4j2_path_de247d3f64d8ba12.txt
+03bb6cd4928edb29f1063ab3cc844a408ccaa3b93dedd259dde954c5a1ec4652 test_integration_tmp/report/vuln_log4j2_path_df92125222727f1a.txt
+541a6f853a8e0a8b57be3b0d1198c436930f1f97ee55ff61e3966f705d66f3b1 test_integration_tmp/report/vuln_log4j2_path_e4514427026f2994.txt
+8565f4e2ea21d4d0324b058d2623462f28db045ee6a6f8614e728318b1fde0d8 test_integration_tmp/report/vuln_log4j2_path_e60e2520959fade5.txt
+2824a1805131d3da0664a34166277be2bbd4f480436651785a76130992fa41a4 test_integration_tmp/report/vuln_log4j2_path_e8fde7776c69f777.txt
+a6f2f9847b5bce161210704f5cb639034459e60675fbacb65fca340ba1d29ba5 test_integration_tmp/report/vuln_log4j2_path_ea6b216aa315a0fc.txt
+e92125e900705e9725d4d02473bb611e464dbedde7830722a512640824d51992 test_integration_tmp/report/vuln_log4j2_path_ebdbab2292f7c75a.txt
+cea32d983ec7edab2405354e5212bd102f25678197bfb151f6452d6f9d09d94e test_integration_tmp/report/vuln_log4j2_path_f068965fd049621e.txt
+c9208401bf03daf6018faa03732bd5b0adc8db0d44130ded44e022f832ef72d3 test_integration_tmp/report/vuln_log4j2_path_f2126abf131915aa.txt
+49e1fc1452a9f7680e488f727544fa8c8f06b0c97a2faf2b1c5da03850316193 test_integration_tmp/report/vuln_log4j2_path_f3f114d339e3ba8e.txt
+6f4a9cfce1fd1ab36c02c3789dc4b73923967a1db969927a24a1dccbf41eb4c4 test_integration_tmp/report/vuln_log4j2_path_f415805406861764.txt
+bb68a19bf9519c0a46713802aca4b2b9e9e5356d31da4315462d0afcd5f5e8c3 test_integration_tmp/report/vuln_log4j2_path_fa4f058b8d036660.txt
+ffd9e4af0a4a78d72245907d273e55f4713a832baab9895304255fc354ea9e85 test_integration_tmp/report/vuln_log4j2_path_facbb1e416153e3c.txt
diff --git a/CVE-2021-44228_log4j-core/test_harness b/CVE-2021-44228_log4j-core/test_harness
new file mode 100644
index 0000000..bc839b9
--- /dev/null
+++ b/CVE-2021-44228_log4j-core/test_harness
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+. CVE-2021-44228.sh
+
+# https://github.com/sstephenson/bats/issues/171
+# https://github.com/sstephenson/bats/issues/88
+set +ue
+
+export CANONPWD="$( readlink -f "$PWD" )"
diff --git a/CVE-2021-44228_log4j-core/tests_basic_args.bats b/CVE-2021-44228_log4j-core/tests_basic_args.bats
new file mode 100755
index 0000000..74dee2c
--- /dev/null
+++ b/CVE-2021-44228_log4j-core/tests_basic_args.bats
@@ -0,0 +1,82 @@
+#!/usr/bin/env bats
+
+. test_harness
+
+
+@test "basic_args -- Help #1" {
+ run basic_args -h
+ [[ "$output" == *"Usage"* ]]
+ (( status == 1 ))
+}
+
+
+@test "basic_args -- Help #2" {
+ run basic_args
+ [[ "$output" == *"Usage"* ]]
+ (( status == 1 ))
+}
+
+
+@test "basic_args -- Debug #1" {
+ basic_args -d --scan "$CANONPWD" --tmp "$CANONPWD"
+ (( $? == 0 ))
+ (( debug ))
+ [[ "$RED" == "\033[1;31m" ]]
+ [[ "$GREEN" == "\033[1;32m" ]]
+ [[ "$BOLD" == "\033[1m" ]]
+ [[ "$RESET" == "\033[0m" ]]
+}
+
+
+@test "basic_args -- Debug #2" {
+ basic_args --debug --scan "$CANONPWD" --tmp "$CANONPWD"
+ (( $? == 0 ))
+ (( debug ))
+ [[ "$RED" == "\033[1;31m" ]]
+ [[ "$GREEN" == "\033[1;32m" ]]
+ [[ "$BOLD" == "\033[1m" ]]
+ [[ "$RESET" == "\033[0m" ]]
+}
+
+
+@test "basic_args -- No colors #1" {
+ basic_args -n --scan "$CANONPWD" --tmp "$CANONPWD"
+ (( $? == 0 ))
+ (( ! debug ))
+ [[ ! "$RED" ]]
+ [[ ! "$GREEN" ]]
+ [[ ! "$BOLD" ]]
+ [[ ! "$RESET" ]]
+}
+
+
+@test "basic_args -- No colors #2" {
+ basic_args --no-colors --scan "$CANONPWD" --tmp "$CANONPWD"
+ (( $? == 0 ))
+ (( ! debug ))
+ [[ ! "$RED" ]]
+ [[ ! "$GREEN" ]]
+ [[ ! "$BOLD" ]]
+ [[ ! "$RESET" ]]
+}
+
+
+@test "basic_args -- Regular" {
+ basic_args --scan "$CANONPWD" --tmp "$CANONPWD"
+ (( $? == 0 ))
+ (( ! debug ))
+ [[ "$RED" == "\033[1;31m" ]]
+ [[ "$GREEN" == "\033[1;32m" ]]
+ [[ "$BOLD" == "\033[1m" ]]
+ [[ "$RESET" == "\033[0m" ]]
+}
+
+
+@test "basic_args -- nonexistent #1" {
+ run basic_args --scan NONEXISTENT --tmp NONEXISTENT
+ [[ "$output" == *"Usage"* ]]
+ [[ "$output" == *"SCANPATH doesn't exist or is not a directory."* ]]
+ (( status == 1 ))
+}
+
+
diff --git a/CVE-2021-44228_log4j-core/tests_basic_reqs.bats b/CVE-2021-44228_log4j-core/tests_basic_reqs.bats
new file mode 100755
index 0000000..e9b4378
--- /dev/null
+++ b/CVE-2021-44228_log4j-core/tests_basic_reqs.bats
@@ -0,0 +1,162 @@
+#!/usr/bin/env bats
+
+. test_harness
+
+
+@test "basic_reqs -- Disclaimer" {
+ # run basic_reqs TEST
+ #[[ "$output" == *"is primarily designed to detect CVE-2021-44228 on supported"* ]]
+ :
+}
+
+@test "basic_reqs -- no command available" {
+ command() {
+ return 1
+ }
+
+ set_default_values
+ run basic_reqs xyz
+ (( status == 1 ))
+ [[ "$output" == *"'readlink' command is required"* ]]
+}
+
+@test "basic_reqs -- file not available" {
+ command() {
+ if [[ "$2" == "file" ]] ; then
+ return 1
+ fi
+ return 0
+ }
+
+ set_default_values
+ run basic_reqs xyz
+ (( status == 1 ))
+ [[ "$output" == *"'file' command is required"* ]]
+}
+
+@test "basic_reqs -- unzip not available" {
+ command() {
+ if [[ "$2" == "unzip" ]] ; then
+ return 1
+ fi
+ return 0
+ }
+
+ set_default_values
+ run basic_reqs xyz
+ (( status == 1 ))
+ [[ "$output" == *"'unzip' command is required"* ]]
+ [[ "$output" == *"Please run 'yum install unzip' before running this script."* ]]
+}
+
+@test "basic_reqs -- stat not available" {
+ command() {
+ if [[ "$2" == "stat" ]] ; then
+ return 1
+ fi
+ return 0
+ }
+
+ set_default_values
+ run basic_reqs xyz
+ (( status == 1 ))
+ [[ "$output" == *"'stat' command is required"* ]]
+}
+
+@test "basic_reqs -- sha256sum not available" {
+ command() {
+ if [[ "$2" == "sha256sum" ]] ; then
+ return 1
+ fi
+ return 0
+ }
+
+ set_default_values
+ run basic_reqs xyz
+ (( status == 1 ))
+ [[ "$output" == *"'sha256sum' command is required"* ]]
+}
+
+@test "basic_reqs -- basename not available" {
+ command() {
+ if [[ "$2" == "basename" ]] ; then
+ return 1
+ fi
+ return 0
+ }
+
+ set_default_values
+ run basic_reqs xyz
+ (( status == 1 ))
+ [[ "$output" == *"'basename' command is required"* ]]
+}
+
+@test "basic_reqs -- cat not available" {
+ command() {
+ if [[ "$2" == "cat" ]] ; then
+ return 1
+ fi
+ return 0
+ }
+
+ set_default_values
+ run basic_reqs xyz
+ (( status == 1 ))
+ [[ "$output" == *"'cat' command is required"* ]]
+}
+
+@test "basic_reqs -- grep not available" {
+ command() {
+ if [[ "$2" == "grep" ]] ; then
+ return 1
+ fi
+ return 0
+ }
+
+ set_default_values
+ run basic_reqs xyz
+ (( status == 1 ))
+ [[ "$output" == *"'grep' command is required"* ]]
+}
+
+@test "basic_reqs -- uname not available" {
+ command() {
+ if [[ "$2" == "uname" ]] ; then
+ return 1
+ fi
+ return 0
+ }
+
+ set_default_values
+ run basic_reqs xyz
+ (( status == 1 ))
+ [[ "$output" == *"'uname' command is required"* ]]
+}
+
+@test "basic_reqs -- pwd not available" {
+ command() {
+ if [[ "$2" == "pwd" ]] ; then
+ return 1
+ fi
+ return 0
+ }
+
+ set_default_values
+ run basic_reqs xyz
+ (( status == 1 ))
+ [[ "$output" == *"'pwd' command is required"* ]]
+}
+
+@test "basic_reqs -- /bin/rm not available" {
+ command() {
+ if [[ "$2" == "/bin/rm" ]] ; then
+ return 1
+ fi
+ return 0
+ }
+
+ set_default_values
+ run basic_reqs xyz
+ (( status == 1 ))
+ [[ "$output" == *"'/bin/rm' command is required"* ]]
+}
diff --git a/CVE-2021-44228_log4j-core/tests_integration.bats b/CVE-2021-44228_log4j-core/tests_integration.bats
new file mode 100755
index 0000000..e4a4bd3
--- /dev/null
+++ b/CVE-2021-44228_log4j-core/tests_integration.bats
@@ -0,0 +1,388 @@
+#!/usr/bin/env bats
+
+export RHEL7="3.10.0-520.10.2.el7.x86_64"
+export FEDORA="4.9.14-200.fc25.x86_64"
+export SCRIPT_NAME=$( grep -E '^\. .*\.sh$' test_harness | sed -r 's/^\. (.*)$/\1/g' )
+
+setup_file() {
+ bash ./fake_jars_unpack.sh
+ uname() {
+ echo "$RHEL7"
+ }
+ export -f uname
+ export CANONPWD="$( readlink -f "$( pwd )" )"
+}
+
+teardown_file() {
+ bash ./fake_jars_delete.sh
+ :
+}
+
+
+@test "Integration -- TMPPATH inside SCANPATH" {
+ if ! command -v unzip &> /dev/null; then
+ return 0
+ # This testing environment can't run the script. Lacks unzip.
+ fi
+
+ rm -rf test_integration_tmp
+ mkdir -p test_integration_tmp/tmp
+ run ./"${SCRIPT_NAME}" -n --scan "$CANONPWD"/test_integration_tmp --tmp "$CANONPWD"/test_integration_tmp/tmp
+ (( status == 1 ))
+ [[ "$output" == *"TMPPATH must not be a subdirectory of SCANPATH. Exiting."* ]]
+ rm -rf test_integration_tmp
+}
+
+@test "Integration -- fake_jars_nonvuln" {
+ if ! command -v unzip &> /dev/null; then
+ return 0
+ # This testing environment can't run the script. Lacks unzip.
+ fi
+
+ rm -rf test_integration_tmp
+ mkdir -p test_integration_tmp
+ run ./"${SCRIPT_NAME}" -n --scan "$CANONPWD"/fake_jars_nonvuln --tmp "$CANONPWD"/test_integration_tmp
+ (( status == 0 ))
+ [[ "$output" == *"The specified directory does not contain vulnerable log4j-core jar files."* ]]
+ rm -rf test_integration_tmp
+}
+
+@test "Integration -- fake_jar_test_battery_smoke_1" {
+ if ! command -v unzip &> /dev/null; then
+ return 0
+ # This testing environment can't run the script. Lacks unzip.
+ fi
+
+ rm -rf test_integration_tmp
+ mkdir -p test_integration_tmp
+ run ./"${SCRIPT_NAME}" -n --scan "$CANONPWD"/fake_jar_test_battery_smoke_1 --tmp "$CANONPWD"/test_integration_tmp
+ (( status == 2 ))
+ [[ "$output" == *"The specified directory contains vulnerable log4j-core jar files."* ]]
+ [[ "$output" == *"* 1 files were identified."* ]]
+ ## sha256sum test_integration_tmp/report/vuln_log4j2_path_* > results_fake_jar_test_battery_smoke_1.sha
+ run sha256sum -c --quiet results_fake_jar_test_battery_smoke_1.sha
+ (( status == 0 ))
+ rm -rf test_integration_tmp
+}
+
+
+
+@test "Integration -- fake_jar_test_battery_smoke_2" {
+ if ! command -v unzip &> /dev/null; then
+ return 0
+ # This testing environment can't run the script. Lacks unzip.
+ fi
+
+ rm -rf test_integration_tmp
+ mkdir -p test_integration_tmp
+ run ./"${SCRIPT_NAME}" -n --scan "$CANONPWD"/fake_jar_test_battery_smoke_2 --tmp "$CANONPWD"/test_integration_tmp
+ (( status == 0 ))
+ [[ "$output" == *"The specified directory does not contain vulnerable log4j-core jar files."* ]]
+ rm -rf test_integration_tmp
+}
+
+
+
+@test "Integration -- fake_jar_test_battery_smoke_3" {
+ if ! command -v unzip &> /dev/null; then
+ return 0
+ # This testing environment can't run the script. Lacks unzip.
+ fi
+
+ rm -rf test_integration_tmp
+ mkdir -p test_integration_tmp
+ run ./"${SCRIPT_NAME}" -n --scan "$CANONPWD"/fake_jar_test_battery_smoke_3 --tmp "$CANONPWD"/test_integration_tmp
+ (( status == 2 ))
+ [[ "$output" == *"The specified directory contains vulnerable log4j-core jar files."* ]]
+ [[ "$output" == *"* 1 files were identified."* ]]
+ ## sha256sum test_integration_tmp/report/vuln_log4j2_path_* > results_fake_jar_test_battery_smoke_3.sha
+ run sha256sum -c --quiet results_fake_jar_test_battery_smoke_3.sha
+ (( status == 0 ))
+ rm -rf test_integration_tmp
+}
+
+
+@test "Integration -- fake_jar_test_battery_smoke_4" {
+ if ! command -v unzip &> /dev/null; then
+ return 0
+ # This testing environment can't run the script. Lacks unzip.
+ fi
+
+ rm -rf test_integration_tmp
+ mkdir -p test_integration_tmp
+ run ./"${SCRIPT_NAME}" -n --scan "$CANONPWD"/fake_jar_test_battery_smoke_4 --tmp "$CANONPWD"/test_integration_tmp
+ (( status == 2 ))
+ [[ "$output" == *"The specified directory contains vulnerable log4j-core jar files."* ]]
+ [[ "$output" == *"* 3 files were identified."* ]]
+ ## sha256sum test_integration_tmp/report/vuln_log4j2_path_* > results_fake_jar_test_battery_smoke_4.sha
+ run sha256sum -c --quiet results_fake_jar_test_battery_smoke_4.sha
+ (( status == 0 ))
+ rm -rf test_integration_tmp
+}
+
+
+@test "Integration -- fake_jar_test_battery_smoke_5" {
+ if ! command -v unzip &> /dev/null; then
+ return 0
+ # This testing environment can't run the script. Lacks unzip.
+ fi
+
+ rm -rf test_integration_tmp
+ mkdir -p test_integration_tmp
+ run ./"${SCRIPT_NAME}" -n --scan "$CANONPWD"/fake_jar_test_battery_smoke_5 --tmp "$CANONPWD"/test_integration_tmp
+ (( status == 2 ))
+ [[ "$output" == *"The specified directory contains vulnerable log4j-core jar files."* ]]
+ [[ "$output" == *"* 4 files were identified."* ]]
+ ## sha256sum test_integration_tmp/report/vuln_log4j2_path_* > results_fake_jar_test_battery_smoke_5.sha
+ run sha256sum -c --quiet results_fake_jar_test_battery_smoke_5.sha
+ (( status == 0 ))
+ rm -rf test_integration_tmp
+}
+
+
+@test "Integration -- fake_jars_vuln" {
+ if ! command -v unzip &> /dev/null; then
+ return 0
+ # This testing environment can't run the script. Lacks unzip.
+ fi
+
+ rm -rf test_integration_tmp
+ mkdir -p test_integration_tmp
+ run ./"${SCRIPT_NAME}" -n --scan "$CANONPWD"/fake_jars_vuln --tmp "$CANONPWD"/test_integration_tmp
+ (( status == 2 ))
+ [[ "$output" == *"The specified directory contains vulnerable log4j-core jar files."* ]]
+ ## sha256sum test_integration_tmp/report/vuln_log4j2_path_* > results_fake_jars_vuln.sha
+ run sha256sum -c --quiet results_fake_jars_vuln.sha
+ (( status == 0 ))
+ rm -rf test_integration_tmp
+}
+
+
+
+
+@test "Integration -- fake_jar_test_battery_1" {
+ if ! command -v unzip &> /dev/null; then
+ return 0
+ # This testing environment can't run the script. Lacks unzip.
+ fi
+
+ rm -rf test_integration_tmp
+ mkdir -p test_integration_tmp
+ run ./"${SCRIPT_NAME}" -n --scan "$CANONPWD"/fake_jar_test_battery_1 --tmp "$CANONPWD"/test_integration_tmp
+ (( status == 2 ))
+ [[ "$output" == *"The specified directory contains vulnerable log4j-core jar files."* ]]
+ [[ "$output" == *"* 61 files were identified."* ]]
+ ## sha256sum test_integration_tmp/report/vuln_log4j2_path_* > results_fake_jar_test_battery_1.sha
+ run sha256sum -c --quiet results_fake_jar_test_battery_1.sha
+ (( status == 0 ))
+ rm -rf test_integration_tmp
+}
+
+
+
+@test "Integration -- fake_jar_test_battery_2" {
+ if ! command -v unzip &> /dev/null; then
+ return 0
+ # This testing environment can't run the script. Lacks unzip.
+ fi
+
+ rm -rf test_integration_tmp
+ mkdir -p test_integration_tmp
+ run ./"${SCRIPT_NAME}" -n --scan "$CANONPWD"/fake_jar_test_battery_2 --tmp "$CANONPWD"/test_integration_tmp
+ (( status == 0 ))
+ [[ "$output" == *"The specified directory does not contain vulnerable log4j-core jar files."* ]]
+ rm -rf test_integration_tmp
+}
+
+
+
+@test "Integration -- fake_jar_test_battery_3" {
+ if ! command -v unzip &> /dev/null; then
+ return 0
+ # This testing environment can't run the script. Lacks unzip.
+ fi
+
+ rm -rf test_integration_tmp
+ mkdir -p test_integration_tmp
+ run ./"${SCRIPT_NAME}" -n --scan "$CANONPWD"/fake_jar_test_battery_3 --tmp "$CANONPWD"/test_integration_tmp
+ (( status == 2 ))
+ [[ "$output" == *"The specified directory contains vulnerable log4j-core jar files."* ]]
+ [[ "$output" == *"* 61 files were identified."* ]]
+ ## sha256sum test_integration_tmp/report/vuln_log4j2_path_* > results_fake_jar_test_battery_3.sha
+ run sha256sum -c --quiet results_fake_jar_test_battery_3.sha
+ (( status == 0 ))
+ rm -rf test_integration_tmp
+}
+
+
+@test "Integration -- fake_jar_test_battery_4" {
+ if ! command -v unzip &> /dev/null; then
+ return 0
+ # This testing environment can't run the script. Lacks unzip.
+ fi
+
+ rm -rf test_integration_tmp
+ mkdir -p test_integration_tmp
+ run ./"${SCRIPT_NAME}" -n --scan "$CANONPWD"/fake_jar_test_battery_4 --tmp "$CANONPWD"/test_integration_tmp
+ (( status == 2 ))
+ [[ "$output" == *"The specified directory contains vulnerable log4j-core jar files."* ]]
+ [[ "$output" == *"* 183 files were identified."* ]]
+ ## sha256sum test_integration_tmp/report/vuln_log4j2_path_* > results_fake_jar_test_battery_4.sha
+ run sha256sum -c --quiet results_fake_jar_test_battery_4.sha
+ (( status == 0 ))
+ rm -rf test_integration_tmp
+}
+
+
+@test "Integration -- symlinks 1" {
+ # For CI envs that don't have it.
+ unzip() {
+ return 0
+ }
+ export -f unzip
+
+ rm -rf test_integration_tmp
+ rm -f symlinked_source
+
+ mkdir -p test_integration_tmp
+
+ # sanity check
+ command -v readlink
+
+ # work around variable exported in setup_file being unset in some bats versions
+ echo "CANONPWD is $CANONPWD"
+ export CANONPWD="$( readlink -f "$( pwd )" )"
+ echo "CANONPWD is $CANONPWD"
+
+ ln -s "$CANONPWD"/fake_jar_test_battery_smoke_4 symlinked_source
+
+ echo "symlinked_source resolves to $( readlink -f symlinked_source )"
+ echo "running script like this: ${SCRIPT_NAME} -n --scan $CANONPWD/symlinked_source --tmp $CANONPWD/test_integration_tmp"
+
+ run ./"${SCRIPT_NAME}" -n --scan "$CANONPWD"/symlinked_source --tmp "$CANONPWD"/test_integration_tmp
+ echo "xxxxxxxxxx OUTPUT xxxxxxxxxx"
+ echo "$output"
+ echo "xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ (( status == 1 ))
+ rm -rf test_integration_tmp
+ rm -f symlinked_source
+}
+
+@test "Integration -- symlinks 2" {
+ # For CI envs that don't have it.
+ unzip() {
+ return 0
+ }
+ export -f unzip
+
+ # For CI envs that don't have it.
+ file() {
+ return 0
+ }
+ export -f file
+
+ rm -rf test_integration_tmp
+ rm -rf symlinked_source_2
+
+ mkdir -p test_integration_tmp
+ mkdir -p symlinked_source_2
+
+ # sanity check
+ command -v readlink
+
+ # work around variable exported in setup_file being unset in some bats versions
+ echo "CANONPWD is $CANONPWD"
+ export CANONPWD="$( readlink -f "$( pwd )" )"
+ echo "CANONPWD is $CANONPWD"
+
+ ln -s "$CANONPWD"/fake_jar_test_battery_smoke_4 symlinked_source_2/x
+
+ echo "symlinked_source_2 resolves to $( readlink -f symlinked_source_2 )"
+ echo "running script like this: ${SCRIPT_NAME} -n --scan $CANONPWD/symlinked_source_2 --tmp $CANONPWD/test_integration_tmp"
+
+ run ./"${SCRIPT_NAME}" -n --scan "$CANONPWD"/symlinked_source_2 --tmp "$CANONPWD"/test_integration_tmp
+ echo "xxxxxxxxxx OUTPUT xxxxxxxxxx"
+ echo "$output"
+ echo "xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ (( status == 0 ))
+ # because symlinks are ignored
+ [[ "$output" == *"The specified directory does not contain vulnerable log4j-core jar files."* ]]
+ rm -rf test_integration_tmp
+ rm -rf symlinked_source_2
+}
+
+@test "Integration -- symlinks 3" {
+ # For CI envs that don't have it.
+ unzip() {
+ return 0
+ }
+ export -f unzip
+
+ rm -rf test_integration_tmp
+ rm -rf symlinked_source_2
+
+ mkdir -p test_integration_tmp
+ mkdir -p symlinked_source_2
+
+ # sanity check
+ command -v readlink
+
+ echo "CANONPWD is $CANONPWD"
+ export CANONPWD="$( readlink -f "$( pwd )" )"
+ echo "CANONPWD is $CANONPWD"
+
+ ln -s "$CANONPWD"/fake_jar_test_battery_smoke_4 symlinked_source_2/x
+
+ echo "symlinked_source_2 resolves to $( readlink -f symlinked_source_2 )"
+ echo "symlinked_source_2/x resolves to $( readlink -f symlinked_source_2/x )"
+ echo "CANONPWD/fake_jar_test_battery_smoke_4 resolves to $( readlink -f "$CANONPWD/fake_jar_test_battery_smoke_4" )"
+
+
+ # sanity checks
+ [[ -L symlinked_source_2/x ]]
+ [[ "$( readlink -f "$CANONPWD/symlinked_source_2/x" )" == "$CANONPWD/fake_jar_test_battery_smoke_4" ]]
+
+ echo "running script like this: ${SCRIPT_NAME} -n --scan $CANONPWD/symlinked_source_2/x --tmp $CANONPWD/test_integration_tmp"
+
+ run ./"${SCRIPT_NAME}" -n --scan "$CANONPWD"/symlinked_source_2/x --tmp "$CANONPWD"/test_integration_tmp
+ echo "xxxxxxxxxx OUTPUT xxxxxxxxxx"
+ echo "$output"
+ echo "xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ (( status == 1 ))
+ rm -rf test_integration_tmp
+ rm -rf symlinked_source
+}
+
+
+@test "Integration -- symlinks 4" {
+ # For CI envs that don't have it.
+ unzip() {
+ return 0
+ }
+ export -f unzip
+
+ rm -rf test_integration_tmp
+ rm -f symlinked_tmp
+
+ mkdir -p test_integration_tmp
+
+ ln -s test_integration_tmp symlinked_tmp
+
+ export CANONPWD="$( readlink -f "$( pwd )" )"
+ echo "CANONPWD is $CANONPWD"
+
+ # sanity check
+ command -v readlink
+
+ echo "symlinked_tmp resolves to $( readlink -f symlinked_tmp )"
+
+ echo "running script like this: ${SCRIPT_NAME} -n --scan $CANONPWD/fake_jar_test_battery_smoke_4 --tmp $CANONPWD/symlinked_tmp"
+
+ run ./"${SCRIPT_NAME}" -n --scan "$CANONPWD"/fake_jar_test_battery_smoke_4 --tmp "$CANONPWD"/symlinked_tmp
+ echo "xxxxxxxxxx OUTPUT xxxxxxxxxx"
+ echo "$output"
+ echo "xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+ (( status == 1 ))
+ rm -rf test_integration_tmp
+ rm -f symlinked_tmp
+}
diff --git a/CVE-2021-44228_log4j-core/tests_rm.bats b/CVE-2021-44228_log4j-core/tests_rm.bats
new file mode 100644
index 0000000..b7edf96
--- /dev/null
+++ b/CVE-2021-44228_log4j-core/tests_rm.bats
@@ -0,0 +1,96 @@
+#!/usr/bin/env bats
+
+
+@test "rm -- #1" {
+ # This test shows the following:
+ # * That the rm commands in the script are limited to the lines in approved_rm_lines.txt
+ # (comments are ignored)
+ # * A change in or an addition of an rm command must be reflected in tests_rm.bats and
+ # probably approved_rm_lines.txt, making such a change visibly noticeable and easily
+ # searchable in git history.
+ # * The amount of rm commands is very limited and this test might make it somewhat easier to
+ # audit the rm commands.
+ # This test doesn't prove the following:
+ # * There are no obfuscated ways to execute rm (a manual review of the entire script is
+ # necessary to conclude that).
+ # * All usages of rm are safe, in the right moments, in the right environment (a manual
+ # review of the entire script is necessary to conclude that).
+
+ # make sure the list of approved rm lines wasn't changed by accident
+ [[ "$( sha256sum approved_rm_lines.txt )" == "fa0af65854da355c7ede8af6b1d319053d8239142a8a23aef4ab0236c6ab6c43 approved_rm_lines.txt" ]]
+
+ # make sure there are no empty lines in approved_rm_lines.txt
+ ! grep -Fx '' approved_rm_lines.txt
+
+ # make sure there are no unapproved lines containing 'rm ' (ignoring #comments)
+ ! grep -F 'rm ' CVE-2021-44228.sh | grep -v -E '^ *#.*$' | sed -r 's/^ *//g' | grep -vFxf approved_rm_lines.txt
+
+ # Show that there are no string like these: (ignoring #comments)
+ # rm"
+ # rm;
+ # rm)
+ # rm}
+ # rm'
+ ! grep -E '^[^#]*rm[";)}]' CVE-2021-44228.sh
+ ! grep -E "^[^#]*rm'" CVE-2021-44228.sh
+
+}
+
+
+@test "rm -- #2" {
+ # This test shows the following:
+ # * That the rm commands in the script are limited to the blocks in approved_rm_blocks.txt
+ # (comments are ignored)
+ # * A change in or an addition of an rm command must be reflected in tests_rm.bats and
+ # probably approved_rm_blocks.txt, making such a change visibly noticeable and easily
+ # searchable in git history.
+ # * The amount of rm commands is very limited and this test might make it somewhat easier to
+ # audit the rm commands.
+ # * A limited context of the rm commands is visible, making it easy to audit that appropriate
+ # checks are executed before executing an rm command.
+ # This test doesn't prove the following:
+ # * There are no obfuscated ways to execute rm (a manual review of the entire script is
+ # necessary to conclude that).
+ # * All usages of rm are safe, in the right moments, in the right environment (a manual
+ # review of the entire script is necessary to conclude that).
+
+ # make sure the listing of approved rm blocks wasn't changed by accident
+ [[ "$( sha256sum approved_rm_blocks.txt )" == "2c7f2076e48e2e820a1316e11b65450e48a1138d057e55e4db85b1a552a6df40 approved_rm_blocks.txt" ]]
+
+ # make sure there's a line that checks $dir_to_delete for the most grave problems
+ # (in the whole script, $dir_to_delete is the only mutable variable passed to an rm command)
+ [[ "$( cat approved_rm_blocks.txt )" == *'if [[ "$dir_to_delete" != *..* && "$dir_to_delete" != */* ]] ; then'* ]]
+
+ # check that the blocks with the rm commands as reported by grep are identical to approved_rm_blocks.txt
+ [[ "$( grep -A3 -B5 -E '^[^#]*rm ' CVE-2021-44228.sh | grep -v -E '^ *#.*$' )" == "$( cat approved_rm_blocks.txt )" ]]
+
+
+}
+
+
+@test "rm -- #3" {
+ # This test shows the following:
+ # * The listed variables are used like these in the script. (It can be assumed that it
+ # means that they can't be modified once these lines are executed.)
+ # This test doesn't prove the following:
+ # * That these lines are ever run (a manual review of the entire script is
+ # necessary to conclude that).
+ # * That these lines are never modified (a manual review of the entire script is
+ # necessary to conclude that).
+ # * These lines are run at the right moment (a manual
+ # review of the entire script is necessary to conclude that).
+
+ grep -q -Fx ' readonly queue="CVE_2021_44228_queue"' CVE-2021-44228.sh
+ grep -q -Fx ' readonly catalog="CVE_2021_44228_catalog"' CVE-2021-44228.sh
+ grep -q -Fx ' readonly decompressed="CVE_2021_44228_decompressed"' CVE-2021-44228.sh
+ grep -q -Fx ' readonly parents="CVE_2021_44228_parents"' CVE-2021-44228.sh
+ grep -q -Fx ' readonly backtrack="CVE_2021_44228_backtrack"' CVE-2021-44228.sh
+ grep -q -Fx ' readonly detections="CVE_2021_44228_detections"' CVE-2021-44228.sh
+ grep -q -Fx ' readonly report="report"' CVE-2021-44228.sh
+
+ grep -q -Fx ' readonly tmp_path' CVE-2021-44228.sh
+ grep -q -Fx ' readonly scan_path' CVE-2021-44228.sh
+ grep -q -Fx ' readonly audit_tmp_path' CVE-2021-44228.sh
+ grep -q -Fx ' readonly audit_scan_path' CVE-2021-44228.sh
+}
+