# Copyright (C) 2010-2012 Cuckoo Sandbox Developers. # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org # See the file 'docs/LICENSE' for copying permission. import os import sys import string import logging import hashlib import binascii from datetime import datetime try: import magic except ImportError: pass try: import pydeep HAVE_SSDEEP = True except ImportError: HAVE_SSDEEP = False from lib.cuckoo.common.exceptions import CuckooOperationalError def create_folders(root=".", folders=[]): """Create directories. @param root: root path. @param folders: folders list to be created. @raise CuckooOperationalError: if fails to create folder. """ for folder in folders: if os.path.exists(os.path.join(root, folder)): continue else: create_folder(root, folder) def create_folder(root=".", folder=None): """Create directory. @param root: root path. @param folder: folder name to be created. @raise CuckooOperationalError: if fails to create folder. """ if not os.path.exists(os.path.join(root, folder)) and folder: try: folder_path = os.path.join(root, folder) os.makedirs(folder_path) except OSError as e: raise CuckooOperationalError("Unable to create folder: %s" % folder_path) def convert_char(c): """Escapes characters. @param c: dirty char. @return: sanitized char. """ if c in string.ascii_letters or \ c in string.digits or \ c in string.punctuation or \ c in string.whitespace: return c else: return r'\x%02x' % ord(c) def convert_to_printable(s): """Convert char to printable. @param s: string. @return: sanitized string. """ return ''.join([convert_char(c) for c in s]) def datetime_to_iso(timestamp): """Parse a datatime string and returns a datetime in iso format. @param timestamp: timestamp string @return: ISO datetime """ return datetime.strptime(timestamp, '%Y-%m-%d %H:%M:%S').isoformat() class File: """Basic file object class with all useful utilities.""" def __init__(self, file_path, strip_name=False): """@param file_path: file path.""" self.file_path = file_path self.file_data = open(self.file_path, "rb").read() self.strip_name = strip_name def get_name(self): """Get file name. @return: file name. """ if self.strip_name: file_name = os.path.basename(self.file_path.rstrip(".bin")) else: file_name = os.path.basename(self.file_path) return convert_to_printable(file_name) def get_data(self): """Read file contents. @return: data. """ return self.file_data def get_size(self): """Get file size. @return: file size. """ return os.path.getsize(self.file_path) def get_crc32(self): """Get CRC32. @return: CRC32. """ res = '' crc = binascii.crc32(self.file_data) for i in range(4): t = crc & 0xFF crc >>= 8 res = '%02X%s' % (t, res) return res def get_md5(self): """Get MD5. @return: MD5. """ return hashlib.md5(self.file_data).hexdigest() def get_sha1(self): """Get SHA1. @return: SHA1. """ return hashlib.sha1(self.file_data).hexdigest() def get_sha256(self): """Get SHA256. @return: SHA256. """ return hashlib.sha256(self.file_data).hexdigest() def get_sha512(self): """ Get SHA512. @return: SHA512. """ return hashlib.sha512(self.file_data).hexdigest() def get_ssdeep(self): """Get SSDEEP. @return: SSDEEP. """ if not HAVE_SSDEEP: return None try: return pydeep.hash_file(self.file_path) except Exception: return None def get_type(self): """Get MIME file type. @return: file type. """ try: ms = magic.open(magic.MAGIC_NONE) ms.load() file_type = ms.buffer(self.file_data) except: try: file_type = magic.from_buffer(self.file_data) except: try: import subprocess file_process = subprocess.Popen(['file', '-b', self.file_path], stdout = subprocess.PIPE) file_type = file_process.stdout.read().strip() except: return None return file_type def get_all(self): """Get all information available. @return: information dict. """ infos = {} infos["name"] = self.get_name() infos["size"] = self.get_size() infos["crc32"] = self.get_crc32() infos["md5"] = self.get_md5() infos["sha1"] = self.get_sha1() infos["sha256"] = self.get_sha256() infos["sha512"] = self.get_sha512() infos["ssdeep"] = self.get_ssdeep() infos["type"] = self.get_type() return infos .