Protein_Cookies
Exploiting a Hash Length Extension vulnerability
This challenge involves exploiting a Hash Length Extension vulnerability in a Flask web application to elevate privileges from a guest user to an authenticated member.
Vulnerability Analysis
Prefix-MAC Construction
The application’s core vulnerability lies in how it generates and validates session signatures in models.py. The signature is created by prepending a 16-byte secret to the payload and hashing it with SHA-512:
Python
# models.py
hashlib.sha512(secret + payload).hexdigest()Because SHA-512 uses the Merkle-Damgård construction, an attacker who knows the length of the secret and the original message can calculate the hash of a new message that begins with the original message and its padding.
Parameter Overriding
The session.validate_login function parses the decoded payload using urlparse.parse_qs and retrieves the last instance of isLoggedIn:
Python
# models.py
{k: v[-1] for k, v in urlparse.parse_qs(...).items()}.get('isLoggedIn', '') == 'True'By appending &isLoggedIn=True to the end of a guest session string (username=guest&isLoggedIn=False), we can override the original value.
Exploitation Process
Step 1: Identification
Upon visiting the site, a login_info cookie is issued. Decoding the first segment reveals the payload: username=guest&isLoggedIn=False. The models.py file also explicitly defines a 16-byte secret: secret = os.urandom(16).
Step 2: Generating the Forged Hash
Using the tool hash_extender, we can generate the new signature and the necessary padding for the attack. The command used was:
Bash
./hash_extender --data 'username=guest&isLoggedIn=False' \
--secret 16 \
--append '&isLoggedIn=True' \
--signature c06284311e659ef4ee30c250b14bf130f3783f8858b960105600daf60477fb78ae53a36c4e440c4028f52c4986d4a270db554fa7d16835c6ae035de15677eff1 \
--format sha512Output:
-
New signature:
f053c14b6cabcfb81732cdd0311d56263e0cf7013310474e36cee856277ce6e0b83f934b4e8a7bf6c33aa34792902a40ab4e2644eacb7a3d2ca76d75cca9f72c -
New string (hex):
757365726e616d653d67756573742669734c6f67676564496e3d46616c73658000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001782669734c6f67676564496e3d54727565
Step 3: Automated Payload Delivery
A Python script (solve.py) was used to format the attack string into the cookie format expected by the server:
-
Base64 encode the raw bytes of the new hex string.
-
Base64 encode the new signature hex string.
-
Combine them as
payload.signatureand send the request to the/programendpoint.