There are two endpoints in this challenge: `/new` and `/view`. We have to become admin to get the flag back from the server.with `/new` we can create a note. We have to provide an author and the note content. The server signs our parameters using the SHA1 algorithm, and later in `/view` checks that the signature we provided is the same. The server also adds `admin=False, access_sensitive=False, entrynum=783` as default to our parameters before signing. 
To get the flag, these parameters must be set as the following: `admin=True&access_sensitive=False&entrynum=7`It looks like we can use a hash length extension attack to add some extra parameters at the end, and overwrite admin, access_sensitive and entrynum.
I used hashpumpy to solve this. I extended the id string with `&admin=True&access_sensitive=True&entrynum=7` and set `integrity` to the new sha1 string generated by hashpumpy. One problem I had for a long time is that the server raised exceptions because we send in raw bytes that it cannot utf8 decode. Encoding the string using `unicode-escape` did the trick!
script:```pythonimport hashpumpyimport requestsfrom urllib.parse import quotefrom base64 import b64encode, b64decode
url = 'http://crypto.chal.csaw.io:5003'
res = requests.post(url + '/new', data={"author": "zup", "note": "cool"})print(res.text)
infostr = b64decode(res.text.split()[2].split(':')[0]).strip()sha1 = res.text.split()[2].split(':')[1].strip()print(sha1)print(infostr)
# Bruteforce key lengthfor i in range(256):    newsign = hashpumpy.hashpump(sha1, infostr, "&admin=True&access_sensitive=True&entrynum=7", i)    print(newsign)
    # We need to use unicode-escape because the server prints our extended string and will fail because of invalid utf8 characters    newid = newsign[1].decode('unicode-escape').encode('unicode-escape')    newsha = newsign[0]     print(newid)    print(newsha)     res = requests.post(url + '/view', data={'id': b64encode(newid), 'integrity': newsha})    print(res.text)
    if 'Note' in res.text:        break```