Basic Information

BUG_Author: s0l42

Affected Version: kkFileView 4.4.0

Vendor: kkFileView GitHub Repository

Software: kkFileView

Vulnerability Files:

Description: User can upload a compressed file which includes arbitrary kind of file types, when they preview the compressed file, it will be decompressed automatically without any check, so some dangerous file like .jsp .exe, etc. will be saved in the server.

CWE: CWE-434

**Attack Type:**Remote

Impact: Code Execution, Information Disclosure, Escalation of Privilege

Analysis

  1. The method unRar in CompressFileReader, do not check the files in a compressed file, just create a folder and extract the file and use BufferedOutputStream.write to write the content into disk.
public String unRar(String filePath, String filePassword, String fileName, FileAttribute fileAttribute) throws Exception {
      List<String> imgUrls = new ArrayList<>();
      String baseUrl = BaseUrlFilter.getBaseUrl();
      String packagePath = "_";
      String folderName = filePath.replace(fileDir, ""); //修复压缩包 多重目录获取路径错误
      if (fileAttribute.isCompressFile()) {
          folderName = "_decompression" + folderName;
      }
      Path folderPath = Paths.get(fileDir, folderName + packagePath);
      Files.createDirectories(folderPath);

      try (RandomAccessFile randomAccessFile = new RandomAccessFile(filePath, "r");
           IInArchive inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile))) {

          ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface();
          for (final ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) {
              if (!item.isFolder()) {
                  final Path filePathInsideArchive = getFilePathInsideArchive(item, folderPath);
                  ExtractOperationResult result = item.extractSlow(data -> {
                      try (OutputStream out = new BufferedOutputStream(new FileOutputStream(filePathInsideArchive.toFile(), true))) {
                          out.write(data);
                      } catch (IOException e) {
                          throw new RuntimeException(e);
                      }
                      return data.length;
                  }, filePassword);
                  if (result != ExtractOperationResult.OK) {
                      ExtractOperationResult result1 = ExtractOperationResult.valueOf("WRONG_PASSWORD");
                      if (result1.equals(result)) {
                          throw new Exception("Password");
                      }else {
                          throw new Exception("Failed to extract RAR file.");
                      }
                  }

                  FileType type = FileType.typeFromUrl(filePathInsideArchive.toString());
                  if (type.equals(FileType.PICTURE)) {  //图片缓存到集合,为了特殊符号需要进行编码
                      imgUrls.add(baseUrl + URLEncoder.encode(fileName + packagePath+"/"+ folderPath.relativize(filePathInsideArchive).toString().replace("\\\\", "/"), "UTF-8"));
                  }
              }
          }
          fileHandlerService.putImgCache(fileName + packagePath, imgUrls);
      } catch (Exception e) {
          throw new Exception("Error processing RAR file: " + e.getMessage(), e);
      }
      return folderName + packagePath;
  }
  1. To proof this vulnerability, we make a compressed file called ceshi.7z , we upload it to server and click the green button “预览”

image.png

  1. We could see the directory tree as follows, meanwhile, we check the directory in our server using to store files user uploaded. We find ceshi.7z_ in this directory and 1.jsp is saved successfully.

image.png

image.png

  1. By accessing the file 1.jsp, we could see this.