• Stars
    star
    192
  • Rank 202,019 (Top 4 %)
  • Language
    Go
  • License
    Apache License 2.0
  • Created almost 3 years ago
  • Updated 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A tool that scans archives to check for vulnerable log4j versions

Autorelease

log4j-sniffer

log4j-sniffer crawls for all instances of log4j on disk within a specified directory. It can be used to determine whether there are any vulnerable instances of log4j within a directory tree and report or delete them depending on the mode used.

Scanning for versions affected by CVE-2021-44228, CVE-2021-45046, CVE-2021-45105 and CVE-2021-44832 is currently supported.

What this does

log4j-sniffer will scan a filesystem looking for all files of the following types based upon suffix:

  • Zips: .zip
  • Java archives: .jar, .war, .ear
  • Tar: .tar, .tar.gz, .tgz, .tar.bz2, .tbz2

Archives containing other archives will be recursively inspected up to a configurable maximum depth. See the log4j-sniffer crawl --help output for options on nested archive inspection.

It will look for the following:

  • Jar files matching log4j-core-<version>.jar, including those nested within another archive
  • Class files named org.apache.logging.log4j.core.net.JndiManager within Jar files or other archives and check against md5 hashes of known versions
  • Class files named JndiManager in other package hierarchies and check against md5 hashes of known versions
  • Matching of the bytecode of classes named JndiManager against known classes (see below for more details)
  • Matching of bytecode within obfuscated or shaded jars for partial matches against known classes (see below)

Installing

If Go is available on the host system, the following command can be used to install this program:

go install github.com/palantir/log4j-sniffer@latest

This repository also publishes binaries that can be downloaded and executed.

Downloads

log4j-sniffer executables compiled for linux-amd64, darwin-amd64, darwin-arm64 and windows-amd64 architectures are available on the releases page.

Running

This tool is intensive and is recommended to be run with low priority settings.

On Linux:

ionice -c 3 nice -n 19 log4j-sniffer crawl /path/to/a/directory

Output for vulnerable files looks as follows:

[INFO] Found archive with name matching vulnerable log4j-core format at examples/single_bad_version/log4j-core-2.14.1.jar
[INFO] Found JndiManager class that was an exact md5 match for a known version at org/apache/logging/log4j/core/net/JndiManager.class
[INFO] Found JndiLookup class in the log4j package at org/apache/logging/log4j/core/lookup/JndiLookup.class
[MATCH] CVE-2021-44228, CVE-2021-45046, CVE-2021-45105, CVE-2021-44832 detected in file examples/single_bad_version/log4j-core-2.14.1.jar. log4j versions: 2.14.0-2.14.1, 2.14.1. Reasons: JndiLookup class and package name matched, jar name matched, JndiManager class and package name matched, class file MD5 matched
Files affected by CVE-2021-44228 or CVE-2021-45046 or CVE-2021-45105 or CVE-2021-44832 detected: 1 file(s)
1 total files scanned, skipped identifying 0 files due to config, skipped 0 paths due to permission denied errors, encountered 0 errors processing paths

Getting started

Mac

Download the latest version
  1. Locate releases.
  2. You will need a different asset depending on the generation of your Mac.
    1. Select the asset with “macos-amd” in the file name for older Intel Macs.
    2. Select “macos-arm” for newer m1 Macs
  3. Confirm that the file is downloading to your “Downloads” folder.
Install log4j-sniffer on your machine
  1. Once the download is complete, click on the file to open.
  2. Drag and drop the “log4j-sniffer” icon into your Downloads through the Finder.
    1. Open a Finder window by searching for “Finder” using the magnifying glass on the top right of your screen, or selecting the icon in your Dock.
    2. Drag and drop the “log4j-sniffer” icon into Downloads. dragging and dropping
Use log4j-sniffer
  1. Open the Terminal by searching for “Terminal” using the magnifying glass in the top right corner of the screen.
  2. Run ~/Downloads/log4j-sniffer crawl / --ignore-dir="^/dev" to crawl the entire system
    1. Run ~/Downloads/log4j-sniffer crawl /PATH/TO/YOUR/FOLDER to crawl specific folders
    2. If your computer is unable to locate log4j-sniffer, you may have to make it executable before using it. In your terminal, run the following:
      1. chmod +x ~/Downloads/log4j-sniffer
      2. ./log4j-sniffer crawl /PATH/TO/YOUR/FOLDER

Windows

Download the latest version
  1. Locate [releases] (https://github.com/palantir/log4j-sniffer/releases).
  2. Select the Windows asset.
  3. Confirm that the file is downloading to your “Downloads” folder.
Use log4j-sniffer
  1. Type "Command Prompt" into the search bar at the bottom and in the right pane click "Run as administrator".
  2. Navigate to your Downloads folder, e.g. cd C:\Users\yourname\Downloads
  3. Run log4j-sniffer-1.1.0-windows-amd64.exe crawl C:\ to crawl the entire system, substituting the drive of your choice, e.g. C:\, D:\
    1. Run log4j-sniffer-1.1.0-windows-amd64.exe crawl C:\PATH\TO\YOUR\FOLDER to crawl specific folders

Primary Usage

The primary command for the tool is crawl which takes an argument that is the path to the directory to be crawled. Thus, the standard usage is:

log4j-sniffer crawl [pathToDirectory]

The standard mode prints output in a human-readable format and prints a summary that states the number of vulnerabilities found after running.

Specifying the --json flag makes it such that the output of the program is all in JSON: each line of output is JSON that describes the vulnerability that is found, and if summary mode is enabled then the final summary is also output as a line of JSON.

Here is an example of the output with --json:

{"message":"CVE-2021-44228, CVE-2021-44832, CVE-2021-45046, CVE-2021-45105 detected","filePath":"examples/inside_a_dist/wrapped_log4j.tar.gz","detailedPath":"examples/inside_a_dist/wrapped_log4j.tar.gz!log4j-core-2.14.1.jar","cvesDetected":["CVE-2021-44228","CVE-2021-44832","CVE-2021-45046","CVE-2021-45105"],"findings":["jndiLookupClassPackageAndName","jarNameInsideArchive","jndiManagerClassPackageAndName","classFileMd5"],"log4jVersions":["2.14.0-2.14.1","2.14.1"]}
{"filesScanned":1,"permissionDeniedErrors":0,"pathErrors":0,"pathsSkipped":0,"numImpactedFiles":1}

The JSON fields have the following meaning:

  • message: information about the output
  • filePath: the path to the file on disk where the vulnerability was detected
  • detailedPath: the path to the vulnerable contents, which may be an archived file multiple levels nested. Nesting levels are separated by a '!'
  • cvesDetected: CVEs matched against the version found
  • log4jVersions: the versions detected at this location based on all applied detections, note that some detections are more accurate than others and so a range of versions might be reported

The findings array reports the following possible values:

  • jndiLookupClassName: there was a .class file called JndiLookup
  • jndiLookupClassPackageAndName: there was a .class file called JndiLookup with a package of org.apache.logging.log4j.core.lookup
  • jndiManagerClassName: there was a .class file called JndiManager
  • jndiManagerClassPackageAndName: there was a .class file called JndiManager with a package of org.apache.logging.log4j.core.net
  • jarNameMatched: the file scanned was a .jar file called log4j-core-<version>.jar
  • jarNameInsideArchiveMatched: there was a .jar file called log4j-core-<version>.jar inside the archive
  • classFileMd5Matched: there was a class file called JndiManager that matched the md5 hash of a known version
  • classBytecodeInstructionMd5: the bytecode of a class file called JndiManager exactly matched a known version, see the Bytecode matching section for more details
  • jarFileObfuscated: the jar the match was found in appeared to be obfuscated
  • classBytecodePartialMatch: the bytecode of a class file called JndiManager, or a class within an obfuscated jar, partially matched the bytecode of a known version, see the Bytecode partial matching section for more details

The summary outlines:

  • filesScanned: the total number of files crawled
  • permissionDeniedErrors: the number of directories or files that could not be read due to permissions
  • pathErrors: the number of paths where an unexpected error occurred while trying to identify bad log4j versions
  • pathsSkipped: the numbers of paths skipped from full identification of bad log4j versions due to the config options set
  • numImpactedFiles: the total number of files impacted
  • findings: the total number of findings previously output. For file path only mode, this will equal the number of impacted files.

Specifying --summary=false makes it such that the program does not output a summary line at the end. In this case, the program will only print output if vulnerabilities are found.

Detections quick match table

The following tables shows when each finding is reported based on our testing:

Unmodified log4j-core-2.14.1.jar JndiLookup removed log4j-core-2.14.1.jar Inside a fat jar (no renaming)
jndiLookupClassName
jndiLookupClassPackageAndName
jndiManagerClassName
jndiManagerClassPackageAndName
jarNameMatched
jarNameInsideArchiveMatched
classFileMd5Matched
bytecodeInstructionMd5Matched
jarFileObfuscated
classBytecodePartialMatch
Detected
Shaded (packages renamed only) Shaded (all renamed) Shaded/obfuscated (bytecode optimised)
jndiLookupClassName
jndiLookupClassPackageAndName
jndiManagerClassName
jndiManagerClassPackageAndName
jarNameMatched
jarNameInsideArchiveMatched
classFileMd5Matched
bytecodeInstructionMd5Matched
jarFileObfuscated
classBytecodePartialMatch
Detected
log4j-core-2.14.1.jar inside a .tgz file Heavily obfuscated (additional bytecode instructions inserted)
jndiLookupClassName
jndiLookupClassPackageAndName
jndiManagerClassName
jndiManagerClassPackageAndName
jarNameMatched
jarNameInsideArchiveMatched
classFileMd5Matched
bytecodeInstructionMd5Matched
jarFileObfuscated
classBytecodePartialMatch
Detected

Some of these detections may require non-default settings depending on the file scanned. Some detections may not identify all cases, common shading and obfuscation has been tested but it is not possible to cover every possible change that could be made by such a tool.

Bytecode matching

If a class is shaded (for example, to build a fat jar), then the bytecode is rewritten to update the package. This means the hash of the class will no longer match against known versions, nor will the class appear where expected within a jar.

To account for this, we perform a less accurate hash of a class file: we only hash the fixed parts of the bytecode defining each method, ignoring all parts that might vary upon shading. We take an md5 hash of the resulting bytecode and compare against known versions.

Testing against shaded jars shows this matches when the package version has been changed but the class otherwise left intact. Shading which further modifies classes, such as by removing methods, will not be found with this approach.

Bytecode partial matching

If the event of more aggressive shading, which deletes unused methods, or obfuscated being applied in order to compress the Jar size bytecode matching will not produce matches. The class of interest may also no longer be called JndiManager or appear under a package hierarchy that indicates the presence of log4j.

For these cases we have implemented partial bytecode matching based on signatures generated from obfuscated versions of the log4j jar compared against the version as shipped.

By default we apply this detection to classes called JndiManager which have not been matched by md5 or full bytecode matching, or to all classes in Jar files with an average package and class name length both under 3.

A match here is likely but not guaranteed to be log4j within the reported version range. Obfuscation aimed to preventing reverse engineering rather than simply compressing the Jar size may also cause false negatives.

Testing against know shaded jars in open source products, such as the Hive jdbc driver, has shown this approach to produce matches.

Crawl command

Crawl filesystem to scan for jars vulnerable to CVE-2021-45046.
Root must be provided and can be a single file or directory.
If a directory is provided, it is traversed and all files are scanned.
Use the ignore-dir flag to provide directories of which to ignore all nested files.

Usage:
  log4j-sniffer crawl <root> [flags]

Flags:
      --archive-open-mode string                             Supported values:
                                                               standard - standard file opening will be used. This may cause the filesystem cache to be populated with reads from the archive opens.
                                                               directio - direct I/O will be used when opening archives that require sequential reading of their content without being able to skip to file tables at known locations within the file.
                                                                          For example, "directio" can have an effect on the way that tar-based archives are read but will have no effect on zip-based archives.
                                                                          Using "directio" will cause the filesystem cache to be skipped where possible. "directio" is not supported on tmpfs filesystems and will cause tmpfs archive files to report an error. (default "standard")
      --archives-per-second-rate-limit int                   The maximum number of archives to scan per second. 0 for unlimited.
      --directories-per-second-rate-limit int                The maximum number of directories to crawl per second. 0 for unlimited.
      --disable-cve-2021-44832-detection                     Disable detection of CVE-2021-44832 in versions up to 2.17.0
      --disable-cve-2021-45105-detection                     Disable detection of CVE-2021-45105 in versions up to 2.16.0
      --disable-detailed-findings                            Do not print out detailed finding information when not outputting in JSON.
      --disable-flagging-jndi-lookup                         Do not report results that only match on the presence of a JndiLookup class.
                                                             Even when disabled results which match other criteria will still report the presence of JndiLookup if relevant.
      --disable-unknown-versions                             Only output issues if the version of log4j can be determined (note that this will cause certain detection mechanisms to be skipped)
      --enable-obfuscation-detection                         Enable applying partial bytecode matching to Jars that appear to be obfuscated. (default true)
      --enable-partial-matching-on-all-classes               Enable partial bytecode matching to all class files found.
      --enable-trace-logging                                 Enables trace logging whilst crawling. disable-detailed-findings must be set to false (the default value) for this flag to have an effect.
      --file-path-only                                       If true, output will consist of only paths to the files in which CVEs are detected
  -h, --help                                                 help for crawl
      --ignore-dir strings                                   Specify directory pattern to ignore. Use multiple times to supply multiple patterns.
                                                             Patterns should be relative to the provided root.
                                                             e.g. ignore "^/proc" to ignore "/proc" when using a crawl root of "/"
      --json                                                 If true, output will be in JSON format
      --maximum-average-obfuscated-class-name-length int     The maximum class name length for a class to be considered obfuscated. (default 3)
      --maximum-average-obfuscated-package-name-length int   The maximum average package name length a class to be considered obfuscated. (default 3)
      --nested-archive-disk-swap-dir string                  When nested-archive-disk-swap-max-size is non-zero, this is the directory in which temporary files will be created for writing temporary large nested archives to disk. (default "/tmp")
      --nested-archive-disk-swap-max-size uint               The maximum size in bytes of disk space allowed to use for inspecting nest archives that are over the nested-archive-max-size.
                                                             By default no disk swap is to be allowed, nested archives will only be inspected if they fit into the configured nested-archive-max-size.
                                                             When an archive is encountered that is over the nested-archive-max-size, an the archive may be written out to a temporary file so that it can be inspected without a large memory penalty.
                                                             If large archives are nested within each other, an archive will be opened only if the accumulated space used for archives on disk would not exceed the configured nested-archive-disk-swap-max-size.
      --nested-archive-max-depth uint                        The maximum depth to recurse into nested archives.
                                                             A max depth of 0 will open up an archive on the filesystem but not any nested archives.
      --nested-archive-max-size uint                         The maximum compressed size in bytes of any nested archive that will be unarchived for inspection.
                                                             This limit is made a per-depth level.
                                                             The overall limit to nested archive size unarchived should be controlled
                                                             by both the nested-archive-max-size and nested-archive-max-depth. (default 5242880)
      --per-archive-timeout duration                         If this duration is exceeded when inspecting an archive,
                                                             an error will be logged and the crawler will move onto the next file. (default 15m0s)
      --summary                                              If true, outputs a summary of all operations once program completes (default true)

Archives

Archives can both contain many files listed and have other archives nested within them. If either is followed without limit then it would be possible to cause scans to take either an unacceptable amount of time or consume an acceptable amount of memory.

--per-archive-timeout allows for control of the maximum time a single archive will be examined. --nested-archive-max-size and --nested-archive-max-depth control how many nested archives are opened, and how large each one may be. The total memory required will be on the order to the product of these two values.

Rate limiting

While nice and ionice on Linux and other platform specific tooling can be used to limit the priority of processes it may be desired to further limit resource use. One example is when running on AWS instances with a burst balance for IO, which might be consumed by running this tool leading to a negative impact on other processes running on that instance.

--directories-per-second-rate-limit and --archives-per-second-rate-limit limit how quickly directories will be traversed and how quickly archives will be processed.

Obfuscation detection

For partial bytecode matching we apply a heuristic for whether a Jar is obfuscated. This is because the partial matching is expensive to apply and as such running it on every matching Jar on a system may not be feasible.

The heuristic used is that both the average package name length and class name length need to be below a certain value for a Jar to be considered obfuscated. By default this is 3. You can tune these values using --maximum-average-obfuscated-class-name-length and --maximum-average-obfuscated-package-name-length.

If you wish to turn off obfuscation detection entirely then --enable-obfuscation-detection can be used. If instead you wish to apply partial matching to all Jars, regardless of whether they appear obfuscated, then you can use --enable-partial-matching-on-all-classes.

CVE-2021-45105 and CVE-2021-44832

If you do not wish to report results for CVE-2021-45105 or CVE-2021-44832 then pass the --disable-cve-2021-45105-detection or --disable-cve-2021-44832-detection flags to the crawl command.

By default, both CVE-2021-45046 and CVE-2021-45105 will be reported.

Examples

Running on Linux against the entire filesystem at a low priority:

ionice -c 3 nice -n 19 log4j-sniffer crawl / --ignore-dir "^/dev" --ignore-dir "^/proc"

Running against a specific Jar with all limits removed:

log4j-sniffer crawl jar-under-suspicion.jar --enable-partial-matching-on-all-classes --nested-archive-max-depth 255 --nested-archive-max-size 5242880000

Delete command

Most of the flags are shared with the crawl command and so it is recommended that delete be run using configuration that is known to not negatively impact performance of a host.

Delete files containing log4j vulnerabilities.

Crawl the file system from root, detecting files containing log4j-vulnerabilities and deleting them if they meet certain requirements determined by the command flags.
Root must be provided and can be a single file or directory.

Dry-run mode is enabled by default, where a line will be output to state where a file would be deleted when running not in dry run mode.
It is recommended to run using dry-run mode enabled, checking the logged output and then running with dry-run disabled using the same configuration flags.
Use --dry-run=false to turn off dry-run mode, enabling deletes.

When used on windows, deleting based on file ownership is unsupported and skip-owner-check should be used instead of filepath-owner.

Usage:
  log4j-sniffer delete <root> [flags]

Examples:
Delete all findings nested beneath /path/to/dir that are owned by foo and contain findings that match both classFileMd5 and jarFileObfuscated.

log4j-sniffer delete /path/to/dir --dry-run=false --filepath-owner ^/path/to/dir/.*:foo --finding-match classFileMd5 --finding-match jarFileObfuscated

Flags:
      --archive-open-mode string                             Supported values:
                                                               standard - standard file opening will be used. This may cause the filesystem cache to be populated with reads from the archive opens.
                                                               directio - direct I/O will be used when opening archives that require sequential reading of their content without being able to skip to file tables at known locations within the file.
                                                                          For example, "directio" can have an effect on the way that tar-based archives are read but will have no effect on zip-based archives.
                                                                          Using "directio" will cause the filesystem cache to be skipped where possible. "directio" is not supported on tmpfs filesystems and will cause tmpfs archive files to report an error. (default "standard")
      --archives-per-second-rate-limit int                   The maximum number of archives to scan per second. 0 for unlimited.
      --directories-per-second-rate-limit int                The maximum number of directories to crawl per second. 0 for unlimited.
      --disable-cve-2021-44832-detection                     Disable detection of CVE-2021-44832 in versions up to 2.17.0
      --disable-cve-2021-45105-detection                     Disable detection of CVE-2021-45105 in versions up to 2.16.0
      --dry-run                                              When true, a line with be output instead of deleting a file. Use --dry-run=false to enable deletion. (default true)
      --enable-obfuscation-detection                         Enable applying partial bytecode matching to Jars that appear to be obfuscated. (default true)
      --enable-partial-matching-on-all-classes               Enable partial bytecode matching to all class files found.
      --enable-trace-logging                                 Enables trace logging whilst crawling. disable-detailed-findings must be set to false (the default value) for this flag to have an effect.
      --filepath-owner strings                               Provide a filepath pattern and owner template that will be used to check whether a file should be deleted or not when it is deemed to be vulnerable.
                                                             Multiple values can be provided and values must be provided in the form filepath_pattern:owner_template, where a filepath pattern and owner template are colon separated.

                                                             When a file is deemed to be vulnerable, the path of the file containing the vulnerability will be matched against all filepath patterns.
                                                             For all filepath matches, the owner template will be expanded against the filepath pattern match to resolve to a file owner value that the actual file owner will then be compared against.
                                                             Owner templates may use template variables, e.g. $1, $2, $name, that correspond to capture groups in the filepath pattern. Please refer to the standard go regexp package documentation at https://pkg.go.dev/regexp#Regexp.Expand for more detailed expanding behaviour.

                                                             If no filepaths match, the file will not be deleted. If any filepaths match, all matching filepath patterns' corresponding expanded templated owner values must match against the actual file owner for the file to be deleted.

                                                             Architecture-specific behaviour:
                                                             - linux-amd64: libc-backed code is used, which is able to infer the owner of a file over a broad range of account setups.
                                                             - linux-arm64: only the user running or users from /etc/passwd will be available to infer file ownership.
                                                             - darwin-*: only the user running or users from /etc/passwd will be available to infer file ownership.
                                                             - windows-*: file ownership is unsupported and --skip-owner-check should be used instead.

                                                             Examples:
                                                             --filepath-owner ^/foo/bar/.+:qux would consider /foo/bar/baz for deletion only if it is owned by qux.
                                                             --filepath-owner ^/foo/bar/.+:qux and --filepath-owner ^/foo/bar/baz/.+:quuz would not consider /foo/bar/baz/corge for deletion if owned by either qux or quuz because both would need to match.
                                                             --filepath-owner ^/foo/(\w+)/.*:$1 would consider /foo/bar/baz for deletion only if it is owned by bar.

      --finding-match strings                                When supplied, any vulnerable finding must contain all values that are provided to finding-match for it to be considered for deletion.
                                                             These values are considered on a finding-by-finding basis, i.e. an archive containing two separate vulnerable jars will only be deleted if either of the contained jars matches all finding-match values.

                                                             Supported values are as follows, but can be provided case-insensitively:
                                                             - ClassBytecodeInstructionMd5
                                                             - ClassBytecodePartialMatch
                                                             - ClassFileMd5
                                                             - JarFileObfuscated
                                                             - JarName
                                                             - JarNameInsideArchive
                                                             - JndiLookupClassName
                                                             - JndiLookupClassPackageAndName
                                                             - JndiManagerClassName
                                                             - JndiManagerClassPackageAndName

                                                             Example:
                                                             --finding-match classFileMd5 and --finding-match jarFileObfuscated would only delete a file containing a vulnerability if the vulnerability contains a class file hash match and an obfuscated jar name.
                                                             If a vulnerable finding contained only one of these finding-match values then the file would not be considered for deletion.

  -h, --help                                                 help for delete
      --ignore-dir strings                                   Specify directory pattern to ignore. Use multiple times to supply multiple patterns.
                                                             Patterns should be relative to the provided root.
                                                             e.g. ignore "^/proc" to ignore "/proc" when using a crawl root of "/"
      --maximum-average-obfuscated-class-name-length int     The maximum class name length for a class to be considered obfuscated. (default 3)
      --maximum-average-obfuscated-package-name-length int   The maximum average package name length a class to be considered obfuscated. (default 3)
      --nested-archive-disk-swap-dir string                  When nested-archive-disk-swap-max-size is non-zero, this is the directory in which temporary files will be created for writing temporary large nested archives to disk. (default "/tmp")
      --nested-archive-disk-swap-max-size uint               The maximum size in bytes of disk space allowed to use for inspecting nest archives that are over the nested-archive-max-size.
                                                             By default no disk swap is to be allowed, nested archives will only be inspected if they fit into the configured nested-archive-max-size.
                                                             When an archive is encountered that is over the nested-archive-max-size, an the archive may be written out to a temporary file so that it can be inspected without a large memory penalty.
                                                             If large archives are nested within each other, an archive will be opened only if the accumulated space used for archives on disk would not exceed the configured nested-archive-disk-swap-max-size.
      --nested-archive-max-depth uint                        The maximum depth to recurse into nested archives.
                                                             A max depth of 0 will open up an archive on the filesystem but not any nested archives.
      --nested-archive-max-size uint                         The maximum compressed size in bytes of any nested archive that will be unarchived for inspection.
                                                             This limit is made a per-depth level.
                                                             The overall limit to nested archive size unarchived should be controlled
                                                             by both the nested-archive-max-size and nested-archive-max-depth. (default 5242880)
      --per-archive-timeout duration                         If this duration is exceeded when inspecting an archive,
                                                             an error will be logged and the crawler will move onto the next file. (default 15m0s)
      --skip-owner-check                                     When provided, the owner of a file will not be checked before attempting a delete.

Identify command

Produces hashes to identify a class file within a JAR.
The entire class is hashed to allow for matching against the exact version.
The bytecode opcodes making up the methods are hashed, for matching versions
with modifications.
Use the class-name option to change which class is analysed within the JAR.

Usage:
  log4j-sniffer identify <jar> [flags]

Flags:
      --class-name string   Specify the full class name and package to scan.
                            Defaults to the log4j JdniManager class. (default "org.apache.logging.log4j.core.net.JndiManager")
  -h, --help                help for identify


Identify runs against a Jar and produces both an md5 hash and a bytecode instruction hash. The primary purpose for this command is generating signatures for the crawl command.

Example output:

$ log4j-sniffer identify examples/single_bad_version/log4j-core-2.14.1.jar 
Size of class: 5029
Hash of complete class: f1d630c48928096a484e4b95ccb162a0
Hash of all bytecode instructions: 8139e14cd3955ef709139c3f23d38057-v0

Compare command

Compares the classes specified within source_jar and target_jar.
Outputs the parts the jars have in common in order to build signatures for matching.
The class names must be fully qualified and not end with .class.

Usage:
  log4j-sniffer compare <source_jar> <class> <target_jar> <class> [flags]

Flags:
  -h, --help   help for compare

Compare two classes and output similar bytecode in hex encoding. The primary purpose of this command is to produce signatures for partial bytecode matching. It is not intended to provide useful output if run against Jar files of unknown construction.

More Repositories

1

blueprint

A React-based UI toolkit for the web
TypeScript
19,885
star
2

tslint

🚦 An extensible linter for the TypeScript language
TypeScript
5,916
star
3

plottable

📊 A library of modular chart components built on D3
TypeScript
2,926
star
4

python-language-server

An implementation of the Language Server Protocol for Python
Python
2,579
star
5

windows-event-forwarding

A repository for using windows event forwarding for incident detection and response
Roff
1,215
star
6

pyspark-style-guide

This is a guide to PySpark code style presenting common situations and the associated best practices based on the most frequent recurring topics across the PySpark repos we've encountered.
Python
1,019
star
7

osquery-configuration

A repository for using osquery for incident detection and response
814
star
8

policy-bot

A GitHub App that enforces approval policies on pull requests
Go
756
star
9

tslint-react

📙 Lint rules related to React & JSX for TSLint.
TypeScript
752
star
10

bulldozer

GitHub Pull Request Auto-Merge Bot
Go
742
star
11

gradle-docker

a Gradle plugin for orchestrating docker builds and pushes.
Groovy
723
star
12

alerting-detection-strategy-framework

A framework for developing alerting and detection strategies for incident response.
657
star
13

stacktrace

Stack traces for Go errors
Go
498
star
14

palantir-java-format

A modern, lambda-friendly, 120 character Java formatter.
Java
427
star
15

docker-compose-rule

A JUnit rule to manage docker containers using docker-compose
Java
422
star
16

conjure

Strongly typed HTTP/JSON APIs for browsers and microservices
Java
417
star
17

go-githubapp

A simple Go framework for building GitHub Apps
Go
342
star
18

eclipse-typescript

An Eclipse plug-in for developing in the TypeScript language.
JavaScript
340
star
19

gradle-git-version

a Gradle plugin that uses `git describe` to produce a version string.
Java
339
star
20

godel

Go tool for formatting, checking, building, distributing and publishing projects
Go
304
star
21

jamf-pro-scripts

A collection of scripts and extension attributes created for managing Mac workstations via Jamf Pro.
Shell
304
star
22

gradle-baseline

A set of Gradle plugins that configure default code quality tools for developers.
Java
283
star
23

gradle-graal

A plugin for Gradle that adds tasks to download, extract and interact with GraalVM tooling.
Java
227
star
24

tfjson

Terraform plan file to JSON
Go
181
star
25

k8s-spark-scheduler

A Kubernetes Scheduler Extender to provide gang scheduling support for Spark on Kubernetes
Go
175
star
26

Sysmon

A lightweight platform monitoring tool for Java VMs
Java
155
star
27

documentalist

📝 A sort-of-static site generator optimized for living documentation of software projects
TypeScript
153
star
28

exploitguard

Documentation and supporting script sample for Windows Exploit Guard
PowerShell
148
star
29

typesettable

📐 A typesetting library for SVG and Canvas
TypeScript
146
star
30

bouncer

An application to cycle (bounce) all nodes in a coordinated fashion in an AWS ASG or set of related ASGs
Go
129
star
31

gradle-consistent-versions

Compact, constraint-friendly lockfiles for your dependencies
Java
112
star
32

Cinch

A Java library that manages component action/event bindings for MVC patterns
Java
110
star
33

redoodle

An addon library for Redux that enhances its integration with TypeScript.
TypeScript
100
star
34

gradle-jacoco-coverage

Groovy
99
star
35

sqlite3worker

A threadsafe sqlite worker for Python
Python
94
star
36

phishcatch

A browser extension and API server for detecting corporate password use on external websites
CSS
90
star
37

python-jsonrpc-server

A Python 2 and 3 asynchronous JSON RPC server
Python
83
star
38

conjure-java-runtime

Opinionated libraries for HTTP&JSON-based RPC using Retrofit, Feign, OkHttp as clients and Jetty/Jersey as servers
Java
78
star
39

go-baseapp

A lightweight starting point for Go web servers
Go
72
star
40

stashbot

A plugin for Atlassian Stash to allow easy, self-service continuous integration with Jenkins
Java
67
star
41

stash-codesearch-plugin

Provides global repository, commit, and file content search for Atlassian Stash instances
Java
62
star
42

gradle-processors

Gradle plugin for integrating Java annotation processors
Groovy
62
star
43

go-java-launcher

A simple Go program for launching Java programs from a fixed configuration. This program replaces Gradle-generated Bash launch scripts which are susceptible to attacks via injection of environment variables of the form JAVA_OPTS='$(rm -rf /)'.
Go
59
star
44

pkg

A collection of stand-alone Go packages
Go
53
star
45

rust-zipkin

A library for logging and propagating Zipkin trace information in Rust
Rust
53
star
46

witchcraft-go-server

A highly opinionated Go embedded application server for RESTy APIs
Go
51
star
47

grunt-tslint

A Grunt plugin for tslint.
JavaScript
51
star
48

spark-influx-sink

A Spark metrics sink that pushes to InfluxDb
Scala
51
star
49

giraffe

Gracefully Integrated Remote Access For Files and Execution
Java
49
star
50

language-servers

[Deprecated and No longer supported] A collection of implementations for the Microsoft Language Server Protocol
Java
48
star
51

go-license

Go tool that applies and verifies that proper license headers are applied to Go files
Go
47
star
52

hadoop-crypto

Library for per-file client-side encyption in Hadoop FileSystems such as HDFS or S3.
Java
41
star
53

roboslack

A pluggable, fluent, straightforward Java library for interacting with Slack.
Java
39
star
54

tritium

Tritium is a library for instrumenting applications to provide better observability at runtime
Java
39
star
55

sls-packaging

A set of Gradle plugins for creating SLS-compatible packages
Shell
38
star
56

dropwizard-web-security

A Dropwizard bundle for applying default web security functionality
Java
37
star
57

goastwriter

Go library for writing Go source code programatically
Go
34
star
58

palantir-python-sdk

Palantir Python SDK
Python
33
star
59

gradle-gitsemver

Java
31
star
60

gradle-revapi

Gradle plugin that uses Revapi to check whether you have introduced API/ABI breaks in your Java public API
Java
29
star
61

checks

Go libraries and programs for performing static checks on Go projects
Go
29
star
62

dialogue

A client-side RPC library for conjure-java
Java
29
star
63

gradle-circle-style

🚀🚀🚀MOVED TO Baseline
Java
28
star
64

conjure-java

Conjure generator for Java clients and servers
Java
27
star
65

trove

Patched version of the Trove 3 library - changes the Collections semantics to match proper java.util.Map semantics
Java
27
star
66

atlasdb

Transactional Distributed Database Layer
Java
27
star
67

stylelint-config-palantir

Palantir's stylelint config
JavaScript
25
star
68

typedjsonrpc

A typed decorator-based JSON-RPC library for Python
Python
24
star
69

distgo

Go tool for building, distributing and publishing Go projects
Go
23
star
70

encrypted-config-value

Tooling for encrypting certain configuration parameter values in dropwizard apps
Java
22
star
71

typescript-service-generator

Java
21
star
72

streams

Utilities for working with Java 8 streams
Java
21
star
73

gradle-npm-run-plugin

Groovy
20
star
74

conjure-rust

Conjure support for Rust
Rust
20
star
75

conjure-python

Conjure generator for Python clients
Java
19
star
76

amalgomate

Go tool for combining multiple different main packages into a single program or library
Go
19
star
77

serde-encrypted-value

A crate which wraps Serde deserializers and decrypts values
Rust
19
star
78

gradle-docker-test-runner

Gradle plugin for running tests in Docker environments
Groovy
19
star
79

gradle-shadow-jar

Gradle plugin to precisely shadow either a dependency or its transitives
Groovy
19
star
80

tracing-java

Java library providing zipkin-like tracing functionality
Java
18
star
81

gerrit-ci

Plugin for Gerrit enabling self-service continuous integration workflows with Jenkins.
Java
18
star
82

gpg-tap-notifier-macos

Show a macOS notification when GPG is waiting for you to tap/touch a security device (e.g. YubiKey).
Swift
18
star
83

conjure-typescript

Conjure generator for TypeScript clients
TypeScript
17
star
84

plottable-moment

Plottable date/time formatting library built on Moment.js
JavaScript
16
star
85

spark-tpcds-benchmark

Utility for benchmarking changes in Spark using TPC-DS workloads
Java
16
star
86

assertj-automation

Automatic code rewriting for AssertJ using error-prone and refaster
Java
16
star
87

metric-schema

Schema for standard metric definitions
Java
14
star
88

safe-logging

Interfaces and utilities for safe log messages
Java
14
star
89

resource-identifier

Common resource identifier specification for inter-application object sharing
Java
14
star
90

dropwizard-web-logger

WebLoggerBundle is a Dropwizard bundle used to help log web activity to log files on a server’s backend
Java
14
star
91

gradle-miniconda-plugin

Plugin that sets up a Python environment for building and running tests using Miniconda.
Java
13
star
92

human-readable-types

A collection of human-readable types
Java
12
star
93

conjure-go-runtime

Go implementation of the Conjure runtime
Go
12
star
94

gulp-count

Counts files in vinyl streams.
CoffeeScript
12
star
95

palantir-r-sdk

Palantir R SDK
R
12
star
96

go-compiles

Go check that checks that Go source and tests compiles
Go
12
star
97

go-generate

Go tool that runs and verifies the output of go generate
Go
12
star
98

asana_mailer

A script that uses Asana's RESTful API to generate plaintext and HTML emails.
Python
12
star
99

ontology-starter-react-app

Example starter repo for building React applications on top of a Foundry Ontology
TypeScript
12
star
100

eclipse-less

An Eclipse plug-in for compiling LESS files.
Java
11
star