length-extension-attack
Length Extension Attack
A Length Extension Attack exploits the way some cryptographic hash functions (MD5, SHA1, SHA256, etc.) process input internally.
If an application uses a hash incorrectly to “sign” data, an attacker may be able to append extra data without knowing the secret and still produce a valid signature.
This attack commonly appears when developers implement authentication like:
HASH(secret || data)
instead of using HMAC. HMAC explicitly prevents length extension.
Root Cause
Hash functions such as MD5 / SHA1 / SHA256 are based on the Merkle–Damgård construction.
Key properties:
- Hashing happens in fixed-size blocks
- Internal state is carried over block by block
- Padding is predictable and deterministic
Because of this, if an attacker knows:
HASH(secret || data)- the length of secret
- the original
data
They can compute:
HASH(secret || data || padding || attacker_data)
Without knowing
secret
Length extension attacks can lead to:
- Authentication bypass
- Privilege escalation
- Directory traversal
- Access to unauthorized files
- API parameter manipulation
Directory Traversal
Original valid request:
file = myfile.rb
sig = HASH(secret || "myfile.rb")
Attacker crafts:
file = myfile.rb[PADDING]/../anotherfile
sig = HASH(secret || "myfile.rb" || PADDING || "/../anotherfile")
Result:
- Signature still validates
- Server reads
anotherfile - Traversal bypass achieved
What the Attacker Needs
To perform the attack:
- Hash value:
HASH(secret || data) - Hash algorithm (MD5, SHA1, SHA256…)
- Length of
data - Length of
secret(or brute-force it)
If secret length is unknown, attackers simply brute-force likely sizes (e.g., 8–64 bytes).
Exploitation Tools
hash_extender
- Supports MD5, SHA1, SHA256
- Automatically computes padding
- Appends attacker-controlled data
Example usage:
hash_extender master ✗ ./hash_extender -d supersecret.rb -s f3d60a7ceefaf4bb82170a5dbee817872dad4bd2c3304b70cd4eae9428ec0b50 --append '/../key.txt' --out-data-format=html
Type: sha256
Secret length: 8
New signature: 3a2c0f9da402a17c30ad41a60a9e494055f2ab530d9bbd6a1505322fcf5f318b
New string: supersecret%2erb%80%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%b0%2f%2e%2e%2fkey%2etxt
Once we have new string and new signature, we can use it to perform directory traversal: