# Evilize – MD5 Collision Walkthrough

This note explains how **evilize** can generate two programs that behave differently but share the **same MD5 hash**.

The goal is to demonstrate a **practical MD5 collision attack**.

Two binaries are created:

- `good` → benign behaviour  
- `evil` → malicious behaviour  

Even though the files are different, they will produce the **same MD5 checksum**.

---

# Overall Process

Steps involved:

1. Write a C program with **two behaviors** (`main_good()` and `main_evil()`).
2. Compile it and link it with `goodevil.o`.
3. Compute the **MD5 internal state** of the compiled program.
4. Generate **two colliding MD5 blocks**.
5. Inject the collision blocks into the executable to produce two different programs.

Result:

```
good  ≠  evil
but
MD5(good) = MD5(evil)
```

---

# Step 4 — Generate the Initialization Vector

Command:

```bash
./evilize hello-erase -i
```

What this command does:

- Reads the compiled binary `hello-erase`
- Hashes the program prefix
- Extracts the **internal MD5 state**

Example output:

```
0x23d3e487 0x3e3ea619 0xc7bdd6fa 0x2d0271e7
```

MD5 internally maintains **four 32‑bit registers**:

```
A  B  C  D
```

Together they form the **128‑bit internal state**.

These numbers represent the state of MD5 **after hashing the program prefix**.

Conceptually:

```
prefix (compiled program)
+
collision block
=
same final MD5
```

---

# Step 5 — Generate the MD5 Collision

Command:

```bash
./md5coll 0x23d3e487 0x3e3ea619 0xc7bdd6fa 0x2d0271e7 > init.txt
```

`md5coll` computes **two different blocks of data** that produce the **same MD5 state** when starting from the vector computed in Step 4.

Formally:

```
MD5(prefix + blockA) = MD5(prefix + blockB)
```

Where:

```
blockA ≠ blockB
```

The two collision blocks are saved into:

```
init.txt
```

Why does this take time?

Even though MD5 is broken, generating **controlled collisions** still requires:

- differential cryptanalysis
- large numbers of hash computations

This step may take **several hours**.

---

# Step 6 — Generate the Good and Evil Programs

Command:

```bash
./evilize hello-erase -c init.txt -g good -e evil
```

This command:

1. Takes the compiled program `hello-erase`
2. Inserts the collision blocks
3. Produces two executables:

```
good
evil
```

Internal structure:

```
good = prefix + collision_block_A + code_good
evil = prefix + collision_block_B + code_evil
```

Because of the collision:

```
MD5(good) = MD5(evil)
```

Even though the binaries differ.

---

# Why the Programs Behave Differently

Your C program defines two entry points:

```
main_good()
main_evil()
```

The helper object file `goodevil.o` contains logic that:

- reads the collision block
- determines which version is running
- calls the appropriate function

Therefore:

```
good → main_good()
evil → main_evil()
```

But both files share the **same MD5 hash**.

---

# Running Everything in One Command

Instead of steps 4–6 separately, you can run:

```bash
./evilize hello-erase -g good -e evil
```

This automatically performs:

1. initialization vector computation
2. collision generation
3. binary creation

However, splitting the steps is useful because **collision generation can take hours**.

---

# Final Verification

Check that the hashes match:

```bash
md5sum good evil
```

Example result:

```
d131dd02c5e6eec4693d9a0698aff95c good
d131dd02c5e6eec4693d9a0698aff95c evil
```

Run both programs:

```
./good
./evil
```

They will show **different behaviour**, despite having the **same MD5 hash**.

---

# Why This Matters

This experiment demonstrates why **MD5 is no longer secure**.

If MD5 is used for:

- digital signatures
- software integrity checks
- certificates

an attacker could create **two different files with the same hash**, bypassing the verification process.