
Biham と Kocher の既知平文攻撃を使用してレガシーZIP暗号化を解読します。
ZIPアーカイブには、圧縮や暗号化が施された多数のエントリが含まれる場合があります。
特に、エントリは従来のPKWARE暗号化、レガシー暗号化、またはZipCryptoと呼ばれるパスワードベースの対称暗号アルゴリズムで暗号化できます。
このアルゴリズムは、疑似ランダムバイトストリーム(キーストリーム)を生成し、エントリの内容(平文)にXORして暗号化データ(暗号文)を生成します。
ジェネレータの状態は、3つの32ビット整数で構成され、パスワードを使用して初期化され、暗号化の進行に伴って平文で継続的に更新されます。
この暗号アルゴリズムは、Eli Biham と Paul C. Kocher の研究論文 A known plaintext attack on the PKZIP stream cipher で示されているように、既知平文攻撃に対して脆弱です。
暗号文と対応する平文の12バイト以上が与えられると、キーストリームジェネレータの内部状態を回復できます。
この内部状態があれば、暗号文全体を解読できるだけでなく、同じパスワードで暗号化された他のエントリも解読できます。
また、パスワードのブルートフォースにも使用でき、複雑度は nl-6 です。ここで n は文字セットのサイズ、 l はパスワードの長さです。
bkcrack は、この既知平文攻撃を実装したコマンドラインツールです。
主な機能は次のとおりです。
最新の公式リリースは GitHub から入手できます。
Ubuntu、MacOS、Windows向けのプリコンパイル済みパッケージがダウンロード可能です。
ダウンロードしたアーカイブを任意の場所に展開してください。
Windowsでは、bkcrackを実行するためにMicrosoftランタイムライブラリが必要です。
システムにまだインストールされていない場合は、最新のMicrosoft Visual C++再頒布可能パッケージをダウンロードしてインストールしてください。
あるいは、CMake を使用してプロジェクトをコンパイルすることもできます。
まず、ソースファイルをダウンロードするか、gitリポジトリをクローンします。
その後、ソースツリーで以下のコマンドを実行すると、install フォルダにインストールが作成されます。
cmake -S . -B build -DCMAKE_INSTALL_PREFIX=install
cmake --build build --config Release
cmake --build build --config Release --target install
bkcrackは、以下にリストされているパッケージリポジトリでも利用できます。
これらのパッケージは外部のメンテナによって提供されています。
archive.zip というアーカイブ内のエントリ名とメタデータを次のように表示できます。
bkcrack -L archive.zip
ZipCrypto暗号化を使用するエントリは、既知平文攻撃に対して脆弱です。
攻撃には少なくとも12バイトの既知平文が必要です。
そのうち少なくとも8バイトは連続している必要があります。
連続した既知平文が大きいほど、攻撃は速くなります。
暗号化zipアーカイブ encrypted.zip にエントリ cipher (暗号文)があり、平文zip plain.zip にエントリ plain (既知平文)がある場合、bkcrackは次のように実行できます。
bkcrack -C encrypted.zip -c cipher -P plain.zip -p plain
暗号文(暗号化ヘッダに対応する12バイトから始まる)を含むファイル cipherfile と、既知平文を含むファイル plainfile がある場合、bkcrackは次のように実行できます。
bkcrack -c cipherfile -p plainfile
平文が暗号文の先頭以外の部分に対応する場合、オフセットを指定できます。
平文に暗号化ヘッダの一部が含まれる場合は、負の値も指定できます。
bkcrack -c cipherfile -p plainfile -o offset
連続した平文を少ししか知らない(8~11バイト)が、他の既知のオフセットにいくつかのバイトを知っている場合、この情報を提供して合計12バイトの既知条件を満たすことができます。
これを行うには、-x フラグの後にオフセットと16進数のバイトを指定します。
bkcrack -c cipherfile -p plainfile -x 25 4b4f -x 30 21
攻撃が成功した場合、攻撃に使用した暗号文に対応する復号データを保存できます。
bkcrack -c cipherfile -p plainfile -d decipheredfile
以前の攻撃でキーがわかっている場合、bkcrackを使用してデータを復号することもできます。
bkcrack -c cipherfile -k 12345678 23456789 34567890 -d decipheredfile
復号データは、zipファイル作成時に圧縮が使用されたかどうかに応じて圧縮されている場合があります。
Deflate圧縮が使用された場合、tools フォルダに提供されているPython 3スクリプトを使用してデータを展開できます。
python3 tools/inflate.py < decipheredfile > decompressedfile
暗号化アーカイブのすべてのエントリに一度にアクセスするには、同じ内容で暗号化されていない新しいアーカイブを生成できます。
すべてのエントリが元々同じパスワードで暗号化されていたことを前提としています。
bkcrack -C encrypted.zip -k 12345678 23456789 34567890 -D decrypted.zip
任意のパスワードで暗号化された新しいアーカイブを生成することも可能です。
bkcrack -C encrypted.zip -k 12345678 23456789 34567890 -U unlocked.zip new_password
また、対応する内部表現で新しいパスワードを定義することもできます。
bkcrack -C encrypted.zip -k 12345678 23456789 34567890 --change-keys unlocked.zip 581da44e 8e40167f 50c009a0
これら2つのコマンドを組み合わせて、パスワードを知らなくても内部キーのみを知っていれば、暗号化アーカイブの内容を変更できます。つまり、選択したパスワードで暗号化されたコピーを作成し、アーカイブマネージャでそのコピーを編集(パスワードの入力を求められたら選択したパスワードを入力)し、最後に変更したコピーを元の暗号化キーで再暗号化します。
内部キーが与えられると、bkcrackは元のパスワードを見つけようとします。
指定された文字セットを使用してパスワードを検索できます。
bkcrack -k 1ded830c 24454157 7213b8c5 -b ?p
検索を特定の長さまたは長さの範囲に制限できます。
bkcrack -k 1ded830c 24454157 7213b8c5 -b ?p -l 9
bkcrack -k 1ded830c 24454157 7213b8c5 -b ?p -l 8..10
オプション -r <length> <charset> は -l 0..<length> -b <charset> のショートカットです。
bkcrack -k 1ded830c 24454157 7213b8c5 -r 10 ?p
パスワードの構成についてある程度の知識がある場合、マスクを指定して検索空間を制限し、回復を大幅に高速化できます。
これは、ブルートフォースが非常に時間がかかる長いパスワード(12文字以上など)に有効です。
たとえば、パスワードが小文字8文字、ハイフン、10進数字6文字で構成されていると漠然と覚えている場合、次のコマンドを使用できます。
bkcrack -k 1940e266 d3fd3d89 71ce9871 -m ?l?l?l?l?l?l?l?l-?d?d?d?d?d?d
これはミリ秒単位で実行されますが、ブルートフォースの代替手段では数時間かかります。
ブルートフォースとマスクベースのパスワード回復の両方の検索空間は、文字セットで定義されます。
文字セットは、文字のシーケンスまたは既存の文字セットのショートカットです。
定義済みの文字セットは以下のとおりです。
定義済み文字セットに加えて、-s オプションでカスタム文字セットを定義できます。
カスタム文字セットは、定義済み文字セットや他のカスタム文字セットを参照できます。
カスタム文字セットは、マスクベースの回復の検索空間を正確に指定するのに特に便利です。
たとえば、パスワードが10文字の英字(大文字小文字問わず)と5文字の2進数字で構成されていることがわかっている場合、次のコマンドを使用できます。
bkcrack -k b8c377a6 f603160f 1832a78b -m ?x?x?x?x?x?x?x?x?x?x?y?y?y?y?y -s x ?u?l -s y 01
example フォルダにチュートリアルが用意されています。
詳細については、ドキュメントを参照し、ソースを読んでください。
改善の提案やプルリクエストは、GitHub でお気軽にどうぞ。
プロジェクトを支援したい場合は、Github Sponsors から寄付またはスポンサーになることができます。
このプロジェクトは、zlib/pngライセンス の条件の下で提供されています。
| ショートカット | 説明 | 値 |
|---|
?l | 小文字 | abcdefghijklmnopqrstuvwxyz |
?u | 大文字 | ABCDEFGHIJKLMNOPQRSTUVWXYZ |
?d | 10進数字 | 0123456789 |
?s | 特殊文字 | !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ |
?a | 英数字 | ?l?u?dと同じ |
?p | 印字可能なASCII文字 | ?l?u?d?sと同じ |
?b | 全バイト | 0x00 .. 0xff |