
Collisioni di hash e i loro sfruttamenti
TL;DR ottenere una collisione MD5 di queste due immagini è ora(*) banale e istantaneo.
⟷
<a href=http://gunshowcomic.com/648>
Non giocare col fuoco, non fare affidamento su MD5.
(*) Collidere qualsiasi coppia di file è possibile da molti anni, ma richiede diverse ore ogni volta, senza scorciatoie.
Questa pagina fornisce trucchi specifici per i formati di file e prefissi di collisione precalcolati per rendere la collisione istantanea.
git clone. Esegui lo script. Fatto.
Di Ange Albertini e Marc Stevens.
L'obiettivo è esplorare a fondo gli attacchi esistenti - e mostrare strada facendo quanto sia debole MD5 (collisioni istantanee di qualsiasi JPG, PNG, PDF, MP4, PE...) - e anche esplorare in dettaglio i formati di file comuni per determinare come possano essere sfruttati con attacchi attuali o futuri.
Infatti, lo stesso trucco sui formati di file può essere usato su diversi hash (gli stessi trucchi JPG sono stati usati per MD5, malicious SHA-1 e SHA1), finché le collisioni seguono gli stessi pattern di byte.
Questo documento non riguarda nuovi attacchi (il più recente è stato documentato nel 2012), ma nuove forme di sfruttamento degli attacchi esistenti.
Stato attuale - a dicembre 2018 - degli attacchi noti:
ottenere un file che abbia l'hash di un altro file o un dato hash: impossibile
ottenere due file diversi con lo stesso MD5: istantaneo
far sì che due file arbitrari ottengano lo stesso MD5: poche ore (72 hours.core)
far sì che due file arbitrari di formati specifici (PNG, JPG, PE...) ottengano lo stesso MD5: istantaneo
ottenere due file diversi con lo stesso SHA1: 6500 years.core
import crypt crypt.crypt("5dUD&66", "br") 'brokenOz4KxMc' crypt.crypt("O!>',%$", "br") 'brokenOz4KxMc'
# Attacchi
MD5 e SHA1 operano su blocchi di 64 byte.
Se due contenuti A e B hanno lo stesso hash, allora aggiungendo lo stesso contenuto C a entrambi, l'hash rimarrà lo stesso.``` text
hash(A) = hash(B) -> hash(A + C) = hash(B + C)
Collisions work by inserting at a block boundary a number of computed collision blocks that depends on what came before in the file. These collision blocks are very random-looking with some minor differences (that follow a specific pattern for each attack) and they will introduce tiny differences while eventually getting hashes the same value after these blocks.
Queste differenze vengono sfruttate per creare file validi con proprietà specifiche.
Anche i formati di file funzionano dall'alto verso il basso, e la maggior parte di essi lavora per chunk a livello di byte.
Alcuni chunk 'commento' possono essere inseriti per allineare i chunk del file ai confini di blocco, per allineare strutture specifiche alle differenze dei blocchi di collisione, per nascondere ai parser del file la casualità residua dei blocchi di collisione, e per nascondere al parser contenuti altrimenti validi (così che ne veda altri).
Questi chunk 'commento' spesso non sono commenti ufficiali reali: sono usati solo come contenitori di dati ignorati dal parser (ad esempio, i chunk PNG con ID che inizia con una lettera minuscola sono ancillari, non critici).
La maggior parte delle volte, una differenza nei blocchi di collisione viene usata per modificare la lunghezza di un chunk di commento,
che in genere viene dichiarato subito prima dei dati di questo chunk:
nello spazio tra la versione più corta e quella più lunga di questo chunk,
viene dichiarato un altro chunk di commento per saltare il contenuto A di un file.
Dopo questo contenuto A, basta aggiungere un altro contenuto B.

Poiché i formati di file di solito definiscono un terminatore che fa fermare i parser dopo di esso,
A terminerà il parsing, facendo sì che il contenuto aggiunto B venga ignorato.
Quindi in genere servono almeno due commenti - spesso tre:
Queste proprietà comuni dei formati di file rendono tutto ciò possibile - non sono in genere considerate debolezze, ma possono essere rilevate o normalizzate:
| Prefisso | = | Prefisso |
|---|---|---|
| Collisione A | ≠ | Collisione B |
| Suffisso | = | Suffisso |
Entrambi i file sono quasi identici (i loro contenuti hanno solo pochi bit di differenze)
Sfruttamento:
Prepara due contenuti, quindi:
Due file con questa struttura:
| Prefisso | = | Prefisso |
|---|---|---|
| Collisione A | ≠ | Collisione B |
| A | = | |
| = | B |
mostreranno A oppure B.
Versione finale nel 2009.
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
.. .. .. X. .. .. .. .. .. .. .. .. .. .. .. ..
.. .. .. .. .. .. .. .. .. .. .. .. .. X. .X ..
.. .. .. .. .. .. .. .. .. .. .. .. X. .. .. .. ..
Le differenze non sono vicine all'inizio/fine dei blocchi, quindi è molto difficile sfruttarle poiché non controlli nessun byte circostante. Una potenziale soluzione è forzare a forza bruta i byte circostanti - cfr. PoCGTFO 14:10.
Esempi:
Con un prefisso vuoto:``` 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
Altri esempi, con un prefisso identico: [1](https://github.com/decalage2/collisions/blob/master/examples/fastcoll1.bin) ⟷ [2](https://github.com/decalage2/collisions/blob/master/examples/fastcoll2.bin)
**Variante**: esiste una [collisione MD5 a blocco singolo](https://marc-stevens.nl/research/md5-1block-collision/) ma richiede cinque settimane di calcolo.
Ecco una [registrazione](https://github.com/decalage2/collisions/blob/master/examples/fastcoll.svg) di un calcolo FastColl senza alcun prefisso
e [un'altra](https://github.com/decalage2/collisions/blob/master/examples/fastcoll-prefix.svg) con un prefisso.
### [UniColl](https://github.com/decalage2/collisions/blob/master/unicoll.md) (MD5)
Documentata nel [2012](https://www.cwi.nl/system/files/PhD-Thesis-Marc-Stevens-Attacks-on-Hash-Functions-and-Applications.pdf#page=199), implementata nel [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) ti permette di controllare alcuni byte nei blocchi di collisione,
prima e dopo la prima differenza, il che la rende una collisione a prefisso identico con alcune differenze controllabili, quasi come una collisione a prefisso scelto.
Questo è molto comodo e, ancora meglio, la differenza può essere molto prevedibile:
nel caso di `m2+= 2^8` (noto anche come `N=1` / `m2 9` nello script [poc_no.sh](https://github.com/cr-marcstevens/hashclash/blob/master/scripts/poc_no.sh#L30) di HashClash),
la differenza è +1 sul nono byte, il che la rende molto sfruttabile,
tanto che puoi persino ragionare sulla collisione a mente:
il nono carattere di quella frase verrà sostituito con il successivo: `0` sostituito da `1`, `a` sostituito da `b`..
- tempo: alcuni minuti (dipende dalla quantità di byte che vuoi controllare )
- spazio: due blocchi
- differenze: ```
.. .. .. .. DD .. .. .. ..
.. .. .. .. +1 .. .. .. ..
Esempi con N=1 e 20 byte di testo fisso nei blocchi di collisione:```
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 ha meno controllo di una vera collisione a prefisso scelto,
ma è molto più veloce, soprattutto perché richiede solo due blocchi.
Ecco una [registrazione](https://github.com/decalage2/collisions/blob/master/examples/unicoll.svg) di un calcolo UniColl.
### [Shattered](http://shattered.io) (SHA1)
Documentato nel [2013](https://marc-stevens.nl/research/papers/EC13-S.pdf), calcolato nel [2017](http://shattered.io).
- tempo: 6500 anni.CPU e 110 anno.GPU
- spazio: due blocchi
- differenze: ```
.. .. .. DD ?? ?? ?? ??
or
?? ?? ?? DD .. .. .. ..
La differenza tra i blocchi di collisione di ciascun lato è questa maschera 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
Esempi: [PoC||GTFO 0x18](https://github.com/angea/pocorgtfo#0x18) usa i prefissi SHA1 calcolati,
riutilizzando l'immagine direttamente dal sorgente PDFLaTeX (vedere [articolo 18:10](https://archive.org/stream/pocorgtfo18#page/n62/mode/1up)),
ma controlla anche il valore dei prefissi tramite JavaScript nella pagina HTML (il file è poliglotta, ZIP HTML e PDF).
## Collisioni a prefisso scelto
Consentono di far collidere qualsiasi contenuto.
| 𝓐 | ≠ | 𝔅 |
| :----: |:-:| :----: |
| Collisione *A* | ≠ | Collisione *B* |
1. prendere due prefissi arbitrari
2. allungare il più corto finché non è lungo quanto il più lungo. entrambi vengono riempiti fino al blocco successivo - meno 12 byte
- questi 12 byte di dati casuali verranno aggiunti su entrambi i lati per randomizzare la ricerca del compleanno
3. X blocchi di quasi-collisione verranno calcolati e aggiunti.
Quanti meno blocchi, tanto più lunga è la computazione.
Es.: [400 kHours per un blocco](https://www.win.tue.nl/hashclash/SingleBlock/). 72 core-ore per nove blocchi con [HashClash](https://github.com/cr-marcstevens/hashclash).
Le collisioni a prefisso scelto sono potentissime, ma possono richiedere molto tempo anche solo per una coppia di file.
### [HashClash](https://github.com/cr-marcstevens/hashclash) (MD5)
Versione finale nel [2009](https://www.win.tue.nl/hashclash/ChosenPrefixCollisions/).
Esempi: facciamo collidere `yes` e `no`. Ci sono volute tre ore su 24 core.```
'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
Ecco un log dell'intera operazione.
Shambles è una collisione a prefisso scelto molto costosa che utilizza 9 blocchi.
Ogni blocco ha lo stesso pattern XOR di Shattered:``` 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
## Riepilogo degli attacchi
Hash | Nome | Data | Durata | Tipo di prefisso | Controllo vicino alla diff
---- | --------- | ---- | -------- | ----------- | -----------------
MD5 | FastColl | 2009 | 2s | Identico | nessuno
| UniColl | 2012 | 7-40min | Identico | 4-10 byte
| HashClash | 2009 | 72h | Scelto | n/a
| | | | |
SHA1 | Shattered | 2013 | 6500yr | Identico | prefisso e suffisso
| Shambles | 2020 | ? | Scelto | n/a
# Sfruttamenti
Le collisioni a prefisso identico sono generalmente considerate (molto) limitate, ma il prefisso scelto richiede tempo.
Un altro approccio consiste nel creare prefissi riutilizzabili tramite un attacco a prefisso identico come UniColl - oppure a prefisso scelto per superare alcune limitazioni - ma riutilizzando quella coppia di prefissi in combinazione con due payload come in un classico attacco a prefisso identico.
Una volta calcolata la coppia di prefissi, far collidere due contenuti diventa immediato:
è solo questione di manipolare i dati del file (secondo i formati di file specifici) affinché si adattino alle specifiche dei formati e ai requisiti del prefisso precalcolato.
## Strategia standard
Collisioni classiche di due file validi con lo stesso tipo di file.
### JPG
Limitazioni teoriche e soluzioni alternative:
- il segmento *Application* dovrebbe in teoria stare subito dopo il marker *Start of Image*.
In pratica, non è necessario, quindi la nostra collisione può essere generica: l'unica limitazione è la dimensione dell'immagine più piccola.
- la lunghezza di un commento è memorizzata su due byte, quindi la quantità che può contenere è limitata a 65536 byte (circa la dimensione di una foto 400x400)
- invece di saltare oltre un intero file JPG, si può dividere il file nei suoi segmenti e aggiungere trampolini di salto tra i segmenti
*commenti su ogni segmento dell'immagine*
*come funzionano i trampolini dei commenti*
- mentre la maggior parte della struttura di un JPG è composta da segmenti tutti limitati a 65536 byte di dimensione,
i dati compressi veri e propri sono memorizzati nel *Entropy Coded Segment* che non rispetta queste limitazioni:
la sua dimensione non è nota in anticipo e cresce oltre quel limite.
Cresce con la dimensione dell'immagine, costituendo gran parte della dimensione del file in un'immagine baseline (non progressiva).
Per far rientrare l'intera immagine in blocchi da 64kb, il modo semplice è provare prima a salvare l'immagine come progressiva (cosa che qualsiasi software può fare, e che divide l'ECS tipicamente in fino a sei scansioni). Il modo più avanzato è usare *JPEGTran* con il suo parametro da riga di comando 'wizard' `--scans` e definire scansioni personalizzate.
Non ci sono altre restrizioni oltre ai segmenti delle scansioni,
quindi una collisione MD5 di due JPG arbitrari è *istantanea* e non richiede una collisione a prefisso scelto, ma solo UniColl.
Con lo [script](https://github.com/decalage2/collisions/blob/master/scripts/jpg.py):```
21:07:35.65>jpg.py Ange.jpg Marc.jpg
21:07:35.75>
Esempi:
⟷
2 JPG con collisione MD5
Ecco un esempio di definizione degli scan di JPEGTran per trasformare un'immagine RGB 1944x2508 in un JPG al 100% con 20 scan, in cui rientrano tutti in 64kb.``` // : -, , ;
// 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;
Risultato:
*una immagine RGB 1944x2508 come JPG al 100% con 20 scansioni*
### PNG
Limitazioni teoriche e soluzioni alternative:
- PNG usa CRC32 alla fine dei suoi chunk, ma in pratica vengono ignorati. Possono essere corretti ma non è richiesto.
- i metadati dell'immagine (dimensioni, spazio colore...) sono memorizzati nel chunk `IHDR`,
che in teoria dovrebbe trovarsi subito dopo la firma (cioè prima di qualsiasi potenziale commento),
quindi significherebbe che possiamo precalcolare collisioni solo di immagini con gli stessi metadati.
Tuttavia, quel chunk può in realtà trovarsi dopo un blocco di commento (nella stragrande maggioranza dei lettori, eccetto quelli Apple), quindi possiamo mettere i dati di collisione prima dell'header,
il che consente di collidere qualsiasi coppia di PNG con un singolo precalcolo.
Poiché un chunk PNG ha una lunghezza di quattro byte, non c'è bisogno di modificare la struttura di nessuno dei due file: possiamo saltare un'intera immagine in un colpo solo.
Possiamo inserire tutti i chunk scartati che vogliamo, quindi possiamo aggiungerne uno per l'allineamento, poi uno la cui lunghezza verrà alterata da una UniColl. così la lunghezza sarà `00` `75` e `01` `75`.
Quindi una collisione MD5 di due immagini PNG arbitrarie è *istantanea*, senza prerequisiti (nessun calcolo, solo alcune piccole modifiche ai file), e non richiede una collisione a prefisso scelto, solo UniColl.
Con lo [script](https://github.com/decalage2/collisions/blob/master/scripts/png.py):```
19:27:04.79>png.py nintendo.png sega.png
19:27:04.87>
Esempi:
⟷
2 PNG in collisione MD5 con proprietà diverse
Ecco una registrazione dell'intera operazione.
La maggior parte dei lettori accetta senza problemi file PNG che iniziano con un chunk che non è IHDR.
Tuttavia, alcuni (come Safari e Preview - altri?) non lo tollerano. In questo caso, l'header dell'immagine e le sue proprietà (dimensioni, spazio colore) devono venire prima, davanti a qualsiasi blocco di collisione.
In questo caso, entrambi i file in collisione devono avere le stesse proprietà. Anche in questo caso UniColl è sufficiente e, naturalmente, la coppia di prefissi calcolata può essere riutilizzata per qualsiasi altra coppia di file con le stesse proprietà
Ecco uno script per far collidere qualsiasi coppia di tali file, che avvia UniColl se necessario per calcolare la coppia di prefissi.
Esempi:
⟷
⟷
2 coppie di PNG in collisione MD5 con proprietà identiche per la massima compatibilità
Ecco una registrazione dell'intera operazione quando viene invocato UniColl,
e un'altra quando il prefisso è già stato calcolato.
Il formato GIF è complicato:
Tuttavia, i chunk di commento seguono una struttura peculiare: sono una catena di <length:1> <data:length> fino a quando non viene definita una lunghezza nulla.
Quindi qualsiasi byte non nullo diventa un valido 'salto in avanti'. Ciò lo rende adatto all'uso con FastColl,
come mostrato in PoC||GTFO 14:11.
Quindi almeno, anche se non possiamo avere un prefisso generico, possiamo far collidere qualsiasi coppia di GIF con gli stessi metadati (dimensioni, palette) e ci serve solo un secondo di FastColl per calcolarne il prefisso.
Ora il problema è che non possiamo saltare un'intera immagine come nel PNG o su una grande struttura come nel JPG.
Una possibile soluzione alternativa è rimaneggiare i dati compressi o suddividere l'immagine in aree minuscole come nel caso della hashquine GIF, ma non è ottimale.
Un'altra idea che funziona genericamente è che anche i dati dell'immagine sono memorizzati usando questa struttura a sequenza length data:
quindi se prendiamo due GIF senza animazione, dobbiamo solo:
Con una configurazione minima (solo poche centinaia di byte di overhead), possiamo scivolare su qualsiasi immagine GIF e aggirare il limite di 256 byte. Questa idea è stata suggerita da Marc, ed è geniale!
Quindi, in definitiva, le attuali limitazioni GIF per le collisioni MD5 istantanee sono:
gifsicle --use-colormap webUna scorciatoia semplice per normalizzare immagini GIF statiche è trasformarle in frame di animazione della stessa immagine; poi possiamo usare uno script per riutilizzare o calcolare blocchi FastColl e creare una coppia di file che li mostri entrambi.
Esempi:
⟷
2 GIF in collisione MD5 - immagini di KidMoGraph
Ecco una registrazione dell'intera operazione.
Specifiche GZIP v4.3: RFC 1952 (1996).
1F 8B. Se non corrisponde alla firma, il parsing si ferma, il che può essere usato per fermare forzatamente il parsing tra due payload, ma attiverà alcuni avvisi che potrebbero causare problemi. Un'altra strategia è aggiungere un membro vuoto extra alla fine del file e far terminare il parsing di entrambi i payload lì - sul membro o sul suo corpo.filename e il file comment opzionali sono terminati da null, mentre il Extra field è definito da una dimensione a 16 bit, quindi abusabile. È composto da uno o più sottocampi, con un ID e una propria sotto-lunghezza, ma i sottocampi non sono obbligatori - pochissimi sono definiti ufficialmente.Pertanto un membro gzip vuoto con un extra field è un perfetto host parassita.
Se il file superiore è troppo grande per entrare in un extra field, il suo stream non compresso può essere diviso in file più piccoli finché non riescono tutti a entrare negli extra field.
Dopo l'header di un membro vengono il suo corpo compresso, il suo CRC32 e la sua dimensione non compressa (non obbligatori). Pertanto un corpo dati vuoto con CRC32 e dimensione nulli costituisce un postwrap generico, che può persino essere condiviso da diversi header di membri.
Varie implementazioni si basano sulla dimensione non compressa dell'ultimo membro invece che sulla somma di tutti i membri. Quindi i nostri file in collisione risulteranno avere dimensione nulla, perché questi file terminano con un membro vuoto usato come trampolino.
Ecco uno script per generare collisioni MD5 istantanee di due file GZip. Impiega la maggior parte del tempo a decomprimere e ricomprimere i dati se i file di input sono grandi - i prefissi di collisione sono precalcolati. Non è possibile dividere i membri senza decomprimere, perché il CRC32 non compresso deve essere calcolato.
Un .tar.gz è semplicemente l'archivio gzip di un archivio tar. Funzionerà bene con tar gzippati, a differenza di tar stesso.
Esempi: collision1.tar.gz (Pacome) ⟷ collision2.tar.gz (Reg)
Il Portable Executable ha una struttura peculiare:
Quindi la strategia è:
DOS/Collisions/Header1/Header2. Basta applicare un delta agli offset delle due tabelle delle sezioni.Questo significa che è possibile far collidere istantaneamente qualsiasi coppia di eseguibili PE. Anche se usano sottosistemi o architetture diverse.
Mentre le collisioni di eseguibili sono di solito banali tramite qualsiasi loader, questo tipo di sfruttamento qui è trasparente: il codice è identico e caricato allo stesso indirizzo.
Esempi: tweakPNG.exe (GUI) ⟷ fastcoll.exe (CLI)
Ecco uno script per generare collisioni MD5 istantanee di eseguibili Windows.
Il container di questo formato è una sequenza di chunk Length Type Value chiamati Atom.
La lunghezza è un big-endian a 32 bit e copre sé stessa, il tipo e il valore, quindi la lunghezza normale minima è 8
(il tipo è una stringa di 4 caratteri ASCII).
Se la lunghezza è nulla, l'atom occupa il resto del file - come gli atom jp2c nei file JP2.
Se è 1, il Type è seguito da una lunghezza a 64 bit, trasformando l'atom in Type Length Value, rendendolo compatibile con altre collisioni come Shattered.
Alcuni atom contengono altri atom: in questi casi vengono chiamati box. Ecco perché questa struttura altrimenti senza nome è chiamata "atom/box".
Questo formato "atom/box" usato in MP4 è in realtà un derivato di Apple Quicktime, ed è usato da molti altri formati (JP2, HEIF, F4V).
Il primo tipo di atom è di solito ftyp, che consente di differenziare il formato file effettivo.
Il formato è piuttosto permissivo:
basta concatenare atom free, abusare della lunghezza di uno con UniColl, e poi saltare il primo payload.
Per i file MP4, l'unica cosa da aggiungere è regolare le tabelle stco (Sample Table - Chunk Offsets) o co64 (l'equivalente a 64 bit), poiché sono offset assoluti(!) che puntano ai dati video mdat - e sono effettivamente obbligatori!
Questo dà uno script che fa collidere istantaneamente qualsiasi video arbitrario - e come accennato, potrebbe funzionare su formati diversi da MP4.

Esempi (video di KidMoGraph):
lunghezze a 32 bit (standard) collision1.mp4 ⟷ collision2.mp4
⟷
lunghezze a 64 bit collisionl1.mp4 ⟷ collisionl2.mp4
⟷
Nota che alcuni visualizzatori (OS X, Safari, FireFox) non permettono un file che inizia con un Atom diverso da ftyp.
In questo caso, il prefisso deve coprire questo aspetto, e non è così generico, ma per il resto è la stessa strategia - solo limitata a un singolo tipo di file.
I file JPEG2000 di solito iniziano con la struttura Atom/Box come MP4,
poi l'ultimo atom jp2c arriva tipicamente fino alla fine del file (lunghezza nulla),
e da questo punto in poi segue la struttura JFIF, come JPEG (iniziando con FF 4F come marcatore di segmento).
Anche la forma puramente JFIF è tollerata, nel qual caso la collisione è come JPEG: compatibile con Shattered, ma con commenti limitati a 64Kb.
D'altra parte, se manipoli i file JPEG2000 con la struttura Atom/Box, non hai questa limitazione.
Come accennato prima, se stai cercando di far collidere questa struttura e
se ci sono più restrizioni - per esempio iniziare con un atom free non è tollerato da alcuni formati -
puoi calcolare un'altra coppia di prefissi UniColl specifica per questo formato:
JPEG2000 sembra imporre un atom 'jP ' prima del solito ftyp,
ma a parte questo, questa è l'unica restrizione: non c'è bisogno di spostare nulla.
Quindi lo script risultante è ancora più semplice!

Esempi: collision1.jp2 ⟷ collision2.jp2
A proposito di Shattered
Lo sfruttamento di Shattered non era un trucco PDF, ma un trucco JPG all'interno di un PDF.
Permetteva solo a un PDF di contenere un oggetto compresso JPG che poteva avere due contenuti diversi. Per il resto, entrambi i PDF dovevano essere del tutto identici.
Nota che i documenti possono essere del tutto normali e possono semplicemente ritagliare il JPG in collisione e visualizzarlo in punti diversi, come nei documenti multipagina.
il documento Shattered che usa un JPG in collisione in due punti
Collisioni PDF con MD5
Con MD5 (e altri pattern di collisione), possiamo fare collisioni PDF a livello di documento, senza alcuna restrizione su nessuno dei due file!
Il PDF ha una struttura molto diversa dagli altri formati di file. Usa numeri di oggetto e riferimenti per definire un albero. L'intero documento dipende dall'elemento Root.
Questo (valido) 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>>
è equivalente a:``` 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>>
Trucchi:
XREF.Quindi memorizzare due alberi di documenti nello stesso file è consentito. Dobbiamo solo fare in modo che l'oggetto root faccia riferimento all'oggetto root di uno dei due documenti.
Quindi dobbiamo solo prendere due documenti,
rinumerare oggetti e riferimenti in modo che non ci siano sovrapposizioni,
creare una collisione in modo che il numero di elemento referenziato come oggetto Root possa essere modificato mantenendo lo stesso valore hash,
il che è perfetto per UniColl con N=1, e adattare di conseguenza la tabella XREF.
In questo modo, possiamo mettere in collisione in sicurezza qualsiasi coppia di PDF, indipendentemente da numeri di pagina, dimensioni, immagini...
commenti
I PDF possono memorizzare dati esterni in due modi:
\r e \n).
Questo può essere usato all'interno di un oggetto dizionario, per modificare ad esempio un riferimento a un oggetto, tramite UniColl.
Quindi questo è un oggetto PDF valido anche se contiene blocchi di collisione binari — basta riprovare finché non ci sono caratteri newline: ```
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
colliding text
Il primo caso rende possibile evidenziare la bellezza di UniColl, una collisione in cui le differenze sono prevedibili, così puoi scrivere poesie su dati in collisione - grazie a Jurph!
Piuttosto che modificare la struttura del documento e ingannare i parser, useremo semplicemente i blocchi di collisione direttamente per produrre direttamente testo, con una lettura alternativa!``` 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. ^ ^
Esempi: [poeMD5 A](https://github.com/decalage2/collisions/blob/master/examples/poeMD5_A.pdf) ⟷ [poeMD5 B](https://github.com/decalage2/collisions/blob/master/examples/poeMD5_B.pdf)
*Una vera creazione artistica crittografica :)*
(Nota: ho combinato un pasticcio con la compatibilità Adobe, ma è colpa mia, non di UniColl)
**Struttura del documento in collisione**
Che tu usi UniColl come commento inline o come prefisso scelto in un oggetto di flusso fittizio, la strategia è simile:
rimescolare i numeri degli oggetti, poi far sì che l'oggetto Root punti a oggetti diversi,
quindi, a differenza di Shattered, questo significa una collisione istantanea di qualsiasi coppia arbitraria di PDF, a livello di documento.
Un trucco utile è che l'output di [`mutool clean`](https://mupdf.com/docs/manual-mutool-clean.html) è prevedibilmente affidabile,
quindi può essere usato per normalizzare PDF come input e sistemare il PDF unito mantenendo le parti importanti del file non modificate.
MuTool non scarta chiavi/valori fittizi - a meno che non glielo si chieda - e li mantiene nello stesso ordine,
quindi usare voci di dizionario finte come `/MD5_is /REALLY_dead_now__` è perfetto per allineare le cose in modo prevedibile senza bisogno di un altro tipo di commenti.
Tuttavia non mantiene i commenti nei dizionari (quindi niente trucco del commento inline)
Un modo semplice per eseguire l'operazione di rimescolamento degli oggetti senza problemi è semplicemente unire entrambi i file PDF
tramite `mutool merge` e poi dividere l'oggetto `/Pages` in due.
Per fare spazio a questo oggetto, basta unire un PDF fittizio davanti ai due documenti.
Facoltativamente, crea un riferimento fittizio all'array pendente
per impedire che la garbage collection elimini il secondo insieme di pagine.
**Esempio**:
con questo [script](https://github.com/decalage2/collisions/blob/master/scripts/pdf.py),
ci vogliono [meno di un secondo](https://github.com/decalage2/collisions/blob/master/examples/pdf.log) per far collidere i due articoli PDF pubblici come Spectre e Meltdown:
Esempi: [spectre.pdf](https://github.com/decalage2/collisions/blob/master/examples/collision1.pdf) ⟷ [meltdown.pdf](https://github.com/decalage2/collisions/blob/master/examples/collision2.pdf)
Possibile estensione: concatenare blocchi UniColl per mantenere anche coppie dei vari [oggetti non critici](https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/PDF32000_2008.pdf#page=81)
che possono essere referenziati nell'oggetto Root - come `Outlines`, `Names`, `AcroForm` e Additional Actions (`AA`) - nei file sorgente originali.
**in PDFLaTeX**
Le tecniche precedenti funzionano con una semplice coppia di file PDF,
ma è anche possibile farlo direttamente dai sorgenti TeX
tramite [specifici operatori PDFTeX](http://texdoc.net/texmf-dist/doc/pdftex/manual/pdftex-a.pdf).
Puoi definire oggetti direttamente - incluse chiavi e valori fittizi per gli allineamenti - e definire oggetti vuoti per riservare alcuni slot di oggetti includendo questo all'inizio stesso dei tuoi sorgenti 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
Non dimenticare di normalizzare l'output di PDFLaTeX - con mutool per esempio - se necessario:
PDFLaTeX rende difficile ottenere build riproducibili tra distribuzioni - potresti persino voler fissare il tempo di esecuzione per ottenere l'hash esatto se richiesto.
Potresti pensare che il JPG sia solo immagini, ma in un PDF e in alcuni lettori PDF (non browser, come Evince e Adobe Reader), può essere usato come contenuto di pagina proprio come qualsiasi altro oggetto incorporato, che è incorporato in un'immagine JPEG.
Per archiviare i dati JPEG senza perdite, salvalo come scala di grigi al 100%, oppure usa un'immagine di una singola riga/colonna, o ripeti la riga di dati 8 volte (poiché i blocchi JPEG sono 8x8), e i tuoi dati vengono archiviati senza perdite e referenziati dalle pagine PDF.
Esempi di due PDF in collisione SHA-1 tramite dati di pagina JPEG (un'immagine in scala di grigi che renderizza colori) come contenuto di pagina vettoriale:
2 PDF in collisione SHA-1 con dati immagine archiviati come JPG
È possibile referenziare il JPG in collisione due volte: come contenuto di pagina, senza perdite, che si riferisce anche a se stesso come immagine lossy da visualizzare. Di nuovo, l'immagine da visualizzare è in scala di grigi, ma il contenuto di pagina può renderizzare alcuni colori tramite operatori PDF.
La parte superiore dell'immagine mostra il contenuto di pagina ripetuto 8 volte.
Esempi di due PDF in collisione SHA-1 tramite JPEG usato come dati di pagina e immagine da visualizzare:
2 PDF in collisione SHA-1 con JPG usato come immagine e contenuto di pagina
TL;DR Non esiste una collisione generica riutilizzabile per ZIP, ma esiste per i formati basati su ZIP. Dovrebbe essere possibile far collidere due file in 2h.core (36 volte più veloce del chosen-prefix)
Gli archivi ZIP sono un sandwich di 3 strati (almeno).
Prima arriva il contenuto dei file (sequenza di strutture Local File Header, una per file o directory archiviata),
poi un indice (di nuovo, una sequenza di Central Directory),
poi una singola struttura che punta a questo indice (End Of Central Directory).
L'ordine di questi strati non può essere modificato. Alcuni parser necessitano solo della struttura del contenuto del file, ma non è un modo corretto di eseguire il parsing e può essere abusato.
A causa di questo ordine richiesto, non esiste un prefisso generico che possa aiutare per qualsiasi collisione.
approccio non generico
Un altro approccio potrebbe essere semplicemente unire entrambi gli archivi, con i loro livelli uniti, e usare UniColl - ma con N=2, che introduce una differenza sul 4° byte - per neutralizzare la firma magica dell'End of Central Directory.
Questo significa che si potrebbero far collidere due ZIP arbitrari con un singolo UniColl e 24 byte di prefisso impostato.
Un tipico End of Central Directory, che è di 22 byte se il commento è vuoto:``` 00: 504b 0506 0000 0000 0000 0000 0000 0000 PK.............. 10: 0000 0000 0000 ......
Se usiamo questo come prefisso (riempiamo il prefisso a 16 bit) per UniColl e `N=2`, la differenza è sul 4° byte, annullando il magic `.P .K 05 06` cambiandolo prevedibilmente in `.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..(
[No content provided to translate.]``` 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..(
Questo non è affatto generico, ma molto più veloce della collisione con prefisso scelto:```
real 12m23.993s
user 112m24.072s
sys 2m0.194s
Un problema è che alcuni parser analizzano ancora i file ZIP alla rovescia anche se dovrebbero analizzarli partendo dal fondo:
un modo per assicurarsi che entrambi i file siano analizzati correttamente è concatenare due blocchi UniColl,
per abilitare/disabilitare ogni End of Central Directory.
Per evitare che i parser ZIP si lamentino dello spazio inutilizzato,
si può abusare degli Extra Fields,
dei commenti di file nella Central Directory e dei commenti di archivio nell'End of Central Directory.

Esempio: ecco un sorgente assembly che descrive la struttura di uno ZIP duale, in grado di contenere due diversi file di archivio.
Dopo due computazioni UniColl, produce i due file in collisione: collision1.zip ⟷ collision2.zip
Anche se il formato Zip stesso non può essere sfruttato genericamente come Gzip, alcuni formati che si basano su Zip possono essere sfruttati genericamente all'interno di archivi Zip con una struttura predefinita. È necessario prendere alcune precauzioni per rendere generica la collisione Zip.
Alcuni formati sono multi-file memorizzati in un archivio Zip e si affidano a un file radice con un nome file fisso che punta ad altri file dell'archivio. Molti di essi usano XML o testo per il file radice e memorizzano gli altri file così come sono.
Idea : far coesistere 2 insiemi di file nello stesso archivio e puntare a uno o all'altro insieme di file. Una radice generica può essere memorizzata per prima all'inizio del file, ma i blocchi di collisione sono memorizzati all'esterno del contenuto del file, nell'archivio (poiché le collisioni hanno un'entropia molto elevata, è impossibile sfruttare file XML o solo ASCII con le collisioni).
Steps:
Mettere 2 insiemi di file da 2 origini nello stesso archivio - ad esempio in sottodirectory diverse.
Modificare il file radice per puntare alternativamente a ciascun insieme.
Poiché timestamp, lunghezza e CRC del file radice sono memorizzati sia nel Local File Header - prima del contenuto del file - sia nella Central Directory - dopo il contenuto del file - questi valori non dovrebbero cambiare tra le due versioni dei file.
Central Directory non è corretto, questa copia del valore potrebbe essere ignorata dal parser, ma forgiare un CRC32 su un valore costante è utile per evitare del tutto il problema.
Forgiare il CRC aggiungendo 4 byte casuali probabilmente non sarà sufficiente, poiché questi file radice sono tipicamente in XML o testo con sintassi rigide, e quindi diventerebbero invalidi.
CrcHack aiuta notevolmente a forgiare CRC con bit arbitrari e senza brute force, assicurando che il file di output sia ASCII e che i bit modificati si trovino comunque in un commento.Usare l'extra field di un file fittizio extra -- anche vuoto -- nell'archivio dopo il file radice è un modo elegante per memorizzare i blocchi di collisione di Hashclash: in questo modo, l'archivio Zip mantiene una struttura standard e può essere facilmente manipolato in seguito, anche con strumenti standard.
Gli Extra Fields non hanno CRC32 e la loro lunghezza di 16 bit è dichiarata negli header precedenti. Hanno un proprio formato interno ID:2 Size:2 Data ma di solito viene ignorato, e sono presenti sia nel Local File Header sia nella Central Directory, ma possono essere assenti dalla Central Directory per mantenere il suffisso identico dopo i blocchi di collisione.
La presenza del file extra che copre i blocchi di collisione nel suo extra field potrebbe dover essere dichiarata nella struttura del formato, ad esempio nel file [Content_Types].xml di un documento OOXML. Altri file XML nel suffisso potrebbero dover essere modificati, poiché alcuni formati richiedono l'uso di percorsi assoluti.
Ecco la struttura complessiva dell'exploit generico per uno specifico formato basato su Zip:``` [Root file] (with constant CRC32)
[Dummy file] (with collision blocks in the extra field)
[...] <- rest of the archive, with 2 documents merged
So by predefining the root file contents and forging ASCII CRC32s, one can compute a generic re-usable Hashclash collision for a specific zip-based format.
### Riepilogo dei requisiti
- due o più prefissi
- uno o più tipi di file (i polyglot funzionano senza problemi)
- un file radice XML con nome file, lunghezza del file e CRC fissi: queste informazioni sono presenti due volte, prima e dopo i blocchi di collisione
- i contenuti sono XML arbitrari
- il padding è possibile, anche tramite commento XML, per raggiungere la stessa lunghezza.
- il CRC può essere impostato (tramite CrcHack) su ciascun contenuto.
- entrambi i set di file coesistono nel suffisso, probabilmente in directory diverse. Alcuni strumenti hardcodano il percorso, il che può ridurre la compatibilità.
- potrebbe essere necessario unire un file XML *Content type* per coprire tutti i file, supportati e non supportati (blocchi di collisione e documento alternativo)
### Esempi
#### CRC32
Un commento XML minimale (solo ASCII) con un CRC32 forgiato (calcolo immediato) con CrcHack.``` 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-->
Un altro esempio in cui si regola il CRC con il caso di un messaggio alfabetico.```bash echo "" | crchack.exe -b 4:+.8*32:.8 - 0xcafebabe
#### Collisioni
[zInsider](https://github.com/decalage2/collisions/blob/master/scripts/zinsider.py) è uno script per generare istantaneamente collisioni MD5 di coppie di documenti arbitrari usando questi formati ZIP+XML:
- Office Open XML: docx / pptx / xlsx
- Open Container Format: epub
- Open Packaging Conventions:
- formato di produzione 3D: 3mf
- XML Paper Specification: xps / oxps
Per generare i tuoi prefissi di collisione, [ecco uno script](https://github.com/decalage2/collisions/blob/master/scripts/makezip.py) per generare una coppia di zip radice.
Dopo aver calcolato le collisioni, usa [quest'altro script](https://github.com/decalage2/collisions/blob/master/scripts/extendzip.py) per combinare questa coppia di radici con un suffisso comune.
Alcuni PoC di collisione:
- Office Open XML: Excel ([1](https://github.com/decalage2/collisions/blob/master/examples/free/md5-1.xls) - [2](https://github.com/decalage2/collisions/blob/master/examples/free/md5-2.xls)), Powerpoint ([1](https://github.com/decalage2/collisions/blob/master/examples/free/md5-1.pptx) - [2](https://github.com/decalage2/collisions/blob/master/examples/free/md5-2.pptx)), Word ([1](https://github.com/decalage2/collisions/blob/master/examples/free/md5-1.docx) - [2](https://github.com/decalage2/collisions/blob/master/examples/free/md5-2.docx)).
- Open Container Format: Epub ([1](https://github.com/decalage2/collisions/blob/master/examples/collision-1.epub) - [2](https://github.com/decalage2/collisions/blob/master/examples/collision-2.epub)).
- Open Packaging Conventions: 3MF ([1](https://github.com/decalage2/collisions/blob/master/examples/collision-1.3mf) - [2](https://github.com/decalage2/collisions/blob/master/examples/collision-2.3mf)), XPS ([1](https://github.com/decalage2/collisions/blob/master/examples/collision-1.xps) - [2](https://github.com/decalage2/collisions/blob/master/examples/collision-2.xps)).
Alcuni formati con più file basati su Zip non possono essere sfruttati genericamente:
- Quake PK3: uno zip di file senza una radice specifica.
- Open Document Format: il file `META-INF/manifest.xml` deve menzionare tutti gli altri file, quindi non può essere generico.
- APK, JAR, XPI: anche il file `META-INF/MANIFEST.mf` deve menzionare tutti gli altri file, con i loro hash.
Grazie a [Philippe Lagadec](https://twitter.com/decalage2) per il suo aiuto sui formati di file Office!
## Strategie insolite
Le collisioni di solito riguardano due file validi dello stesso tipo.
### MultiColls: catena di collisioni multiple
Nulla impedisce di concatenare più blocchi di collisione,
e avere più di due contenuti con lo stesso valore di hash.
Un esempio sono gli *hashquines* - che mostrano il proprio valore MD5.
Il file [PoCGTFO 14](https://github.com/angea/pocorgtfo#0x14) contiene 609 collisioni FastColl,
per farlo tramite due tipi di file nello stesso file.
### Validità
Una strategia diversa sarebbe uccidere il tipo di file per bypassare la scansione come file corrotto.
Basterà sovrascrivere la firma magica.
Appendere entrambi i file (validi o non validi) con un formato
che non deve trovarsi all'offset 0 (archivio, come ZIP/RAR/...) rivelerebbe un altro tipo di file.
Questo consente collisioni poliglotte senza usare una collisione chosen-prefix:
1. usa UniColl per abilitare o disabilitare una firma magica, ad esempio un PNG:
2. appende un archivio ZIP
Sebbene tecnicamente entrambi i file siano uno ZIP valido, poiché la maggior parte dei parser restituisce il primo tipo di file trovato e inizia a scansionare dall'offset 0, vedranno un tipo di file diverso.
Esempi:
⟷ [non valido](https://github.com/decalage2/collisions/blob/master/examples/png-invalid.png)
### PolyColls: collisioni tra tipi di file diversi
È anche possibile avere entrambi i lati di una collisione con tipi diversi per ridurre i sospetti:
Scenario d'attacco:
1. invia `holiday.jpg`
2. fallo inserire nella whitelist
3. invia `evil.exe`, che ha lo stesso MD5.
In questi casi, è richiesta una collisione chosen-prefix
se entrambi i formati di file devono iniziare all'offset 0.
Alcuni esempi di layout polycoll:

*Polycoll PDF/JPG*

*Polycoll PE/PNG*
#### PE - JPG
Poiché un header PE di solito è più piccolo di 0x500 byte, è perfetto per un commento JPG:
1. inizia con gli header DOS/JPG
2. il commento JPEG salta oltre l'header PE
3. inserisci l'immagine JPG completa
4. inserisci tutte le specifiche PE
Ancora una volta, la collisione è [istantanea](https://github.com/decalage2/collisions/blob/master/scripts/jpgpe.py)
Esempi: [fastcoll.exe](https://github.com/decalage2/collisions/blob/master/examples/jpg-pe.exe) ⟷ [Marc.jpg](https://github.com/decalage2/collisions/blob/master/examples/jpg-pe.jpg)
#### PDF - PE
Unire un PDF a un file fittizio con `mutool` è un buon modo generico per riordinare gli oggetti
e poi rendere i primi due oggetti scartabili (pagina fittizia e contenuto),
il che è perfetto per un oggetto `stream` contenitore di lunghezza sconosciuta come `1 0`,
e la cui lunghezza è referenziata più avanti (dopo i blocchi di collisione) nel secondo oggetto.
L'unico problema è che `mutool` incorporerà sempre la lunghezza - e rimuoverà il riferimento alla lunghezza,
quindi deve essere reinserita nel PDF al posto del valore,
ma la maggior parte dei riferimenti `2 0 R` sarà più piccola delle lunghezze hardcoded.
Per fortuna questo può essere sistemato senza alterare alcun offset degli oggetti,
quindi non c'è bisogno di correggere la XREF.
Ecco uno [script](https://github.com/decalage2/collisions/blob/master/scripts/pdfpe.py) per, ad esempio, far collidere all'istante un visualizzatore PDF ([Sumatra](https://www.sumatrapdfreader.org/free-pdf-reader.html) è leggero e standalone) e un documento PDF:
Esempi: [Poster.pdf](https://github.com/decalage2/collisions/blob/master/examples/pepdf.pdf) ⟷ [Sumatra.exe](https://github.com/decalage2/collisions/blob/master/examples/pepdf.exe)

*un visualizzatore PDF che mostra un PDF (che a sua volta mostra un PDF) con lo stesso MD5*
#### PDF - PNG
Allo stesso modo, è possibile far collidere ad esempio file PDF e PNG arbitrari senza restrizioni su nessuno dei due lati. È istantaneo, riutilizzabile e generico.
Esempi: [Hello.pdf](https://github.com/decalage2/collisions/blob/master/examples/png-pdf.pdf) ⟷ [1x1.png](https://github.com/decalage2/collisions/blob/master/examples/png-pdf.png)
### PileUps (multi-collisione)
Le collisioni crittografiche non sono limitate a due file!
Come dimostrato nell'esperimento [Nostradamus](https://www.win.tue.nl/hashclash/Nostradamus/) del 2008,
concatenare collisioni rende possibile far collidere più di due file.
Le prime collisioni possono essere identiche o chosen-prefix, le successive devono essere chosen-prefix.
Puoi chiamarle multi-collisioni, io preferisco *pileups* - è più corto :)
#### PE - PNG - MP4 - PDF
Combinando tutte le conoscenze acquisite finora,
ho usato 3 collisioni chosen-prefix per creare 4 prefissi diversi per diversi tipi di file:
documento (PDF), video (MP4), eseguibile (PE) e immagine (PNG).

*diagramma di un pileup PE/PNG/MP4/PDF*
Questo script è generico e istantaneo:

Esempi: [commodore.pdf](https://github.com/decalage2/collisions/blob/master/examples/pileup.pdf) ⟷ [diagram.png](https://github.com/decalage2/collisions/blob/master/examples/pileup.png) ⟷ [kidmo.mp4](https://github.com/decalage2/collisions/blob/master/examples/pileup.mp4) ⟷ [sumatra18.exe](https://github.com/decalage2/collisions/blob/master/examples/pileup.exe)
Poiché potresti distribuire un solo file
ed è impossibile indovinare gli altri valori dei prefissi da esso,
una soluzione è incorporare tutti i prefissi della collisione in codice JavaScript
e inserirlo nei tuoi PoC,
trasformando i tuoi file in [poliglotti HTML](https://github.com/decalage2/collisions/blob/master/examples/polyglot.html) per condividere facilmente i file in collisione correlati.
Il [numero 19](https://github.com/angea/pocorgtfo#0x19) di 'PoC or GTFO' è un tale pileup **e** poliglotta,
che combina un documento di 80 pagine generato con PDFLaTeX, un visualizzatore PDF per Windows,
un diagramma PNG e un breve video MP4 'collision' di [KidMoGraph](https://www.kidmograph.com/)
con un payload HTML per generare gli altri file dalla release PDF
(e anche un archivio ZIP):
Grazie a Rafał Hirsz per il suo costante aiuto su JavaScript.
## Casi d'uso
Meglio eliminare del tutto MD5, perché ispezionare i file richiede troppo tempo ed è troppo rischioso!
### Devi colliderli tutti!
Un altro uso delle collisioni istantanee, riutilizzabili e generiche sarebbe nascondere qualsiasi file di un dato tipo - diciamo PNG - dietro file fittizi (o lo stesso file ogni volta) - che in pratica significa semplicemente concatenarlo allo stesso prefisso dopo aver rimosso la firma - si potrebbe persino fare a livello di libreria!
Da una prospettiva di parsing rigorosa,
tutti i tuoi file mostreranno lo stesso contenuto,
e le immagini maligne verrebbero rivelate come un file con lo stesso MD5 di quelli raccolti in precedenza.
Prendiamo due file:
⟷
e collidiamoli con lo stesso PNG.
Ora mostrano la stessa immagine fittizia, e sono assolutamente identici fino alla seconda immagine a livello di file!
⟷
Il loro payload malvagio è nascosto, rispettivamente, dietro un file con lo stesso MD5.
### File incriminanti
Un altro caso d'uso delle collisioni è nascondere qualcosa di incriminante dentro qualcosa di innocente, ma desiderabile: se l'unico modo per raccogliere prove è confrontare hash deboli,
allora non puoi negare di non avere l'altro file (che mostra contenuti incriminanti ma nasconde contenuti innocenti).
I software in genere si concentrano su un parsing (rapido), non su un'analisi dettagliata dei file.
*un'immagine che mostra anteprime diverse in schede diverse di EnCase Forensic*
## Fallimenti
Non tutti i formati possono avere prefissi generici riutilizzabili:
se una qualche forma di contenitore di dati non può essere inserita tra la firma magica
e gli header standard che sono critici e specifici per ogni file,
allora le collisioni generiche non sono possibili.
Naturalmente, si potrebbero comunque trasformare i vecchi file in uno nuovo,
e persino usare codice per diramarsi verso due payload diversi,
ma è più una questione di porting di payload che di collisione della struttura dei file.
### ELF
L'header ELF è richiesto all'offset 0 e contiene informazioni critiche come 32b/64b,
endianness e ABI fin dall'inizio,
quindi è impossibile avere un prefisso universale e poi blocchi di collisione
prima di parametri critici specifici del file originale.
### Mach-O
Mach-O non inizia nemmeno con la stessa magic per 32b (`feedface`) e 64b (`feedfacf`).
Subito dopo, ci sono il numero e la dimensione dei comandi (come definizione dei segmenti, symtab, versione, ...).
Come per ELF, le collisioni riutilizzabili non sono possibili.
### Java Class
Subito dopo la magic iniziale si trovano le versioni (che possono essere problematiche),
ma il conteggio del constant pool è piuttosto specifico per ogni file,
quindi niente collisioni universali per tutti i file.
Tuttavia, molti file condividono ancora una versione comune e possiamo applicare padding al constant pool più corto fino al conteggio più lungo.
Per prima cosa, inserisci un *literal UTF8* per allineare le informazioni,
poi dichiarane un altro con la lunghezza sfruttata da una UniColl (la lunghezza è memorizzata su 16 byte in big endian).
Tuttavia questo richiederà una manipolazione del codice, poiché tutti gli indici del pool verranno spostati.
Collisioni MD5 riutilizzabili e istantanee per Java Class dovrebbero essere possibili, ma richiedono analisi e modifica del codice.
### TAR
**TL;DR** Nessuna collisione riutilizzabile per i file TAR, nessun'altra strategia se non chosen-prefix.
I Tape Archive sono una sequenza di header e contenuti di file concatenati, tutti allineati a 512 byte.
Non c'è una struttura centrale per l'intero file. Quindi non c'è alcun header globale o commento di alcun tipo da sfruttare.
Un trucco potrebbe essere iniziare con un file fittizio di lunghezza variabile, ma la lunghezza è sempre allo stesso offset, il che non è compatibile con UniColl, il che significa che qui sono utili solo collisioni chosen-prefix.
## Riepilogo dello sfruttamento
Formato | Generico? | 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 ha alcune limitazioni sui dati che possono essere migliorate in una certa misura manipolando la codifica degli scan.
2. PDF con JPG è l'[implementazione iniziale](http://shattered.io) dell'attacco Shattered, ma è solo un puro trucco JPG in un documento PDF.
3. PNG: Safari/Preview richiede che i PNG abbiano il chunk `IHDR` nella prima posizione, prima di qualsiasi blocco di collisione. Questo impedisce un prefisso generico, nel qual caso la collisione è limitata a dimensioni specifiche, spazio colore, BPP e interlacciamento.
4. I formati Atom/Box come MP4 possono funzionare con lo stesso prefisso per diversi sottoformati. Alcuni sottoformati come JPEG2000 o HEIF richiedono una rifinitura extra, ma la strategia di exploit è la stessa - semplicemente la collisione non è possibile tra sottoformati, ma solo con una coppia di prefissi per un sottoformato specifico.
5. Atom/Box è compatibile con Shattered quando si utilizzano lunghezze a 64 bit.
6. Alcuni formati basati su Zip possono essere sfruttati genericamente.
7. Per una migliore compatibilità, ZIP richiede due UniColl per un archivio completo, e queste collisioni dipendono dal contenuto di entrambi i file.
## File di test
[Qui](https://github.com/decalage2/collisions/blob/master/examples/free/README.md) ci sono coppie di test in collisione libere (senza copyright, senza PII).
# Riferimenti
Articoli:
- 2004
- [MD5 To Be Considered Harmful Someday](https://eprint.iacr.org/2004/357.pdf) - Dan Kaminsky
- [Practical Attacks on Digital Signatures Using MD5 Message Digest](https://eprint.iacr.org/2004/356.pdf) - Ondredj Mikle
- 2005:
- [A Note on Practical Value of Single Hash Collisions for Special File Formats](https://github.com/decalage2/collisions/blob/master/papers/Illies_NIST_05.pdf) - Max Gebhardt, Georg Illies, Werner Schindler
- 2014:
- [Malicious Hashing: Eve’s Variant of SHA-1](https://malicioussha1.github.io/) - Ange Albertini, Jean-Philippe Aumasson, Maria Eichlseder, Florian Mendel, Martin Schläffer
- 2017:
- [The first collision for full SHA-1](http://shattered.io) - Marc Stevens, Elie Bursztein, Pierre Karpman, Ange Albertini, Yarik Markov
- [Postscript that shows its own MD5](https://archive.org/stream/pocorgtfo14#page/n45/mode/1up) di Gregor "Greg" Kopf
- [A PDF That Shows Its Own MD5](https://archive.org/stream/pocorgtfo14#page/n49/mode/1up) di Mako
- [This GIF shows its own MD5!](https://archive.org/stream/pocorgtfo14#page/n52/mode/1up) di Kristoffer "spq" Janke
- [This PDF is an NES ROM that prints its own MD5 hash!](https://archive.org/stream/pocorgtfo14#page/n55/mode/1up) di Evan Sultanik, Evan Teran
- 2018:
- [Easy SHA-1 Colliding PDFs with PDFLaTeX.](https://archive.org/stream/pocorgtfo18#page/n62/mode/1up) di Ange Albertini
- 2020:
- [SHA-1 is a Shambles](https://eprint.iacr.org/2020/014.pdf) di Gaëtan Leurent, Thomas Peyrin
Presentazioni:
- 2017 Exploiting Hash Collisions at Black Alps:
- [slides](https://speakerdeck.com/ange/exploiting-hash-collisions)
[](https://speakerdeck.com/ange/exploiting-hash-collisions)
- [video](https://www.youtube.com/watch?v=Y-oJWEYKVLA)
[](https://www.youtube.com/watch?v=Y-oJWEYKVLA)
- 2019 KILL MD5 at Pass the Salt:
- [slides](https://speakerdeck.com/ange/kill-md5)
[](https://speakerdeck.com/ange/kill-md5)
- [video](https://passthesalt.ubicast.tv/videos/kill-md5-demystifying-hash-collisions/)
[](https://passthesalt.ubicast.tv/videos/kill-md5-demystifying-hash-collisions/)
Workshop (CollTris):
- [slides](https://speakerdeck.com/ange/colltris)
[](https://speakerdeck.com/ange/colltris)
- [video](https://www.youtube.com/watch?v=BcwrMnGVyBI)
[](https://www.youtube.com/watch?v=BcwrMnGVyBI)
- [materiali](https://github.com/decalage2/collisions/blob/master/workshop/README.md)
- sessioni
- 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
Sfide CTF:
- [Prudentialv2](https://ctftime.org/task/3453), dalla *Boston Key Party CTF 2017*.
- [HREFIN](https://ctftime.org/task/6965), dal *Google CTF 2018*.
- [Looking glass](https://ctftime.org/task/9271) dal *Dragon Sector Teaser CTF 2019*.
<!-- - [Not my digest](https://ctftime.org/task/4784) da *Hack.lu CTF 2017*: non legato alle collisioni, ma risolto da Marc stesso :p -->
Una difficoltà comune per questi task CTF è non dare un vantaggio o una penalizzazione troppo grande in base alla potenza di calcolo a cui ogni giocatore ha accesso.
# Crediti
Tutto questo è stato possibile grazie a [Marc Stevens](https://marc-stevens.nl/research/),
non solo per i suoi contributi crittografici, ma anche per il suo aiuto e i suoi suggerimenti costanti!
Grazie anche a Philippe Teuwen per il suo ampio feedback sui formati di file in generale.
# Conclusione
**Uccidi MD5!**
A meno che non verifichi attivamente la presenza di malformazioni o blocchi di collisione nei file, non usare MD5!
Non è un hash crittografico, è una funzione giocattolo!