1. ホーム
  2. スクリプト・コラム
  3. パイソン

Pythonを使って簡単なzipファイルの解凍パスワードを手作業で解く

2022-01-02 17:19:41

はじめに

使用するコアモジュールは、python標準ライブラリのzipfileモジュールです。このモジュールは zip ファイルに関する様々な関数を実装することができ、その内容は公式のリファレンスドキュメントに記載されています。ここでいうブルートフォースクラッキングとは、パスワードの並びうる値の中から一つずつパスワードを試していくことで、人間には難しいがコンピュータには不可能である。私たちは、解凍するためにパスワードを必要とするZIPファイルをダウンロードすることがありますが、それは私たちが知らないものであり、知るためにお金を払う必要があります。そこで、暴力的なクラッキングのためのパスワードの2つの主要な種類を紹介します:純粋な数字パスワードと英数字の組み合わせパスワードです。

ファイルの作成

最初のテストファイルはtest.txt(1行のテキストのみ含む)、圧縮ファイルはtest.zip、圧縮パスワードは2340、ディレクトリ内のtxtファイルを削除するために圧縮します。

上の画像では、従来の暗号化にチェックが入っていることに注意してください。

純粋数値暗号

とは、0 から始まらない数字のパスワードを指す。 0 の後に続く文字の組み合わせを参照。原理は、zipfile モジュールが圧縮ファイルを展開するとき、パスワードが不正になるとプログラムが終了し、try 文の中で展開に成功したパスワードだけが、extract 関数が続く文を呼び出すまで実行されることになる。

コード

import zipfile
import time
import threading
startTime = time.time()
# Determine if the thread needs to be terminated
flag = True
 
 
def extract(password, file):
    try:
        password = str(password)
        file.extractall(path='.' , pwd=password.encode('utf-8'))
        print("the password is {}".format(password))
        nowTime = time.time()
        print("send time is {}".format(nowTime - startTime))
        global flag
        # Successfully decompress the rest of the threads to terminate
        flag = False
    except Exception as e:
        print(e)
 
 
def do_main():
    zfile = zipfile.ZipFile("test.zip", 'r')
    # Start trying
    for number in range(1, 9999):
        if flag is True:
            t = threading.Thread(target=extract, args=(number, zfile))
            t.start()
            t.join()
 
 
if __name__ == '__main__':
    do_main()

明らかに解凍は成功しました。ここで重要なのは、このエンコーディングパスワードは従来のZIP暗号化に対してのみ有効で、winrarには新しいタイプのデフォルトの暗号化があることです。

英数字混じりのパスワード

この場合、パスワードの組み合わせが多すぎるため、メモリのオーバーフローを防ぐために、代わりにイテレータが使用されます。このケースは時間がかかるので、暇なときにスクリプトにぶら下げることができる。ここでは、ファイルは再び圧縮され、パスワードはpythonです。

import zipfile
import random
import time
import sys
 
 
class MyIterator():
    # The set of unit characters
    letters = 'abcdefghijklmnopqrstuvwxyz012345678'
    min_digits = 0
    max_digits = 0
 
    def __init__(self, min_digits, max_digits):
        # instantiate the object with a range of password digits, typically 4 to 10 digits
        if min_digits < max_digits:
            self.min_digits = min_digits
            self.max_digits = max_digits
        else:
            self.min_digits = max_digits
            self.max_digits = min_digits
 
    # Iterator access definition
    def __iter__(self):
        return self
 
    def __next__(self):
        rst = str()
        for item in range(0, random.randrange(self.min_digits, self.max_digits+1)):
            rst += random.choice(MyIterator.letters)
        return rst
 
 
def extract():
    start_time = time.time()
    zfile = zipfile.ZipFile("test.zip")
    for p in MyIterator(5, 6):
        try:
            zfile.extractall(path=". ", pwd=str(p).encode('utf-8'))
            print("the password is {}".format(p))
            now_time = time.time()
            print("send time is {}".format(now_time - start_time))
            sys.exit(0)
        except Exception as e:
            pass
 
 
if __name__ == '__main__':
    extract()

文字の並びは組み合わせが多いので、待つ必要があります。

補足説明

この方法が有効でないのは、主にファイルパスが正しくないこと(私のコードは解凍のためにPythonスクリプトがあるディレクトリのzipファイルをデフォルトとしています)、暗号化方法が従来の暗号化でないことが理由です。このブルートフォース方式は、ビット数とパスワードの形式(文字だけなど)を覚えている場合にのみ有効で、完全なブルートフォースクラッキングは現実的ではありません、何しろ暗号化は無意味に行われるものではありませんからね。

今回はPythonを使った簡単なzipファイルの解凍パスワードについて紹介しましたが、より関連するPythonのzipファイルの解凍パスワードの内容はBinaryDevelopの過去の記事を検索するか、以下の関連記事を引き続き閲覧してください!今後ともBinaryDevelopをよろしくお願いします。