def ExtractData(self, fd, info): offset = info.header_offset fd.seek(offset) sig = struct.unpack("<H", fd.read(2))[0] if sig != 0x4B50: fd.seek(offset - 8) sig = struct.unpack("<H", fd.read(2))[0] if sig != 0x4B50: print "FU!" sys.exit(42) offset = offset - 8 fd.seek(offset + 26) file_name_len, extra_len = struct.unpack("<HH", fd.read(4)) file_name = fd.read(file_name_len) if file_name != info.filename: print "[-] there is something wrong!" return "" fd.seek(offset + 30 + file_name_len + extra_len) buf = fd.read(info.compress_size) decoder = zlib.decompressobj(-zlib.MAX_WBITS) if info.flag_bits & 0x1: # ENCRYPTED password = self.ExtractPassword(info.extra) zd = _ZipDecrypter(password) buf = ''.join(zd(c) for c in buf) buf_u = decoder.decompress(buf[0xC:]) else: buf_u = decoder.decompress(buf) return buf_u
def check_password(password, check_bytes): """Checks the password by comparing the check byte against what ZipDecrypter says it should be""" #looping through all zipped files to avoid false positives for bytes, check_byte in check_bytes: zd = zipfile._ZipDecrypter(password) h = map(zd, bytes[0:12]) if ord(h[11]) != check_byte: return False return True
def _zFile(zFile, fileName, password, info, checkByte, bytes, zef_file): try: zef_file.init() zd = _ZipDecrypter(password) h = map(zd, bytes[0:12]) if ord(h[11]) != checkByte: # error password return False fileExt = ZipExtFile(zef_file, "r", info, zd, True) fileExt.read1(1) except Exception as e: #print(e) return False return True
def try_words(without_vim_header, words_file): print('guessing passwords from [%s]' % words_file) for i, word in enumerate(open(words_file)): word = word.strip() if i % 5000 == 0: print('Testing word #%d' % i) zd = _ZipDecrypter(word) decrypted = ''.join(zd(c) for c in without_vim_header) if 'key' in decrypted: print('*' * 80) print('Found "key" with password [%s]' % word) print decrypted dec = is_ascii(decrypted) if dec and 'key' in dec: print('*' * 80) print('Found "key" in ascii decrypted with password [%s]' % word) print dec os.system('say "Found potential password %s"' % word)
def extract_archive(f, outdir="out/"): i = 0 #z = zipfile.ZipFile('launcher.zip', 'r') if not os.path.exists(outdir): os.mkdir(outdir) z = zipfile.ZipFile(f) for info in z.infolist(): passw = extract_passw(info.extra, info.filename) z.fp.seek(info.header_offset + 26) file_name_len, extra_len = struct.unpack("<HH", z.fp.read(4)) file_name = z.fp.read(file_name_len) #print file_name stfu, extra_len = struct.unpack("<HH", z.fp.read(4)) z.fp.seek(info.header_offset + 30 + file_name_len + 4 + extra_len) buf = z.fp.read(info.compress_size) zd = _ZipDecrypter(passw) buf = ''.join(zd(c) for c in buf) decoder = zlib.decompressobj(-zlib.MAX_WBITS) buf_u = decoder.decompress(buf[0x0C:]) if len(os.path.dirname(info.filename)) > 0: if not os.path.exists(outdir + os.path.dirname(info.filename)): os.makedirs(outdir + os.path.dirname(info.filename)) open(outdir + info.filename, "wb").write(buf_u)
def test_zipdecryptor_decrypt(): a, b = zipfile._ZipDecrypter("password"), ZipCrypt("password") s1 = "".join(a(ch) for ch in "foobar") s2 = "".join(b.decrypt(ch) for ch in "foobar") assert s1 == s2
for i in range(1, maxlength + 1))) def percentage_printable(text): x = 0.0 for c in text: if c in string.printable: x += 1 return x / len(text) fp = open(sys.argv[1], 'rb') print sys.argv[1] text = fp.read(12) words = open('american-english-small', 'r') # for attempt in tqdm.tqdm(bruteforce(string.ascii_letters + string.digits, 10)): for attempt in tqdm.tqdm(words): zd = _ZipDecrypter(attempt.rstrip()) fp.seek(12) res = ''.join(zd(c) for c in fp.read()) try: p = percentage_printable(res) except: p = 0 if p > 0.95: print p, repr(res), attempt exit() fp.close()
def open(self, name, mode="r", pwd=None): """Return file-like object for 'name'.""" if mode not in ("r", "U", "rU"): raise RuntimeError('open() requires mode "r", "U", or "rU"') if 'U' in mode: import warnings warnings.warn("'U' mode is deprecated", DeprecationWarning, 2) if pwd and not isinstance(pwd, bytes): raise TypeError("pwd: expected bytes, got %s" % type(pwd)) if not self.fp: raise RuntimeError( "Attempt to read ZIP archive that was already closed") # Make sure we have an info object if isinstance(name, zipfile.ZipInfo): # 'name' is already an info object zinfo = name else: # Get info object for name zinfo = self.getinfo(name) self._fileRefCnt += 1 zef_file = zipfile._SharedFile(self.fp, zinfo.header_offset, self._fpclose, self._lock) try: # Skip the file header: fheader = zef_file.read(zipfile.sizeFileHeader) if len(fheader) != zipfile.sizeFileHeader: raise zipfile.BadZipFile("Truncated file header") fheader = struct.unpack(zipfile.structFileHeader, fheader) if fheader[zipfile._FH_SIGNATURE] != zipfile.stringFileHeader: raise zipfile.BadZipFile("Bad magic number for file header") fname = zef_file.read(fheader[zipfile._FH_FILENAME_LENGTH]) if fheader[zipfile._FH_EXTRA_FIELD_LENGTH]: zef_file.read(fheader[zipfile._FH_EXTRA_FIELD_LENGTH]) if zinfo.flag_bits & 0x20: # Zip 2.7: compressed patched data raise NotImplementedError( "compressed patched data (flag bit 5)") if zinfo.flag_bits & 0x40: # strong encryption raise NotImplementedError("strong encryption (flag bit 6)") if zinfo.flag_bits & 0x800: # UTF-8 filename fname_str = fname.decode("utf-8") else: fname_str = fname.decode("cp437") fname_str = '/'.join(fname_str.split('\\')) if fname_str != zinfo.orig_filename: raise zipfile.BadZipFile( 'File name in directory %r and header %r differ.' % (zinfo.orig_filename, fname_str)) # check for encrypted flag & handle password is_encrypted = zinfo.flag_bits & 0x1 zd = None if is_encrypted: if not pwd: pwd = self.pwd if not pwd: raise RuntimeError("File %s is encrypted, password " "required for extraction" % name) zd = zipfile._ZipDecrypter(pwd) # The first 12 bytes in the cypher stream is an encryption header # used to strengthen the algorithm. The first 11 bytes are # completely random, while the 12th contains the MSB of the CRC, # or the MSB of the file time depending on the header type # and is used to check the correctness of the password. header = zef_file.read(12) h = list(map(zd, header[0:12])) if zinfo.flag_bits & 0x8: # compare against the file type from extended local headers check_byte = (zinfo._raw_time >> 8) & 0xff else: # compare against the CRC otherwise check_byte = (zinfo.CRC >> 24) & 0xff if h[11] != check_byte: raise RuntimeError("Bad password for file", name) return zipfile.ZipExtFile(zef_file, mode, zinfo, zd, True) except: zef_file.close() raise
def open(self, name, mode="r", pwd=None, *, force_zip64=False): """ Returns file-like object for 'name'. @param name is a string for the file name within the ZIP file, or a ZipInfo object. @param mode should be 'r' to read a file already in the ZIP file, or 'w' to write to a file newly added to the archive. @param pwd is the password to decrypt files (only used for reading). When writing, if the file size is not known in advance but may exceed 2 GiB, pass force_zip64 to use the ZIP64 format, which can handle large files. If the size is known in advance, it is best to pass a ZipInfo instance for name, with zinfo.file_size set. """ if mode not in {"r", "w"}: raise ValueError('open() requires mode "r" or "w"') if pwd and not isinstance(pwd, bytes): raise TypeError("pwd: expected bytes, got %s" % type(pwd).__name__) if pwd and (mode == "w"): raise ValueError("pwd is only supported for reading files") if not self.fp: raise ValueError( "Attempt to use ZIP archive that was already closed") # Make sure we have an info object if isinstance(name, ZipInfo): # 'name' is already an info object zinfo = name elif mode == 'w': zinfo = ZipInfo(name) zinfo.compress_type = self.compression else: # Get info object for name zinfo = self.getinfo(name) if mode == 'w': return self._open_to_write(zinfo, force_zip64=force_zip64) if hasattr(self, "_writing") and self._writing: raise ValueError("Can't read from the ZIP file while there " "is an open writing handle on it. " "Close the writing handle before trying to read.") # Open for reading: self._fileRefCnt += 1 if sys.version_info[:2] <= (3, 5): zef_file = _SharedFile( # pylint: disable=E1120 self.fp, zinfo.header_offset, self._fpclose, self._lock) zef_file = _SharedFile( self.fp, zinfo.header_offset, self._fpclose, self._lock, lambda: hasattr(self, "_writing") and self._writing) try: # Skip the file header: fheader = zef_file.read(sizeFileHeader) if len(fheader) != sizeFileHeader: raise BadZipFile("Truncated file header") fheader = struct.unpack(structFileHeader, fheader) if fheader[_FH_SIGNATURE] != stringFileHeader: raise BadZipFile("Bad magic number for file header") fname = zef_file.read(fheader[_FH_FILENAME_LENGTH]) if fheader[_FH_EXTRA_FIELD_LENGTH]: zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH]) if zinfo.flag_bits & 0x20: # Zip 2.7: compressed patched data raise NotImplementedError( "compressed patched data (flag bit 5)") if zinfo.flag_bits & 0x40: # strong encryption raise NotImplementedError("strong encryption (flag bit 6)") if zinfo.flag_bits & 0x800: # UTF-8 filename fname_str = fname.decode("utf-8") else: fname_str = fname.decode("cp437") if sys.platform.startswith("win"): if fname_str.replace("\\", "/") != zinfo.orig_filename.replace( "\\", "/"): raise BadZipFile( 'File name in directory %r and header %r differ.' % (zinfo.orig_filename, fname)) else: if fname_str != zinfo.orig_filename: raise BadZipFile( 'File name in directory %r and header %r differ.' % (zinfo.orig_filename, fname)) # check for encrypted flag & handle password is_encrypted = zinfo.flag_bits & 0x1 zd = None if is_encrypted: if not pwd: pwd = self.pwd if not pwd: raise RuntimeError("File %r is encrypted, password " "required for extraction" % name) zd = _ZipDecrypter(pwd) # The first 12 bytes in the cypher stream is an encryption header # used to strengthen the algorithm. The first 11 bytes are # completely random, while the 12th contains the MSB of the CRC, # or the MSB of the file time depending on the header type # and is used to check the correctness of the password. header = zef_file.read(12) h = list(map(zd, header[0:12])) if zinfo.flag_bits & 0x8: # compare against the file type from extended local headers check_byte = (zinfo._raw_time >> 8) & 0xff else: # compare against the CRC otherwise check_byte = (zinfo.CRC >> 24) & 0xff if h[11] != check_byte: raise RuntimeError("Bad password for file %r" % name) return ZipExtFile(zef_file, mode, zinfo, zd, True) except Exception: zef_file.close() raise
keylen=2**4 multiple=16 if __name__=='__main__': data=urandom(datalen) bigdata=urandom(datalen*multiple) key=urandom(keylen) assert len(data)==datalen assert len(bigdata)==datalen*multiple assert len(key)==keylen rs={} _printer=partial(printer,result=rs) # initialize crctable _ZipDecrypter(b'a')(b'b') for n in range(3): func=_ZipDecrypter(key) with Timer(name='_ZipDecrypter',printer=_printer): func(data) for n in range(5): func=C_ZipDecrypter(key) with Timer(name='C_ZipDecrypter',printer=_printer): func(bigdata) pn='_ZipDecrypter' cn='C_ZipDecrypter' pavg=sum(rs[pn])/len(rs[pn]) cavg=sum(rs[cn])/len(rs[cn])
def open(self, name, mode="r", pwd=None, *, force_zip64=False): """ Returns file-like object for 'name'. @param name is a string for the file name within the ZIP file, or a ZipInfo object. @param mode should be 'r' to read a file already in the ZIP file, or 'w' to write to a file newly added to the archive. @param pwd is the password to decrypt files (only used for reading). When writing, if the file size is not known in advance but may exceed 2 GiB, pass force_zip64 to use the ZIP64 format, which can handle large files. If the size is known in advance, it is best to pass a ZipInfo instance for name, with zinfo.file_size set. """ if mode not in {"r", "w"}: raise ValueError('open() requires mode "r" or "w"') if pwd and not isinstance(pwd, bytes): raise TypeError("pwd: expected bytes, got %s" % type(pwd).__name__) if pwd and (mode == "w"): raise ValueError("pwd is only supported for reading files") if not self.fp: raise ValueError( "Attempt to use ZIP archive that was already closed") # Make sure we have an info object if isinstance(name, ZipInfo): # 'name' is already an info object zinfo = name elif mode == 'w': zinfo = ZipInfo(name) zinfo.compress_type = self.compression else: # Get info object for name zinfo = self.getinfo(name) if mode == 'w': return self._open_to_write(zinfo, force_zip64=force_zip64) if hasattr(self, "_writing") and self._writing: raise ValueError("Can't read from the ZIP file while there " "is an open writing handle on it. " "Close the writing handle before trying to read.") # Open for reading: self._fileRefCnt += 1 if sys.version_info[:2] <= (3, 5): zef_file = _SharedFile( # pylint: disable=E1120 self.fp, zinfo.header_offset, self._fpclose, self._lock) zef_file = _SharedFile(self.fp, zinfo.header_offset, self._fpclose, self._lock, lambda: hasattr(self, "_writing") and self._writing) try: # Skip the file header: fheader = zef_file.read(sizeFileHeader) if len(fheader) != sizeFileHeader: raise BadZipFile("Truncated file header") fheader = struct.unpack(structFileHeader, fheader) if fheader[_FH_SIGNATURE] != stringFileHeader: raise BadZipFile("Bad magic number for file header") fname = zef_file.read(fheader[_FH_FILENAME_LENGTH]) if fheader[_FH_EXTRA_FIELD_LENGTH]: zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH]) if zinfo.flag_bits & 0x20: # Zip 2.7: compressed patched data raise NotImplementedError( "compressed patched data (flag bit 5)") if zinfo.flag_bits & 0x40: # strong encryption raise NotImplementedError("strong encryption (flag bit 6)") if zinfo.flag_bits & 0x800: # UTF-8 filename fname_str = fname.decode("utf-8") else: fname_str = fname.decode("cp437") if sys.platform.startswith("win"): if fname_str.replace("\\", "/") != zinfo.orig_filename.replace("\\", "/"): raise BadZipFile( 'File name in directory %r and header %r differ.' % (zinfo.orig_filename, fname)) else: if fname_str != zinfo.orig_filename: raise BadZipFile( 'File name in directory %r and header %r differ.' % (zinfo.orig_filename, fname)) # check for encrypted flag & handle password is_encrypted = zinfo.flag_bits & 0x1 zd = None if is_encrypted: if not pwd: pwd = self.pwd if not pwd: raise RuntimeError("File %r is encrypted, password " "required for extraction" % name) zd = _ZipDecrypter(pwd) # The first 12 bytes in the cypher stream is an encryption header # used to strengthen the algorithm. The first 11 bytes are # completely random, while the 12th contains the MSB of the CRC, # or the MSB of the file time depending on the header type # and is used to check the correctness of the password. header = zef_file.read(12) h = list(map(zd, header[0:12])) if zinfo.flag_bits & 0x8: # compare against the file type from extended local headers check_byte = (zinfo._raw_time >> 8) & 0xff else: # compare against the CRC otherwise check_byte = (zinfo.CRC >> 24) & 0xff if h[11] != check_byte: raise RuntimeError("Bad password for file %r" % name) return ZipExtFile(zef_file, mode, zinfo, zd, True) except Exception: zef_file.close() raise
def percentage_printable(text): x = 0.0 for c in text: if c in string.printable: x += 1 return x / len(text) fp = open(sys.argv[1], 'rb') print sys.argv[1] text = fp.read(12) words = open('american-english-small', 'r') # for attempt in tqdm.tqdm(bruteforce(string.ascii_letters + string.digits, 10)): for attempt in tqdm.tqdm(words): zd = _ZipDecrypter(attempt.rstrip()) fp.seek(12) res = ''.join(zd(c) for c in fp.read()) try: p = percentage_printable(res) except: p = 0 if p > 0.95: print p, repr(res), attempt exit() fp.close()
def test_zipdecryptor_encrypt(): a, b = zipfile._ZipDecrypter("password"), ZipCrypt("password") assert "".join(a(b.encrypt(ch)) for ch in "barfoo") == "barfoo"
def update_event(self, inp=-1): self.set_output_val(0, zipfile._ZipDecrypter(self.input(0)))
from os import urandom from zipfile import _ZipDecrypter from czipdecrypter import _ZipDecrypter as C_ZipDecrypter datalen = 2**10 keylen = 2**10 if __name__ == '__main__': data = urandom(datalen) key = urandom(keylen) assert len(data) == datalen and len(key) == keylen func = _ZipDecrypter(key) out0 = func(data[:12]) out0 += func(data[12:]) func = C_ZipDecrypter(key) out1 = func(data[:12]) out1 += func(data[12:]) print('correct' if out0 == out1 else 'wrong')