Ejemplo n.º 1
0
    def extract_v1(self):
        for l in self.layout:
            if l.filename is not None:
                self.fd.seek(l.offset)
                out_filename = unique_file_name(l.filename.decode())
                with open(out_filename, 'w+b') as out_fd:
                    n, cz = 0, self.chunksize
                    while n < l.size:
                        n += cz
                        if n > l.size:
                            cz -= n - l.size
                        out_fd.write(str2bytes(self.fd.read(cz)))

                if self.password_extractor is not None:
                    if l.type == CSP_LAYOUT_PASSWORD:
                        try:
                            self.password = check_output(
                                [self.password_extractor, l.filename])
                        except CalledProcessError as e:
                            warning(str(e))

                    elif l.type == CSP_LAYOUT_APPL:
                        if self.password is None:
                            warning('Password wasn\'t extracted')
                            continue

                        app_out_filename = splitext(out_filename)[0]
                        self.decrypt_v1(out_filename, l.size, app_out_filename)
                        os.unlink(out_filename)
                        self.untar(app_out_filename,
                                   splitext(app_out_filename)[0])
Ejemplo n.º 2
0
    def extract(self):
        if not self.valid:
            return False

        for sec in self.sections:
            if sec.type in [
                    SECTION_TYPE_ARCHIVE_TBZ2,
                    SECTION_TYPE_ENCRYPTED_ARCHIVE_TBZ2
            ]:
                self.fd.seek(sec.data_offset)

                if sec.type == SECTION_TYPE_ENCRYPTED_ARCHIVE_TBZ2:
                    decryptor = AES.new(self.key, AES.MODE_CBC, sec.vector)

                out_filename = unique_file_name('{}_off{:X}.{}.tbz2'.format(
                    abspath(self.fd.path), sec.offset, sec.name))
                with open(out_filename, 'w+b') as out_fd:
                    n, cz = 0, self.chunksize
                    while n < sec.data_size:
                        n += cz
                        if n > sec.data_size:
                            cz -= n - sec.data_size
                        chunk = str2bytes(self.fd.read(cz))
                        if sec.type == SECTION_TYPE_ENCRYPTED_ARCHIVE_TBZ2:
                            chunk = decryptor.decrypt(chunk)
                        out_fd.write(chunk)

                self.untar(out_filename, splitext(out_filename)[0])

        return True
Ejemplo n.º 3
0
    def __init__(self, fd):
        super(Section, self).__init__()
        self.fd = fd
        self.offset = fd.tell()
        self.type, self.name, self.size = unpack(
            SEC_HEADER_FORMAT, str2bytes(fd.read(SEC_HEADER_SIZE)))
        self.name = self.name.decode().strip('\x00')
        self.data_offset = self.offset + SEC_HEADER_SIZE
        self.is_encryped = self.type == SECTION_TYPE_ENCRYPTED_ARCHIVE_TBZ2
        self.data_size = self.real_size = self.size

        if self.is_encryped:
            self.real_size = unpack('<Q', str2bytes(fd.read(calcsize('Q'))))[0]
            self.vector = str2bytes(fd.read(16))
            self.hash = str2bytes(fd.read(56))
            self.data_offset = fd.tell()
            self.data_size -= self.data_offset - self.offset - SEC_HEADER_SIZE

        fd.seek(self.offset + SEC_HEADER_SIZE + self.size)
Ejemplo n.º 4
0
    def __init__(self, fd, mod):
        super(CSPFile, self).__init__()
        self.fd = fd
        self.csp_header = CSPFileHeader._make(
            unpack(CSP_HEADER_FORMAT, str2bytes(fd.read(CSP_HEADER_SIZE))))
        assert self.csp_header.magic == CSP_SIGNATURE_GUID

        self.key_type = self.csp_header.flag & 0x03
        self.key_version = ((self.csp_header.flag >> 2) & 0x3F)
        self.key_version_c = bytes(str(self.key_version), 'ascii').hex()
        self.version = ((self.csp_header.flag >> 8) & 0xFF)
        self.verbose = mod.config.verbose
        self.verbose_offset = mod.HEADER_FORMAT.strip('\n') % ('', '', '')
        getattr(self, 'load_v{:d}'.format(self.version),
                self.unsupported_csp)()
Ejemplo n.º 5
0
 def decrypt_v1(self,
                in_filename,
                in_filesize,
                out_filename,
                key_length=32):
     with open(in_filename, 'rb') as in_file, open(out_filename,
                                                   'wb') as out_file:
         salt = in_file.read(AES.block_size)[len('Salted__'):]
         key, iv = self.derive_key_and_iv(self.password, salt, key_length,
                                          AES.block_size)
         cipher = AES.new(key, AES.MODE_CBC, iv)
         n, cz = 0, self.chunksize
         while n < in_filesize:
             n += cz
             if n > in_filesize:
                 cz -= n - in_filesize
             chunk = str2bytes(in_file.read(cz))
             chunk = cipher.decrypt(chunk)
             out_file.write(chunk)
Ejemplo n.º 6
0
    def __init__(self, fd):
        super(PKGFile, self).__init__()
        self.fd = fd
        magic, self.version, self.num_sections, self.type, _ = unpack(
            PKG_HEADER_FORMAT, str2bytes(fd.read(PKG_HEADER_SIZE)))
        assert magic == MAGIC_NUMBER

        self.sections = list(Section(fd) for _ in range(self.num_sections))
        if self.type in [
                ENCRYPTED_CONTENT_CHECKSUM_PKG_TYPE,
                ENCRYPTED_CONTENT_SIGNED_CHECKSUM_PKG_TYPE
        ]:
            for sec in self.sections:
                if sec.type == SECTION_TYPE_KEY:
                    decryptor = AES.new(ON_BOX_ENC_KEY, AES.MODE_CBC,
                                        '\x00' * 16)
                    self.key = decryptor.decrypt(sec.value)
                    break
            self.valid = self.key is not None
Ejemplo n.º 7
0
    def load_v1(self):
        v1_header = CSPv1Header._make(
            unpack(CSPv1_HEADER_FORMAT,
                   str2bytes(self.fd.read(CSPv1_HEADER_SIZE))))
        self.size = CSP_HEADER_SIZE + CSPv1_HEADER_SIZE + v1_header.password_len + \
         v1_header.appl_name_len + v1_header.metadata_len + v1_header.sign_len + \
         v1_header.appl_len + v1_header.sign_len

        self.layout = [
            Layout(self.fd, CSP_LAYOUT_PASSWORD, v1_header.password_len),
            Layout(self.fd, CSP_LAYOUT_APPL_NAME, v1_header.appl_name_len),
            Layout(self.fd, CSP_LAYOUT_METADATA, v1_header.metadata_len),
            Layout(self.fd, CSP_LAYOUT_METADATA_SIGN, v1_header.sign_len),
            Layout(self.fd, CSP_LAYOUT_APPL, v1_header.appl_len),
            Layout(self.fd, CSP_LAYOUT_SIGNATURE_ENVELOPE, v1_header.sign_len)
        ]

        filename = v1_header.filename.strip(b'\x00')
        metadata_filename, appl_filename = next(
            filter(lambda l: l.type == CSP_LAYOUT_APPL_NAME,
                   self.layout)).value.split()

        layout_filenames = {
            CSP_LAYOUT_PASSWORD: filename + b'.pwd',
            CSP_LAYOUT_METADATA: metadata_filename,
            CSP_LAYOUT_METADATA_SIGN: metadata_filename + b'.sig',
            CSP_LAYOUT_APPL: appl_filename + b'.enc',
            CSP_LAYOUT_SIGNATURE_ENVELOPE: filename + b'.sig'
        }

        for l in self.layout:
            l.filename = layout_filenames.get(l.type, None)

        self.password_extractor = join(dirname(__file__),
                                       ZL_CSP_v1_PWD_EXTRACTOR)
        if not isfile(self.password_extractor):
            warning('Invalid password extractor ({})'.format(
                self.password_extractor))
            self.password_extractor = None
Ejemplo n.º 8
0
 def value(self):
     self.fd.seek(self.offset)
     return str2bytes(self.fd.read(self.size))
Ejemplo n.º 9
0
 def value(self):
     self.fd.seek(self.data_offset)
     return str2bytes(
         self.fd.read(self.data_size if self.is_encryped else self.size))