modules.packages.zip

Package modules :: Package packages :: Module zip |
[hide private]
[frames] | no frames]

# Source Code for Module modules.packages.zip

     1  # Copyright (C) 2010-2013 Claudio Guarnieri.
     2  # Copyright (C) 2014-2016 Cuckoo Foundation.
     3  # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org
     4  # See the file 'docs/LICENSE' for copying permission.
     5
     6  import os
     7  import shutil
     8  import logging
     9
    10  from zipfile import ZipFile, BadZipfile
    11
    12  from lib.common.abstracts import Package
    13  from lib.common.exceptions import CuckooPackageError
    14
    15  log = logging.getLogger(__name__)
    16
    17 -class Zip(Package):
    18      """Zip analysis package."""
    19
    20 -    def extract_zip(self, zip_path, extract_path, password):
    21          """Extracts a nested ZIP file.
    22          @param zip_path: ZIP path
    23          @param extract_path: where to extract
    24          @param password: ZIP password
    25          """
    26          # Test if zip file contains a file named as itself.
    27          if self.is_overwritten(zip_path):
    28              log.debug("ZIP file contains a file with the same name, original is going to be overwrite")
    29              # TODO: add random string.
    30              new_zip_path = zip_path + ".old"
    31              shutil.move(zip_path, new_zip_path)
    32              zip_path = new_zip_path
    33
    34          # Extraction.
    35          with ZipFile(zip_path, "r") as archive:
    36              try:
    37                  archive.extractall(path=extract_path, pwd=password)
    38              except BadZipfile:
    39                  raise CuckooPackageError("Invalid Zip file")
    40              except RuntimeError:
    41                  try:
    42                      archive.extractall(path=extract_path, pwd="infected")
    43                  except RuntimeError as e:
    44                      raise CuckooPackageError("Unable to extract Zip file: "
    45                                               "{0}".format(e))
    46              finally:
    47                  # Extract nested archives.
    48                  for name in archive.namelist():
    49                      if name.endswith(".zip"):
    50                          # Recurse.
    51                          self.extract_zip(os.path.join(extract_path, name), extract_path, password)
    52
    53 -    def is_overwritten(self, zip_path):
    54          """Checks if the ZIP file contains another file with the same name, so it is going to be overwritten.
    55          @param zip_path: zip file path
    56          @return: comparison boolean
    57          """
    58          with ZipFile(zip_path, "r") as archive:
    59              try:
    60                  # Test if zip file contains a file named as itself.
    61                  for name in archive.namelist():
    62                      if name == os.path.basename(zip_path):
    63                          return True
    64                  return False
    65              except BadZipfile:
    66                  raise CuckooPackageError("Invalid Zip file")
    67
    68 -    def get_infos(self, zip_path):
    69          """Get information from ZIP file.
    70          @param zip_path: zip file path
    71          @return: ZipInfo class
    72          """
    73          try:
    74              with ZipFile(zip_path, "r") as archive:
    75                  return archive.infolist()
    76          except BadZipfile:
    77              raise CuckooPackageError("Invalid Zip file")
    78
    79 -    def start(self, path):
    80          password = self.options.get("password")
    81
    82          zipinfos = self.get_infos(path)
    83          self.extract_zip(path, self.curdir, password)
    84
    85          file_name = self.options.get("file")
    86          # If no file name is provided via option, take the first file.
    87          if not file_name:
    88              # No name provided try to find a better name.
    89              if len(zipinfos):
    90                  # Take the first one.
    91                  file_name = zipinfos[0].filename
    92                  log.debug("Missing file option, auto executing: {0}".format(file_name))
    93              else:
    94                  raise CuckooPackageError("Empty ZIP archive")
    95
    96          file_path = os.path.join(self.curdir, file_name)
    97          return self.execute(file_path, self.options.get("arguments"))
    98