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

Source Code for Module modules.packages.zip

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