# 🎯 CTF Challenge: "Nothing Ever Changes" - HOW TO SOLVE

## TL;DR - The Solution

**You need to create MD5 collision attacks on PNG files.**

This is the ONLY way to solve this challenge because:
- ✅ Model is deterministic (confirmed via testing)
- ✅ PIL is deterministic (confirmed via testing)  
- ✅ No bugs in verification logic (checked thoroughly)
- ✅ MD5 check is strict: `img1_bytes` must equal `img2_bytes`

## The Challenge Requirement

For each of 10 pairs, create PNG files where:
```
md5(img1_bytes) == md5(img2_bytes)  ← Must be IDENTICAL
classify(img1) != classify(img2)     ← Must be DIFFERENT
```

This seems impossible... unless you can create **MD5 collisions**!

## Step-by-Step Solution

### Option 1: Use Existing MD5 Collision Tools (RECOMMENDED)

#### 1. Install HashClash
```bash
git clone https://github.com/cr-marcstevens/hashclash.git
cd hashclash
# Follow installation instructions in their README
```

#### 2. Create Adversarial Digit Images

First, create images that classify as the target digits:
- Start with reference images (src/data/refs/)
- Use adversarial attack techniques (FGSM, PGD, etc.) to modify them
- Ensure they classify as the target class

#### 3. Generate Collision Blocks

Use HashClash to create chosen-prefix collision:
```bash
# This generates collision blocks that make two different files have same MD5
./hashclash_gen --chosen-prefix prefix1.bin prefix2.bin --output collision.bin
```

#### 4. Embed in PNG Files

Modify PNG files to include collision blocks:
- Add as ancillary chunks (tEXt, iTXt, etc.)
- Or embed in IDAT chunks carefully
- Ensure both PNGs remain valid and classify correctly

### Option 2: Use Pre-existing MD5 Collision Examples

Search for existing MD5 collision examples and adapt them:
- "shattered" attack on PDF files
- Existing PNG collision examples from other CTFs
- Adapt the collision blocks to your PNG files

### Option 3: Python Script for MD5 Collision

```python
# Install required tools
# pip install pillow numpy torch torchvision

import hashlib
from pathlib import Path
from PIL import Image

# Step 1: Create adversarial examples
def create_adversarial_pair(ref_path, target_class, budget):
    """
    Create an image that:
    - Starts from reference
    - Modifies up to 'budget' pixels
    - Classifies as target_class
    """
    # Use FGSM or PGD attack here
    # Or manual pixel manipulation
    pass

# Step 2: Use MD5 collision tool
def create_md5_collision(img1_path, img2_path, output1, output2):
    """
    Use HashClash or similar to create collision
    """
    # Call external MD5 collision tool
    # Embed collision blocks in PNG chunks
    pass

# Step 3: Verify
def verify_collision(path1, path2):
    with open(path1, 'rb') as f:
        data1 = f.read()
    with open(path2, 'rb') as f:
        data2 = f.read()
    
    md5_1 = hashlib.md5(data1).hexdigest()
    md5_2 = hashlib.md5(data2).hexdigest()
    
    print(f"MD5 collision: {md5_1 == md5_2}")
    
    # Test classification
    img1 = Image.open(path1)
    img2 = Image.open(path2)
    # ... predict and compare
```

## Why This is HARD

1. **MD5 Collision Generation**: Requires significant computational resources
2. **Chosen-Prefix Collisions**: More complex than simple collisions
3. **PNG Format Constraints**: Must remain valid PNG files
4. **Classification Requirements**: Must classify correctly after modification
5. **10 Pairs**: Must repeat this process 10 times!

## Estimated Difficulty

- **CTF Points**: 400-500 points (very hard challenge)
- **Time Required**: 4-8 hours (with experience)
- **Skills Needed**: 
  - Cryptography (MD5 collisions)
  - File formats (PNG structure)
  - ML (adversarial examples)
  - Programming (automation)

## Resources

### Papers & Research
- "Chosen-Prefix Collisions for MD5 and Applications" - Marc Stevens (2009)
- "The first collision for full SHA-1" - Similar techniques
- HashClash documentation

### Tools
- **HashClash**: https://github.com/cr-marcstevens/hashclash
- **Unicoll**: Simple MD5 collision generator
- **FastColl**: Fast MD5 collision finder (identical-prefix only)

### Similar CTF Challenges
Search for:
- "MD5 collision CTF writeup"
- "HashClash PNG challenge"
- "Shattered attack CTF"

## Testing Your Solution

```bash
# 1. Create your collision PNGs for all 10 pairs
python create_collisions.py

# 2. Package them into a ZIP
zip solution.zip pair_*_img*.png

# 3. Test locally
python test_client.py solution.zip

# 4. Submit to actual server
curl -X POST http://35.245.68.223:5000/submit \
  -F "file=@solution.zip"
```

## Alternative Approaches (Less Likely)

### 1. Find a Verification Bug
- Review verification.py for logic errors
- Test edge cases
- Look for race conditions

### 2. PNG Format Tricks
- Exploit PIL parsing quirks
- Use ancillary chunks creatively
- Test with malformed PNGs

### 3. Library Bugs
- Check for version-specific bugs in PIL/PyTorch
- Test with different Python versions
- Look for non-deterministic behavior

## The "Aha!" Moment

The challenge name "**Nothing Ever Changes**" is brilliantly ironic:
- The **BYTES** don't change (same MD5 hash)
- But the **MEANING** changes (different classification)

This is the essence of:
- **MD5 collision attacks** (same hash, different content)
- **Adversarial examples** (small changes, different predictions)
- **File format exploitation** (syntax vs semantics)

## Final Tips

1. **Start Simple**: Get ONE pair working first
2. **Use Tools**: Don't try to implement MD5 collision from scratch
3. **Verify Often**: Test each step locally before submitting
4. **Read Writeups**: Look for similar challenges and learn from them
5. **Ask for Help**: If this is from an active CTF, check the Discord/forum

## Need Help?

If you're stuck:
1. Check CTF forums/Discord for hints
2. Look for similar challenge writeups
3. Study HashClash documentation
4. Consider teaming up with someone who knows crypto

**Good luck! This is a challenging but educational puzzle!** 🎯🔐🤖

---

**Local Testing**: http://localhost:5001
**Original Challenge**: http://35.245.68.223:5000
