Skip to content

Instantly share code, notes, and snippets.

@gwarser
Created March 28, 2013 21:18
Show Gist options
  • Save gwarser/5266894 to your computer and use it in GitHub Desktop.
Save gwarser/5266894 to your computer and use it in GitHub Desktop.
ZIP bruteforce extractor
import sys, os
import struct
import zlib
def zipr(file):
try:
f = open(file, 'rb')
except IOError as e:
print("IOError: {0}!".format(e))
return 1
numoffiles = 0
while True:
data = f.read(4)
if 4 != len(data):
print('Truncated file! File size: {0} bytes!'.format(f.tell()))
f.close()
return 2
lfile_hdr = struct.unpack('<L', data)[0]
if lfile_hdr != 0x04034b50 and numoffiles == 0:
print('Not zip file? Local file header found: {0:#010x}, '
'must be: 0x04034b50!'.format(lfile_hdr))
f.close()
return 3
elif lfile_hdr == 0x02014b50 and numoffiles > 0:
print('\nEnd of archive? Directory header (0x02014b50) found '
'at {size}B.\nTotal files: {nfiles}.'
''.format(nfiles=numoffiles, size=f.tell()-4))
f.close()
return 0
data = f.read(14)
if 14 != len(data):
print('Archive corupted? First part of header nr. {0} truncated. '
'Filesize: {1}.'.format(numoffiles+1, f.tell()))
f.close()
return 5
fields = struct.unpack('<2B4HL', data)
v_spec, v_sys, gen_bitf, comp_meth, modt, modd, crc32 = fields
data = f.read(12)
if 12 != len(data):
print('Archive corupted? Second part of header nr. {0} truncated. '
'Filesize: {1}.'.format(numoffiles+1, f.tell()))
f.close()
return 6
fields = struct.unpack('<2L2H', data)
comp_size, uncomp_size, filenamesize, extra_size = fields
filename = f.read(filenamesize)
if filenamesize != len(filename):
print('Filename "{0}" stripped! Expected: {1}B, get {2}B!'
''.format(filename, filenamesize, len(data)))
return 7
#utf = 1<<11
if gen_bitf & 0x800: #utf
filename = filename.decode('utf-8') + ' (UTF-8)'
else:
#must be local (for machine that compress) OEM code page, not only cp437
#import ctypes
#str(ctypes.windll.kernel32.GetOEMCP())
filename = filename.decode('ascii', 'ignore')#cut bytes > 127
numoffiles += 1
outputstr = 'FNR: {FNR:2d}, '\
'FNS: {FNS:3d}, '\
'FNM: "{FNM}",\n'\
'HDR: {HDR:08x}, '\
'VSY: {VSY:2d}, '\
'VSP: {VSP:2d}, '\
'BFD: {BFD:016b}, '\
'CPM: {CPM:016b},\n'\
'MDT: {MDT:04x}, '\
'MDD: {MDD:04x}, '\
'CRC: {CRC:08x}, '\
'CPS: {CPS:7d}B, '\
'DCS: {DCS:7d}B, '\
'ESE: {ESE:d}B'.format(
HDR=lfile_hdr,
VSY=v_sys,
VSP=v_spec,
BFD=gen_bitf,
CPM=comp_meth,
MDT=modt,
MDD=modd,
CRC=crc32,
CPS=comp_size,
DCS=uncomp_size,
FNS=filenamesize,
FNM=filename,
ESE=extra_size,
FNR=numoffiles)
print(outputstr)
f.seek(extra_size, 1)
if comp_size > 0:
curfilec = f.read(comp_size)
if len(curfilec) > 0:
try:
curfile = zlib.decompress(curfilec, -15)
except Exception as e:
print('ZLIB ERROR!', e)
input()
curcrc32 = zlib.crc32(curfile)
if curcrc32 == crc32:
print('CRC:', hex(curcrc32), 'OK!')
else:
print('CRC:', hex(curcrc32), 'MISMATCH!')
input()
try:
os.makedirs(os.path.dirname(filename))
except WindowsError:
pass
try:
f2 = open(filename, 'wb')
f2.write(curfile)
f2.close()
except:
pass
def main():
for fzip in sys.argv[1:]:
if os.path.exists(fzip):
os.chdir(os.path.dirname(os.path.abspath(fzip)))
if zipr(fzip) > 0:
input()
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
pass
except:
import traceback
print("Unhandled exception:\n")
traceback.print_exc()
input('\nPress any key...')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment