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