CVE-2022-21675 (published 2022-01-12T19:15Z)

Bytecode Viewer (BCV) is a Java/Android reverse engineering suite. Versions of the package prior to 2.11.0 are vulnerable to Arbitrary File Write via Archive Extraction (AKA "Zip Slip"). The vulnerability is exploited using a specially crafted archive that holds directory traversal filenames (e.g. ../../evil.exe). The Zip Slip vulnerability can affect numerous archive formats, including zip, jar, tar, war, cpio, apk, rar and 7z. The attacker can then overwrite executable files and either invoke them remotely or wait for the system or user to call them, thus achieving remote command execution on the victim’s machine. The impact of a Zip Slip vulnerability would allow an attacker to create or overwrite existing files on the filesystem. In the context of a web application, a web shell could be placed within the application directory to achieve code execution. All users should upgrade to BCV v2.11.0 when possible to receive a patch. There are no recommended workarounds aside from upgrading.

Severity: MEDIUM
CVSS v2 base score: 6.8 (AV:N/AC:M/Au:N/C:P/I:P/A:P)
CVSS v3 base score: 7.8, HIGH (CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-22
cwe_name: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
description: The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.
extended_description: 
            Many file operations are intended to take place within a restricted directory. By using special elements such as ".." and "/" separators, attackers can escape outside of the restricted location to access files or directories that are elsewhere on the system. One of the most common special elements is the "../" sequence, which in most modern operating systems is interpreted as the parent directory of the current location. This is referred to as relative path traversal. Path traversal also covers the use of absolute pathnames such as "/usr/local/bin" to access unexpected files. This is referred to as absolute path traversal.
         
         

Fix information:
repo_url: https://github.com/Konloch/bytecode-viewer
commit_details: repo_url: https://github.com/Konloch/bytecode-viewer
author: Nico Mexis
author_date: 2022-01-07 21:37:24+01:00
msg: Mitigate Zip Slip exlpoit
repository: repo_url: https://github.com/Konloch/bytecode-viewer
repo_name: Konloch/bytecode-viewer
description: A Java 8+ Jar & Android APK Reverse Engineering Suite (Decompiler, Editor, Debugger & More)
repo_language: Java
owner: Konloch
file_changes: filename: ZipUtils.java
change_type: ModificationType.MODIFY
diff: @@ -35,6 +35,7 @@ import java.util.zip.ZipOutputStream;
  */
 public final class ZipUtils {
 
+    // TODO: Maybe migrate to org.apache.commons.compress.archivers.examples.Expander?
     /**
      * Unzip files to path.
      *
@@ -67,6 +68,11 @@ public final class ZipUtils {
                 String fileName = destinationDir + File.separator + entry.getName();
                 File f = new File(fileName);
 
+                if (!f.getCanonicalPath().startsWith(destinationDir)) {
+                    System.out.println("Zip Slip exploit detected. Skipping entry " + entry.getName());
+                    continue;
+                }
+
                 File parent = f.getParentFile();
                 if (!parent.exists()) {
                     parent.mkdirs();
@@ -106,7 +112,7 @@ public final class ZipUtils {
 
     public static void zipFolder(String srcFolder, String destZipFile, String ignore) throws Exception {
         try (FileOutputStream fileWriter = new FileOutputStream(destZipFile);
-             ZipOutputStream zip = new ZipOutputStream(fileWriter)){
+             ZipOutputStream zip = new ZipOutputStream(fileWriter)) {
             addFolderToZip("", srcFolder, zip, ignore);
             zip.flush();
         }
@@ -114,7 +120,7 @@ public final class ZipUtils {
 
     public static void zipFolderAPKTool(String srcFolder, String destZipFile) throws Exception {
         try (FileOutputStream fileWriter = new FileOutputStream(destZipFile);
-             ZipOutputStream zip = new ZipOutputStream(fileWriter)){
+             ZipOutputStream zip = new ZipOutputStream(fileWriter)) {
             addFolderToZipAPKTool("", srcFolder, zip);
             zip.flush();
         }
@@ -199,4 +205,4 @@ public final class ZipUtils {
             }
         }
     }
-}
\ No newline at end of file
+}

programming_language: Java
repo_url: https://github.com/Konloch/bytecode-viewer
commit_details: repo_url: https://github.com/Konloch/bytecode-viewer
author: Nico Mexis
author_date: 2022-01-07 21:52:01+01:00
msg: Improve Zip Slip detection
repository: repo_url: https://github.com/Konloch/bytecode-viewer
repo_name: Konloch/bytecode-viewer
description: A Java 8+ Jar & Android APK Reverse Engineering Suite (Decompiler, Editor, Debugger & More)
repo_language: Java
owner: Konloch
file_changes: filename: ZipUtils.java
change_type: ModificationType.MODIFY
diff: @@ -44,6 +44,11 @@ public final class ZipUtils {
      * @throws IOException Signals that an I/O exception has occurred.
      */
     public static void unzipFilesToPath(String jarPath, String destinationDir) throws IOException {
+        String canonicalDestDir = new File(destinationDir).getCanonicalPath();
+        if (!canonicalDestDir.endsWith(File.separator)) {
+            canonicalDestDir += File.separator;
+        }
+
         File file = new File(jarPath);
         try (JarFile jar = new JarFile(file)) {
 
@@ -68,7 +73,7 @@ public final class ZipUtils {
                 String fileName = destinationDir + File.separator + entry.getName();
                 File f = new File(fileName);
 
-                if (!f.getCanonicalPath().startsWith(destinationDir)) {
+                if (!f.getCanonicalPath().startsWith(canonicalDestDir)) {
                     System.out.println("Zip Slip exploit detected. Skipping entry " + entry.getName());
                     continue;
                 }

programming_language: Java