This challenge is vulnerable to a hash length extension attack. Here is the relevant section of the server code:```pythonletters = string.ascii_letterssecret = ''.join(random.choice(letters) for i in range(random.randint(15,35)))
def new_user():    user = "admin=False"    data = secret + user    mac = sha1(data.encode()).hexdigest()    cookie_val = user.encode().hex() + "." + mac    return cookie_val
def validate(cookie):    user_hex = cookie.split(".")[0]    user = bytes.fromhex(user_hex)    data = secret.encode() + user     cookie_mac = cookie.split(".")[1]    if cookie_mac != sha1(data).hexdigest():        raise Exception("MAC does not match!")     return ast.literal_eval(user.split(b"=")[-1].decode()) 
@app.route("/", methods=["GET"])def base():    if not request.cookies.get('auth'):        resp = make_response(render_template('index.html'))        resp.set_cookie('auth', new_user())        return resp    else:        try:            admin = validate(request.cookies.get('auth'))        except Exception as e:            flash(str(e), 'danger')            return render_template('index.html')
        if admin:            return render_template('admin.html')        else:            return render_template('index.html')```
We see that an `auth` cookie is set to the hex of `admin=False` separated by a period from the SHA1 hash of a secret between 15-35 chars prepended to `admin=False`. This is an insecure way to implement a MAC because the secret is prepended to user-controlled input (the user can send anything before the `.` and it will be decoded from hex and taken as the user identification string). This means we have a hash length extension vulnerability. 
I can't do a better job of explaining the attack than the following three blogs, so just read those if you want to understand what's happening:- https://blog.skullsecurity.org/2012/everything-you-need-to-know-about-hash-length-extension-attacks- https://journal.batard.info/post/2011/03/04/exploiting-sha-1-signed-messages- https://blog.skullsecurity.org/2014/plaidctf-web-150-mtpox-hash-extension-attack
The tool [`hash_extender`](https://github.com/iagox86/hash_extender) will do all the work for us. We just need to tell it the initial data, initial hash of that data, the length of the secret prepended to the data, the type of hash, and what we want to append. 
We want to append `=True` because of this section in the code splitting the user string: `return ast.literal_eval(user.split(b"=")[-1].decode())`. Here is an example of the output from the tool:```console$hash_extender -d="admin=False" -s="b73beb3af33ddffa4572253f464b9e44acfa4424" -f=sha1 -a "=True" -l 33Type: sha1Secret length: 33New signature: e94525e0d87e439340ee9cb5ebc39e894af5cf60New string: 61646d696e3d46616c736580000000000000000000000000000000000001603d54727565```The only thing we do not know is the length, as it is a number between 15-35. We just have to brute force it then.
Here is my solution bash script:```bash#!/bin/bash
# get initial cookieinit_cookie=$(curl -s -D - -o /dev/null http://localhost:5000 | sed -nr 's/.*auth=(.*);.*/\1/p')init_hash=$(echo $init_cookie | cut -d "." -f 2)
# brute force lengths from 15-35for i in $(seq 15 35)do    echo $i    # use hash_extender for new string and signature    out=$(/opt/tools/hash_extender/hash_extender -d="admin=False" -s=$init_hash -f=sha1 -a "=True" -l $i)    sig=$(echo $out | cut -d " " -f 8) # cut out signature from output    string=$(echo $out | cut -d " " -f 11) # cut out new string from output    cookie=$(echo "$string.$sig") # set cookie to string.signature    # make request and see if PCTF is in output    if curl -s 'http://localhost:5000' -H "Cookie: auth=$cookie" | grep "PCTF"; then        break    fidone```
Run it:
