
Hash collisions and their exploitations
TL;DR conseguir una colisión MD5 de estas dos imágenes ahora es(*) trivial e instantáneo.
⟷
<a href=http://gunshowcomic.com/648>
No juegues con fuego, no confíes en MD5.
(*) Colisionar cualquier par de archivos ha sido posible durante muchos años, pero lleva varias horas cada vez, sin atajos.
Esta página proporciona trucos específicos para formatos de archivo y prefijos de colisión precomputados para hacer la colisión instantánea.
git clone. Ejecuta el script. Listo.
Por Ange Albertini y Marc Stevens.
El objetivo es explorar ampliamente los ataques existentes - y mostrar de paso lo débil que es MD5 (colisiones instantáneas de cualquier JPG, PNG, PDF, MP4, PE...) - y también explorar en detalle los formatos de archivo comunes para determinar cómo pueden ser explotados con ataques presentes o futuros.
De hecho, el mismo truco de formato de archivo puede usarse en varios hashes (los mismos trucos JPG se usaron para MD5, malicious SHA-1 y SHA1), siempre que las colisiones sigan los mismos patrones de bytes.
Este documento no trata sobre nuevos ataques (el más reciente fue documentado en 2012), sino sobre nuevas formas de explotación de los ataques existentes.
Estado actual - a diciembre de 2018 - de los ataques conocidos:
obtener un archivo que tenga el hash de otro archivo o un hash dado: imposible
obtener dos archivos diferentes con el mismo MD5: instantáneo
hacer que dos archivos arbitrarios tengan el mismo MD5: unas pocas horas (72 horas.núcleo)
hacer que dos archivos arbitrarios de formatos de archivo específicos (PNG, JPG, PE...) tengan el mismo MD5: instantáneo
obtener dos archivos diferentes con el mismo SHA1: 6500 años.núcleo
(*) ejemplo con crypt - gracias Sven!```
import crypt crypt.crypt("5dUD&66", "br") 'brokenOz4KxMc' crypt.crypt("O!>',%$", "br") 'brokenOz4KxMc'
# Ataques
MD5 y SHA1 trabajan con bloques de 64 bytes.
Si dos contenidos A y B tienen el mismo hash, entonces añadir el mismo contenido C a ambos mantendrá el mismo hash.``` text
hash(A) = hash(B) -> hash(A + C) = hash(B + C)
Las colisiones funcionan insertando en un límite de bloque un número de bloques de colisión calculados que depende de lo que haya antes en el archivo. Estos bloques de colisión tienen una apariencia muy aleatoria con algunas diferencias menores (que siguen un patrón específico para cada ataque) e introducirán pequeñas diferencias mientras que, finalmente, se logra que los hashes tengan el mismo valor después de estos bloques.
Estas diferencias se aprovechan para crear archivos válidos con propiedades específicas.
Los formatos de archivo también funcionan de arriba hacia abajo, y la mayoría funcionan por fragmentos a nivel de bytes.
Algunos fragmentos 'comentario' pueden insertarse para alinear los fragmentos del archivo con los límites de bloque, para alinear estructuras específicas con las diferencias de los bloques de colisión, para ocultar el resto de la aleatoriedad de los bloques de colisión de los analizadores del archivo, y para ocultar contenido por lo demás válido del analizador (de modo que vea otro contenido).
Estos fragmentos 'comentario' a menudo no son comentarios oficiales reales: solo se utilizan como contenedores de datos que el analizador ignora (por ejemplo, los fragmentos PNG con un ID que comienza en minúscula son auxiliares, no críticos).
La mayoría de las veces, una diferencia en los bloques de colisión se usa para modificar la longitud de un fragmento comentario,
que normalmente se declara justo antes de los datos de este fragmento:
en el espacio entre la versión más corta y la más larga de este fragmento,
se declara otro fragmento comentario para saltar sobre el contenido A de un archivo.
Después de este contenido A, simplemente añade otro contenido B.

Dado que los formatos de archivo suelen definir un terminador que hará que los analizadores se detengan después de él,
A terminará el análisis, lo que hará que el contenido añadido B se ignore.
Así que normalmente se necesitan al menos dos comentarios - a menudo tres:
Estas propiedades comunes de los formatos de archivo lo hacen posible - no suelen considerarse debilidades, pero pueden detectarse o eliminarse mediante normalización:
| Prefijo | = | Prefijo |
|---|---|---|
| Colisión A | ≠ | Colisión B |
| Sufijo | = | Sufijo |
Ambos archivos son casi idénticos (su contenido solo tiene unas pocas diferencias de bits)
Explotación:
Empaqueta dos contenidos y luego:
Dos archivos con esta estructura:
mostrarán A o B.
Versión final en 2009.
.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
.. .. .. X. .. .. .. .. .. .. .. .. .. .. .. ..
.. .. .. .. .. .. .. .. .. .. .. .. .. X. .X ..
.. .. .. .. .. .. .. .. .. .. .. X. .. .. .. ..
Las diferencias no están cerca del inicio/fin de los bloques, por lo que es muy difícil de explotar ya que no controlas ningún byte cercano. Una solución potencial es forzar por fuerza bruta los bytes circundantes - cf PoCGTFO 14:10.
Ejemplos:
Con un prefijo vacío:``` 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
Other examples, with an identical prefix: [1](https://github.com/decalage2/collisions/blob/HEAD/examples/fastcoll1.bin) ⟷ [2](https://github.com/decalage2/collisions/blob/HEAD/examples/fastcoll2.bin)
**Variante**: there is a [single-block MD5 collision](https://marc-stevens.nl/research/md5-1block-collision/) but it takes five weeks of computation.
Here is a [recording](https://github.com/decalage2/collisions/blob/HEAD/examples/fastcoll.svg) of a FastColl computation without any prefix
and [another one](https://github.com/decalage2/collisions/blob/HEAD/examples/fastcoll-prefix.svg) with a prefix.
### [UniColl](https://github.com/decalage2/collisions/blob/HEAD/unicoll.md) (MD5)
Documented in [2012](https://www.cwi.nl/system/files/PhD-Thesis-Marc-Stevens-Attacks-on-Hash-Functions-and-Applications.pdf#page=199), implemented in [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) lets you control a few bytes in the collision blocks,
before and after the first difference, which makes it an identical-prefix collision with some controllable differences, almost like a chosen-prefix collision.
This is very handy, and even better the difference can be very predictable:
in the case of `m2+= 2^8` (a.k.a. `N=1` / `m2 9` in HashClash [poc_no.sh](https://github.com/cr-marcstevens/hashclash/blob/master/scripts/poc_no.sh#L30) script),
the difference is +1 on the 9th byte, which makes it very exploitable,
as you can even think about the collision in your head:
the 9th character of that sentence will be replaced with the next one: `0` replaced by `1`, `a` replaced by `b`..
- time: a few minutes (depends on the amount of byte you want to control )
- space: two blocks
- differences: ```
.. .. .. .. DD .. .. .. ..
.. .. .. .. +1 .. .. .. ..
Ejemplos con N=1 y 20 bytes de texto fijo en los bloques de colisión:```
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 tiene menos control que una colisión de prefijo elegido real,
pero es mucho más rápida, especialmente porque solo requiere dos bloques.
Aquí hay una [grabación](https://github.com/decalage2/collisions/blob/HEAD/examples/unicoll.svg) de un cómputo de UniColl.
### [Shattered](http://shattered.io) (SHA1)
Documentado en [2013](https://marc-stevens.nl/research/papers/EC13-S.pdf), calculado en [2017](http://shattered.io).
- tiempo: 6500 años.CPU y 110 año.GPU
- espacio: dos bloques
- diferencias: ```
.. .. .. DD ?? ?? ?? ??
or
?? ?? ?? DD .. .. .. ..
La diferencia entre los bloques de colisión de cada lado es esta máscara 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
Ejemplos: [PoC||GTFO 0x18](https://github.com/angea/pocorgtfo#0x18) usa los prefijos SHA1 calculados,
reutilizando la imagen directamente de la fuente PDFLaTeX (ver [artículo 18:10](https://archive.org/stream/pocorgtfo18#page/n62/mode/1up)),
pero también comprueba el valor de los prefijos mediante JavaScript en la página HTML (el archivo es políglota: ZIP, HTML y PDF).
## Colisiones de prefijo elegido
Permiten colisionar cualquier contenido.
| 𝓐 | ≠ | 𝔅 |
| :----: |:-:| :----: |
| Colisión *A* | ≠ | Colisión *B* |
1. Tomar dos prefijos arbitrarios
2. Rellenar el más corto para que sea tan largo como el más largo. Ambos se rellenan hasta el siguiente bloque - menos 12 bytes
- estos 12 bytes de datos aleatorios se añadirán en ambos lados para aleatorizar la búsqueda de cumpleaños
3. Se calcularán y añadirán X bloques de casi colisión.
Cuantos menos bloques, más largo será el cómputo.
Ej.: [400 khoras para un bloque](https://www.win.tue.nl/hashclash/SingleBlock/). 72 horas-núcleo para nueve bloques con [HashClash](https://github.com/cr-marcstevens/hashclash).
Las colisiones de prefijo elegido son todopoderosas, pero pueden tardar mucho tiempo solo para un par de archivos.
### [HashClash](https://github.com/cr-marcstevens/hashclash) (MD5)
Versión final en [2009](https://www.win.tue.nl/hashclash/ChosenPrefixCollisions/).
Ejemplos: colisionemos `yes` y `no`. Tardó tres horas en 24 núcleos.```
'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
Aquí tienes un registro de toda la operación.
Shambles es una colisión de prefijo elegido muy costosa que utiliza 9 bloques.
Cada bloque tiene el mismo patrón xor que 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
## Resumen de ataques
Hash | Nombre | Fecha | Duración | Tipo de prefijo | Control cerca de la diferencia
---- | --------- | ---- | -------- | ----------- | -----------------
MD5 | FastColl | 2009 | 2s | Idéntico | ninguno
| UniColl | 2012 | 7-40min | Idéntico | 4-10 bytes
| HashClash | 2009 | 72h | Elegido | n/a
| | | | |
SHA1 | Shattered | 2013 | 6500yr | Idéntico | prefijo y sufijo
| Shambles | 2020 | ? | Elegido | n/a
# Explotaciones
Las colisiones de prefijo idéntico suelen considerarse (muy) limitadas, pero el prefijo elegido requiere mucho tiempo.
Otro enfoque es crear prefijos reutilizables mediante un ataque de prefijo idéntico como UniColl - o de prefijo elegido para superar algunas limitaciones - pero reutilizar ese par de prefijos en combinación con dos cargas útiles como en un ataque clásico de prefijo idéntico.
Una vez calculado el par de prefijos, hacer colisionar dos contenidos es instantáneo:
solo es cuestión de manipular los datos del archivo (según los formatos de archivo específicos) para que se ajusten a las especificaciones de los formatos de archivo y a los requisitos del prefijo precalculado.
## Estrategia estándar
Colisiones clásicas de dos archivos válidos con el mismo tipo de archivo.
### JPG
Limitaciones teóricas y soluciones alternativas:
- el segmento *Application* debería, en teoría, ir justo después del marcador *Start of Image*.
En la práctica, esto no es necesario, por lo que nuestra colisión puede ser genérica: la única limitación es el tamaño de la imagen más pequeña.
- la longitud de un comentario se almacena en dos bytes, por lo que la cantidad que puede contener está limitada a 65536 bytes (aproximadamente el tamaño de una foto de 400x400)
- en lugar de saltar sobre un archivo JPG completo, se puede dividir ese archivo en sus segmentos y añadir trampolines de salto entre segmentos
*comentarios sobre cada segmento de imagen*
*cómo funcionan los trampolines de comentarios*
- mientras que la mayor parte de la estructura de un JPG está formada por segmentos que están todos limitados a 65536 bytes de tamaño,
los datos comprimidos reales se almacenan en el *Entropy Coded Segment*, que no respeta esa limitación:
su tamaño se desconoce de antemano y crece más allá de ese límite.
Crece con el tamaño de la imagen, representando la mayor parte del tamaño del archivo en una imagen de línea base (no progresiva).
Para que toda la imagen quepa en fragmentos de 64kb, la forma sencilla es intentar primero guardar la imagen como progresiva (algo que cualquier software puede hacer, y que divide el ECS normalmente en hasta seis escaneos). La forma más avanzada es usar *JPEGTran* con su parámetro de línea de comandos 'wizard' `--scans` y definir escaneos personalizados.
No hay más restricciones aparte de los segmentos de escaneo,
por lo que una colisión MD5 de dos JPG arbitrarios es *instantánea* y no necesita una colisión de prefijo elegido, solo UniColl.
Con el [script](https://github.com/decalage2/collisions/blob/HEAD/scripts/jpg.py):```
21:07:35.65>jpg.py Ange.jpg Marc.jpg
21:07:35.75>
Ejemplos:
⟷
2 JPGs con colisión MD5
Aquí hay un ejemplo de la definición de escaneos de JPEGTran para convertir una imagen RGB de 1944x2508 en un JPG al 100% con 20 escaneos en los que todos caben en 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;
*una imagen RGB de 1944x2508 como un JPG al 100% con 20 escaneos*
### PNG
Limitaciones teóricas y soluciones:
- PNG usa CRC32 al final de sus chunks, pero en la práctica se ignoran. Pueden ser correctos, pero no es obligatorio.
- los metadatos de la imagen (dimensiones, espacio de color...) se almacenan en el chunk `IHDR`,
que en teoría debería estar justo después de la firma (es decir, antes de cualquier posible comentario),
por lo que significaría que solo podemos precomputar colisiones de imágenes con los mismos metadatos.
Sin embargo, ese chunk puede estar realmente después de un bloque de comentarios (en la gran mayoría de los lectores, excepto los de Apple), por lo que podemos poner los datos de colisión antes de la cabecera,
lo que permite colisionar cualquier par de PNG con una sola precomputación.
Dado que un chunk PNG tiene una longitud de cuatro bytes, no hay necesidad de modificar la estructura de ninguno de los dos archivos: podemos saltar sobre una imagen completa de una sola vez.
Podemos insertar tantos chunks descartados como queramos, así que podemos añadir uno para la alineación, luego uno cuya longitud será alterada por un UniColl. por lo que la longitud será `00` `75` y `01` `75`.
Así que una colisión MD5 de dos imágenes PNG arbitrarias es *instantánea*, sin requisitos previos (sin cómputo, solo algunos cambios menores en los archivos), y no necesita colisión de prefijo elegido, solo UniColl.
Con el [script](https://github.com/decalage2/collisions/blob/HEAD/scripts/png.py):```
19:27:04.79>png.py nintendo.png sega.png
19:27:04.87>
Ejemplos:
⟷
2 PNGs que colisionan en MD5 con diferentes propiedades
Aquí hay una grabación de toda la operación.
La mayoría de los lectores aceptan sin problemas archivos PNG que comienzan con un chunk que no es IHDR.
Sin embargo, algunos (como Safari y Preview, ¿algún otro?) no lo toleran. En este caso, la cabecera de la imagen y sus propiedades (dimensiones, espacio de color) deben ir primero, antes de cualquier bloque de colisión.
En este caso, ambos archivos colisionantes deben tener las mismas propiedades. De nuevo, UniColl es suficiente y, por supuesto, el par de prefijos calculado puede reutilizarse para cualquier otro par de archivos con las mismas propiedades
Aquí hay un script para colisionar cualquier par de estos archivos, que lanza UniColl si es necesario para calcular el par de prefijos.
Ejemplos:
⟷
⟷
2 pares de PNGs que colisionan en MD5 con propiedades idénticas para máxima compatibilidad
Aquí hay una grabación de toda la operación cuando se invoca UniColl,
y otra cuando el prefijo ya ha sido calculado.
GIF es complicado:
Sin embargo, los chunks de comentario siguen una estructura peculiar: es una cadena de <length:1> <data:length> hasta que se define una longitud nula.
Por lo tanto, hace que cualquier byte no nulo sea un 'salto hacia adelante' válido. Lo que lo hace adecuado para usarse con FastColl,
como se muestra en PoC||GTFO 14:11.
Así que al menos, aunque no podamos tener un prefijo genérico, podemos colisionar cualquier par de GIF con los mismos metadatos (dimensiones, paleta) y solo necesitamos un segundo de FastColl para calcular su prefijo.
Ahora el problema es que no podemos saltar sobre una imagen completa como en PNG ni sobre una estructura grande como en JPG.
Una posible solución es manipular los datos comprimidos o dividir la imagen en áreas diminutas como en el caso del hashquine de GIF, pero no es lo óptimo.
Otra idea que funciona genéricamente es que los datos de la imagen también se almacenan usando esta estructura de secuencia length data:
así que si tomamos dos GIF sin animación, solo tenemos que:
Con una configuración menor (solo unos pocos cientos de bytes de sobrecarga), podemos deslizarnos sobre cualquier imagen GIF y sortear la limitación de 256 bytes. Esta idea fue sugerida por Marc, ¡y es brillante!
Así que al final, las limitaciones actuales de GIF para colisiones MD5 instantáneas son:
gifsicle --use-colormap webUn atajo fácil para normalizar imágenes GIF fijas es convertirlas en fotogramas de animación de la misma imagen, entonces podemos usar un script para reutilizar o calcular bloques FastColl y crear un par de archivos que muestre cada una de ellas.
Ejemplos:
⟷
2 GIFs que colisionan en MD5 - imágenes de KidMoGraph
Aquí hay una grabación de toda la operación.
Especificaciones GZIP v4.3: RFC 1952 (1996).
1F 8B. Si no coincide con la firma, el análisis se detendrá, lo que puede usarse para forzar la detención del análisis entre dos cargas útiles, pero provocará algunas advertencias que podrían causar problemas. Otra estrategia es añadir un miembro vacío adicional al final del archivo y hacer que el análisis de ambas cargas útiles termine allí, en el miembro o en su cuerpo.filename y file comment opcionales terminan en nulo, mientras que el Extra field está definido por un tamaño de 16 bits, por lo tanto explotable. Está formado por uno o más subcampo(s), con un ID y su propia sublongitud, pero los subcampos no se aplican estrictamente: muy pocos están definidos oficialmente.Por lo tanto, un miembro gzip vacío con un campo extra es un anfitrión parásito perfecto.
Si el archivo superior es demasiado grande para caber en un campo extra, entonces su flujo sin comprimir puede dividirse en archivos más pequeños hasta que todos quepan en campos extra.
Después de la cabecera de un miembro vienen su cuerpo comprimido, su CRC32 y su tamaño sin comprimir (no aplicado). Por lo tanto, un cuerpo de datos vacío con su CRC32 y tamaño nulos constituye un postwrap genérico, que incluso puede compartirse entre diferentes cabeceras de miembro.
Varias implementaciones se basan en el tamaño sin comprimir del último miembro en lugar de la suma de todos los miembros. Así que nuestros archivos colisionantes mostrarán que tienen tamaño nulo, porque estos archivos terminan con un miembro vacío utilizado como trampolín.
Aquí hay un script para generar colisiones MD5 instantáneas de dos archivos GZip. Tarda la mayor parte del tiempo en descomprimir y recomprimir datos si los archivos de entrada son grandes: los prefijos de colisión están precalculados. No es posible dividir miembros sin descomprimir, ya que el CRC32 sin comprimir necesita ser calculado.
Un .tar.gz es simplemente el archivo gzip de un archivo tar. Funcionará bien con tar comprimido con gzip, a diferencia de tar en sí.
Ejemplos: collision1.tar.gz (Pacome) ⟷ collision2.tar.gz (Reg)
El Portable Executable tiene una estructura peculiar:
Así que la estrategia es:
DOS/Collisions/Header1/Header2. Solo necesitas aplicar un delta a los offsets de las dos tablas de secciones.Esto significa que es posible colisionar instantáneamente cualquier par de ejecutables PE. Incluso si usan diferentes subsistemas o arquitectura.
Mientras que las colisiones de ejecutables suelen ser triviales mediante cualquier cargador, este tipo de explotación aquí es transparente: el código es idéntico y se carga en la misma dirección.
Ejemplos: tweakPNG.exe (GUI) ⟷ fastcoll.exe (CLI)
Aquí hay un script para generar colisiones MD5 instantáneas de ejecutables de Windows.
El contenedor de este formato es una secuencia de chunks Length Type Value llamados Atoms.
La longitud es un big-endian de 32 bits y abarca su propio campo, el tipo y el valor, por lo que la longitud normal mínima es 8
(el tipo es una cadena de 4 caracteres ASCII).
Si la longitud es nula, entonces el atom ocupa el resto del archivo, como los atoms jp2c en archivos JP2.
Si es 1, entonces el Type va seguido de una longitud de 64 bits, cambiando el atom a Type Length Value, haciéndolo compatible con otras colisiones como Shattered.
Algunos atoms contienen otros atoms: en estos casos, se llaman boxes. Por eso esta estructura, que de otro modo no tendría nombre, se llama "atom/box".
Este formato "atom/box" utilizado en MP4 es en realidad un derivado de Apple Quicktime, y es utilizado por muchos otros formatos (JP2, HEIF, F4V).
El primer tipo de atom es normalmente ftyp, lo que permite diferenciar el formato de archivo real.
El formato es bastante permisivo:
solo hay que encadenar atoms free, abusar de la longitud de uno con UniColl y luego saltar sobre la primera carga útil.
Para archivos MP4, lo único que hay que añadir es ajustar las tablas stco (Sample Table - Chunk Offsets) o co64 (el equivalente de 64 bits), ya que son offsets absolutos (!) que apuntan a los datos de película mdat, ¡y de hecho se aplican!
Esto da un script que colisiona instantáneamente cualquier video arbitrario, y como se mencionó, puede funcionar en otros formatos además de MP4.

Ejemplos (videos de KidMoGraph):
longitudes de 32b (estándar) collision1.mp4 ⟷ collision2.mp4
⟷
longitudes de 64b collisionl1.mp4 ⟷ collisionl2.mp4
⟷
Ten en cuenta que algunos visores (OS X, Safari, FireFox) no permiten un archivo que comience con un Atom que no sea ftyp.
En este caso, el prefijo tiene que cubrir esto, y no es tan genérico, pero aparte de eso es la misma estrategia: solo limitado a un único tipo de archivo.
Los archivos JPEG2000 suelen comenzar con la estructura Atom/Box como MP4,
luego el último atom jp2c normalmente se extiende hasta el final del archivo (longitud nula),
y a partir de ese punto sigue la estructura JFIF, como JPEG (comenzando con FF 4F como marcador de segmento).
La forma puramente JFIF también se tolera, en cuyo caso la colisión es como en JPEG: compatible con Shattered, pero con comentarios limitados a 64Kb.
Por otro lado, si manipulas archivos JPEG2000 con la estructura Atom/Box, no tienes esta limitación.
Como se mencionó antes, si intentas colisionar esta estructura y
si hay más restricciones, por ejemplo, comenzar con un atom free no es tolerado por algunos formatos,
entonces puedes calcular otros pares de prefijos UniColl específicos para este formato:
JPEG2000 parece exigir un atom 'jP ' primero antes del habitual ftyp,
pero aparte de eso, esa es la única restricción: no hay necesidad de reubicar nada.
¡Así que el script resultante es incluso más simple!

Ejemplos: collision1.jp2 ⟷ collision2.jp2
sobre Shattered
La explotación de Shattered no era un truco de PDF, sino un truco de JPG dentro de un PDF.
Solo permitía que un PDF contuviera un objeto comprimido en JPG que pudiera tener dos contenidos diferentes. Ambos PDFs necesitaban ser totalmente idénticos por lo demás.
Ten en cuenta que los documentos pueden ser totalmente normales y simplemente recortar el JPG colisionante y mostrarlo en diferentes lugares, como en documentos de varias páginas.
Ejemplos: el documento de Shattered, modificado ⟷ el documento de Shattered, original
el documento de Shattered usando un JPG colisionante en dos lugares
Colisiones de PDF con MD5
Con MD5 (y otros patrones de colisión), podemos hacer colisiones de PDF a nivel de documento, ¡sin ninguna restricción en ninguno de los dos archivos!
PDF tiene una estructura muy diferente a la de otros formatos de archivo. Utiliza números de objeto y referencias para definir un árbol. Todo el documento depende del elemento Root.
Este PDF (válido)``` 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>>
es 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>>
Trucos:
XREF.Así que almacenar dos árboles de documentos en el mismo archivo es válido. Solo necesitamos hacer que el objeto raíz haga referencia a cualquiera de los dos objetos raíz de ambos documentos.
Así que solo necesitamos tomar dos documentos,
renumerar objetos y referencias para que no haya solapamiento,
crear una colisión para que el número de elemento referenciado como objeto raíz pueda cambiarse manteniendo el mismo valor hash,
lo cual encaja perfectamente con UniColl con N=1, y ajustar la tabla XREF en consecuencia.
De esta manera, podemos colisionar de forma segura cualquier par de PDFs, sin importar los números de página, las dimensiones, las imágenes...
comentarios
Un PDF puede almacenar datos foráneos de dos maneras:
\r y \n).
Esto puede usarse dentro de un objeto de diccionario, para modificar por ejemplo una referencia a un objeto, mediante UniColl.
Así que esto es un objeto PDF válido incluso si contiene bloques de colisión binarios: simplemente reintenta hasta que no haya caracteres de nueva línea: ```
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
texto en colisión
El primer caso permite resaltar la belleza de UniColl, una colisión donde las diferencias son predecibles, ¡así que puedes escribir poesía sobre datos en colisión! - gracias a Jurph!
En lugar de modificar la estructura del documento y engañar a los analizadores, usaremos bloques de colisión directamente para producir texto directo, ¡con lectura 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. ^ ^
Examples: [poeMD5 A](https://github.com/decalage2/collisions/blob/HEAD/examples/poeMD5_A.pdf) ⟷ [poeMD5 B](https://github.com/decalage2/collisions/blob/HEAD/examples/poeMD5_B.pdf)
*Una verdadera creación artística criptográfica :) *
(Nota: metí la pata con la compatibilidad de Adobe, pero es culpa mía, no de UniColl)
**Estructura de colisión de documentos**
Tanto si usas UniColl como comentario en línea o como prefijo elegido en un objeto de flujo ficticio, la estrategia es similar:
baraja los números de los objetos y haz que el objeto Root apunte a objetos diferentes, por lo que, a diferencia de Shattered, esto significa una colisión instantánea de cualquier par arbitrario de PDF, a nivel de documento.
Un truco útil es que la salida de [`mutool clean`](https://mupdf.com/docs/manual-mutool-clean.html) es predecible de forma fiable,
por lo que se puede usar para normalizar los PDF de entrada y arreglar el PDF combinado manteniendo las partes importantes del archivo sin modificar.
MuTool no descarta claves/valores falsos - a menos que se le pida, y los mantiene en el mismo orden,
así que usar entradas de diccionario falsas como `/MD5_is /REALLY_dead_now__` es perfecto para alinear las cosas de forma predecible sin necesitar otro tipo de comentarios.
Sin embargo, no mantiene los comentarios en los diccionarios (así que no sirve el truco del comentario en línea)
Una forma sencilla de hacer la operación de barajado de objetos sin complicaciones es simplemente fusionar ambos archivos PDF
mediante `mutool merge` y luego dividir el objeto `/Pages` en dos.
Para hacer hueco a este objeto, basta con fusionar un PDF ficticio delante de los dos documentos.
Opcionalmente, crea una referencia falsa al array colgante
para evitar que el recolector de basura elimine el segundo conjunto de páginas.
**Ejemplo**:
con este [script](https://github.com/decalage2/collisions/blob/HEAD/scripts/pdf.py),
se tarda [menos de un segundo](https://github.com/decalage2/collisions/blob/HEAD/examples/pdf.log) en colisionar los dos documentos PDF públicos como Spectre y Meltdown:
Examples: [spectre.pdf](https://github.com/decalage2/collisions/blob/HEAD/examples/collision1.pdf) ⟷ [meltdown.pdf](https://github.com/decalage2/collisions/blob/HEAD/examples/collision2.pdf)
Posible extensión: encadenar bloques UniColl para conservar también pares de los diversos [objetos no críticos](https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/PDF32000_2008.pdf#page=81)
que se pueden referenciar en el objeto Root, como `Outlines`, `Names`, `AcroForm` y Acciones Adicionales (`AA`), en los archivos fuente originales.
**en PDFLaTeX**
Las técnicas anteriores funcionan con solo un par de archivos PDF,
pero también es posible hacerlo directamente desde fuentes TeX
mediante [operadores PDFTeX específicos](http://texdoc.net/texmf-dist/doc/pdftex/manual/pdftex-a.pdf).
Puedes definir objetos directamente (incluyendo claves y valores ficticios para alineaciones) y definir objetos vacíos para reservar algunas ranuras de objeto incluyendo esto al principio mismo de tus fuentes 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
No olvides normalizar la salida de PDFLaTeX - con mutool, por ejemplo - si es necesario:
PDFLaTeX es difícil de lograr compilaciones reproducibles entre distribuciones - incluso puede que quieras enganchar la hora de ejecución para obtener el hash exacto si es necesario.
Podrías esperar que los JPG fueran solo imágenes, pero en un PDF y en algunos lectores de PDF (no navegadores, como Evince y Adobe Reader), pueden usarse como contenido de página igual que cualquier otro objeto incrustado, que está incrustado en una imagen JPEG.
Para almacenar los datos JPEG sin pérdidas, guárdalos en escala de grises al 100%, y luego usa una imagen de una sola fila/columna, o repite la línea de datos 8 veces (ya que los bloques JPEG son de 8x8), y tus datos se almacenarán sin pérdidas y serán referenciados por las páginas del PDF.
Ejemplos de dos PDFs que colisionan en SHA-1 mediante datos de página JPEG (una imagen en escala de grises que renderiza colores) como contenido de página vectorial:
2 PDFs que colisionan en SHA-1 con datos de imagen almacenados como JPG
Es posible referenciar el JPG en colisión dos veces: como contenido de página, sin pérdidas, que además se refiere a sí mismo como una imagen con pérdidas para mostrarse. De nuevo, la imagen a mostrar está en escala de grises, pero el contenido de la página puede renderizar algunos colores mediante operadores PDF.
La parte superior de la imagen muestra el contenido de la página repetido 8 veces.
Ejemplos de dos PDFs que colisionan en SHA-1 mediante JPEG usado como datos de página e imagen a mostrar:
Skulls & Crossbones ⟷ Golden Axe
2 PDFs que colisionan en SHA-1 con JPG usado como imagen y contenido de página
TL;DR No existe una colisión genérica reutilizable para ZIP, pero sí para formatos basados en ZIP. Debería ser posible colisionar dos archivos en 2h.core (36 veces más rápido que el prefijo elegido).
Los archivos ZIP son un sándwich de 3 capas (como mínimo).
Primero viene el contenido de los archivos (secuencia de estructuras Local File Header, una por archivo o directorio archivado),
luego un índice (de nuevo, una secuencia de Central Directory),
y luego una única estructura que apunta a este índice (End Of Central Directory).
El orden de estas capas no se puede cambiar. Algunos parsers solo necesitan la estructura del contenido de los archivos, pero esa no es una forma correcta de parsear y puede ser explotada.
Debido a este orden requerido, no existe un prefijo genérico que pueda ayudar para cualquier colisión.
enfoque no genérico
Otro enfoque podría ser simplemente fusionar ambos archivos, con sus capas fusionadas, y usar UniColl - pero con N=2, que introduce una diferencia en el 4.º byte - para eliminar la firma mágica del End of Central Directory.
Esto significa que se podría colisionar dos ZIP arbitrarios con un solo UniColl y 24 bytes de prefijo fijo.
Un End of Central Directory típico, que ocupa 22 bytes si el comentario está vacío:``` 00: 504b 0506 0000 0000 0000 0000 0000 0000 PK.............. 10: 0000 0000 0000 ......
Si usamos esto como prefijo (rellenar el prefijo a 16 bits) para UniColl y `N=2`, la diferencia está en el cuarto byte, destruyendo la magia `.P .K 05 06` al cambiarla predeciblemente a `.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..(
Esto no es genérico en absoluto, pero mucho más rápido que la colisión de prefijo elegido:```
real 12m23.993s
user 112m24.072s
sys 2m0.194s
Un problema es que algunos analizadores todavía analizan los archivos ZIP al revés, incluso si deberían analizarse de abajo hacia arriba:
una forma de asegurar que ambos archivos se analicen correctamente es encadenar dos bloques UniColl,
para habilitar/deshabilitar cada End of Central Directory.
Para evitar que los analizadores ZIP se quejen del espacio no utilizado,
se puede abusar de los Extra Fields, de los comentarios de archivo en Central Directory y de los comentarios de archivo en End of Central Directory.

Ejemplo: aquí hay una fuente de ensamblador que describe la estructura de un ZIP dual, que puede albergar dos archivos comprimidos diferentes.
Después de dos cálculos de Unicoll, se obtienen los dos archivos en colisión: collision1.zip ⟷ collision2.zip
Aunque el formato Zip en sí no puede ser explotado genéricamente como Gzip, algunos formatos que dependen de Zip sí pueden ser explotados genéricamente dentro de archivos Zip con una estructura predefinida. Hay que tomar algunas precauciones para que la colisión Zip sea genérica.
Algunos formatos consisten en múltiples archivos almacenados en un archivo Zip, y dependen de un archivo raíz con un nombre de archivo fijo que apunta a otros archivos del archivo. Muchos de ellos usan XML o texto para el archivo raíz, y almacenan otros archivos tal cual.
Idea : hacer que dos conjuntos de archivos coexistan en el mismo archivo comprimido, y apuntar a cualquiera de los conjuntos de archivos. Un archivo raíz genérico puede almacenarse primero, al comienzo del archivo, pero los bloques de colisión se almacenan fuera del contenido del archivo, en el archivo comprimido (ya que las colisiones tienen una entropía muy alta, es imposible explotar archivos XML o solo ASCII con colisiones).
Pasos:
Ponga 2 conjuntos de archivos de 2 orígenes en el mismo archivo comprimido, es decir, en diferentes subdirectorios.
Modifique el archivo raíz para que apunte alternativamente a cada conjunto.
Dado que la marca de tiempo, la longitud y el CRC del archivo raíz se almacenan tanto en el Local File Header - antes del contenido del archivo - como en el Central Directory - después del contenido del archivo - estos valores no deberían cambiar entre las dos versiones de los archivos.
Central Directory, esta copia del valor podría ser ignorada por el analizador, pero forjar un CRC32 a un valor constante es útil para evitar por completo el problema.
Es probable que forjar el CRC añadiendo 4 bytes aleatorios no sea suficiente, ya que estos archivos raíz suelen estar en XML o texto con sintaxis estricta, por lo que se volverían inválidos.
CrcHack ayuda enormemente a forjar CRCs con bits arbitrarios y sin fuerza bruta, asegurando que el archivo de salida sea ASCII y que los bits modificados sigan en un comentario.Usar el extra field de un archivo ficticio adicional -- incluso vacío -- en el archivo comprimido después del archivo raíz es una forma elegante de almacenar los bloques de colisión de Hashclash: de esa manera, el archivo Zip mantiene una estructura estándar y puede manipularse fácilmente después, incluso con herramientas estándar.
Los Extra Fields no tienen CRC32, y su longitud de 16 bits se declara en los encabezados anteriores. Tienen su propio formato interno ID:2 Size:2 Data, que normalmente se ignora, y están presentes tanto en el Local File Header como en el Central Directory; sin embargo, el campo puede omitirse del Central Directory para mantener el sufijo idéntico después de los bloques de colisión.
La presencia del archivo extra que cubre los bloques de colisión en su extra field puede tener que declararse en la estructura del formato, como en el archivo [Content_Types].xml en un documento OOXML. Otros archivos XML en el sufijo pueden tener que modificarse, ya que algunos formatos requerían el uso de rutas absolutas.
Aquí está la estructura general del exploit genérico para un formato específico basado en Zip:``` [Root file] (with constant CRC32)
[Dummy file] (with collision blocks in the extra field)
[...] <- rest of the archive, with 2 documents merged
So al predefinir el contenido del archivo raíz y forjar CRC32 ASCII, se puede calcular una colisión Hashclash genérica y reutilizable para un formato específico basado en zip.
### Resumen de requisitos
- dos o más prefijos
- uno o más tipos de archivo (los políglotas funcionan sin problemas)
- un archivo raíz XML con nombre de archivo, longitud de archivo y CRC fijos: esta información está presente dos veces, antes y después de los bloques de colisión
- el contenido es XML arbitrario
- es posible añadir relleno, incluso mediante comentario XML, para alcanzar la misma longitud.
- el CRC se puede establecer (mediante CrcHack) en cada contenido.
- ambos conjuntos de archivos coexisten en el sufijo, probablemente en directorios diferentes. Algunas herramientas codifican la ruta de forma fija, lo que puede reducir la compatibilidad.
- puede ser necesario fusionar un archivo XML de *Content type* para cubrir todos los archivos, compatibles y no compatibles (bloques de colisión y documento alternativo)
### Ejemplos
#### CRC32
Un comentario XML mínimo (solo ASCII) con un CRC32 falsificado (cálculo instantáneo) 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-->
Otro ejemplo en el que ajustas el CRC con el caso de un mensaje alfabético.```bash echo "" | crchack.exe -b 4:+.8*32:.8 - 0xcafebabe
#### Colisiones
[zInsider](https://github.com/decalage2/collisions/blob/HEAD/scripts/zinsider.py) es un script para generar instantáneamente colisiones MD5 de pares de documentos arbitrarios usando estos formatos ZIP+XML:
- Office Open XML: docx / pptx / xlsx
- Open Container Format: epub
- Open Packaging Conventions:
- 3D manufacturing format: 3mf
- XML Paper Specification: xps / oxps
Para generar tus propios prefijos de colisión, [aquí tienes un script](https://github.com/decalage2/collisions/blob/HEAD/scripts/makezip.py) para generar un par de zips raíz.
Después de calcular las colisiones, usa [este otro script](https://github.com/decalage2/collisions/blob/HEAD/scripts/extendzip.py) para combinar ese par de raíces con un sufijo común.
Algunos PoCs de colisión:
- Office Open XML: Excel ([1](https://github.com/decalage2/collisions/blob/HEAD/examples/free/md5-1.xls) - [2](https://github.com/decalage2/collisions/blob/HEAD/examples/free/md5-2.xls)), Powerpoint ([1](https://github.com/decalage2/collisions/blob/HEAD/examples/free/md5-1.pptx) - [2](https://github.com/decalage2/collisions/blob/HEAD/examples/free/md5-2.pptx)), Word ([1](https://github.com/decalage2/collisions/blob/HEAD/examples/free/md5-1.docx) - [2](https://github.com/decalage2/collisions/blob/HEAD/examples/free/md5-2.docx)).
- Open Container Format: Epub ([1](https://github.com/decalage2/collisions/blob/HEAD/examples/collision-1.epub) - [2](https://github.com/decalage2/collisions/blob/HEAD/examples/collision-2.epub)).
- Open Packaging Conventions: 3MF ([1](https://github.com/decalage2/collisions/blob/HEAD/examples/collision-1.3mf) - [2](https://github.com/decalage2/collisions/blob/HEAD/examples/collision-2.3mf)), XPS ([1](https://github.com/decalage2/collisions/blob/HEAD/examples/collision-1.xps) - [2](https://github.com/decalage2/collisions/blob/HEAD/examples/collision-2.xps)).
Algunos formatos con múltiples archivos basados en Zip no se pueden explotar genéricamente:
- Quake PK3: un zip de archivos sin raíz específica.
- Open Document Format: el archivo `META-INF/manifest.xml` tiene que mencionar todos los demás archivos, por lo que no puede ser genérico.
- APK, JAR, XPI: el archivo `META-INF/MANIFEST.mf` también tiene que mencionar todos los demás archivos, con sus hashes.
Gracias a [Philippe Lagadec](https://twitter.com/decalage2) por su ayuda con los formatos de archivo de Office.
## Estrategias poco comunes
Normalmente las colisiones se tratan de dos archivos válidos del mismo tipo.
### MultiColls: cadena de colisiones múltiples
Nada impide encadenar varios bloques de colisión y tener más de dos contenidos con el mismo valor hash.
Un ejemplo de ello son los *hashquines*, que muestran su propio valor MD5.
El archivo [PoCGTFO 14](https://github.com/angea/pocorgtfo#0x14) contiene 609 colisiones FastColl, para hacerlo mediante dos tipos de archivo en el mismo archivo.
### Validez
Una estrategia diferente sería eliminar el tipo de archivo para evitar el escaneo como archivo corrupto.
Con solo sobrescribir la firma mágica bastará.
Añadir a ambos archivos (válidos o inválidos) un formato que no necesite estar en el offset 0 (un archivo, como ZIP/RAR/...) revelaría otro tipo de archivo.
Esto permite colisiones políglotas sin usar una colisión de prefijo elegido:
1. usa UniColl para activar o desactivar una firma mágica, por ejemplo una PNG:
2. añade un archivo ZIP
Aunque técnicamente ambos archivos son un ZIP válido, como la mayoría de los analizadores devuelven el primer tipo de archivo encontrado y empiezan a escanear en el offset 0, verán un tipo de archivo diferente.
Ejemplos:
⟷ [inválido](https://github.com/decalage2/collisions/blob/HEAD/examples/png-invalid.png)
### PolyColls: colisiones de diferentes tipos de archivo
También es posible tener ambos lados de una colisión con tipos diferentes para reducir sospechas:
Escenario de ataque:
1. envía `holiday.jpg`
2. haz que se incluya en la lista blanca
3. envía `evil.exe`, que tiene el mismo MD5.
En estos casos, se requiere una colisión de prefijo elegido si ambos formatos de archivo necesitan empezar en el offset 0.
Algunos ejemplos de diseños polycoll:

*Polycoll PDF/JPG*

*Polycoll PE/PNG*
#### PE - JPG
Como una cabecera PE suele ser más pequeña que 0x500 bytes, encaja perfectamente en un comentario JPG:
1. empieza con las cabeceras DOS/JPG
2. el comentario JPEG salta sobre la cabecera PE
3. pon la imagen JPG completa
4. pon todas las especificaciones PE
Una vez más, la colisión es [instantánea](https://github.com/decalage2/collisions/blob/HEAD/scripts/jpgpe.py)
Ejemplos: [fastcoll.exe](https://github.com/decalage2/collisions/blob/HEAD/examples/jpg-pe.exe) ⟷ [Marc.jpg](https://github.com/decalage2/collisions/blob/HEAD/examples/jpg-pe.jpg)
#### PDF - PE
Fusionar un PDF con un archivo ficticio usando `mutool` es una buena forma genérica de reordenar objetos y luego conseguir que los dos primeros objetos sean descartables (página ficticia y contenido), lo que encaja perfectamente con un objeto `stream` contenedor de longitud desconocida como `1 0`, y su longitud referenciada más adelante (después de los bloques de colisión) en el segundo objeto.
El único problema es que `mutool` siempre incrusta la longitud y elimina la referencia a la longitud, por lo que hay que reinsertarla en el PDF en lugar del valor, pero la mayoría de las referencias `2 0 R` serán más pequeñas que las longitudes fijas.
Afortunadamente, esto se puede arreglar sin alterar ningún offset de objeto, así que no hay que parchear el XREF.
Aquí tienes un [script](https://github.com/decalage2/collisions/blob/HEAD/scripts/pdfpe.py) para, por ejemplo, colisionar instantáneamente un visor de PDF ([Sumatra](https://www.sumatrapdfreader.org/free-pdf-reader.html) es ligero y autónomo) y un documento PDF:
Ejemplos: [Poster.pdf](https://github.com/decalage2/collisions/blob/HEAD/examples/pepdf.pdf) ⟷ [Sumatra.exe](https://github.com/decalage2/collisions/blob/HEAD/examples/pepdf.exe)

*un visor de PDF mostrando un PDF (que a su vez muestra un PDF) con el mismo MD5*
#### PDF - PNG
De manera similar, es posible colisionar, por ejemplo, archivos PDF y PNG arbitrarios sin restricciones en ninguno de los dos lados. Esto es instantáneo, reutilizable y genérico.
Ejemplos: [Hello.pdf](https://github.com/decalage2/collisions/blob/HEAD/examples/png-pdf.pdf) ⟷ [1x1.png](https://github.com/decalage2/collisions/blob/HEAD/examples/png-pdf.png)
### PileUps (multi-colisión)
¡Las colisiones criptográficas no se limitan a dos archivos!
Como se demostró en el experimento [Nostradamus](https://www.win.tue.nl/hashclash/Nostradamus/) en 2008, encadenar colisiones hace posible colisionar más de dos archivos.
Las primeras colisiones pueden ser idénticas o de prefijo elegido; las siguientes tienen que ser de prefijo elegido.
Puedes llamarlas multi-colisiones; yo prefiero *pileups* — es más corto :)
#### PE - PNG - MP4 - PDF
Combinando todos los conocimientos adquiridos anteriormente, usé 3 colisiones de prefijo elegido para crear 4 prefijos diferentes para distintos tipos de archivo: documento (PDF), vídeo (MP4), ejecutable (PE) e imagen (PNG).

*diagrama de un pileup de PE/PNG/MP4/PDF*
Este script es genérico e instantáneo:

Ejemplos: [commodore.pdf](https://github.com/decalage2/collisions/blob/HEAD/examples/pileup.pdf) ⟷ [diagram.png](https://github.com/decalage2/collisions/blob/HEAD/examples/pileup.png) ⟷ [kidmo.mp4](https://github.com/decalage2/collisions/blob/HEAD/examples/pileup.mp4) ⟷ [sumatra18.exe](https://github.com/decalage2/collisions/blob/HEAD/examples/pileup.exe)
Dado que solo puedes distribuir un único archivo y es imposible adivinar los valores de los otros prefijos a partir de él, una solución es incrustar todos los prefijos de la colisión en código JavaScript e insertarlo en tus PoCs, convirtiendo tus archivos en [políglotas HTML](https://github.com/decalage2/collisions/blob/HEAD/examples/polyglot.html) para compartir fácilmente los archivos colisionantes relacionados.
El [número 19](https://github.com/angea/pocorgtfo#0x19) de 'PoC or GTFO' es un pileup **y** políglota de este tipo, que combina un documento de 80 páginas generado con PDFLaTeX, un visor de PDF para Windows, un diagrama PNG y un breve vídeo MP4 de 'colisión' de [KidMoGraph](https://www.kidmograph.com/), con un payload HTML para generar los demás archivos a partir del lanzamiento en PDF (y también un archivo ZIP):
Gracias a Rafał Hirsz por su ayuda permanente con JavaScript.
## Casos de uso
Mejor descartar MD5 por completo, ¡porque la introspección de archivos es demasiado lenta y demasiado arriesgada!
### ¡Hay que colisionarlos todos!
Otro uso de las colisiones instantáneas, reutilizables y genéricas sería ocultar cualquier archivo de un tipo determinado —por ejemplo PNG— detrás de archivos ficticios (o el mismo archivo cada vez) — lo que en realidad se consigue concatenándolo al mismo prefijo después de quitar la firma — ¡incluso podrías hacerlo a nivel de librería!
Desde una estricta perspectiva de análisis, todos tus archivos mostrarán el mismo contenido, y las imágenes maliciosas se revelarían como un archivo con el mismo MD5 que el recopilado anteriormente.
Tomemos dos archivos:
⟷
y colisionémoslos con la misma PNG.
Ahora muestran la misma imagen ficticia, y son absolutamente idénticos hasta la 2ª imagen a nivel de archivo.
⟷
Su payload malicioso está oculto detrás de un archivo con el mismo MD5 respectivamente.
### Archivos incriminatorios
Otro caso de uso para las colisiones es ocultar algo incriminatorio dentro de algo inocente pero deseable: si lo único que se hace para recopilar pruebas es comparar hashes débiles, entonces no puedes negar que tienes el otro archivo (mostrando contenido incriminatorio pero ocultando contenido inocente).
Los softwares normalmente se centran en el análisis (rápido), no en un análisis detallado del archivo.
*una imagen que muestra diferentes vistas previas en diferentes pestañas de EnCase Forensic*
## Fallos
No todos los formatos pueden tener prefijos genéricos reutilizables:
si no se puede insertar algún tipo de contenedor de datos entre la firma mágica
y las cabeceras estándar que son críticas y específicas de cada archivo,
entonces no son posibles las colisiones genéricas.
Por supuesto, aún se podrían convertir los archivos antiguos en uno nuevo,
e incluso usar código para bifurcarse hacia dos payloads diferentes,
pero eso se parece más a portar payloads que a colisionar la estructura del archivo.
### ELF
La cabecera ELF es obligatoria en el offset 0 y contiene información crítica como 32b/64b,
endianness y ABI desde el principio,
por lo que es imposible tener un prefijo universal y luego bloques de colisión
antes de los parámetros críticos específicos del archivo original.
### Mach-O
Los archivos Mach-O ni siquiera empiezan con la misma magia para 32b (`feedface`) y 64b (`feedfacf`).
Poco después está el número y tamaño de comandos (como la definición de segmentos, symtab, versión, ...).
Al igual que con ELF, no son posibles las colisiones reutilizables.
### Java Class
Justo después de la magia inicial se encuentran las versiones (que pueden ser problemáticas),
pero el recuento del constant pool es bastante específico de cada archivo,
por lo que no hay colisiones universales para todos los archivos.
Sin embargo, muchos archivos siguen teniendo una versión común y podemos rellenar el constant pool más corto hasta igualar el recuento más largo.
Primero, inserta un *literal UTF8* para alinear la información,
luego declara otro con su longitud manipulada por un UniColl (la longitud se almacena en 16 bytes como big endian).
Sin embargo, esto requerirá manipulación del código, ya que todos los índices del pool se desplazarán.
Las colisiones MD5 reutilizables e instantáneas de Java Class deberían ser posibles, pero requieren análisis y modificación del código.
### TAR
**TL;DR** No hay colisión reutilizable para archivos TAR, ninguna otra estrategia aparte del prefijo elegido.
Los Tape Archives son una secuencia de cabeceras y contenidos de archivo concatenados, todo alineado a 512 bytes.
No hay una estructura central para todo el archivo. Así que no hay cabecera global ni comentario de ningún tipo que aprovechar.
Un truco sería iniciar un archivo ficticio de longitud variable, pero la longitud siempre está en el mismo offset, lo que no es compatible con UniColl, lo que significa que solo las colisiones de prefijo elegido son útiles aquí.
## Resumen de explotaciones
Formato | ¿Genérico? | 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 tiene algunas limitaciones en los datos que pueden mejorarse hasta cierto punto manipulando la codificación de los escaneos.
2. PDF con JPG es la [implementación inicial](http://shattered.io) del ataque Shattered, pero es solo un truco puramente de JPG en un documento PDF.
3. PNG: Safari/Preview exige que la PNG tenga su chunk `IHDR` en el primer hueco, antes de cualquier bloque de colisión. Eso impide un prefijo genérico, en cuyo caso la colisión se limita a dimensiones específicas, espacio de color, BPP e interlazado.
4. Los formatos Atom/Box como MP4 pueden funcionar con el mismo prefijo para diferentes subformatos. Algunos subformatos como JPEG2000 o HEIF requieren una preparación adicional, pero la estrategia de explotación es la misma: simplemente la colisión no es posible entre subformatos, solo con un par de prefijos para un subformato específico.
5. Atom/Box es compatible con Shattered cuando se usan longitudes de 64 bits.
6. Algunos formatos basados en Zip pueden explotarse genéricamente.
7. Para una mejor compatibilidad, ZIP necesita dos UniColl para un archivo completo, y estas colisiones dependen del contenido de ambos archivos.
## Archivos de prueba
[Aquí](https://github.com/decalage2/collisions/blob/HEAD/examples/free/README.md) tienes pares de prueba colisionantes gratuitos (libres de derechos de autor, sin datos personales).
# Referencias
Artículos:
- 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/HEAD/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) por Gregor "Greg" Kopf
- [A PDF That Shows Its Own MD5](https://archive.org/stream/pocorgtfo14#page/n49/mode/1up) por Mako
- [This GIF shows its own MD5!](https://archive.org/stream/pocorgtfo14#page/n52/mode/1up) por Kristoffer "spq" Janke
- [This PDF is an NES ROM that prints its own MD5 hash!](https://archive.org/stream/pocorgtfo14#page/n55/mode/1up) por Evan Sultanik, Evan Teran
- 2018:
- [Easy SHA-1 Colliding PDFs with PDFLaTeX.](https://archive.org/stream/pocorgtfo18#page/n62/mode/1up) por Ange Albertini
- 2020:
- [SHA-1 is a Shambles](https://eprint.iacr.org/2020/014.pdf) por Gaëtan Leurent, Thomas Peyrin
Presentaciones:
- 2017 Exploiting Hash Collisions en Black Alps:
- [diapositivas](https://speakerdeck.com/ange/exploiting-hash-collisions)
[](https://speakerdeck.com/ange/exploiting-hash-collisions)
- [vídeo](https://www.youtube.com/watch?v=Y-oJWEYKVLA)
[](https://www.youtube.com/watch?v=Y-oJWEYKVLA)
- 2019 KILL MD5 en Pass the Salt:
- [diapositivas](https://speakerdeck.com/ange/kill-md5)
[](https://speakerdeck.com/ange/kill-md5)
- [vídeo](https://passthesalt.ubicast.tv/videos/kill-md5-demystifying-hash-collisions/)
[](https://passthesalt.ubicast.tv/videos/kill-md5-demystifying-hash-collisions/)
Taller (CollTris):
- [diapositivas](https://speakerdeck.com/ange/colltris)
[](https://speakerdeck.com/ange/colltris)
- [vídeo](https://www.youtube.com/watch?v=BcwrMnGVyBI)
[](https://www.youtube.com/watch?v=BcwrMnGVyBI)
- [materiales](https://github.com/decalage2/collisions/blob/HEAD/workshop/README.md)
- sesiones
- 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
Retos CTF:
- [Prudentialv2](https://ctftime.org/task/3453), del *Boston Key Party CTF 2017*.
- [HREFIN](https://ctftime.org/task/6965), del *Google CTF 2018*.
- [Looking glass](https://ctftime.org/task/9271) del *Dragon Sector Teaser CTF 2019*.
<!-- - [Not my digest](https://ctftime.org/task/4784) from *Hack.lu CTF 2017*: not related to collisions, but solved by Marc himself :p -->
Un desafío común en este tipo de retos CTF es no dar una ventaja o desventaja demasiado grande según la cantidad de potencia de cómputo a la que tenga acceso cada jugador.
# Créditos
Todo esto fue posible gracias a [Marc Stevens](https://marc-stevens.nl/research/),
no solo por sus contribuciones criptográficas, sino también por su ayuda y sugerencias permanentes!
Gracias también a Philippe Teuwen por sus extensos comentarios sobre formatos de archivo en general.
# Conclusión
**¡Matemos a MD5!**
A menos que compruebes activamente si hay malformaciones o bloques de colisión en los archivos, ¡no uses MD5!
¡No es un hash criptográfico, es una función de juguete!
| Prefijo | = | Prefijo |
|---|
| Colisión A | ≠ | Colisión B |
| A | = | |
| = | B |