cryptofreemedium

Protein Cookies

hackthebox

Task: Flask app with custom cookie signing using SHA-512(secret || data). Solution: Hash length extension attack to append isLoggedIn=True, exploiting parameter pollution in parse_qs.

$ ls tags/ techniques/
hash_length_extension_attackcookie_signing_bypassparse_qs_parameter_override

$ cat /etc/rate-limit

Rate limit reached (20 reads/hour per IP). Showing preview only — full content returns at the next hour roll-over.

Protein Cookies — HackTheBox

Description

Another day of flexing your muscles in the mirror and still not being satisfied with your body image. Pumped full of adrenaline and creatine, the only thing missing for you is a good workout program. We heard that the best one out there is from the Swole Eagle gym, but they've closed down the registrations because the FDA is hunting them down for the one secret that natty bodybuilders hate. With an appetite for breaking rules, and an oven full of protein cookies ready to become the post-workout treat of the day, you'll have to get the right exercise going to not waste any of that precious muscle mass building potential. Infiltrate the portal of the gym membership and get the exercise program you know you deserve!

Analysis

Application Stack

Python 2 Flask web application (Werkzeug/1.0.1, Python/2.7.18). Source code provided.

Custom Cookie Authentication

The application uses a custom cookie signing system instead of standard Flask sessions. Cookie format:

login_info = base64(data).base64(SHA512(secret || data).hexdigest())

When registering as guest, a cookie is created with data:

username=guest&isLoggedIn=False

Signing Model (models.py)

import hashlib, base64, urlparse, os secret = os.urandom(16) class session: @staticmethod def create(username, logged_in='True'): if username == 'guest': logged_in = 'False' hashing_input = 'username={}&isLoggedIn={}'.format(username, logged_in) crypto_segment = signature.create(hashing_input) return '{}.{}'.format(signature.encode(hashing_input), crypto_segment) @staticmethod def validate_login(payload): hashing_input, crypto_segment = payload.split('.') if signature.integrity(hashing_input, crypto_segment): return { k: v[-1] for k, v in urlparse.parse_qs(signature.decode(hashing_input)).items() }.get('isLoggedIn', '') == 'True' return False class signature: @staticmethod def encode(data): return base64.b64encode(data) @staticmethod def decode(data): return base64.b64decode(data) @staticmethod def create(payload, secret=secret): return signature.encode(hashlib.sha512(secret + payload).hexdigest()) @staticmethod def integrity(hashing_input, crypto_segment): return signature.create(signature.decode(hashing_input)) == crypto_segment

Routes (routes.py)

...

$ grep --similar

Similar writeups