Log4j CVE-2021-44228 Detection and Mitigation

https://github.com/logpresso/CVE-2021-44228-Scanner ?

I have already developed my own analysis and even most of the scan task, but the compatibility is a major issue.

1 Like

Thanks for the info. i’m not as good at writing this stuff as you guys, so I’m wondering if you could help with building something like this due to severity of this issue…

  1. Copy the file CVE-2021-44228.txt task results from the BES folder to another location on the hard drive
  2. Edit the file to append in front and after the path\exe so that it creates a command such as this for each line that is not SCAN_COMPLETE:
    “C:\Program Files\7-Zip\7z.exe” d -tzip “C:\Program Files\Code42\lib\log4j-core-2.13.3.jar” org/apache/logging/log4j/core/lookup/JndiLookup.class
  3. rename as batch
  4. execute

Thoughts?

I’ve tested on RHEL and Linux Oracle. The variable doesn’t stick after a restart when using “export”. This supposedly gets overwritten on each restart.

Did some further digging on CentOS and found that the .bashrc file needs to be edited and adding the export LOG4J_FORMAT_MSG_NO_LOOKUPS=true and saved for it to stick on a restart. Not sure of what the different flavours are out there to edit the .bashrc file either.

If we create a script it SHOULD work. chmod 755 the file to make it executable.

#!/bin/bash

echo ‘export LOG4J_FORMAT_MSG_NO_LOOKUPS=true’ >> ~/.bashrc

1 Like

Thanks Mario , nice to be part of this group

Tested this method on RHEL and it also works well. I’d appreciate any inputs and thoughts from anyone around this.

Some feedback I got internally from someone that know Unix way better than I do :smiley:

The if { unix of operating system } section is Linux (and bash/ksh) specific, and won’t work on all platforms (e.g. AIX and Solaris). Better would be to set the variable, then export it as a separate command. The /etc/profile file is the only file which is guaranteed to be read across OSes, as /etc/profile.d is Linux specific. On the note about shells, this only works for sh (Borne shell compatible) shells – csh uses different files (though that’s pretty uncommon these days).

Finally, /etc/profile (and /etc/profile.d) only works for interactive shells, and most programs will run as system services. The approach for setting global environment variables is highly platform dependent on Unix, and even varies across Linux variants. The most portable approach is probably /etc/environment, but note that this is not a shell script, but rather a file read by libpam (pam_env.so), thus you don’t need the export command in front of it.

http://linux-pam.org/Linux-PAM-html/sag-pam_env.html
https://www.ibm.com/docs/en/aix/7.1?topic=files-environment-file

The closest equivalent on Solaris is /etc/default/init, but even this is deprecated in Solaris 11 (though I believe it is still read):

System Default Parameters - Oracle Solaris Tunable Parameters Reference Manual

The Windows setx command only exists for 2008/Vista onwards, but that shouldn’t be too much of an issue. If you really wanted to accomplish that for 2003/XP style-systems, then you could set the variables directly in the registry using the native commands in the fixlet language:

Windows Environment Variables - Windows CMD - SS64.com

2 Likes

Has anyone faced a problem when there is a CIFS share mounted?
@JasonWalker 's version skips nfs shares but we are observing high resource usage when the servers have other type of share disks with millions of files.

1 Like

These are UNIX / Linux clients mounting a CIFS share? If you have a syntax on the ‘find’ command to block traversing CIFS I’d welcome the update. The issue I face is the syntax may not be the same across all distros’ versions of ‘find’.

1 Like

Yes, these are Linux systems mounting a CIFS share(Most of them the same share but with different names).
Unfortunately, I haven’t found any working syntax for the find command to skip the scans of theses mounts.

While I’m trying to figure out a way to detect it, in a cross-platform cross-version way, it may help you if you know the expected mount paths and can customize your scan to exclude those paths specifically.

Test this on your side, but I expect the syntax will be to change the Linux scan line from

find / -not -fstype nfs -name {parameter "FilePattern"} > "{parameter "ListFile"}"

to

find / -not -fstype nfs -path "/path/to/ignore" -prune -o -name {parameter "FilePattern"} > "{parameter "ListFile"}"

You could test this in a shell, outside the ActionScript, with
find / -not -fstype nfs -path "/path/to/ignore" -prune -o -name log4j-core*.jar

Please let me know if you try that, and whether it helps.

Yes, I saw that as an option… The problem is that we don’t have the list of pathnames, they are mounted with different name variations and we have hundreds of clients doing that

2 Likes

Poll on Mitigation

As we are waiting for vendors to update their individual applications, the cyber community has coalesced on a couple of techniques that may mitigate the problem. Both of these involve modifying the Log4J JAR file. Both of these could have unintended consequences on the products using Log4J and thus come with an element of risk.

Method 1 would be to replace the JAR file entirely, with the latest log4j-2.16.0.jar. To avoid updating whatever application was using log4j, we would need for the new version of the file to retain the old version’s name. Something like
cp -y log4j-core-2.16.0.jar /opt/whatever-program/lib/log4j-2.14.0.jar

In this method, it would be much easier to track which JAR files have already been updated, because there is a single known hash for log4j-core-2.16.0.jar that all of the log4j-core should match once they are replaced.

Method 2, is to unpack the log4j-core-X.X.X.jar file and remove the affected library from the ClassPath via a command such as
zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class

Windows lacks a zip command-line utility on Windows (we could download 7-zip to do this though), but the real complexity comes in knowing which files we have already fixed. Depending on the distribution, version of zip, etc., we could end up with an unknown number of resulting hash versions, so we would need some kind of log/tracking mechanism to know which ones have been fixed already.

So, I wanted to poll the community on which, if either, mitigation you’d like to see us pursue.

  • Unpack the JAR and remove the Class
  • Replace the JAR with 2.16.0
  • Neither; I can only rely on official updates from the affected vendors.

0 voters

(Edit: re-ordered the descriptions to match the order of the poll questions)

1 Like

Apache noted this:

https://logging.apache.org/log4j/2.x/security.html

I have been working on something, will report tomorrow as going bed finally. Needs testing

Anyone found a way to determine whether the jar file is running the JndiLookup.class without having to run a script ?

Looking at command line arguments or a java process or similar ??

Need an output similar to what this command will show but using native relevance

Run below command to check whether it lists any jar files which contains vulnerable class.
find / -type f -name “*.jar” -exec sh -c “zipinfo -1 {} | grep JndiLookup.class && echo {}” ;

This won’t work. This is a per-user location, not system wide.

You don’t need to make a copy of the original txt file to do this, you can just use relevance to build the BAT file within a “create file” command.

That is definitely not intended. You want to exclude all network shares from scanning ideally.

If someone does actually want to go down this path, then it seems like this is the best way to do it on Windows/Linux: GitHub - logpresso/CVE-2021-44228-Scanner: Vulnerability scanner and mitigation patch for Log4j2 CVE-2021-44228 (from @Mario 's link above)

This is my preference, especially because we might not be done with Log4J CVEs and we might have to do this all over again with log4j-core-2.17.0.jar or similar in the future. I feel like if you already going to mess with things in weird ways, then “patching” it forward is better than removing things.

That said, using the environment variable, the logpresso scan and fix utility, and the replacing of the JAR files could all be done together. You don’t technically have to pick and choose which you do.

That said, the fix of removing the class file that the logpresso scan and fix utility does is not reversible as easily as renaming the affected JAR to something like JAR.20211215.backup and placing the new JAR in it’s place. I like the idea that just swapping out the JAR file for the fixed version is a much more easily reversible operation for either the application owner or for a bigfix operator.

The newest version of the script on github actually accounts for this now.

Oh damn, I definitely want this to be for everything, not interactive shells which are actually much less likely to be an issue. Things running as services are the most likely to be a problem. This is what I was worried about. It does seem like /etc/environment would be the right place if it exists and is used on the platform, but then annoying that other platforms have other locations.

If someone has example commands to address this for different OSes as far as setting env vars for system services, that would be extremely helpful.

CC: @QvR

1 Like

No, there is no native relevance to extract a zip file and look inside the contents. That will require an Action.

1 Like

More interested in the reporting. Based on the results from the scan you posted and the results file. Do you have a quick way to develop the action required to pipe the results of the lookup class to file ?

Can you be more specific? Not sure what an example input and desired output looks like, or which thing you are looking at.

Do you mean Jason Walker’s scan results using DIR/Find? or do you mean using the logpresso utility?

Some other feedback internally

I notice that in the scan, we are just looking at log4j-core*.jar files. I’m seeing that since the jndi class can be baked into any jar file or even jar files inside of jar files, is there a plan to expand this fixlet to do a deeper dive on all of the jar files on a system?

The scanners I have seen look to open up the jar files recursively, hash all the files inside, and match against the hashes of known vulnerable files.

1 Like