Hash Functions
Understand cryptographic hash functions and their properties for CTF crypto challenges.
Hash Functions
Cryptographic hash functions take arbitrary-length input and produce a fixed-length output (the hash/digest). They're fundamental to CTF crypto - for verifying inputs, generating tokens, and as building blocks for MACs and HMACs.
Hash Function Concept
Input (any length): "Hello World"
↓
[Hash Function]
↓
Output (fixed length): SHA-256 Hash (256-bit)
2a4d9a96... (64 hex chars)A hash function is a one-way function:
- Easy to compute: Hash("password") = d3c8...
- Hard to reverse: Given d3c8..., can't find the original
- Deterministic: Same input = same output every time
Core Properties
| Property | Definition | Broken When |
|---|---|---|
| Pre-image resistance | Given hash H, can't find m where H(m)=H | You can reverse the hash |
| Second pre-image resistance | Given , can't find with | You can forge an alternate input |
| Collision resistance | Can't find any with | Collisions found |
Common Hash Algorithms: Security Status
| Algorithm | Output | Status |
|---|---|---|
| MD5 | 128 bits (32 hex) | Broken - collisions trivial |
| SHA-1 | 160 bits (40 hex) | Broken - collisions found (SHAttered) |
| SHA-256 | 256 bits (64 hex) | Secure |
| SHA-512 | 512 bits (128 hex) | Secure |
| SHA-3/Keccak | Variable | Secure (different construction) |
| bcrypt | 60 chars | Secure (slow, for passwords) |
| BLAKE2 | Variable | Fast and secure |
Python Hash Generation
import hashlib
# MD5
h = hashlib.md5(b"hello").hexdigest()
print(h) # → 5d41402abc4b2a76b9719d911017c592
# SHA-256
h = hashlib.sha256(b"hello").hexdigest()
print(h) # → 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
# SHA-512
h = hashlib.sha512(b"hello").hexdigest()
# HMAC (keyed hash)
import hmac
h = hmac.new(b"secret_key", b"message", hashlib.sha256).hexdigest()MD5 Collision Attacks
MD5 collisions are computationally feasible. Two different files with the same MD5:
# Download pre-computed collision files
# from: https://md5collision.cr.yp.to/
# Verify:
md5sum file1 file2
# → same hash, different content!CTF application: bypassing MD5 equality checks
// Vulnerable: strcmp checks MD5, not content
if (md5($file1) === md5($file2) && $file1 !== $file2) {
echo "Flag: " . $flag;
}Use two MD5-colliding files that hash to the same value.
MD5 Magic Hashes (PHP Type Juggling)
In PHP with loose comparison (==), a hash starting with 0e[digits] is treated as scientific notation (equals 0 in comparison):
"0e123" == "0e456" // TRUE in PHP! Both = 0 * 10^123 = 0
md5("240610708") = "0e462097431906509019562988736854"
md5("QNKCDZO") = "0e830400451993494058024219903391"
// Both start with "0e" → PHP loose comparison says they're equal!Magic hash values for common algorithms:
| Hash / Input | Result (Magic Hash) |
|---|---|
md5("240610708") | 0e462097431906509019562988736854 |
md5("QNKCDZO") | 0e830400451993494058024219903391 |
sha1("aaroZmOk") | 0e66507019969427134894895893711890 |
sha256("34250003024812") | 0e08f71... |
Hash Extension Attack
See: Length Extension Attack page
HMAC
HMAC is not vulnerable to length extension attacks (unlike plain Hash(secret || message)):
import hmac, hashlib
# HMAC with SHA-256
mac = hmac.new(
key=b"secret_key",
msg=b"message",
digestmod=hashlib.sha256
).hexdigest()
# Verify
expected = "..."
hmac.compare_digest(mac, expected) # timing-safe comparisonBirthday Attack
In a CTF context, the birthday paradox means collision probability is much higher than expected:
For a hash of n bits, expect a collision after ~2^(n/2) attempts:
- MD5 (128 bits): ~2^64 attempts
- SHA-1 (160 bits): ~2^80 attempts
- SHA-256 (256 bits): ~2^128 attempts (infeasible)
# Finding MD5 prefix collisions (simplified)
import hashlib, random, string
target_prefix = "0000" # find input whose MD5 starts with "0000"
for _ in range(10**7):
candidate = ''.join(random.choices(string.ascii_letters, k=10))
h = hashlib.md5(candidate.encode()).hexdigest()
if h.startswith(target_prefix):
print(f"Found: {candidate} → {h}")
breakSee also
- RSA Basics - How RSA uses hashes for signatures and key derivation.
- ECC Basics - How ECC uses hashes in ECDSA and protocols.
Last updated on