作者: 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つのファイル:
AまたはBのどちらかが表示されます。
2009年の最終版。
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
.. .. .. X. .. .. .. .. .. .. .. .. .. .. .. ..
.. .. .. .. .. .. .. .. .. .. .. .. .. X. .X ..
.. .. .. .. .. .. .. .. .. .. .. X. .. .. .. ..
差分はブロックの先頭/末尾付近にはないため、近傍のバイトを制御できないことから、悪用は非常に困難です。潜在的な解決策は、周囲のバイトを総当たりで調べることです - cf PoCGTFO 14:10。
例:
空のプレフィックスを使用する場合:``` MD5: fe6c446ee3a831ee010f33ac9c1b602c SHA256: c5dd2ef7c74cd2e80a0fd16f1dd6955c626b59def888be734219d48da6b9dbdd
00: 37 75 C1 F1-C4 A7 5A E7-9C E0 DE 7A-5B 10 80 26 7u┴±─ºZτ£α▐z[►Ç&
10: 02 AB D9 39-C9 6C 5F 02-12 C2 7F DA-CD 0D A3 B0 ☻½┘9╔l_☻↕┬⌂┌═♪ú░
20: 8C ED FA F3-E1 A3 FD B4-EF 09 E7 FB-B1 C3 99 1D îφ·≤ßú²┤∩○τ√▒├Ö↔
30: CD 91 C8 45-E6 6E FD 3D-C7 BB 61 52-3E F4 E0 38 ═æ╚Eµn²=╟╗aR>⌠α8
40: 49 11 85 69-EB CC 17 9C-93 4F 40 EB-33 02 AD 20 I◄àiδ╠↨£ôO@δ3☻¡
50: A4 09 2D FB-15 FA 20 1D-D1 DB 17 CD-DD 29 59 1E ñ○-√§· ↔╤█↨═▌)Y▲ ................
60: 39 89 9E F6-79 46 9F E6-8B 85 C5 EF-DE 42 4F 46 9ë₧÷yFƒµïà┼∩▐BOF ...X............
70: C2 78 75 9D-8B 65 F4 50-EA 21 C5 59-18 62 FF 7B ┬xu¥ïe⌠PΩ!┼Y↑b { .............XX.
...........X....
................
00: 37 75 C1 F1-C4 A7 5A E7-9C E0 DE 7A-5B 10 80 26 7u┴±─ºZτ£α▐z[►Ç& ...X............
10: 02 AB D9 B9-C9 6C 5F 02-12 C2 7F DA-CD 0D A3 B0 ☻½┘╣╔l_☻↕┬⌂┌═♪ú░ .............XX.
20: 8C ED FA F3-E1 A3 FD B4-EF 09 E7 FB-B1 43 9A 1D îφ·≤ßú²┤∩○τ√▒CÜ↔ ...........X....
30: CD 91 C8 45-E6 6E FD 3D-C7 BB 61 D2-3E F4 E0 38 ═æ╚Eµn²=╟╗a╥>⌠α8
40: 49 11 85 69-EB CC 17 9C-93 4F 40 EB-33 02 AD 20 I◄àiδ╠↨£ôO@δ3☻¡ /
50: A4 09 2D 7B-15 FA 20 1D-D1 DB 17 CD-DD 29 59 1E ñ○-{§· ↔╤█↨═▌)Y▲
60: 39 89 9E F6-79 46 9F E6-8B 85 C5 EF-DE C2 4E 46 9ë₧÷yFƒµïà┼∩▐┬NF
70: C2 78 75 9D-8B 65 F4 50-EA 21 C5 D9-18 62 FF 7B ┬xu¥ïe⌠PΩ!┼┘↑b {
MD5: fe6c446ee3a831ee010f33ac9c1b602c SHA256: e27cf3073c704d0665da42d597d4d20131013204eecb6372a5bd60aeddd5d670
同一プレフィックスを持つ他の例: [1](https://github.com/corkami/collisions/blob/master/examples/fastcoll1.bin) ⟷ [2](https://github.com/corkami/collisions/blob/master/examples/fastcoll2.bin)
**バリアント**: [単一ブロックMD5衝突](https://marc-stevens.nl/research/md5-1block-collision/) もありますが、計算に5週間かかります。
プレフィックスなしの FastColl 計算の[記録](https://github.com/corkami/collisions/blob/master/examples/fastcoll.svg)はこちら、
プレフィックス付きの[別の記録](https://github.com/corkami/collisions/blob/master/examples/fastcoll-prefix.svg)はこちらです。
### [UniColl](https://github.com/corkami/collisions/blob/master/unicoll.md) (MD5)
[2012年](https://www.cwi.nl/system/files/PhD-Thesis-Marc-Stevens-Attacks-on-Hash-Functions-and-Applications.pdf#page=199)に文書化され、[2017年](https://github.com/cr-marcstevens/hashclash/blob/95c2619a8078990056beb7aaa59104021714ee3c/scripts/poc_no.sh)に実装されました。
[UniColl](https://github.com/cr-marcstevens/hashclash#create-you-own-identical-prefix-collision) では、衝突ブロック内の数バイトを制御できます。
最初の差分の前後で制御できるため、一部を制御可能な差分を持つ同一プレフィックス衝突となり、ほぼ選択プレフィックス衝突に近いものになります。
これは非常に便利で、さらに良いことに差分は非常に予測可能です:
`m2+= 2^8`(HashClash の [poc_no.sh](https://github.com/cr-marcstevens/hashclash/blob/master/scripts/poc_no.sh#L30) スクリプトでは別名 `N=1` / `m2 9`)の場合、
差分は9バイト目で +1 になるため、非常に悪用しやすいものになります。
衝突について頭の中で考えることさえできます:
その文の9番目の文字は次の文字に置き換わります: `0` は `1` に、`a` は `b` に置き換わります..
- 時間: 数分(制御したいバイト数に依存します )
- スペース: 2ブロック
- 差分: ```
.. .. .. .. DD .. .. .. ..
.. .. .. .. +1 .. .. .. ..
N=1 で、衝突ブロック内に20バイトの固定テキストがある例:```
00: 55 6E 69 43-6F 6C 6C 20-31 20 70 72-65 66 69 78 UniColl 1 prefix
10: 20 32 30 62-F5 48 34 B9-3B 1C 01 9F-C8 6B E6 44 20b⌡H4╣;∟☺ƒ╚kµD
20: FE F6 31 3A-63 DB 99 3E-77 4D C7 5A-6E B0 A6 88 ■÷1:c█Ö>wM╟Zn░ªê
30: 04 05 FB 39-33 21 64 BF-0D A4 FE E2-A6 9D 83 36 ♦♣√93!d┐♪ñ■Γª¥â6
40: 4B 14 D7 F2-47 53 84 BA-12 2D 4F BB-83 78 6C 70 K¶╫≥GSä║↕-O╗âxlp
50: C6 EB 21 F2-F6 59 9A 85-14 73 04 DD-57 5F 40 3C ╞δ!≥÷YÜà¶s♦▌W_@< .........X......
60: E1 3F B0 DB-E8 B4 AA B0-D5 56 22 AF-B9 04 26 FC ß?░█Φ┤¬░╒V"»╣♦&ⁿ ................
70: 9F D2 0C 00-86 C8 ED DE-85 7F 03 7B-05 28 D7 0F ƒ╥♀ å╚φ▐à⌂♥{♣(╫☼ ................
................
.........X......
00: 55 6E 69 43-6F 6C 6C 20-31 21 70 72-65 66 69 78 UniColl 1!prefix ................
10: 20 32 30 62-F5 48 34 B9-3B 1C 01 9F-C8 6B E6 44 20b⌡H4╣;∟☺ƒ╚kµD ................
20: FE F6 31 3A-63 DB 99 3E-77 4D C7 5A-6E B0 A6 88 ■÷1:c█Ö>wM╟Zn░ªê ................
30: 04 05 FB 39-33 21 64 BF-0D A4 FE E2-A6 9D 83 36 ♦♣√93!d┐♪ñ■Γª¥â6
40: 4B 14 D7 F2-47 53 84 BA-12 2C 4F BB-83 78 6C 70 K¶╫≥GSä║↕,O╗âxlp /
50: C6 EB 21 F2-F6 59 9A 85-14 73 04 DD-57 5F 40 3C ╞δ!≥÷YÜà¶s♦▌W_@<
60: E1 3F B0 DB-E8 B4 AA B0-D5 56 22 AF-B9 04 26 FC ß?░█Φ┤¬░╒V"»╣♦&ⁿ
70: 9F D2 0C 00-86 C8 ED DE-85 7F 03 7B-05 28 D7 0F ƒ╥♀ å╚φ▐à⌂♥{♣(╫☼
UniColl は真の選択プレフィックス衝突よりも制御は劣りますが、特に2ブロックのみで済むため、はるかに高速です。
こちらが UniColl 計算の[録画](https://github.com/corkami/collisions/blob/master/examples/unicoll.svg)です。
### [Shattered](http://shattered.io) (SHA1)
[2013](https://marc-stevens.nl/research/papers/EC13-S.pdf)年に文書化され、[2017](http://shattered.io)年に計算されました。
- 時間: 6500年.CPU および 110年.GPU
- スペース: 2ブロック
- 差分: ```
.. .. .. DD ?? ?? ?? ??
or
?? ?? ?? DD .. .. .. ..
各側のコリジョンブロック間の差分は、このXorマスク:``` 0C 00 00 02 C0 00 00 10 B4 00 00 1C 3C 00 00 04 BC 00 00 1A 20 00 00 10 24 00 00 1C EC 00 00 14 0C 00 00 02 C0 00 00 10 B4 00 00 1C 2C 00 00 04 BC 00 00 18 B0 00 00 10 00 00 00 0C B8 00 00 10
例: [PoC||GTFO 0x18](https://github.com/angea/pocorgtfo#0x18) は、計算された SHA1 プレフィックスを使用し、
PDFLaTeX ソースから画像を直接再利用しています([article 18:10](https://archive.org/stream/pocorgtfo18#page/n62/mode/1up) 参照)。
また、HTML ページ内の JavaScript を介してプレフィックスの値をチェックしています(このファイルはポリグロットであり、ZIP、HTML、PDF です)。
## 選択プレフィックス衝突
これにより、任意のコンテンツを衝突させることができます。
| 𝓐 | ≠ | 𝔅 |
| :----: |:-:| :----: |
| 衝突 *A* | ≠ | 衝突 *B* |
1. 任意のプレフィックスを2つ取ります。
2. 短い方を最長のものと同じ長さまでパディングします。両方とも次のブロック - 12バイトまでパディングされます。
- この12バイトのランダムデータは、誕生日探索をランダム化するために両側に追加されます。
3. X個の近衝突ブロックが計算され、追加されます。
ブロック数が少ないほど、計算時間は長くなります。
例: [1ブロックに400 kHours](https://www.win.tue.nl/hashclash/SingleBlock/)。[HashClash](https://github.com/cr-marcstevens/hashclash) では9ブロックに72コア時間。
選択プレフィックス衝突は非常に強力ですが、1組のファイルだけでも長い時間がかかることがあります。
### [HashClash](https://github.com/cr-marcstevens/hashclash) (MD5)
最終版は[2009](https://www.win.tue.nl/hashclash/ChosenPrefixCollisions/)年です。
例: `yes` と `no` を衝突させてみましょう。24コアで3時間かかりました。```
'yes' prefix:
000: 79 65 73 0A-3D 62 84 11-01 75 D3 4D-EB 80 93 DE yes◙=bä◄☺u╙MδÇô▐ - Prefix, padding
010: 31 C1 D9 30-45 FB BE 1E-71 F0 0A 63-75 A8 30 AA 1┴┘0E√╛▲q≡◙cu¿0¬
020: 98 17 CA E3-A2 6B 8E 3D-44 A9 8F F2-0E 67 96 48 ÿ↨╩πókÄ=D⌐Å≥♫gûH
030: 97 25 A6 FB-00 00 00 00-49 08 09 33-F0 62 C4 E8 ù%ª√ I◘○3≡b─Φ
040: D5 F1 54 CD-CA A1 42 90-7F 9D 3D 9A-67 C4 1B 0F ╒±T═╩íBÉ⌂¥=Üg─←☼ - Collision blocks start
050: 04 9F 19 E8-92 C3 AA 19-43 31 1A DB-DA 96 01 54 ♦ƒ↓ΦÆ├¬↓C1→█┌û☺T
060: 85 B5 9A 88-D8 A5 0E FB-CD 66 9A DA-4F 20 8A AA à╡Üê╪Ñ♫√═fÜ┌O è¬
070: BA E3 9C F0-78 31 8F D1-14 5F 3E B9-0F 9F 3E 19 ║π£≡x1Å╤¶_>╣☼ƒ>↓
080: 09 9C BB A9-45 89 BA A8-03 E6 C0 31-A0 54 D6 26 ○£╗⌐Eë║¿♥µ└1áT╓&
090: 3F 80 4C 06-0F C7 D9 19-09 D3 DA 14-FD CB 39 84 ?ÇL♠☼╟┘↓○╙┌¶²╦9ä
0A0: 1F 0D 77 5F-55 AA 7A 07-4C 24 8B 13-0A 54 A2 BC ▼♪w_U¬z•L$ï‼◙Tó╝
0B0: C5 12 7D 4F-E0 5E F2 23-C5 07 61 E4-80 91 B2 13 ┼↕}Oα^≥#┼•aΣÇæ▓‼
0C0: E7 79 07 2A-CF 1B 66 39-8C F0 8E 7E-75 25 22 1D τy•*╧←f9î≡Ä~u%"↔
0D0: A7 3B 49 4A-32 A4 3A 07-61 26 64 EA-6B 83 A2 8D º;IJ2ñ:•a&dΩkâóì
0E0: BE A3 FF BE-4E 71 AE 18-E2 D0 86 4F-20 00 30 26 ╛ú ╛Nq«↑Γ╨åO 0&
0F0: 0A 71 DE 1F-40 B4 F4 8F-9C 50 5C 78-DD CD 72 89 ◙q▐▼@┤⌠Å£P\x▌═rë
100: BA D1 BF F9-96 80 E3 06-96 F3 B9 7C-77 2D EB 25 ║╤┐∙ûÇπ♠û≤╣|w-δ%
110: 1E 56 70 D7-14 1F 55 4D-EC 11 58 59-92 45 E1 33 ▲Vp╫¶▼UM∞◄XYÆEß3
120: 3E 0E A1 6E-FF D9 90 AD-F6 A0 AD 0E-C6 D6 88 12 >♫ín ┘É¡÷á¡♫╞╓ê↕
130: B8 74 F2 9E-DD 53 F7 88-19 73 85 39-AA 9B E0 8D ╕t≥₧▌S≈ê↓sà9¬¢αì
\
140: 82 BF 9C 5E-58 42 1E 3B-94 CF 5B 54-73 5F A8 4A é┐£^XB▲;ö╧[Ts_¿J
150: FD 5B 64 CF-59 D1 96 74-14 B3 0C AF-11 1C F9 47 ²[d╧Y╤ût¶│♀»◄∟∙G ................
160: C5 7A 2C F7-D5 24 F5 EB-BE 54 3E 12-B0 24 67 3F ┼z,≈╒$⌡δ╛T>↕░$g? ................
170: 01 DD 95 76-8D 0D 58 FB-50 23 70 3A-BD ED BE AC ☺▌òvì♪X√P#p:╜φ╛¼ ...............X
................
180: B8 32 DB AE-E8 DC 3A 83-7A C8 D5 0F-08 90 1D 99 ╕2█«Φ▄:âz╚╒☼◘É↔Ö
190: 2D 7D 17 34-4E A8 21 98-61 1A 65 DA-FC 9B A4 BA -}↨4N¿!ÿa→e┌ⁿ¢ñ║ ................
1A0: E1 42 2B 86-0C 94 2A F6-D6 A4 81 B5-2B 0B E9 37 ßB+å♀ö*÷╓ñü╡+♂Θ7 ................
1B0: 44 D2 E4 23-14 7C 16 B8-84 90 8B E0-A1 A7 BD 27 D╥Σ#¶|▬╕äÉïαíº╜' ..............X.
................
1C0: C7 7E E6 17-1A 93 C5 EE-59 70 91 26-4E 9D C7 7C ╟~µ↨→ô┼εYpæ&N¥╟|
1D0: 1D 3D AB F1-B4 F4 F1 D9-86 48 75 77-6E FE 98 84 ↔=½±┤⌠±┘åHuwn■ÿä ................
1E0: EF 3C 1C C7-16 5A 1F 83-60 EC 5C FE-CA 17 0C 74 ∩<∟╟▬Z▼â`∞\■╩↨♀t ................
1F0: EB 8E 9D F6-90 A3 CD 08-65 D5 5A 4C-2E C6 BE 54 δÄ¥÷Éú═◘e╒ZL.╞╛T ...............X
................
'no' prefix: ................
000: 6E 6F 0A E5-5F D0 83 01-9B 4D 55 06-61 AB 88 11 no◙σ_╨â☺¢MU♠a½ê◄ ................
010: 8A FA 4D 34-B3 75 59 46-56 97 EF 6C-4A 07 90 CC è·M4│uYFVù∩lJ•É╠ ............X...
020: FE 19 D7 CF-6F 92 03 9C-91 AA A5 DA-56 92 C1 04 ■↓╫╧oÆ♥£æ¬Ñ┌VÆ┴♦ ................
030: E6 4C 08 A3-00 00 00 00-8D B6 4E 47-FF AF 7A 3C µL◘ú ì╢NG »z<
................
040: D5 F1 54 CD-CA A1 42 90-7F 9D 3D 9A-67 C4 1B 0F ╒±T═╩íBÉ⌂¥=Üg─←☼ ................
050: 04 9F 19 E8-92 C3 AA 19-43 31 1A DB-DA 96 01 54 ♦ƒ↓ΦÆ├¬↓C1→█┌û☺T ............X...
060: 85 B5 9A 88-D8 A5 0E FB-CD 66 9A DA-4F 20 8A A9 à╡Üê╪Ñ♫√═fÜ┌O è⌐ ................
070: BA E3 9C F0-78 31 8F D1-14 5F 3E B9-0F 9F 3E 19 ║π£≡x1Å╤¶_>╣☼ƒ>↓
................
080: 09 9C BB A9-45 89 BA A8-03 E6 C0 31-A0 54 D6 26 ○£╗⌐Eë║¿♥µ└1áT╓& ................
090: 3F 80 4C 06-0F C7 D9 19-09 D3 DA 14-FD CB 39 84 ?ÇL♠☼╟┘↓○╙┌¶²╦9ä .............X..
0A0: 1F 0D 77 5F-55 AA 7A 07-4C 24 8B 13-0A 54 B2 BC ▼♪w_U¬z•L$ï‼◙T▓╝ ................
0B0: C5 12 7D 4F-E0 5E F2 23-C5 07 61 E4-80 91 B2 13 ┼↕}Oα^≥#┼•aΣÇæ▓‼
................
0C0: E7 79 07 2A-CF 1B 66 39-8C F0 8E 7E-75 25 22 1D τy•*╧←f9î≡Ä~u%"↔ ................
0D0: A7 3B 49 4A-32 A4 3A 07-61 26 64 EA-6B 83 A2 8D º;IJ2ñ:•a&dΩkâóì ...............X
0E0: BE A3 FF BE-4E 71 AE 18-E2 D0 86 4F-20 00 30 22 ╛ú ╛Nq«↑Γ╨åO 0" ................
0F0: 0A 71 DE 1F-40 B4 F4 8F-9C 50 5C 78-DD CD 72 89 ◙q▐▼@┤⌠Å£P\x▌═rë
/
100: BA D1 BF F9-96 80 E3 06-96 F3 B9 7C-77 2D EB 25 ║╤┐∙ûÇπ♠û≤╣|w-δ%
110: 1E 56 70 D7-14 1F 55 4D-EC 11 58 59-92 45 E1 33 ▲Vp╫¶▼UM∞◄XYÆEß3
120: 3E 0E A1 6E-FF D9 90 AD-F6 A0 AD 0E-CA D6 88 12 >♫ín ┘É¡÷á¡♫╩╓ê↕
130: B8 74 F2 9E-DD 53 F7 88-19 73 85 39-AA 9B E0 8D ╕t≥₧▌S≈ê↓sà9¬¢αì
140: 82 BF 9C 5E-58 42 1E 3B-94 CF 5B 54-73 5F A8 4A é┐£^XB▲;ö╧[Ts_¿J
150: FD 5B 64 CF-59 D1 96 74-14 B3 0C AF-11 1C F9 47 ²[d╧Y╤ût¶│♀»◄∟∙G
160: C5 7A 2C F7-D5 24 F5 EB-BE 54 3E 12-70 24 67 3F ┼z,≈╒$⌡δ╛T>↕p$g?
170: 01 DD 95 76-8D 0D 58 FB-50 23 70 3A-BD ED BE AC ☺▌òvì♪X√P#p:╜φ╛¼
180: B8 32 DB AE-E8 DC 3A 83-7A C8 D5 0F-08 90 1D 99 ╕2█«Φ▄:âz╚╒☼◘É↔Ö
190: 2D 7D 17 34-4E A8 21 98-61 1A 65 DA-FC 9B A4 BA -}↨4N¿!ÿa→e┌ⁿ¢ñ║
1A0: E1 42 2B 86-0C 94 2A F6-D6 A4 81 B5-2B 2B E9 37 ßB+å♀ö*÷╓ñü╡++Θ7
1B0: 44 D2 E4 23-14 7C 16 B8-84 90 8B E0-A1 A7 BD 27 D╥Σ#¶|▬╕äÉïαíº╜'
1C0: C7 7E E6 17-1A 93 C5 EE-59 70 91 26-4E 9D C7 7C ╟~µ↨→ô┼εYpæ&N¥╟|
1D0: 1D 3D AB F1-B4 F4 F1 D9-86 48 75 77-6E FE 98 84 ↔=½±┤⌠±┘åHuwn■ÿä
1E0: EF 3C 1C C7-16 5A 1F 83-60 EC 5C FE-CA 17 0C 54 ∩<∟╟▬Z▼â`∞\■╩↨♀T
1F0: EB 8E 9D F6-90 A3 CD 08-65 D5 5A 4C-2E C6 BE 54 δÄ¥÷Éú═◘e╒ZL.╞╛T
ここに操作全体のログがあります。
Shambles は、9ブロックを使用する非常に高コストな選択プレフィックス衝突です。
各ブロックは Shattered と同じ xor パターンを持ちます:``` 0C 00 00 02 C0 00 00 10 B4 00 00 1C 3C 00 00 04 BC 00 00 1A 20 00 00 10 24 00 00 1C EC 00 00 14 0C 00 00 02 C0 00 00 10 B4 00 00 1C 2C 00 00 04 BC 00 00 18 B0 00 00 10 00 00 00 0C B8 00 00 10
しかし、Shattered が FastColl よりもはるかに悪用しやすいとしても、
衝突ブロックの差分に関する制約は無関係です。
Shambles は Chosen Prefix Collision であるためです。
## 攻撃の概要
ハッシュ | 名前 | 日付 | 所要時間 | プレフィックス種別 | 差分付近の制御
---- | --------- | ---- | -------- | ----------- | -----------------
MD5 | FastColl | 2009 | 2s | 同一 | なし
| UniColl | 2012 | 7-40分 | 同一 | 4-10バイト
| HashClash | 2009 | 72h | 選択 | n/a
| | | | |
SHA1 | Shattered | 2013 | 6500年 | 同一 | プレフィックス & サフィックス
| Shambles | 2020 | ? | 選択 | n/a
# 悪用
同一プレフィックス衝突は通常、(非常に)限定的と見なされますが、選択プレフィックスは時間がかかります。
別のアプローチは、UniColl のような同一プレフィックス攻撃、またはいくつかの制限を克服するための選択プレフィックス攻撃を介して再利用可能なプレフィックスを作成し、そのプレフィックスのペアを古典的な同一プレフィックス攻撃のように2つのペイロードと組み合わせて再利用することです。
プレフィックスペアが計算されると、2つのコンテンツの衝突は即座に行えます。
後は、特定のファイル形式に従ってファイルデータを調整し、ファイル形式の仕様と事前計算されたプレフィックスの要件に適合させるだけです。
## 標準的な戦略
同じファイルタイプを持つ2つの有効なファイルの古典的な衝突。
### JPG
理論上の制限と回避策:
- *Application* セグメントは理論上、*Start of Image* マーカーの直後にあるべきです。
実際にはこれは必須ではないため、衝突を汎用的にできます。唯一の制限は、最も小さい画像のサイズです。
- コメントの長さは2バイトに格納されるため、保存できる量は65536バイト(およそ400x400の写真のサイズ)に制限されます。
- 完全なJPGファイルをスキップするのではなく、そのファイルをセグメントに分割し、セグメント間にジャンプ用トランポリンを追加することができます。
*各画像セグメント上のコメント*
*コメントのトランポリンがどのように機能するか*
- JPG構造のほとんどは、サイズがすべて65536バイトに制限されたセグメントで構成されていますが、
実際の圧縮データは *Entropy Coded Segment* に格納されており、この制限に従いません。
そのサイズは事前に不明で、その制限を超えて増加します。
画像のサイズとともに増加し、ベースライン(非プログレッシブ)画像ではファイルサイズの大部分を占めます。
画像全体を64kbチャンクに収める簡単な方法は、まず画像をプログレッシブとして保存することです(これはどのソフトウェアでもでき、通常最大6つのスキャンにECSを分割します)。
より高度な方法は、*JPEGTran* を 'wizard' `--scans` コマンドラインパラメータとともに使用し、カスタムスキャンを定義することです。
スキャンセグメント以外に制約はないため、
任意の2つのJPGのMD5衝突は *即時* であり、選択プレフィックス衝突は不要で、UniCollだけで十分です。
[スクリプト](https://github.com/corkami/collisions/blob/master/scripts/jpg.py) を使うと:```
21:07:35.65>jpg.py Ange.jpg Marc.jpg
21:07:35.75>
例:
⟷
2つのMD5衝突JPG
以下は、JPEGTran のスキャン定義の例です。 1944x2508のRGB画像 を、20スキャンすべてが64kbに収まる100% JPGに変換します。``` // : -, , ;
// 0=luma 0: 0-0, 0, 0; 0: 1-1, 0, 0; 0: 2-6, 0, 0; 0: 7-10, 0, 0; 0: 11-13, 0, 0; 0: 14-20, 0, 0; 0: 21-26, 0, 0; 0: 27-32, 0, 0; 0: 33-40, 0, 0; 0: 41-48, 0, 0; 0: 49-54, 0, 0; 0: 55-63, 0, 0;
// 1=blueness 1: 0-0, 0, 0; 1: 1-16, 0, 0; 1: 17-32, 0, 0; 1: 33-63, 0, 0;
// 2=redness 2: 0-0, 0, 0; 2: 1-16, 0, 0; 2: 17-32, 0, 0; 2: 33-63, 0, 0;
結果:
*1944x2508のRGB画像(100% JPG、20回スキャン)*
### PNG
理論上の制限と回避策:
- PNGはチャンクの末尾にCRC32を使用しますが、実際には無視されます。正しい値を入れることもできますが、必須ではありません。
- 画像のメタデータ(寸法、色空間など)は`IHDR`チャンクに格納されます。
このチャンクは理論的にはシグネチャの直後(つまり、潜在的なコメントの前)にあるべきですが、
そのため、同じメタデータを持つ画像の衝突のみを事前計算できることになります。
しかし、実際にはそのチャンクはコメントブロックの後ろに置くことができます(Apple製を除く大多数のリーダーで)。したがって、衝突データをヘッダの前に置くことができ、
単一の事前計算で任意のPNGペアを衝突させることができます。
PNGチャンクの長さは4バイトで表されるため、どちらかのファイルの構造を変更する必要はありません。一気に画像全体を飛び越えることができます。
破棄チャンクは必要なだけ挿入できるため、アライメント用に1つ追加し、次にUniCollによって長さが変更されるチャンクを1つ追加できます。そのため、長さは`00` `75`と`01` `75`になります。
つまり、任意の2つのPNG画像のMD5衝突は*即時*であり、前提条件はありません(計算は不要で、わずかなファイル変更のみです)。また、選択プレフィックス衝突は必要なく、UniCollだけで済みます。
この[スクリプト](https://github.com/corkami/collisions/blob/master/scripts/png.py)を使うと:```
19:27:04.79>png.py nintendo.png sega.png
19:27:04.87>
例:
⟷
プロパティが異なる2つのMD5衝突PNG
操作全体の録画はこちら。
ほとんどのリーダーは、IHDR 以外のチャンクで始まるPNGファイルを問題なく受け入れます。
しかし、一部のリーダー(SafariやPreviewなど - 他にもありますか?)はそれを許容しません。 この場合、画像ヘッダーとそのプロパティ(寸法、色空間)は、衝突ブロックより前に最初に配置されなければなりません。
この場合、衝突する両方のファイルは同じプロパティを持つ必要があります。 繰り返しますが、UniCollで十分です。もちろん、計算されたプレフィックスペアは、同じプロパティを持つ他のファイルペアにも再利用できます。
プレフィックスペアの計算が必要な場合にUniCollを起動して、そのようなファイルの任意のペアを衝突させるためのスクリプトはこちら。
例:
⟷
⟷
最大限の互換性のために同一プロパティを持つ2組のMD5衝突PNG
UniCollが呼び出されたときの操作全体の録画はこちら。
プレフィックスがすでに計算されている場合は、別の録画もどうぞ。
GIFは厄介です:
ただし、コメントチャンクは特殊な構造に従います:ヌル長が定義されるまで、length:1 data:length のチェーンです。 そのため、ヌル以外の任意のバイトが有効な「前方ジャンプ」になります。これによりFastCollでの使用に適しており、 PoC||GTFO 14:11 に示されているとおりです。
つまり、少なくとも共通のプレフィックスは持てなくても、同じメタデータ(寸法、パレット)を持つ任意のGIFのペアを衝突させることができ、プレフィックスの計算にはFastCollをほんの1秒使うだけで済みます。
問題は、PNGのように画像全体を、JPGのような大きな構造を飛び越えることができないことです。
可能な回避策は、圧縮データを調整するか、GIFハッシュクインの場合のように画像を小さな領域に分割することですが、 これは最適ではありません。
汎用的に機能する別のアイデアは、画像データもこの length data シーケンス構造を使用して格納されることです:
つまり、アニメーションのない2つのGIFを取る場合、次のことだけを行えばよいのです:
わずかなセットアップ(わずか数百バイトのオーバーヘッド)で、任意のGIF画像上を滑走し、256バイトの制限を回避できます。 このアイデアはMarcによって提案されたものですが、見事です!
結局のところ、インスタント MD5衝突に対する現在のGIFの制限は次のとおりです:
gifsicle --use-colormap web を参照静止GIF画像を正規化する簡単なショートカットは、それらを同じ画像のアニメーションフレームにすることです。 その後、スクリプトを使用してFastCollブロックを再利用または計算し、それぞれを表示するファイルペアを作成できます。
例:
⟷
2つのMD5衝突GIF - 画像提供:KidMoGraph
操作全体の録画はこちら。
GZIP仕様v4.3:RFC 1952(1996年)。
1F 8B と照合されます。シグネチャが一致しない場合、解析は停止します。これは2つのペイロード間で解析を強制的に停止させるために使用できますが、問題を引き起こす可能性のある警告を発生させます。もう1つの戦略は、ファイルの末尾に空のメンバーを1つ追加し、両方のペイロードの解析をそこで終了させることです - メンバー上またはその本体で終了させます。filename と file comment はヌル終端ですが、Extra field は16ビットサイズで定義されるため、悪用可能です。これは1つ以上のサブフィールドで構成され、IDと独自のサブ長を持ちますが、サブフィールドは強制されません - 公式に定義されているものはごくわずかです。したがって、エクストラフィールドを持つ空のgzipメンバーは完璧なパラサイトホストです。
先頭ファイルが大きすぎてエクストラフィールドに収まらない場合、その非圧縮ストリームは、すべてがエクストラフィールドに収まるまで小さなファイルに分割できます。
メンバーのヘッダーの後には、その圧縮ボディ、CRC32、非圧縮サイズ(強制されません)が続きます。したがって、ヌルのCRC32とサイズを持つ空のデータボディは汎用ポストラップになり、異なるメンバーヘッダー間で共有することもできます。
さまざまな実装が、全メンバーの合計ではなく最後のメンバーの非圧縮サイズに依存しています。そのため、衝突したファイルはサイズがヌルであると表示されます。これらのファイルはトランポリンとして使用される空のメンバーで終わるためです。
2つのGZipファイルのインスタントMD5衝突を生成するためのスクリプトはこちら。入力ファイルが大きい場合、ほとんどの時間をデータの解凍と再圧縮に費やします - 衝突プレフィックスは事前計算されています。非圧縮CRC32を計算する必要があるため、解凍せずにメンバーを分割することは不可能です。
.tar.gz は tar アーカイブの gzip アーカイブにすぎません。tar 自体とは異なり、gzipされたtarでは正常に機能します。
例:collision1.tar.gz(Pacome)⟷ collision2.tar.gz(Reg)
LZ4とZstandardは2つの異なる圧縮形式ですが、全体的な構造は似ています:
フレームで構成されており、各フレームは特定のマジックで始まります:Zstandardフレームは 0xFD2FB528、Lz4フレームは 0x184D2204 です。
また、同じ「スキップ可能な」TLVフレームを共有しています。これは4バイトのマジック(範囲 0x184D2A50 - 0x184D2A5F)で始まり、次にユーザーデータの長さ(4バイト、リトルエンディアン)、そしてユーザーデータ本体が続きます。
これらのフレームは完全にオプションで、任意の長さで、繰り返し可能です。ファイルはこれらのフレームで始めることができます。そのため、これらのフレームを連結して、2つの形式にまたがる完璧な汎用衝突プレフィックスを作成できます。
2つのZstd/Lz4ファイルのインスタントMD5衝突を生成するためのスクリプトはこちら。Gzipと同様に、コンテンツに関係なく外部からは2つの異なるアーカイブが見えます:たとえば、.cpio.zst などです。
例:
Portable Executableは特殊な構造を持っています:
したがって、戦略は次のとおりです:
DOS/Collisions/Header1/Header2 構造の後に隣り合わせに配置できます。2つのセクションテーブルのオフセットにデルタを適用するだけで済みます。つまり、任意のPE実行ファイルのペアを即座に衝突させることが可能です。異なるサブシステムやアーキテクチャを使用していても同様です。
実行ファイルの衝突は通常、どのローダーを介しても簡単ですが、ここでのこの種の悪用は透過的です:コードは同一で、同じアドレスにロードされます。
例:tweakPNG.exe(GUI)⟷ fastcoll.exe(CLI)
Windows実行ファイルのインスタントMD5衝突を生成するためのスクリプトはこちら。
この形式のコンテナーは、アトムと呼ばれる Length Type Value チャンクのシーケンスです。
長さは32ビットビッグエンディアンで、それ自体、タイプ、値をカバーするため、通常の最小長は8です
(タイプは4文字のASCII文字列です)。
長さがヌルの場合、アトムはファイルの残り全体を占有します - JP2ファイルの jp2c アトムなどです。
長さが1の場合、タイプの後に64ビットの長さが続き、アトムが Type Length Value に変わります。これにより、Shatteredなどの他の衝突との互換性が生まれます。
一部のアトムは他のアトムを含みます:この場合、それらはボックスと呼ばれます。そのため、この他に名前のない構造は「アトム/ボックス」と呼ばれます。
MP4で使用されるこの「アトム/ボックス」形式は、実際にはApple Quicktimeの派生であり、 他の多くの形式(JP2、HEIF、F4V)で使用されています。
最初のアトムタイプは通常 ftyp であり、実際のファイル形式を区別することができます。
この形式はかなり寛容です:
free アトムを連結し、UniCollで1つの長さを悪用して、最初のペイロードを飛び越えるだけです。
MP4ファイルの場合、追加する必要があるのは stco(サンプルテーブル - チャンクオフセット)または co64(64ビット相当)テーブルを調整することだけです。これらは mdat ムービーデータを指す絶対(!)オフセットであり、実際に強制されるためです!
これにより、任意のビデオを即座に衝突させるスクリプトが得られます - そして、 前述のように、MP4以外の形式でも機能する可能性があります。

例(動画提供:KidMoGraph):
32ビット長(標準)collision1.mp4 ⟷ collision2.mp4
⟷
64ビット長 collisionl1.mp4 ⟷ collisionl2.mp4
⟷
一部のビューアー(OS X、Safari、FireFox)は、ftyp 以外のアトムで始まるファイルを許可しないことに注意してください。
この場合、プレフィックスがこれをカバーする必要があり、それほど汎用的ではありませんが、それ以外は同じ戦略です - 単一のファイルタイプに限定されるだけです。
JPEG2000ファイルは通常、MP4のようなアトム/ボックス構造で始まり、
最後のアトム jp2c は通常ファイルの末尾まで続き(ヌル長)、
この時点からはJPEGのようにJFIF構造に従います(セグメントマーカーとして FF 4F で始まります)。
純粋なJFIF形式も許容され、その場合の衝突はJPEGと同様です: Shattered互換ですが、コメントは64Kbに制限されます。
一方、アトム/ボックスを使用してJPEG2000ファイルを操作する場合、 この制限はありません。
前述のように、この構造を衝突させようとして、
さらに制限がある場合 - たとえば free アトムで始まることが一部の形式で許容されない場合 -
この形式に固有の別のUniCollプレフィックスペアを計算できます:
JPEG2000は、通常の ftyp の前に 'jP ' アトムを最初に強制しているようです。
しかし、それ以外はそれが唯一の制限です:何かを再配置する必要はありません。
そのため、結果として得られるスクリプトはさらにシンプルです!

例:collision1.jp2 ⟷ collision2.jp2
Shatteredについて
Shatteredの悪用はPDFのトリックではなく、PDF内のJPGのトリックでした。
これは、PDFが2つの異なるコンテンツを持ち得るJPG圧縮オブジェクトを含むことを可能にするだけでした。 両方のPDFは、それ以外は完全に同一である必要がありました。
ドキュメントは完全に正常でもかまわず、衝突JPGをクリップして、複数ページのドキュメントなど、異なる場所に表示するだけでよいことに注意してください。
例:Shatteredの論文、改変版 ⟷ Shatteredの論文、原本
2つの場所で衝突JPGを使用したShatteredの論文
MD5によるPDF衝突
MD5(および他の衝突パターン)を使用すると、ドキュメントレベルでPDF衝突を行うことができ、 どちらのファイルにもまったく制限がありません!
PDFは他のファイル形式とは非常に異なる構造を持っています。 オブジェクト番号と参照を使用してツリーを定義します。 ドキュメント全体はルート要素に依存します。
この(有効な)PDF``` text %PDF-1. 1 0 obj<</Pages 2 0 R>>endobj 2 0 obj<</Kids[3 0 R]/Count 1>>endobj 3 0 obj<</Parent 2 0 R>>endobj trailer <</Root 1 0 R>>
は次と同等です:``` text
%PDF-1.
11 0 obj<</Pages 12 0 R>>endobj
12 0 obj<</Kids[13 0 R]/Count 1>>endobj
13 0 obj<</Parent 12 0 R>>endobj
trailer <</Root 11 0 R>>
Tricks:
XREF テーブルには番号をスキップする公式の方法さえあります。つまり、2 つのドキュメントツリーを同じファイルに保存しても問題ありません。ルートオブジェクトが両方のドキュメントのどちらかのルートオブジェクトを参照するようにすればよいだけです。
つまり、2 つのドキュメントを取得し、オブジェクトと参照が重複しないように番号を振り直し、ハッシュ値を同じに保ったままルートオブジェクトとして参照される要素番号を変更できる衝突を細工し、N=1 の UniColl にぴったり合わせて、それに応じて XREF テーブルを調整するだけです。
こうすることで、ページ番号、寸法、画像などに関係なく、あらゆる PDF のペアを安全に衝突させることができます。
コメント
PDF は外部データを 2 つの方法で格納できます。
\r と \n)だけです。
これは、例えば UniColl 経由でオブジェクト参照を変更するために、ディクショナリオブジェクト内部で使用できます。
したがって、バイナリ衝突ブロックが含まれていても、改行文字がなくなるまでリトライすれば、これは有効な PDF オブジェクトです: ```
1 0 obj
<< /Type /Catalog /MD5_is /REALLY_dead_now__ /Pages 2 0 R
%¥┬•σe╕█╙X₧_~π▌╒εX∟■φe♦%τ8╞■[...]p╛╬ûFZ»‼v◘Åp↑╝%▓% ▼σφj╔◄dZ▀c²aU≤╨╩[├└─yNΓ5╔+▀╪yδ☻ß⌐░¼à(☺z₧
endobj
衝突テキスト
最初のケースは、UniCollの美しさを際立たせます。UniCollは、差異が予測可能な衝突であり、 衝突するデータ上で詩を書くことができます - Jurphに感謝!
文書の構造を変更してパーサーを欺くのではなく、 衝突ブロックを直接使用して、テキストを直接生成します。 別の読み方で!``` V V Now he hash MD5, Now he hath MD5, No enemy cares! No enemy dares! Only he gave Only he have the shards. the shares. Can’t be owned & Can’t be pwned & his true gold, his true hold, like One Frail, like One Grail, sound as fold. sound as gold. ^ ^
例: [poeMD5 A](https://github.com/corkami/collisions/blob/master/examples/poeMD5_A.pdf) ⟷ [poeMD5 B](https://github.com/corkami/collisions/blob/master/examples/poeMD5_B.pdf)
*真の暗号学的芸術作品 :)*
(注: Adobe互換性のところでやらかしましたが、それは私のミスであり、UniCollのせいではありません)
**ドキュメント構造を衝突させる**
UniCollをインラインコメントとして使うか、ダミーストリームオブジェクト内の選択プレフィックスとして使うかにかかわらず、戦略は同様です:
オブジェクト番号をシャッフルし、Rootオブジェクトが異なるオブジェクトを指すようにします。このため、Shatteredとは異なり、任意のPDFペアをドキュメントレベルで即座に衝突させることができます。
便利なトリックとして、[`mutool clean`](https://mupdf.com/docs/manual-mutool-clean.html) の出力は確実に予測可能です。
そのため、入力を正規化するために使用したり、ファイルの重要な部分を変更せずにマージ済みPDFを修正したりできます。
MuToolは、要求しない限り偽のキー/値を破棄せず、同じ順序で保持します。
したがって、`/MD5_is /REALLY_dead_now__` のような偽の辞書エントリを使うことは、他の種類のコメントを必要とせずに物事を予測可能に整列させるのに最適です。
ただし、辞書内のコメントは保持されないため、インラインコメントのトリックは使えません。
オブジェクトのシャッフル操作を手間なく行う簡単な方法は、両方のPDFファイルをマージすることです
`mutool merge` を使用してから、`/Pages` オブジェクトを2つに分割します。
このオブジェクトのためのスペースを確保するには、2つのドキュメントの前にダミーPDFをマージするだけです。
必要に応じて、ダングリング配列への偽の参照を作成し、
ガベージコレクションが2番目のページセットを削除しないようにします。
**例**:
この [スクリプト](https://github.com/corkami/collisions/blob/master/scripts/pdf.py) を使えば、
Spectre や Meltdown のような公開PDF論文2件を衝突させるのに [1秒未満](https://github.com/corkami/collisions/blob/master/examples/pdf.log) しかかかりません:
例: [spectre.pdf](https://github.com/corkami/collisions/blob/master/examples/collision1.pdf) ⟷ [meltdown.pdf](https://github.com/corkami/collisions/blob/master/examples/collision2.pdf)
可能な拡張: UniCollブロックを連鎖させて、[非クリティカルオブジェクト](https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/PDF32000_2008.pdf#page=81) のペアも保持します。
これらはRootオブジェクトで参照できます - 元のソースファイル内の `Outlines`、`Names`、`AcroForm`、および追加アクション (`AA`) などです。
**PDFLaTeXでの使用**
前述のテクニックはPDFファイルのペアだけで機能しますが、
TeXソースから直接行うことも可能です。
[特定のPDFTeXオペレーター](http://texdoc.net/texmf-dist/doc/pdftex/manual/pdftex-a.pdf) を使用して。
オブジェクトを直接定義できます - アライメント用のダミーキーと値も含めて - また、TeXソースの冒頭にこれを記述することで、オブジェクトスロットを予約するための空のオブジェクトを定義できます:``` latex
% set PDF version low to prevent stream XREF
\pdfminorversion=3
\begingroup
% disable compression to keep alignments
\pdfcompresslevel=0\relax
\immediate
\pdfobj{<<
/Type /Catalog
% cool alignment padding
/MD5_is /REALLY_dead_now__
% the first reference number should be on offset 0x49,
% so the '2' object number will be changed to '3' by UniColl
/Pages 2 0 R
% now padding so that the collision blocks (ends at 0xC0) are covered
/0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF
% with an extra character to be replaced by a return char
/0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0
>>}
% the original catalog of the shifted doc
\immediate\pdfobj{<</Type/Pages/Count 1/Kids[8 0 R]>>}
% the original catalog of the host doc
\immediate\pdfobj{<</Type/Pages/Count 1/Kids[33 0 R]>>}
% now we need to reserve PDF Objects so that there is no overlap
\newcount\objcount
% the host size (+3 for spare object slots) - 1
% putting a higher margin will just work, and XREF can have huge gaps
\objcount=25
\loop
\message{\the\objcount}
\advance \objcount -1
\immediate\pdfobj{<<>>} % just an empty object
\ifnum \objcount>0
\repeat
\endgroup
必要に応じて、PDFLaTeX出力を正規化するのを忘れないでください - 例えば mutool を使用して -:
PDFLaTeXは、ディストリビューションをまたいで再現可能なビルドを得るのは困難です - 必要であれば、実行時に時刻をフックして正確なハッシュを得たいかもしれません。
JPGは単なる画像だと思うかもしれませんが、PDFや一部のPDFリーダー(ブラウザではなく、EvinceやAdobe Readerなど)では、JPEG画像に埋め込まれた他の埋め込みオブジェクトと同様に、ページコンテンツとして使用できます。
JPEGデータをロスレスで保存するには、100%グレースケールで保存し、単一の行/列の画像を使用するか、データ行を8回繰り返します(JPEGブロックは8x8のため)。これにより、データはロスレスで保存され、PDFページから参照されます。
JPEGページデータ(色を描画するグレースケール画像)をベクターページコンテンツとして使用し、SHA-1が衝突する2つのPDFの例:
画像データをJPGとして保存した2つのSHA-1衝突PDF
衝突するJPGを2回参照することが可能です。ページコンテンツとしてロスレスで参照し、同時に表示用の非可逆画像として自分自身を参照します。 繰り返しになりますが、表示される画像はグレースケールですが、ページコンテンツはPDFオペレーターを介していくつかの色をレンダリングできます。
画像の上部には、ページコンテンツが8回繰り返して表示されています。
JPEGをページデータおよび表示用画像として使用した、SHA-1が衝突する2つのPDFの例:
Skulls & Crossbones ⟷ Golden Axe
JPGを画像とページコンテンツに使用した2つのSHA-1衝突PDF
TL;DR ZIP用の汎用的で再利用可能な衝突(コリジョン)はありませんが、ZIPベースのフォーマットにはあります。 2h.core を使用すれば、2つのファイルを衝突させることが可能なはずです(chosen-prefix よりも36倍高速です)。
ZIPアーカイブは、3つのレイヤー(少なくとも)からなるサンドイッチ構造です。
最初にファイルのコンテンツ(アーカイブされた各ファイルまたはディレクトリごとに1つのLocal File Header構造体の並び)、次にインデックス(これもCentral Directoryの並び)、そして最後にこのインデックスを指し示す単一の構造体(End Of Central Directory)が来ます。
これらのレイヤーの順序は動かせません。 一部のパーサーはファイルコンテンツの構造のみを必要としますが、それは正しい解析方法ではなく、悪用される可能性があります。
この必須の順序のため、あらゆる衝突に役立つ汎用的なプレフィックスは存在しません。
非汎用的アプローチ
もう1つのアプローチは、両方のアーカイブを、それらのレイヤーを統合したまま単純にマージし、UniCollを使用することです - ただしN=2であり、これにより4バイト目に差異が生じます - End of Central Directoryのマジックシグネチャを破壊します。
これはつまり、単一のUniCollと24バイトの設定済みプレフィックスにより、任意の2つのZIPを衝突させられることを意味します。
典型的なEnd of Central Directoryは、コメントが空の場合22バイトです:``` 00: 504b 0506 0000 0000 0000 0000 0000 0000 PK.............. 10: 0000 0000 0000 ......
これをUniCollのプレフィックスとして使用し(プレフィックスを16ビットにパディング)、`N=2`の場合、差分は4バイト目に現れ、マジック`.P .K 05 06`を予測可能な形で`.P .K 05 86`に変更して壊します。```
00: 504b 0506 0000 0000 0000 0000 0000 0000 PK..............
10: 0000 0000 0000 2121 eb66 cf9d db01 83bb ......!!.f......
20: 2888 4c41 e345 7d07 1634 5d4a 3b61 89a0 (.LA.E}..4]J;a..
30: 0029 94af 4168 2517 0bbc b841 cbf2 9587 .)..Ah%....A....
40: e438 0043 6390 279d 7c9e a01e e476 4c36 .8.Cc.'.|....vL6
50: 527f b1f4 653e d866 f98d 7278 5324 0bd5 R...e>.f..rxS$..
60: b31d ef6d d5d6 1163 5a2e a8a5 21bf eab4 ...m...cZ...!...
70: c59c 028e a913 f6b7 0036 c93f 5092 a628 .........6.?P..(
Input text for chunk 39 was not provided, so there is no content to translate. Please supply the chunk text.``` 00: 504b 0586 0000 0000 0000 0000 0000 0000 PK.............. 10: 0000 0000 0000 2121 eb66 cf1d db01 83bb ......!!.f...... 20: 2888 4c41 e345 7d07 1634 5d4a 3b61 89a0 (.LA.E}..4]J;a.. 30: 0029 94af 4168 251f 0bbc b841 cbf2 9587 .)..Ah%....A.... 40: e438 00c3 6390 279d 7c9e a01e e476 4c36 .8..c.'.|....vL6 50: 527f b1f4 653e d866 f98d 72f8 5324 0bd5 R...e>.f..r.S$.. 60: b31d ef6d d5d6 1163 5a2e a8a5 21bf eab4 ...m...cZ...!... 70: c59c 028e a913 f6af 0036 c93f 5092 a628 .........6.?P..(
これはまったく汎用的ではありませんが、chosen-prefix collision よりはるかに高速です:```
real 12m23.993s
user 112m24.072s
sys 2m0.194s
A problem is that some parsers still parse ZIP files upside-down even if they should be parsed bottom-up:
a way to make sure that both files are properly parsed is to chain two UniColl blocks,
to enable/disable each End of Central Directory.
ZIPパーサーが未使用スペースについて警告しないようにするには、
Extra Fields、Central Directory内のファイルコメント、End of Central Directory内のアーカイブコメントを悪用できます。

例: 2つの異なるアーカイブファイルを保持できるデュアルZIPの構造を記述したアセンブリソースがあります。
2回のUnicoll計算の後、次の2つの衝突するファイルが得られます: collision1.zip ⟷ collision2.zip
Zipフォーマット自体はGzipのように汎用的に悪用することはできませんが、Zipに依存する一部のフォーマットは、事前に定義された構造を持つZipアーカイブ内で汎用的に悪用できます。Zipコリジョンを汎用的にするには、いくつかの注意事項があります。
一部のフォーマットはZipアーカイブに格納された複数ファイルで構成され、アーカイブ内の他のファイルを指す固定ファイル名のルートファイルに依存しています。それらの多くはルートファイルにXMLまたはテキストを使用し、他のファイルはそのまま格納しています。
アイデア : 同じアーカイブ内に2つのファイルセットを共存させ、どちらかのファイルセットを指すようにします。汎用的なルートはファイルの先頭に最初に格納できますが、コリジョンブロックはファイルコンテンツの外側、アーカイブ内に格納されます(コリジョンは非常に高いエントロピーを持つため、XMLやASCIIのみのファイルをコリジョンで悪用することは不可能です)。
手順:
2つの由来を持つ2つのファイルセットを同じアーカイブ内に配置します - すなわち、異なるサブディレクトリに配置します。
ルートファイルを変更して、各セットを交互に指すようにします。
ルートファイルのタイムスタンプ、長さ、CRCは、ファイルの内容の前にあるLocal File Headerと、ファイルの内容の後にあるCentral Directoryの両方に格納されるため、これらの値は2つのバージョンのファイル間で変更すべきではありません。
Central Directory内のCRC32が正しくない場合、この値のコピーはパーサーに無視されるかもしれませんが、CRC32を定数値に偽装することは問題を完全に回避するのに役立ちます。
4バイトのランダムなデータを追加してCRCを偽装するだけでは不十分なことが多いです。これらのルートファイルは通常、構文が厳格なXMLまたはテキストであるため、無効になってしまうからです。
CrcHackは、総当たりなしで任意のビットのCRCを偽装するのに大いに役立ち、出力ファイルがASCIIであり、変更されたビットが依然としてコメント内にあることを保証します。ルートファイルの後にあるアーカイブ内の余分なダミーファイルのextra field(空であっても)を使用することは、Hashclashコリジョンブロックを格納するエレガントな方法です。これにより、Zipアーカイブは標準的な構造を維持し、その後、標準的なツールでも簡単に操作できます。
Extra FieldsにはCRC32がなく、その16ビット長は前のヘッダーで宣言されます。これらは独自の内部ID:2 Size:2 Data形式を持っていますが、通常は無視され、Local File HeaderとCentral Directoryの両方に存在します。ただし、コリジョンブロックの後に同一のサフィックスを維持するために、Central Directoryからは省略できます。
コリジョンブロックをそのextra field内に含む追加ファイルの存在は、OOXMLドキュメントの[Content_Types].xmlファイルのように、フォーマット構造内で宣言する必要がある場合があります。一部のフォーマットでは絶対パスの使用が必要なため、サフィックス内の他のXMLファイルを変更しなければならない場合があります。
特定のZipベースのフォーマットに対する汎用エクスプロイトの全体的な構造は次のとおりです:``` [Root file] (with constant CRC32)
[Dummy file] (with collision blocks in the extra field)
[...] <- rest of the archive, with 2 documents merged
したがって、ルートファイルの内容を事前定義し、ASCII CRC32を偽造することで、特定のzipベース形式に対して、再利用可能な汎用Hashclash衝突を計算できます。
### 要件の概要
- 2つ以上のプレフィックス
- 1つ以上のファイルタイプ(ポリグロットは問題なく動作します)
- 固定のファイル名、ファイル長、CRCを持つXMLルートファイル:この情報は衝突ブロックの前後に2回存在します
- 内容は任意のXMLです
- 同じ長さにするために、XMLコメントを使ったパディングも可能です。
- CRCは各コンテンツに(CrcHack経由で)設定できます。
- 両方のファイルセットはサフィックス内に共存し、おそらく異なるディレクトリにあります。一部のツールはパスをハードコードするため、互換性が低下する可能性があります。
- サポート対象および非対象のすべてのファイル(衝突ブロックと代替ドキュメント)をカバーするには、*Content type* XMLファイルをマージする必要があるかもしれません。
### 例
#### CRC32
CrcHackを使った、偽造されたCRC32(即時計算)を含む最小限のXMLコメント(ASCIIのみ)。``` bash
echo "<!--ABCDEF-->" | crchack -b 4.0:+.8*6:1 -b 4.1:+.8*6:1 -b 4.2:+.8*6:1 -b 4.3:+.8*6:1 -b 4.4:+.8*6:1 -b 4.5:+.8*5:1 - 0xdeadf00d
<!--X{]EZF-->
アルファベットのメッセージの場合にCRCを調整する別の例です。```bash echo "" | crchack.exe -b 4:+.8*32:.8 - 0xcafebabe
#### 衝突
[zInsider](https://github.com/corkami/collisions/blob/master/scripts/zinsider.py) は、以下の ZIP+XML 形式を使用して、任意のドキュメントのペアの MD5 衝突を即座に生成するスクリプトです。
- Office Open XML: docx / pptx / xlsx
- Open Container Format: epub
- Open Packaging Conventions:
- 3D 製造フォーマット: 3mf
- XML Paper Specification: xps / oxps
独自の衝突プレフィックスを生成するには、ルート zip ペアを生成する[スクリプトはこちら](https://github.com/corkami/collisions/blob/master/scripts/makezip.py)。
衝突を計算した後、[この別のスクリプト](https://github.com/corkami/collisions/blob/master/scripts/extendzip.py)を使用して、これらのルートペアを共通のサフィックスと組み合わせます。
衝突 PoC の例:
- Office Open XML: Excel ([1](https://github.com/corkami/collisions/blob/master/examples/free/md5-1.xls) - [2](https://github.com/corkami/collisions/blob/master/examples/free/md5-2.xls)), Powerpoint ([1](https://github.com/corkami/collisions/blob/master/examples/free/md5-1.pptx) - [2](https://github.com/corkami/collisions/blob/master/examples/free/md5-2.pptx)), Word ([1](https://github.com/corkami/collisions/blob/master/examples/free/md5-1.docx) - [2](https://github.com/corkami/collisions/blob/master/examples/free/md5-2.docx))。
- Open Container Format: Epub ([1](https://github.com/corkami/collisions/blob/master/examples/collision-1.epub) - [2](https://github.com/corkami/collisions/blob/master/examples/collision-2.epub))。
- Open Packaging Conventions: 3MF ([1](https://github.com/corkami/collisions/blob/master/examples/collision-1.3mf) - [2](https://github.com/corkami/collisions/blob/master/examples/collision-2.3mf)), XPS ([1](https://github.com/corkami/collisions/blob/master/examples/collision-1.xps) - [2](https://github.com/corkami/collisions/blob/master/examples/collision-2.xps))。
Zip ベースの複数ファイル形式の中には、一般的に悪用できないものがあります:
- Quake PK3: 特定のルートを持たないファイルの zip。
- Open Document Format: `META-INF/manifest.xml` ファイルは他のすべてのファイルを記載する必要があるため、汎用化できません。
- APK、JAR、XPI: `META-INF/MANIFEST.mf` ファイルも、他のすべてのファイルをそのハッシュとともに記載する必要があります。
Office ファイル形式について支援してくれた [Philippe Lagadec](https://twitter.com/decalage2) に感謝します!
### その他
- Wasm、カスタムセクション経由: [スクリプト](https://github.com/corkami/collisions/blob/master/scripts/wasm.py)、例: [md5-1.wasm](https://github.com/corkami/collisions/blob/master/examples/free/md5-1.wasm) ⟷ [md5-2.wasm](https://github.com/corkami/collisions/blob/master/examples/free/md5-2.wasm)
## 特殊な戦略
衝突は通常、同じタイプの2つの有効なファイルに関するものです。
### MultiColls: 多重衝突チェーン
複数の衝突ブロックをチェーンすることを妨げるものは何もなく、
同じハッシュ値を持つ2つ以上のコンテンツを持つことができます。
その例が *hashquines* です。これは自分自身の MD5 値を示します。
[PoCGTFO 14](https://github.com/angea/pocorgtfo#0x14) ファイルには 609 個の FastColl 衝突が含まれており、
同じファイル内の2つのファイルタイプを通じてそれを実現しています。
#### Hashquines
Hashquines は、自分自身のハッシュ値を表示するファイルです。それらは[ここ](https://github.com/corkami/collisions/blob/master/hashquines)で説明されています。
### 有効性
別の戦略として、破損したファイルとしてスキャンされるのを回避するために、ファイルタイプを無効化する方法があります。
マジックシグネチャを上書きするだけで十分です。
オフセット 0 にある必要のない形式(ZIP/RAR/... などのアーカイブ)を両方のファイル(有効または無効として)に追加すると、
別のファイルタイプが明らかになります。
これにより、選択プレフィックス衝突を使用せずにポリグロット衝突が可能になります:
1. UniColl を使用してマジックシグネチャを有効または無効にします。たとえば PNG:
2. ZIP アーカイブを追加します
技術的には両方のファイルが有効な ZIP ですが、ほとんどのパーサーは最初に見つかったファイルタイプを返し、オフセット 0 からスキャンを開始するため、異なるファイルタイプとして認識されます。
例:
⟷ [無効](https://github.com/corkami/collisions/blob/master/examples/png-invalid.png)
### PolyColls: 異なるファイルタイプの衝突
また、衝突の両側を異なるタイプにして、疑われにくくすることも可能です:
攻撃シナリオ:
1. `holiday.jpg` を送信する
2. ホワイトリストに登録させる
3. 同じ MD5 を持つ `evil.exe` を送信する
これらの場合、両方のファイル形式がオフセット 0 から始まる必要がある場合は、選択プレフィックス衝突が必要です。
ポリコルレイアウトの例:

*PDF/JPG ポリコル*

*PE/PNG ポリコル*
#### PE - JPG
PE ヘッダーは通常 0x500 バイトより小さいため、JPG コメントに最適です:
1. DOS/JPG ヘッダーで始める
2. JPEG コメントが PE ヘッダーを飛び越える
3. 完全な JPG 画像を配置する
4. PE 仕様全体を配置する
繰り返しますが、衝突は[即時](https://github.com/corkami/collisions/blob/master/scripts/jpgpe.py)です。
例: [fastcoll.exe](https://github.com/corkami/collisions/blob/master/examples/jpg-pe.exe) ⟷ [Marc.jpg](https://github.com/corkami/collisions/blob/master/examples/jpg-pe.jpg)
#### PDF - PE
`mutool` を使用して PDF をダミーファイルとマージすることは、オブジェクトを並べ替え、
最初の2つのオブジェクトを破棄可能にする(ダミーページとコンテンツ)ための優れた汎用的な方法です。
これは、未知の長さの `stream` オブジェクトを `1 0` としてホストし、
その長さを2番目のオブジェクト内で(衝突ブロックの後に)参照するのに最適です。
唯一の問題は、`mutool` が常に長さをインライン化し、長さ参照を削除することです。
そのため、値の代わりに PDF に再挿入する必要がありますが、
ほとんどの参照 `2 0 R` はハードコードされた長さよりも小さくなります。
ありがたいことに、これはオブジェクトオフセットを変更せずに修正できるため、
XREF をパッチする必要はありません。
たとえば、PDF ビューア([Sumatra](https://www.sumatrapdfreader.org/free-pdf-reader.html) は軽量でスタンドアロン)と PDF ドキュメントを即座に衝突させる[スクリプト](https://github.com/corkami/collisions/blob/master/scripts/pdfpe.py)があります:
例: [Poster.pdf](https://github.com/corkami/collisions/blob/master/examples/pepdf.pdf) ⟷ [Sumatra.exe](https://github.com/corkami/collisions/blob/master/examples/pepdf.exe)

*同じ MD5 を持つ PDF を表示する PDF ビューア(それ自体も PDF を表示している)*
#### PDF - PNG
同様に、たとえば任意の PDF ファイルと PNG ファイルを、どちら側にも制限なく衝突させることが可能です。これは即時的で、再利用可能で、汎用的です。
例: [Hello.pdf](https://github.com/corkami/collisions/blob/master/examples/png-pdf.pdf) ⟷ [1x1.png](https://github.com/corkami/collisions/blob/master/examples/png-pdf.png)
### PileUps (多重衝突)
暗号学的衝突は2つのファイルに限定されません!
2008 年の [Nostradamus](https://www.win.tue.nl/hashclash/Nostradamus/) 実験で実証されたように、
衝突を連鎖させることで、2つ以上のファイルを衝突させることが可能になります。
最初の衝突は同一または選択プレフィックスにすることができますが、次の衝突は選択プレフィックスでなければなりません。
マルチコリジョンと呼んでも構いませんが、私は *pileups* の方が好きです。より短いので :)
#### PE - PNG - MP4 - PDF
これまでに得たすべての知識を組み合わせて、
3 つの選択プレフィックス衝突を使用して、異なるファイルタイプ用の 4 つの異なるプレフィックスを作成しました:
ドキュメント (PDF)、ビデオ (MP4)、実行可能ファイル (PE)、画像 (PNG)。

*PE/PNG/MP4/PDF パイルアップの図*
このスクリプトは汎用的で即時的です:

例: [commodore.pdf](https://github.com/corkami/collisions/blob/master/examples/pileup.pdf) ⟷ [diagram.png](https://github.com/corkami/collisions/blob/master/examples/pileup.png) ⟷ [kidmo.mp4](https://github.com/corkami/collisions/blob/master/examples/pileup.mp4) ⟷ [sumatra18.exe](https://github.com/corkami/collisions/blob/master/examples/pileup.exe)
単一のファイルのみを配布する場合、
そこから他のプレフィックス値を推測することは不可能なため、
解決策として、衝突のすべてのプレフィックスを JavaScript コードに埋め込み、
それを PoC に挿入して、
ファイルを [HTML ポリグロット](https://github.com/corkami/collisions/blob/master/examples/polyglot.html) に変換し、関連する衝突ファイルを簡単に共有できます。
'PoC or GTFO' の[第19号](https://github.com/angea/pocorgtfo#0x19)は、まさにそのようなパイルアップ **かつ** ポリグロットであり、
PDFLaTeX で生成された 80 ページのドキュメント、Windows 用 PDF ビューア、
PNG 図、[KidMoGraph](https://www.kidmograph.com/) による短い 'collision' MP4 ビデオに加え、
PDF リリースから他のファイルを生成する HTML ペイロード
(ZIP アーカイブも)を組み合わせたものです。
JavaScript について常に支援してくれた Rafał Hirsz に感謝します。
## ユースケース
ファイルのイントロスペクションは時間がかかりすぎてリスクが高すぎるため、MD5 は完全に廃止する方がよいでしょう!
### 全部衝突させなきゃ!
即時的で再利用可能な汎用衝突の別の用途は、特定のタイプのファイル(たとえば PNG)をダミーファイル(または毎回同じファイル)の背後に隠すことです。これは実際には、シグネチャを除去した後に同じプレフィックスに連結するだけで実現できます。ライブラリレベルでも実行可能です!
厳密なパーシングの観点から見ると、
すべてのファイルは同じコンテンツを示し、
悪意のある画像は、以前に収集されたものと同じ MD5 を持つファイルとして明らかになります。
2つのファイルを例に取りましょう:
⟷
そして、それらを同じ PNG と衝突させます。
これで、それらは同じダミー画像を表示し、ファイルレベルで2番目の画像まで完全に同一です!
⟷
それぞれの悪意のあるペイロードは、同じ MD5 を持つファイルの背後に隠れています。
### 有罪を示すファイル
衝突の別のユースケースは、無実だが望ましい何かの内部に有罪を示す何かを隠すことです。
証拠を収集する唯一の方法が弱いハッシュの比較である場合、
もう一方のファイル(有罪を示すコンテンツを表示し、無実のコンテンツを隠している)を持っていないと否定することはできません。
ソフトウェアは通常、(迅速な)パーシングに重点を置いており、詳細なファイル分析には重点を置いていません。
*EnCase Forensic の異なるタブの下での異なるプレビューを示す画像*
## 失敗
すべての形式が再利用可能な汎用プレフィックスを持てるわけではありません。
マジックシグネチャと、各ファイルに固有で重要な標準ヘッダーの間に
何らかのデータホルダーを挿入できない場合、
汎用衝突は不可能です。
もちろん、古いファイルを新しいファイルに変換したり、
コードを使用して2つの異なるペイロードに分岐させたりすることは可能ですが、
それはファイル構造の衝突というよりは、ペイロードの移植に近いものです。
### ELF
ELF ヘッダーはオフセット 0 に必要であり、当初から 32b/64b、エンディアン、ABI などの重要な情報を含んでいるため、
元のファイルに固有の重要なパラメータの前に
普遍的なプレフィックスと衝突ブロックを置くことは不可能です。
### Mach-O
Mach-O は、32b (`feedface`) と 64b (`feedfacf`) で同じマジックで始まるわけでもありません。
その直後に、コマンドの数とサイズ(セグメント定義、symtab、バージョンなど)があります。
ELF と同様に、再利用可能な衝突は不可能です。
### Java Class
開始直後のマジックにはバージョン(問題を引き起こす可能性があります)がありますが、
定数プールカウントは各ファイルにかなり固有であるため、
すべてのファイルに対する普遍的な衝突はありません。
ただし、多くのファイルは依然として共通のバージョンを持っており、最短の定数プールを最長のカウントにパディングできます。
まず、*UTF8 リテラル* を挿入して情報を整列させ、
次に UniColl によって長さが悪用された別のものを宣言します(長さは 16 バイトのビッグエンディアンとして格納されます)。
ただし、すべてのプールインデックスがシフトされるため、コード操作が必要になります。
Java Class の即時 MD5 再利用可能衝突は可能であるはずですが、コード分析と修正が必要です。
### TAR
**TL;DR** TAR ファイルには再利用可能な衝突はなく、選択プレフィックス以外の戦略はありません。
Tape Archive は、連結されたヘッダーとファイルコンテンツのシーケンスであり、すべて 512 バイトに整列されています。
ファイル全体に対する中央構造はありません。したがって、悪用できるグローバルヘッダーやコメントは一切ありません。
可変長のダミーファイルを開始するというトリックもありますが、長さは常に同じオフセットにあり、UniColl と互換性がありません。つまり、ここでは選択プレフィックス衝突のみが有効です。
## 悪用の概要
形式 | 汎用? | FastColl | UniColl | Shattered | HashClash / Shambles
-------- | -------- | :------: | :-----: | --------- | :-------:
PDF | Y | | x | | x
JPG | Y (1) | | x | x (2) | x
GZ | Y | | x | | x
PNG | Y/N (3) | | x | | x
MP4 | Y (4) | | x | x (5) | x
PE | Y | | | | x
ZIP-based (6) | Y | | | | x
| | | | |
GIF | N | x | | | x
ZIP | N | | x (7) | | x
| | | | |
ELF | N | | | | x
TAR | N | | | | x
Mach-O | N | | | | x
Class | N | | | | x
1. JPG にはデータに関するいくつかの制限があり、スキャンエンコーディングを操作することである程度改善できます。
2. PDF w/ JPG は Shattered 攻撃の[初期実装](http://shattered.io)ですが、これは PDF ドキュメント内の純粋な JPG トリックに過ぎません。
3. PNG: Safari/Preview は、PNG の `IHDR` チャンクが、衝突ブロックより前に最初のスロットに配置されることを要求します。これを行うと汎用プレフィックスが妨げられ、その場合、衝突は特定の寸法、カラースペース、BPP、インターレーシングに限定されます。
4. MP4 などの Atom/Box 形式は、異なるサブフォーマットに対して同じプレフィックスで機能する場合があります。JPEG2000 や HEIF などの一部のサブフォーマットでは追加のグルーミングが必要ですが、エクスプロイト戦略は同じです。唯一の違いは、衝突がサブフォーマット間では不可能であり、特定のサブフォーマット用のプレフィックスのペアでのみ可能であることです。
5. Atom/Box は、64 ビット長を使用する場合に Shattered と互換性があります。
6. Zip ベースの一部の形式は汎用的に悪用できます。
7. 互換性を高めるには、ZIP は完全なアーカイブに 2 つの UniColl を必要とし、この衝突は両方のファイルのコンテンツに依存します。
## テストファイル
[ここ](https://github.com/corkami/collisions/blob/master/examples/free/README.md)に、フリー(著作権フリー、PII フリー)のテスト用衝突ペアがあります。
# 検出
ファイル内のハッシュ衝突を検出するには、さまざまな方法があります。
1. 2つのファイル: 異なるコンテンツと同じハッシュを持つ2つ以上のファイルがある場合は、差分を取るだけです!
ただし、単一のファイルしかない場合、そのファイルにハッシュ衝突が含まれているかどうかを判断するのは難しい場合があります。
2. ファイル構造: ブロック境界でファイルを分析し、高エントロピーのブロックや、場合によっては同一のプレフィックス/サフィックスに気付いた場合、使用されている衝突を特定できるかもしれませんが、非常にエラーが発生しやすいです。選択プレフィックス衝突の場合、衝突ブロックのほとんどを除いて両方のファイルがほとんど異なる可能性があるため、発見することは不可能かもしれません。
3. ハッシュ計算: Marc Stevens の DetectColl の実装([C](https://github.com/cr-marcstevens/hashclash/tree/collisiondetection/src/collisiondetection) または [Go](https://github.com/therealmik/detectcoll))を使用します(彼の [Counter-cryptanalysis](https://marc-stevens.nl/research/papers/C13-S.pdf) 論文を参照)。これには1つのファイルしか必要ありませんが、衝突が機能している状態(正確なプレフィックスとそれに対応する衝突ブロック)である必要があり、低速です。
DetectColl は、衝突自体に関する技術情報を提供し、衝突したハッシュの横に `*coll*` を表示します。
## 例
Flame マルウェア証明書の場合:```
$ detectcoll flame.der
Found collision in block 11:
dm: dm4=80000000 dm11=ffff8000 dm14=80000000
ihv1=1ba33aac3a7f9ed70aec349b40390e85
ihv2=9ba33aac3c7f60ee8cebf69bc2391085
*coll* c38a66643af816f8438b375b5f42ccbb flame.der
ba2499ba3dda9ef818f854b75a2bd1cd9f2b7bed flame.der
Detectcoll はハッシュ衝突に使用されるブロックを識別できるため、安全なハッシュ によって衝突を緩和できます。つまり、衝突ブロックが検出された場合、それを再処理して衝突特性を破壊します。したがって DetectColl は、ファイル内に衝突がある場合でも、同じハッシュ関数を使用して異なるコンテンツを区別できます。
要するに:
2005年のWang氏による元の衝突の例:``` $ md5sum wang* 79054025255fb1a26e4bc422aef54eb4 *wang1.bin 79054025255fb1a26e4bc422aef54eb4 *wang2.bin
これらのファイルの安全なMD5:```
$ detectcoll wang1.bin | grep coll
*coll* ff531291d102a41aa131e0e09f64ca60 wang1.bin
############################################################
$ detectcoll wang2.bin | grep coll
*coll* 6a8e7124724d5c819401afc202a4fbd0 wang2.bin
```
## シグネチャ
簡単のため、Detectcoll の出力をこの[スクリプト](https://github.com/corkami/collisions/blob/master/scripts/logparse.py)で解析し、[既知のシグネチャ](https://github.com/corkami/collisions/blob/7f7876c431614f33f765bfc1cb62506b476a2eb0/scripts/logparse.py#L15-L24)とより簡単に照合できます:``` shell
$ detectcoll_unsafe * | ./logparse.py
apop-1.bin
block: 2, collision: APop
cpc1.bin
block: 9, collision: HashClashCPC
fastcoll1.bin
block: 2, collision: FastColl
single-cpc1.bin
block: 1, collision: SingleCPC
single-ipc1.bin
block: 0, collision: SingleIPC
wang1.bin
block: 1, collision: FastColl
pileup.exe
block: 10, collision: HashClashCPC
block: 20, collision: HashClashCPC
04-unicoll-1.bin
block: 1, collision: Unicoll1
05-uc-n2-1.bin
block: 1, collision: Unicoll2
05-uc-n3-1.bin
block: 1, collision: Unicoll3
05-uc-n3-2.bin
block: 1, collision: Unicoll3
12-shattered1.bin
block: 3, collision: SHAttered/Shambles
block: 4, collision: SHAttered/Shambles
13-shambles1.bin
block: 9, collision: SHAttered/Shambles
13-shambles2.bin
block: 9, collision: SHAttered/Shambles
ca-rogue.der
block: 10, collision: HashClashCPC
flame.der
block: 11, collision: Flame
```
### 複数の衝突
セーフハッシュの小さな欠点は、同じファイル内で複数の衝突を検出できないことですが、DetectCollは「standard」ハッシュを使用した衝突を依然として検出できます。
PoCorGTFO 0x14(代替カバー画像付きのNES+PDFハッシュクワイン)の例。
セーフハッシュは1つの衝突しか見つけることができません:```
$ detectcoll_safe pocorgtfo14.pdf
Found collision in block 135:
dm: dm4=80000000 dm11=ffff8000 dm14=80000000
ihv1=73b615bd01d5e48032d3d1a549d0f956
ihv2=f3b615bd83d5e480b4d3d1a5cbd0f956
*coll* c4b085f9fa4b38669fa79d4c410538e9 pocorgtfo14.pdf
eb5d0fb7607c1262236a5a7f591bb510ee9afbbc pocorgtfo14.pdf
```
安全でないハッシュはそれらをすべて見つけます:```
$ detectcoll_unsafe pocorgtfo14.pdf | grep Found | wc -l
609
```
最後のいくつかの衝突を確認すると:```
$ detectcoll_unsafe pocorgtfo14.pdf | tail | grep Found
Found collision in block 34169:
Found collision in block 34250:
Found collision in block 34324:
Found collision in block 34389:
Found collision in block 34456:
Found collision in block 34523:
Found collision in block 34585:
Found collision in block 34738:
```
最後のものが前のものほど近くないことに気づくでしょう:
それは、前のものがhashquines用の同じ画像ファイルに属している一方、
最後のものは代替カバー用だからです。
# 参考文献
論文(ファイル形式の悪用に関するもの):
- 2004
- [MD5はいつか有害と見なされるであろう](https://eprint.iacr.org/2004/357.pdf) - Dan Kaminsky
- [MD5メッセージダイジェストを用いたデジタル署名への実用的攻撃](https://eprint.iacr.org/2004/356.pdf) - Ondredj Mikle
- 2005:
- [特殊なファイル形式に対する単一ハッシュ衝突の実用的価値に関するノート](https://github.com/corkami/collisions/blob/master/papers/Illies_NIST_05.pdf) - Max Gebhardt, Georg Illies, Werner Schindler
- 2014:
- [悪意あるハッシュ:Eve版SHA-1](https://malicioussha1.github.io/) - Ange Albertini, Jean-Philippe Aumasson, Maria Eichlseder, Florian Mendel, Martin Schläffer
- 2017:
- [完全なSHA-1に対する最初の衝突](http://shattered.io) - Marc Stevens, Elie Bursztein, Pierre Karpman, Ange Albertini, Yarik Markov
- [自身のMD5を表示するPostscript](https://archive.org/stream/pocorgtfo14#page/n45/mode/1up) 著:Gregor "Greg" Kopf
- [自身のMD5を表示するPDF](https://archive.org/stream/pocorgtfo14#page/n49/mode/1up) 著:Mako
- [このGIFは自身のMD5を表示します!](https://archive.org/stream/pocorgtfo14#page/n52/mode/1up) 著:Kristoffer "spq" Janke
- [このPDFは自身のMD5ハッシュを出力するNES ROMです!](https://archive.org/stream/pocorgtfo14#page/n55/mode/1up) 著:Evan Sultanik, Evan Teran
- 2018:
- [PDFLaTeXで簡単にSHA-1衝突PDFを作成する。](https://archive.org/stream/pocorgtfo18#page/n62/mode/1up) 著:Ange Albertini
- 2020:
- [SHA-1はShambles](https://eprint.iacr.org/2020/014.pdf) 著:Gaëtan Leurent, Thomas Peyrin
発表:
- 2017 Black Alpsでのハッシュ衝突の悪用:
- [スライド](https://speakerdeck.com/ange/exploiting-hash-collisions)
[](https://speakerdeck.com/ange/exploiting-hash-collisions)
- [動画](https://www.youtube.com/watch?v=Y-oJWEYKVLA)
[](https://www.youtube.com/watch?v=Y-oJWEYKVLA)
- 2019 Pass the SaltでのKILL MD5:
- [スライド](https://speakerdeck.com/ange/kill-md5)
[](https://speakerdeck.com/ange/kill-md5)
- [動画](https://passthesalt.ubicast.tv/videos/kill-md5-demystifying-hash-collisions/)
[](https://passthesalt.ubicast.tv/videos/kill-md5-demystifying-hash-collisions/)
ワークショップ(CollTris):
- [スライド](https://speakerdeck.com/ange/colltris)
[](https://speakerdeck.com/ange/colltris)
- [動画](https://www.youtube.com/watch?v=BcwrMnGVyBI)
[](https://www.youtube.com/watch?v=BcwrMnGVyBI)
- [資料](https://github.com/corkami/collisions/blob/master/workshop/README.md)
- セッション
- 2019/07/02 150p, Pass The Salt
- 2019/07/24 199p, Google
- 2019/08/19 208p, Google
- 2019/10/23 222p, Hack.lu
- 2019/11/07 225p, Black Alps
- 2019/12/03 229p, Google
CTFタスク:
- [Prudentialv2](https://ctftime.org/task/3453)、*Boston Key Party CTF 2017* より。
- [HREFIN](https://ctftime.org/task/6965)、*Google CTF 2018* より。
- [Looking glass](https://ctftime.org/task/9271)、*Dragon Sector Teaser CTF 2019* より。
<!-- - [Not my digest](https://ctftime.org/task/4784) は *Hack.lu CTF 2017* より:衝突とは関係ないが、Marc自身が解いた :p -->
このようなCTFタスクに共通する課題は、各プレイヤーが利用できる計算能力に応じて、大きすぎるアドバンテージやハンディキャップを与えないようにすることです。
# 謝辞
これらすべては、[Marc Stevens](https://marc-stevens.nl/research/)のおかげで可能になりました。
暗号学的な貢献だけでなく、彼の絶え間ない助力と提案にも感謝します!
また、ファイル形式全般に関する広範なフィードバックをいただいたPhilippe Teuwenにも感謝します。
# 結論
**MD5を殺せ!**
ファイル内の異常や衝突ブロックを積極的にチェックしない限り、MD5を使うな!
それは暗号学的ハッシュではなく、おもちゃの関数だ!
<!-- pandoc -s -f gfm -t html README.md -o README.html -->
| プレフィックス | = | プレフィックス |
|---|
| 衝突 A | ≠ | 衝突 B |
| A | = | |
| = | B |