何かを書き留める何か

数学や読んだ本について書く何かです。最近は社会人として生き残りの術を学ぶ日々です。

パス付Zipファイルをこじ開ける

作ってみたかったので作ってみた。

"""
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は標準ライブラリが充実しているので比較的簡単だった。