Skip to content

Commit

Permalink
Added --restore option. v2.5.0
Browse files Browse the repository at this point in the history
  • Loading branch information
xeraph committed Dec 21, 2021
1 parent 9052bed commit cd56bce
Show file tree
Hide file tree
Showing 7 changed files with 259 additions and 55 deletions.
31 changes: 20 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
log4j2-scan is a single binary command-line tool for CVE-2021-44228 vulnerability scanning and mitigation patch. It also supports nested JAR file scanning and patch. It also detects CVE-2021-45046 (log4j 2.15.0), CVE-2021-45105 (log4j 2.16.0), CVE-2021-4104 (log4j 1.x), and CVE-2021-42550 (logback 0.9-1.2.7) vulnerabilities.

### Download
* [log4j2-scan 2.4.2 (Windows x64, 7z)](https://github.com/logpresso/CVE-2021-44228-Scanner/releases/download/v2.4.2/logpresso-log4j2-scan-2.4.2-win64.7z)
* [log4j2-scan 2.4.2 (Windows x64, zip)](https://github.com/logpresso/CVE-2021-44228-Scanner/releases/download/v2.4.2/logpresso-log4j2-scan-2.4.2-win64.zip)
* [log4j2-scan 2.5.0 (Windows x64, 7z)](https://github.com/logpresso/CVE-2021-44228-Scanner/releases/download/v2.5.0/logpresso-log4j2-scan-2.5.0-win64.7z)
* [log4j2-scan 2.5.0 (Windows x64, zip)](https://github.com/logpresso/CVE-2021-44228-Scanner/releases/download/v2.5.0/logpresso-log4j2-scan-2.5.0-win64.zip)
* If you get `VCRUNTIME140.dll not found` error, install [Visual C++ Redistributable](https://docs.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist?view=msvc-170).
* If native executable doesn't work, use the JAR instead. 32bit is not supported.
* 7zip is available from www.7zip.org, and is open source and free.
* [log4j2-scan 2.4.2 (Linux x64)](https://github.com/logpresso/CVE-2021-44228-Scanner/releases/download/v2.4.2/logpresso-log4j2-scan-2.4.2-linux.tar.gz)
* [log4j2-scan 2.4.2 (Linux aarch64)](https://github.com/logpresso/CVE-2021-44228-Scanner/releases/download/v2.4.2/logpresso-log4j2-scan-2.4.2-linux-aarch64.tar.gz)
* [log4j2-scan 2.5.0 (Linux x64)](https://github.com/logpresso/CVE-2021-44228-Scanner/releases/download/v2.5.0/logpresso-log4j2-scan-2.5.0-linux.tar.gz)
* [log4j2-scan 2.5.0 (Linux aarch64)](https://github.com/logpresso/CVE-2021-44228-Scanner/releases/download/v2.5.0/logpresso-log4j2-scan-2.5.0-linux-aarch64.tar.gz)
* If native executable doesn't work, use the JAR instead. 32bit is not supported.
* [log4j2-scan 2.4.2 (Mac OS)](https://github.com/logpresso/CVE-2021-44228-Scanner/releases/download/v2.4.2/logpresso-log4j2-scan-2.4.2-darwin.tar.gz)
* [log4j2-scan 2.4.2 (Any OS, 20KB)](https://github.com/logpresso/CVE-2021-44228-Scanner/releases/download/v2.4.2/logpresso-log4j2-scan-2.4.2.jar)
* [log4j2-scan 2.5.0 (Mac OS)](https://github.com/logpresso/CVE-2021-44228-Scanner/releases/download/v2.5.0/logpresso-log4j2-scan-2.5.0-darwin.tar.gz)
* [log4j2-scan 2.5.0 (Any OS, 20KB)](https://github.com/logpresso/CVE-2021-44228-Scanner/releases/download/v2.5.0/logpresso-log4j2-scan-2.5.0.jar)

### Build
* [How to build Native Image](https://github.com/logpresso/CVE-2021-44228-Scanner/wiki/FAQ#how-to-build-native-image)
Expand All @@ -22,7 +22,7 @@ Just run log4j2-scan.exe or log4j2-scan with target directory path. The logpress

Usage
```
Logpresso CVE-2021-44228 Vulnerability Scanner 2.4.2 (2021-12-21)
Logpresso CVE-2021-44228 Vulnerability Scanner 2.5.0 (2021-12-21)
Usage: log4j2-scan [--scan-log4j1] [--fix] target_path1 target_path2
-f [config_file_path]
Expand All @@ -41,20 +41,26 @@ Usage: log4j2-scan [--scan-log4j1] [--fix] target_path1 target_path2
With --scan-log4j1 option, it also removes JMSAppender.class, SocketServer.class, SMTPAppender.class, SMTPAppender$1.class
--force-fix
Do not prompt confirmation. Don't use this option unless you know what you are doing.
--restore [backup_file_path]
Unfix JAR files using zip archived file.
--all-drives
Scan all drives on Windows
--drives c,d
Scan specified drives on Windows. Spaces are not allowed here.
--no-symlink
Do not detect symlink as vulnerable file.
--exclude [path_prefix]
Full paths of directories whose absolute path starts with the specified value will be excluded. Does not support relative paths. You can specify multiple --exclude [path_prefix] pairs
Full paths of directories whose absolute path starts with the specified value will be excluded.
Does not support relative paths. You can specify multiple --exclude [path_prefix] pairs
--exclude-config [config_file_path]
Specify exclude path list in text file. Paths should be separated by new line. Prepend # for comment.
--exclude-pattern [pattern]
Exclude specified paths of directories by pattern. Supports fragments. You can specify multiple --exclude-pattern [pattern] pairs (non regex)
Exclude specified paths of directories by pattern. Supports fragments.
You can specify multiple --exclude-pattern [pattern] pairs (non regex)
--exclude-fs nfs,tmpfs
Exclude paths by file system type. nfs, nfs3, nfs4, cifs, tmpfs, devtmpfs, fuse.sshfs and iso9660 is ignored by default.
--syslog-udp [host:port]
Send alert to remote syslog host for vulnerable or potentially vulnerable binaries
--report-csv
Generate log4j2_scan_report_yyyyMMdd_HHmmss.csv in working directory if not specified otherwise via --report-path [path]
--report-json
Expand Down Expand Up @@ -87,10 +93,12 @@ On Linux
```
On UNIX (AIX, Solaris, and so on)
```
java -jar logpresso-log4j2-scan-2.4.2.jar [--fix] target_path
java -jar logpresso-log4j2-scan-2.5.0.jar [--fix] target_path
```

If you add `--fix` option, this program will copy vulnerable original JAR file to .bak file, and create new JAR file without `org/apache/logging/log4j/core/lookup/JndiLookup.class` entry. In most environments, JNDI lookup feature will not be used. However, you must use this option at your own risk. Depending the Operating System:
If you add `--fix` option, this program will copy vulnerable original JAR file to .bak file, and create new JAR file without `org/apache/logging/log4j/core/lookup/JndiLookup.class` entry. All .bak files are archived into the single zip file which is named by `log4j2_scan_backup_yyyyMMdd_HHmmss.zip`, then deleted safely. In most environments, JNDI lookup feature will not be used. However, you must use this option at your own risk. You can easily restore original vulnerable JAR files using `--restore` option.

Depending the Operating System:

- Windows: It is necessary to shutdown any running JVM process before applying patch due to lock files. Start affected JVM process after fix.
- Linux/macOS: Apply patch, restart the JVM after
Expand Down Expand Up @@ -127,6 +135,7 @@ Run in 5 steps:
4. Compare log4j2 version and print vulnerable version.
5. If --fix option is used, backup vulnerable file and patch it.
* For example, original vulnerable.jar is copied to vulnerable.jar.bak
6. Archive all backup files into the zip file `log4j2_scan_backup_yyyyMMdd_HHmmss.zip`, then delete .bak files.

### Exit code for automation
* -1 failed to run
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.logpresso</groupId>
<artifactId>log4j2-scanner</artifactId>
<version>2.4.3</version>
<version>2.5.0</version>
<packaging>jar</packaging>
<name>Logpresso Log4j2 Scanner</name>

Expand Down
76 changes: 72 additions & 4 deletions src/main/java/com/logpresso/scanner/Configuration.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public class Configuration {
private boolean oldExitCode = false;
private Charset zipCharset = null;

private File backupPath = null;
private String reportPath = null;
private String reportDir = null;
private InetSocketAddress udpSyslogAddr = null;
Expand Down Expand Up @@ -67,20 +68,23 @@ public static void pringUsage() {
"\tWith --scan-log4j1 option, it also removes JMSAppender.class, SocketServer.class, SMTPAppender.class, SMTPAppender$1.class");
System.out.println("--force-fix");
System.out.println("\tDo not prompt confirmation. Don't use this option unless you know what you are doing.");
System.out.println("--restore [backup_file_path]");
System.out.println("\tUnfix JAR files using zip archived file.");
System.out.println("--all-drives");
System.out.println("\tScan all drives on Windows");
System.out.println("--drives c,d");
System.out.println("\tScan specified drives on Windows. Spaces are not allowed here.");
System.out.println("--no-symlink");
System.out.println("\tDo not detect symlink as vulnerable file.");
System.out.println("--exclude [path_prefix]");
System.out.println("\tFull paths of directories whose absolute path starts with the specified value will be excluded. Does not support relative paths. You can specify multiple --exclude [path_prefix] pairs");
System.out.println("\tFull paths of directories whose absolute path starts with the specified value will be excluded.\n"
+ "\tDoes not support relative paths. You can specify multiple --exclude [path_prefix] pairs");
System.out.println("--exclude-config [config_file_path]");
System.out.println(
"\tSpecify exclude path list in text file. Paths should be separated by new line. Prepend # for comment.");
System.out.println("--exclude-pattern [pattern]");
System.out.println(
"\tExclude specified paths of directories by pattern. Supports fragments. You can specify multiple --exclude-pattern [pattern] pairs (non regex)");
System.out.println("\tExclude specified paths of directories by pattern. Supports fragments.\n"
+ "\tYou can specify multiple --exclude-pattern [pattern] pairs (non regex)");
System.out.println("--exclude-fs nfs,tmpfs");
System.out.println(
"\tExclude paths by file system type. nfs, nfs3, nfs4, cifs, tmpfs, devtmpfs, fuse.sshfs and iso9660 is ignored by default.");
Expand Down Expand Up @@ -120,6 +124,16 @@ public static Configuration parseArguments(String[] args) throws Exception {
} else if (args[i].equals("--force-fix")) {
c.fix = true;
c.force = true;
} else if (args[i].equals("--restore")) {
verifyArgument(args, i, "Backup file path", "Specify backup file path.");
c.backupPath = new File(args[i + 1]);
if (!c.backupPath.exists())
throw new IllegalArgumentException("Backup file not found: " + c.backupPath.getAbsolutePath());

if (!c.backupPath.getName().toLowerCase().endsWith(".zip"))
throw new IllegalArgumentException("Backup file should be zip format: " + c.backupPath.getAbsolutePath());

i++;
} else if (args[i].equals("--debug")) {
c.debug = true;
} else if (args[i].equals("--trace")) {
Expand Down Expand Up @@ -300,7 +314,8 @@ else if (!reportFile.isDirectory())
if (c.allDrives && !c.driveLetters.isEmpty())
throw new IllegalArgumentException("Cannot specify both --all-drives and --drives options.");

if (!c.allDrives && c.driveLetters.isEmpty() && c.includeFilePath == null && c.targetPaths.isEmpty())
if (!c.allDrives && c.driveLetters.isEmpty() && c.includeFilePath == null && c.targetPaths.isEmpty()
&& c.getBackupPath() == null)
throw new IllegalArgumentException("Specify scan target path.");

if (c.includeFilePath != null && c.allDrives)
Expand All @@ -309,9 +324,58 @@ else if (!reportFile.isDirectory())
if (c.includeFilePath != null && !c.driveLetters.isEmpty())
throw new IllegalArgumentException("Cannot specify both --drives and -f options.");

if (c.getBackupPath() != null) {
// cannot use any other options
rejectInvalidOptionForRestore(c);
}

return c;
}

private static void rejectInvalidOptionForRestore(Configuration c) {
if (!c.targetPaths.isEmpty())
throw new IllegalArgumentException("Cannot specify scan target path with --restore option.");

if (c.getIncludeFilePath() != null)
throw new IllegalArgumentException("Cannot use --restore option with -f option.");

if (c.isScanZip())
throw new IllegalArgumentException("Cannot use --restore option with --scan-zip option.");

if (c.isScanForLog4j1())
throw new IllegalArgumentException("Cannot use --restore option with --scan-log4j1 option.");

if (c.isScanForLogback())
throw new IllegalArgumentException("Cannot use --restore option with --scan-logback option.");

if (c.isFix())
throw new IllegalArgumentException("Cannot use --restore option with --fix option.");

if (c.isForce())
throw new IllegalArgumentException("Cannot use --restore option with --force-fix option.");

if (c.isAllDrives())
throw new IllegalArgumentException("Cannot use --restore option with --all-drives option.");

if (!c.getDriveLetters().isEmpty())
throw new IllegalArgumentException("Cannot use --restore option with --drives option.");

if (c.isReportCsv())
throw new IllegalArgumentException("Cannot use --restore option with --report-csv option.");

if (c.isReportJson())
throw new IllegalArgumentException("Cannot use --restore option with --report-json option.");

if (c.getReportDir() != null)
throw new IllegalArgumentException("Cannot use --restore option with --report-dir option.");

if (c.getReportPath() != null)
throw new IllegalArgumentException("Cannot use --restore option with --report-path option.");

if (c.getUdpSyslogAddr() != null)
throw new IllegalArgumentException("Cannot use --restore option with --syslog-udp option.");
}

private static InetSocketAddress parseAddress(String s) {
int portNum = 514;
int p = s.indexOf(':');
Expand Down Expand Up @@ -467,6 +531,10 @@ public boolean isOldExitCode() {
return oldExitCode;
}

public File getBackupPath() {
return backupPath;
}

public String getReportPath() {
return reportPath;
}
Expand Down
Loading

0 comments on commit cd56bce

Please sign in to comment.