From a4bb9689fd2c74a8f5b34b5de1fb21b8f8d7cb70 Mon Sep 17 00:00:00 2001 From: Christian Kemper <96070075+ChKemper@users.noreply.github.com> Date: Sun, 13 Feb 2022 14:45:44 +0100 Subject: [PATCH] Fixes logpresso/CVE-2021-44228-Scanner#273 (#274) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Printed versions of secure versions "Copyright © 2021 Atruvia AG " --- .../com/logpresso/scanner/Configuration.java | 14 ++++- .../java/com/logpresso/scanner/Detector.java | 57 +++++++++++++++---- .../com/logpresso/scanner/ReportEntry.java | 4 ++ 3 files changed, 61 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/logpresso/scanner/Configuration.java b/src/main/java/com/logpresso/scanner/Configuration.java index 509ee98..a7e6372 100644 --- a/src/main/java/com/logpresso/scanner/Configuration.java +++ b/src/main/java/com/logpresso/scanner/Configuration.java @@ -37,6 +37,7 @@ public class Configuration { private boolean scanForLogback = false; private boolean noEmptyReport = false; private boolean oldExitCode = false; + private boolean reportSecureVersions; private Charset zipCharset = null; private String apiKey = null; @@ -147,6 +148,8 @@ public static void pringUsage() { System.out.println("\tSpecify csv log file path. If log file exists, log will be appended."); System.out.println("--json-log-path"); System.out.println("\tSpecify json log file path. If log file exists, log will be appended."); + System.out.println("--reportSecureVersions"); + System.out.println("\tReport also secure version in System.out and in report files."); System.out.println("--old-exit-code"); System.out.println("\tReturn sum of vulnerable and potentially vulnerable files as exit code."); System.out.println("--debug"); @@ -367,7 +370,10 @@ else if (!reportFile.isDirectory()) verifyArgument(args, i, "JSON Log path", "Specify JSON log output path."); c.jsonLogPath = new File(args[i + 1]); i++; - } else if (args[i].equals("--old-exit-code")) { + } else if(args[i].equals("--reportSecureVersions")) { + c.reportSecureVersions = true; + } + else if (args[i].equals("--old-exit-code")) { c.oldExitCode = true; } else if (args[i].equals("--api-key")) { verifyArgument(args, i, "API key", "Specify API key of https://watch.logpresso.com."); @@ -703,7 +709,11 @@ public boolean isOldExitCode() { return oldExitCode; } - public String getApiKey() { + public boolean isReportSecureVersions() { + return reportSecureVersions; + } + + public String getApiKey() { return apiKey; } diff --git a/src/main/java/com/logpresso/scanner/Detector.java b/src/main/java/com/logpresso/scanner/Detector.java index 731ddd0..71696b8 100644 --- a/src/main/java/com/logpresso/scanner/Detector.java +++ b/src/main/java/com/logpresso/scanner/Detector.java @@ -345,6 +345,9 @@ private DetectResult scanStream(File jarFile, ZipFileIterator it, List p else result.setVulnerable(); } + else { + printSafeLog4j2(jarFile, pathChain, log4j2Version); + } } else if (!log4j2Mitigated) { printDetectionForLog4j2(jarFile, pathChain, POTENTIALLY_VULNERABLE, false, true); result.setPotentiallyVulnerableLog4j2(); @@ -362,8 +365,12 @@ private DetectResult scanStream(File jarFile, ZipFileIterator it, List p boolean vulnerable = true; if (log4j1Version != null) { vulnerable = isVulnerableLog4j1(Version.parse(log4j1Version)); - if (vulnerable) + if (vulnerable) { printDetectionForLog4j1(jarFile, pathChain, log4j1Version, log4j1Mitigated); + } + else { + printSafeLog4j1(jarFile, pathChain, log4j1Version); + } } else { printDetectionForLog4j1(jarFile, pathChain, POTENTIALLY_VULNERABLE, log4j1Mitigated); } @@ -376,10 +383,10 @@ private DetectResult scanStream(File jarFile, ZipFileIterator it, List p } } - boolean logbackFound = isVulnerableLogback(logbackVersion, foundJndiUtil, foundEnvUtil); + boolean vulnerableLogbackFound = isVulnerableLogback(logbackVersion, foundJndiUtil, foundEnvUtil); boolean logbackMitigated = !foundJndiUtil; - if (logbackFound) { + if (vulnerableLogbackFound) { if (logbackVersion != null) { printDetectionForLogback(jarFile, pathChain, logbackVersion, logbackMitigated); } else { @@ -508,9 +515,7 @@ private boolean isVulnerableLogback(Version v) { private void printDetectionForLog4j2(File jarFile, List pathChain, String version, boolean mitigated, boolean potential) { - String path = jarFile.getAbsolutePath(); - if (pathChain != null && !pathChain.isEmpty()) - path += " (" + StringUtils.toString(pathChain) + ")"; + String path = getPath(jarFile, pathChain); String msg = potential ? "[?]" : "[*]"; @@ -539,9 +544,7 @@ else if ((v.getMinor() == 17 && v.getPatch() == 0) || (v.getMinor() == 12 && v.g } private void printDetectionForLog4j1(File jarFile, List pathChain, String version, boolean mitigated) { - String path = jarFile.getAbsolutePath(); - if (pathChain != null && !pathChain.isEmpty()) - path += " (" + StringUtils.toString(pathChain) + ")"; + String path = getPath(jarFile, pathChain); Version v = null; if (!version.equals("N/A")) @@ -567,9 +570,7 @@ else if (v.getPatch() == 18 && v.getPatch2() == 2) } private void printDetectionForLogback(File jarFile, List pathChain, String version, boolean mitigated) { - String path = jarFile.getAbsolutePath(); - if (pathChain != null && !pathChain.isEmpty()) - path += " (" + StringUtils.toString(pathChain) + ")"; + String path = getPath(jarFile, pathChain); String msg = "[?] Found CVE-2021-42550 (logback 1.2.7) vulnerability in " + path + ", logback " + version; if (mitigated) @@ -580,6 +581,29 @@ private void printDetectionForLogback(File jarFile, List pathChain, Stri addReport(jarFile, pathChain, "Logback", version, "CVE-2021-42550", mitigated, true); } + private void printSafeLog4j1(File jarFile, List pathChain, String version) { + if(config.isReportSecureVersions()) { + String path = getPath(jarFile, pathChain); + System.out.println("[-] Found safe version of 'Log4j 1' in " + path); + addSafeReport(jarFile, pathChain, "Log4j 1", version); + } + } + + private void printSafeLog4j2(File jarFile, List pathChain, String version) { + if(config.isReportSecureVersions()) { + String path = getPath(jarFile, pathChain); + System.out.println("[-] Found safe version of 'Log4j 2' in " + path); + addSafeReport(jarFile, pathChain, "Log4j 2", version); + } + } + + private String getPath(File jarFile, List pathChain) { + String path = jarFile.getAbsolutePath(); + if (pathChain != null && !pathChain.isEmpty()) + path += " (" + StringUtils.toString(pathChain) + ")"; + return path; + } + public void addErrorReport(File jarFile, String error) { errorCount++; @@ -635,4 +659,13 @@ private void reportError(File jarFile, String msg) { addErrorReport(jarFile, msg); } + private void addSafeReport(File jarFile, List pathChain, String product, String version) { + List entries = fileReports.get(jarFile); + if (entries == null) { + entries = new ArrayList(); + fileReports.put(jarFile, entries); + } + ReportEntry entry = new ReportEntry(jarFile, StringUtils.toString(pathChain), product, version); + entries.add(entry); + } } diff --git a/src/main/java/com/logpresso/scanner/ReportEntry.java b/src/main/java/com/logpresso/scanner/ReportEntry.java index 25cd4db..ada8b62 100644 --- a/src/main/java/com/logpresso/scanner/ReportEntry.java +++ b/src/main/java/com/logpresso/scanner/ReportEntry.java @@ -23,6 +23,10 @@ public ReportEntry(File path, String error) { this.error = error; } + public ReportEntry(File path, String entry, String product, String version) { + this(path, entry, product, version, null, Status.NOT_VULNERABLE); + } + public ReportEntry(File path, String entry, String product, String version, String cve, Status status) { this.path = path; this.entry = entry;