作者: Ange Albertini と Marc Stevens.
Q: ファイルに任意のMD2/MD4/MD5/MD6/SHA1/SHA2/SHA3、または別のファイルと同じハッシュを付与することは可能ですか?
A: いいえ。
Q: 同じハッシュを持つ2つの異なるファイルを作成できますか?
A: MD5なら、標準的なコンピュータで数秒です。SHA1なら、可能ですが、エンドユーザーには現実的ではありません(計算量: 2^61.2 コスト: $11k)。
Q: データを追加することで、2つの異なるファイルに同じハッシュを持たせられますか?
A: MD5なら、標準的なコンピュータで数時間です。SHA1なら、可能ですが、エンドユーザーには現実的ではありません(計算量: 2^63.4 コスト: $45K)。
Q: 2つのファイルは有効なままですか?
A: 一般的にははい。ほとんどのファイル形式は追加データを許容するためです。その一方で、ファイル署名はおそらく壊れます。
Q: 任意の内容を持つ2つの異なるファイルに同じハッシュを持たせられますか?
A: はい、特別なファイル構造に依存すれば瞬時に行えます:
Q: どの形式で即座にMD5衝突ファイルのペアを入手できますか?
A: JPG、PNG、GIF、GZIP、Portable Executable、MP4、JPEG2000、PDF、DOCX/PPTX/XSLX、EPUB、3MF、XPS。対応するスクリプトを実行するだけです。
Q: SHA1ではどうですか?
A: SHA1では、PDF内のJPGが計算され、実装されています。
Q: MD5ですでにサポートされている形式(JPG、PNG...)をSHA1で使う場合はどうですか?
A: おそらくSHA1でもサポートされていますが、それらの衝突はまだ計算されていません。
Q: 類似した(ただし異なる)内容の場合、計算は速くなりますか?
A: いいえ。わずかな違いでも完全な計算が必要です。
Q: どの形式にはそのようなショートカットがないのですか?
A: ELF、Mach-O、Java Class、TAR、ZIP(その他にもあります...)
Q: これらの形式でも従来の衝突(数時間)は可能ですか?
A: はい、任意の量の追加データが許容される限り可能です(つまり、ZIPやClassではおそらく不可能)。
Q: 衝突の例を提供していますか?
A: はい。
このドキュメントの目的は、既存の攻撃を広範囲に調査すること - その過程でMD5がどれほど弱いかを示すこと(あらゆるJPG、PNG、PDF、MP4、PE...の即時衝突) - また、一般的なファイル形式を詳細に調査して、 現在または将来の攻撃でどのように悪用され得るかを明らかにすることです。
実際、同じファイル形式のトリックは複数のハッシュに使用できます (同じJPGのトリックはMD5、 malicious SHA-1、SHA1に使用されました)、 衝突が同じバイトパターンに従う限り。
このドキュメントは、新しい攻撃(最新のものは2012年に文書化されました)についてではなく、 既存の攻撃に対する新しい悪用形態についてです。
既知の攻撃の現在のステータス:
ファイルに別のファイルのハッシュまたは指定したハッシュを持たせること:不可能
同じMD5を持つ2つの異なるファイルを取得:瞬時
2つの任意のファイルに同じMD5を持たせること:数時間(72時間.core)
特定のファイル形式(PNG、JPG、PE...)の2つの任意のファイルに同じMD5を持たせること:瞬時
同じSHA1を持つ2つの異なるファイルを取得:6500年.core
import crypt crypt.crypt("5dUD&66", "br") 'brokenOz4KxMc' crypt.crypt("O!>',%$", "br") 'brokenOz4KxMc'
# 攻撃
MD5 と SHA1 は 64 バイトのブロックで動作します。
2 つのコンテンツ A と B が同じハッシュを持つ場合、両方に同じコンテンツ C を追加しても、ハッシュは同じままになります。``` text
hash(A) = hash(B) -> hash(A + C) = hash(B + C)
衝突は、ブロック境界に、ファイル内のそれまでの内容に依存する計算済みの衝突ブロックを挿入することで機能します。これらの衝突ブロックは、各攻撃に固有のパターンを持つわずかな差分を伴って、非常にランダムに見えます。それらは微小な差分を導入しますが、結局これらのブロックの後ではハッシュ値が同じになります。
これらの差分は、特定のプロパティを持つ有効なファイルを細工するために悪用されます。
ファイル形式もトップダウンで処理され、そのほとんどがバイトレベルのチャンクで動作します。
一部の「コメント」チャンクは、ファイルチャンクをブロック境界に整列させたり、特定の構造を衝突ブロックの差分に合わせたり、衝突ブロックの残りのランダム性をファイルパーサーから隠したり、そうでなければ有効なコンテンツをパーサーから隠したり(別のコンテンツが見えるようにするため)するために挿入できます。
これらの「コメント」チャンクは、公式には実際のコメントではないことがよくあります。それらは単にパーサーに無視されるデータコンテナとして使用されます(例えば、小文字で始まるIDを持つPNGチャンクは付随的であり、必須ではありません)。
ほとんどの場合、衝突ブロックの差分はコメントチャンクの長さを変更するために使用され、その長さは通常このチャンクのデータの直前に宣言されます。このチャンクの短いバージョンと長いバージョンの間のギャップに、別のコメントチャンクを宣言して、一方のファイルのコンテンツ A を飛び越えます。このファイルコンテンツ A の後に、別のファイルコンテンツ B を単に追加します。

ファイル形式は通常、パーサーをそこで停止させるターミネータを定義するため、A はパースを終了させ、追加されたコンテンツ B は無視されます。
したがって、通常は少なくとも2つのコメントが必要です - 多くの場合3つです:
これらのファイル形式の共通プロパティによってそれが可能になります - それらは通常、弱点としては見なされませんが、検出したり正規化で除去したりできます:
| プレフィックス | = | プレフィックス |
|---|---|---|
| 衝突 A | ≠ | 衝突 B |
| サフィックス | = | サフィックス |
両方のファイルはほぼ同一です(それらのコンテンツには数ビットの差分しかありません)。
悪用:
2つのコンテンツをバンドルし、次に以下のいずれかを行います:
この構造を持つ2つのファイル: