作ってみたかったので作ってみた。
""" openzip2: パスワード付zipファイルを総当りでこじ開けるスクリプト 使い方:python openzip.py zipfile.zip strset passlength zipfile.zip : こじ開けたいzipファイル strset : 対象文字列 小文字・大文字・数字・記号 をバイナリで指定 例えば小文字、数字で検索するならば 1010 と与える passlength : パスワードの文字数 """ import zipfile import os import sys import itertools # 文字列の定義 small = "".join([chr(x) for x in range(ord('a'), ord('z')+1)]) large = "".join([chr(x) for x in range(ord('A'), ord('Z')+1)]) number = "".join([str(x) for x in range(10)]) other = r"~@#$%^&*()_+-=[]{},.\"/?:;`" if len(sys.argv)== 4 and os.path.isfile(sys.argv[1]): dest = os.path.splitext(sys.argv[1])[0] zf = zipfile.ZipFile(sys.argv[1], mode = 'r') try: #パスワードが掛かってない場合 zf.extractall(dest) print('Completed') zf.close() sys.exit(0) #解凍して終了 # パスワードが掛かっている場合 except RuntimeError: targetlen = "".join([strset*bit for (strset, bit) in zip([small,large,number,other], [int(x) for x in sys.argv[2]])]) for (index,challenge) in enumerate( itertools.product(targetlen,repeat=int(sys.argv[3]))): try: inputpwd = "".join(challenge).encode() zf.extractall(dest, pwd = inputpwd) # 失敗するとRunTimeErrorが発生する print('Completed') print('Pass: '+"".join(challenge)) zf.close() break except KeyboardInterrupt: # Ctrl-C print('KeyboardInterrupt') zf.close() sys.exit(-1) except: if index % 1000 == 0: print("".join(challenge)) continue else: #見つからなければ終了 print('Failer...') zf.close() else: #引数が間違っていればこちらへ print('Usage: python openzip.py zipfile.zip strset passlength') print('example: python openzip.py zipfile.zip 1100 4')
動さは遅いがプログラム自体はPythonは標準ライブラリが充実しているので比較的簡単だった。