hashcat to crafting a length extension payload against a server-side MAC.
Step 1: Identify the Hash Algorithm
The first thing you do with any unknown hash is figure out what algorithm produced it. Hash length and character set narrow it down quickly, andhashid confirms it.
1
Check the Hash Length and Format
Most common hash algorithms produce output of a fixed, recognizable length:
If the hash starts with
$2b$, $2a$, or $2y$, it’s bcrypt. If it’s 32 hex characters, it could be MD5 or NTLM — context usually disambiguates.2
Run hashid
hashid analyses the hash format and returns a ranked list of likely algorithms. Give it the hash directly or point it at a file.-m flag prints the hashcat mode alongside each algorithm name, which saves you from looking it up separately.3
Try Online Lookups First
Before spending GPU time cracking, check crackstation.net and hashes.com. These sites maintain rainbow tables of billions of pre-computed hashes. Many CTF flags and challenge passwords appear immediately.
Step 2: Crack with hashcat
hashcat is the fastest hash cracking tool available and handles virtually every algorithm you’ll encounter in a CTF. It runs on the GPU by default, which makes it orders of magnitude faster than CPU-based tools for most algorithms.
hashcat Mode Reference
Common hashcat mode numbers
Common hashcat mode numbers
Run
hashcat --help | grep -i sha to search for a specific algorithm by name.Step 3: Crack with John the Ripper
John the Ripper (john) is more flexible than hashcat in some scenarios — it auto-detects many hash formats, handles complex file formats (ZIP, PDF, SSH keys) out of the box, and works well on CPU when a GPU isn’t available.
John format names for common algorithms
John format names for common algorithms
Step 4: Hash Length Extension Attack
This is the most technically interesting hash attack you’ll encounter in CTFs. Many applications compute a MAC like this:H is a Merkle–Damgård hash function (MD5, SHA-1, or SHA-256), secret is a server-side key, and message is attacker-controlled. The flaw: you can append extra data to message and compute a valid MAC for the extended message — without knowing secret.
Why It Works
Merkle–Damgård hashes process input in blocks. After all blocks are processed, the internal state is the hash output. If you resume hashing from that state, you continue as if you were still hashing the same stream — including the secret you never saw.1
Confirm the Vulnerability
Look for a server endpoint that accepts a
(message, mac) pair and validates it as mac == H(secret || message). The hash algorithm must be MD5, SHA-1, or SHA-256 (all Merkle–Damgård constructions). SHA-3 and HMAC are not vulnerable.2
Automate with hash_extender
hash_extender handles all the padding calculation and state manipulation for you. You need: the original message, the known valid MAC, the data you want to append, and (if known) the secret length.3
Implement It in Python (Manual Approach)
If
hash_extender isn’t available, you can implement length extension manually using a custom hash state loader.Step 5: Hash Comparison Bypasses
PHP and other loosely typed languages introduce their own class of hash vulnerabilities that have nothing to do with cracking.PHP Magic Hash (Type Juggling)
PHP Magic Hash (Type Juggling)
In PHP, the
== operator performs type coercion. If a hash string looks like a float in scientific notation (0e...), PHP converts it to 0 before comparing. Two different inputs that produce hashes starting with 0e followed only by digits will compare as equal.Hash Collision (MD5 and SHA-1)
Hash Collision (MD5 and SHA-1)
MD5 and SHA-1 are both collision-broken. You can find two different inputs that produce the same hash. In CTF challenges, this sometimes means you upload two different files with the same hash to bypass an integrity check.For SHA-1, use the SHAttered collision PDFs or
sha1collisiondetection. Generating novel SHA-1 collisions requires significant compute, so CTF challenges that use SHA-1 collisions typically provide the collision pair and ask you to exploit the application.Null Byte Truncation
Null Byte Truncation
Some older implementations pass hashes through C-string functions that stop at null bytes (This is rare in modern challenges but appears in binary exploitation scenarios where a hash comparison lives inside native code.
\x00). If you can include a null byte in your input, everything after it may be ignored.Rainbow Table Lookups
For unsalted MD5 and SHA-1 hashes of common strings, rainbow tables give you instant results. Use these resources before runninghashcat:
Salted hashes completely defeat rainbow tables. If the hash was computed as
H(salt || password) with a unique per-user salt, you must crack it directly with hashcat or John using the salt as part of the hash format. Always check whether the challenge provides a salt alongside the hash.